/**
 * @brief Resets the MPU6000 FIFO from an ISR
 * @param woken[in,out] If non-NULL, will be set to true if woken was false and a higher priority
 *                      task has is now eligible to run, else unchanged
 * @return  0 if operation was successful
 * @return -1 if unable to claim SPI bus
 * @return -2 if write to the device failed
 */
static int32_t PIOS_MPU6000_ResetFifoISR(bool *woken)
{
    int32_t result = 0;

    /* Register writes must be at < 1MHz SPI clock.
     * Speed can only be changed when SPI bus semaphore is held, but
     * device chip select must not be enabled, so we use the direct
     * SPI bus claim call here */
    if (PIOS_SPI_ClaimBusISR(dev->spi_id, woken) != 0) {
        return -1;
    }
    /* Reduce SPI clock speed. */
    PIOS_SPI_SetClockSpeed(dev->spi_id, PIOS_SPI_PRESCALER_256);
    /* Enable chip select */
    PIOS_SPI_RC_PinSet(dev->spi_id, dev->slave_num, 0);
    /* Reset FIFO. */
    if (PIOS_SPI_TransferByte(dev->spi_id, 0x7f & PIOS_MPU6000_USER_CTRL_REG) != 0) {
        result = -2;
    } else if (PIOS_SPI_TransferByte(dev->spi_id, (dev->cfg->User_ctl | PIOS_MPU6000_USERCTL_FIFO_RST)) != 0) {
        result = -2;
    }
    /* Disable chip select. */
    PIOS_SPI_RC_PinSet(dev->spi_id, dev->slave_num, 1);
    /* Increase SPI clock speed. */
    PIOS_SPI_SetClockSpeed(dev->spi_id, PIOS_SPI_PRESCALER_16);
    /* Release the SPI bus semaphore. */
    PIOS_SPI_ReleaseBusISR(dev->spi_id, woken);
    return result;
}
Example #2
0
/**
 * @brief Writes one byte to the MPU9250 register
 * \param[in] reg Register address
 * \param[in] data Byte to write
 * @returns 0 when success
 */
static int32_t PIOS_MPU9250_WriteReg(uint8_t reg, uint8_t data)
{
	if (PIOS_MPU9250_ClaimBus(true) != 0)
		return -1;

	PIOS_SPI_TransferByte(dev->spi_id, 0x7f & reg);
	PIOS_SPI_TransferByte(dev->spi_id, data);

	PIOS_MPU9250_ReleaseBus(true);

	return 0;
}
Example #3
0
/**
 * @brief Write a BMA180 register.  EEPROM must be unlocked before calling this function.
 * @return none
 * @param reg[in] address of register to be written
 * @param data[in] data that is to be written to register
 */
int32_t PIOS_BMA180_SetReg(uint8_t reg, uint8_t data)
{
	if(PIOS_BMA180_ClaimBus() != 0)
		return -1;
	
	PIOS_SPI_TransferByte(dev->spi_id, 0x7f & reg);
	PIOS_SPI_TransferByte(dev->spi_id, data);

	PIOS_BMA180_ReleaseBus();
	
	return 0;
}
Example #4
0
/**
 * @brief Writes one byte to the L3GD20
 * \param[in] reg Register address
 * \param[in] data Byte to write
 * \return 0 if operation was successful
 * \return -1 if unable to claim SPI bus
 * \return -2 if unable to claim i2c device
 */
static int32_t PIOS_L3GD20_SetReg(uint8_t reg, uint8_t data)
{
	if (PIOS_L3GD20_ClaimBus() != 0)
		return -1;

	PIOS_SPI_TransferByte(pios_l3gd20_dev->spi_id, 0x7f & reg);
	PIOS_SPI_TransferByte(pios_l3gd20_dev->spi_id, data);

	PIOS_L3GD20_ReleaseBus();

	return 0;
}
Example #5
0
/**
 * @brief Read a register from MPU6000
 * @returns The register value or -1 if failure to get bus
 * @param reg[in] Register address to be read
 */
static int32_t PIOS_MPU6000_GetReg(uint8_t reg)
{
	uint8_t data;

	if (PIOS_MPU6000_ClaimBus() != 0)
		return -1;

	PIOS_SPI_TransferByte(pios_mpu6000_dev->spi_id, (0x80 | reg)); // request byte
	data = PIOS_SPI_TransferByte(pios_mpu6000_dev->spi_id, 0);     // receive response

	PIOS_MPU6000_ReleaseBus();
	return data;
}
/**
 * @brief Reads the contents of the MPU6000 Interrupt Status register from an ISR
 * @return The register value or -1 on failure to claim the bus
 */
static int32_t PIOS_MPU6000_GetInterruptStatusRegISR(bool *woken)
{
    /* Interrupt Status register can be read at high SPI clock speed */
    uint8_t data;

    if (PIOS_MPU6000_ClaimBusISR(woken) != 0) {
        return -1;
    }
    PIOS_SPI_TransferByte(dev->spi_id, (0x80 | PIOS_MPU6000_INT_STATUS_REG));
    data = PIOS_SPI_TransferByte(dev->spi_id, 0);
    PIOS_MPU6000_ReleaseBusISR(woken);
    return data;
}
Example #7
0
/**
 * @brief Read a register from MPU9250
 * @returns The register value
 * @param reg[in] Register address to be read
 */
static uint8_t PIOS_MPU9250_ReadReg(uint8_t reg)
{
	uint8_t data;

	PIOS_MPU9250_ClaimBus(true);

	PIOS_SPI_TransferByte(dev->spi_id, 0x80 | reg); // request byte
	data = PIOS_SPI_TransferByte(dev->spi_id, 0);   // receive response

	PIOS_MPU9250_ReleaseBus(true);

	return data;
}
Example #8
0
/**
 * @brief Read a register from L3GD20 from ISR context
 * @returns The register value or -1 if failure to get bus
 * @param reg[in] Register address to be read
 * \param[in] task woken
 */
static int32_t PIOS_L3GD20_GetRegIsr(uint8_t reg, bool *woken)
{
	uint8_t data;

	if(PIOS_L3GD20_ClaimBusIsr(woken) != 0)
		return -1;

	PIOS_SPI_TransferByte(dev->spi_id,(0x80 | reg) ); // request byte
	data = PIOS_SPI_TransferByte(dev->spi_id,0 );     // receive response

	PIOS_L3GD20_ReleaseBusIsr(woken);
	return data;
}
Example #9
0
/**
 * @brief Read a register from BMA180
 * @returns The register value or -1 if failure to get bus
 * @param reg[in] Register address to be read
 */
int32_t PIOS_BMA180_GetReg(uint8_t reg)
{
	if(PIOS_BMA180_Validate(dev) != 0)
		return -1;

	uint8_t data;
	
	if(PIOS_BMA180_ClaimBus() != 0)
		return -1;	

	PIOS_SPI_TransferByte(dev->spi_id,(0x80 | reg) ); // request byte
	data = PIOS_SPI_TransferByte(dev->spi_id,0 );     // receive response
	
	PIOS_BMA180_ReleaseBus();
	return data;
}
Example #10
0
/**
 * @brief Writes one byte to the MPU6000
 * \param[in] reg Register address
 * \param[in] data Byte to write
 * \return 0 if operation was successful
 * \return -1 if unable to claim SPI bus
 * \return -2 if unable to claim i2c device
 */
static int32_t PIOS_MPU6000_SetReg(uint8_t reg, uint8_t data)
{
	if (PIOS_MPU6000_ClaimBus() != 0)
		return -1;

	if (PIOS_SPI_TransferByte(pios_mpu6000_dev->spi_id, 0x7f & reg) != 0) {
		PIOS_MPU6000_ReleaseBus();
		return -2;
	}

	if (PIOS_SPI_TransferByte(pios_mpu6000_dev->spi_id, data) != 0) {
		PIOS_MPU6000_ReleaseBus();
		return -3;
	}

	PIOS_MPU6000_ReleaseBus();

	return 0;
}
Example #11
0
enum opahrs_result PIOS_OPAHRS_resync(void)
{
	struct opahrs_msg_v1 req;
	struct opahrs_msg_v1 rsp;

	enum opahrs_result rc = OPAHRS_RESULT_FAILED;

	opahrs_msg_v1_init_link_tx(&req, OPAHRS_MSG_LINK_TAG_NOP);

	PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 0);
#ifdef PIOS_INCLUDE_FREERTOS
	vTaskDelay(MS2TICKS(1));
#else
	PIOS_DELAY_WaitmS(20);
#endif

	for (uint32_t i = 0; i < sizeof(req); i++) {
		/* Tx a shortened (by one byte) message to walk through all byte positions */
		opahrs_msg_v1_init_rx(&rsp);
		PIOS_SPI_TransferBlock(PIOS_OPAHRS_SPI, (uint8_t *) & req, (uint8_t *) & rsp, sizeof(req) - 1, NULL);

		/* Good magic means we're sync'd */
		if ((rsp.head.magic == OPAHRS_MSG_MAGIC_HEAD) && (rsp.tail.magic == OPAHRS_MSG_MAGIC_TAIL)) {
			/* We need to shift out one more byte to compensate for the short tx */
			PIOS_SPI_TransferByte(PIOS_OPAHRS_SPI, 0x00);
			rc = OPAHRS_RESULT_OK;
			break;
		}
#ifdef PIOS_INCLUDE_FREERTOS
		vTaskDelay(MS2TICKS(1));
#else
		PIOS_DELAY_WaitmS(10);
#endif
	}

	PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 1);
	//vTaskDelay(MS2TICKS(5));

	return rc;
}
Example #12
0
/**
 * @brief Write one page of data (up to 256 bytes) aligned to a page start
 * @param[in] addr Address in flash to write to
 * @param[in] data Pointer to data to write to flash
 * @param[in] len Length of data to write (max 256 bytes)
 * @return Zero if success or error code
 * @retval -1 Unable to claim SPI bus
 * @retval -2 Size exceeds 256 bytes
 * @retval -3 Length to write would wrap around page boundary
 */
static int32_t PIOS_Flash_Jedec_WriteData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
{
	struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;

	if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
		return -1;

	uint8_t ret;
	uint8_t out[4] = {JEDEC_PAGE_WRITE, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff};

	/* Can only write one page at a time */
	if (len > 0x100)
		return -2;

	/* Ensure number of bytes fits after starting address before end of page */
	if (((addr & 0xff) + len) > 0x100)
		return -3;

	if ((ret = PIOS_Flash_Jedec_WriteEnable(flash_dev)) != 0)
		return ret;

	/* Execute write page command and clock in address.  Keep CS asserted */
	if (PIOS_Flash_Jedec_ClaimBus(flash_dev) != 0)
		return -1;

	if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
		PIOS_Flash_Jedec_ReleaseBus(flash_dev);
		return -1;
	}

	/* Clock out data to flash */
	if (PIOS_SPI_TransferBlock(flash_dev->spi_id,data,NULL,len,NULL) < 0) {
		PIOS_Flash_Jedec_ReleaseBus(flash_dev);
		return -1;
	}

	PIOS_Flash_Jedec_ReleaseBus(flash_dev);

	// Keep polling when bus is busy too
#if defined(FLASH_FREERTOS)
	while (PIOS_Flash_Jedec_Busy(flash_dev) != 0) {
		vTaskDelay(1);
	}
#else

	// Query status this way to prevent accel chip locking us out
	if (PIOS_Flash_Jedec_ClaimBus(flash_dev) < 0)
		return -1;

	PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS);
	while (PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS) & JEDEC_STATUS_BUSY);

	PIOS_Flash_Jedec_ReleaseBus(flash_dev);

#endif
	return 0;
}

/**
 * @brief Write multiple chunks of data in one transaction
 * @param[in] addr Address in flash to write to
 * @param[in] data Pointer to data to write to flash
 * @param[in] len Length of data to write (max 256 bytes)
 * @return Zero if success or error code
 * @retval -1 Unable to claim SPI bus
 * @retval -2 Size exceeds 256 bytes
 * @retval -3 Length to write would wrap around page boundary
 */
static int32_t PIOS_Flash_Jedec_WriteChunks(uintptr_t flash_id, uint32_t addr, struct pios_flash_chunk chunks[], uint32_t num)
{
	struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;

	if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
		return -1;

	uint8_t ret;
	uint8_t out[4] = {JEDEC_PAGE_WRITE, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff};

	/* Can only write one page at a time */
	uint32_t len = 0;
	for (uint32_t i = 0; i < num; i++)
		len += chunks[i].len;

	if (len > 0x100)
		return -2;

	/* Ensure number of bytes fits after starting address before end of page */
	if (((addr & 0xff) + len) > 0x100)
		return -3;

	if ((ret = PIOS_Flash_Jedec_WriteEnable(flash_dev)) != 0)
		return ret;

	/* Execute write page command and clock in address.  Keep CS asserted */
	if (PIOS_Flash_Jedec_ClaimBus(flash_dev) != 0)
		return -1;

	if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
		PIOS_Flash_Jedec_ReleaseBus(flash_dev);
		return -1;
	}

	for (uint32_t i = 0; i < num; i++) {
		struct pios_flash_chunk * chunk = &chunks[i];

		/* Clock out data to flash */
		if (PIOS_SPI_TransferBlock(flash_dev->spi_id,chunk->addr,NULL,chunk->len,NULL) < 0) {
			PIOS_Flash_Jedec_ReleaseBus(flash_dev);
			return -1;
		}

	}
	PIOS_Flash_Jedec_ReleaseBus(flash_dev);

	// Skip checking for busy with this to get OS running again fast

	return 0;
}

/**
 * @brief Read data from a location in flash memory
 * @param[in] addr Address in flash to write to
 * @param[in] data Pointer to data to write from flash
 * @param[in] len Length of data to write (max 256 bytes)
 * @return Zero if success or error code
 * @retval -1 Unable to claim SPI bus
 */
static int32_t PIOS_Flash_Jedec_ReadData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
{
	struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;

	if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
		return -1;

	if (PIOS_Flash_Jedec_ClaimBus(flash_dev) == -1)
		return -1;

	/* Execute read command and clock in address.  Keep CS asserted */
	uint8_t out[] = {JEDEC_READ_DATA, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff};

	if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
		PIOS_Flash_Jedec_ReleaseBus(flash_dev);
		return -2;
	}

	/* Copy the transfer data to the buffer */
	if (PIOS_SPI_TransferBlock(flash_dev->spi_id,NULL,data,len,NULL) < 0) {
		PIOS_Flash_Jedec_ReleaseBus(flash_dev);
		return -3;
	}

	PIOS_Flash_Jedec_ReleaseBus(flash_dev);

	return 0;
}

/* Provide a flash driver to external drivers */
const struct pios_flash_driver pios_jedec_flash_driver = {
	.start_transaction = PIOS_Flash_Jedec_StartTransaction,
	.end_transaction   = PIOS_Flash_Jedec_EndTransaction,
	.erase_chip        = PIOS_Flash_Jedec_EraseChip,
	.erase_sector      = PIOS_Flash_Jedec_EraseSector,
	.write_chunks      = PIOS_Flash_Jedec_WriteChunks,
	.write_data        = PIOS_Flash_Jedec_WriteData,
	.read_data         = PIOS_Flash_Jedec_ReadData,
};