Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

TWI reading and writing basics

Hello all, 

I have pinged the sensor on the "twi bus" successfully, now I am following the post on the read/write function that is needed to actually read the data off the sensor. This is what I am reading at the moment:  https://medium.com/vicara-hardware-university/setting-up-twi-on-nrf52xx-dcaf83a50baa

Indeed, I have the sensor's library , however, I am not really sure how to apply the following example and use the library.


/*
 * dev_addr -> Device address
 * reg_adddr -> Register address
 * data -> Buffer which holds data to be written
 * length -> Length of data to be written
 */
int8_t twi_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t length)
{
    uint32_t err_code;

    uint8_t buffer[255] = {0};
    buffer[0] = reg_addr;
    memcpy(&buffer[1], data, length);
    m_xfer_done = false;
    err_code = nrf_drv_twi_tx(&m_twi, dev_addr, buffer, sizeof(length), false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

   return err_code;
}

/*
 * dev_addr -> Device address
 * reg_adddr -> Register address
 * data -> Buffer where data read from TWI will be stored
 * length -> Length of data to be read
 */
int8_t twi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t length)
{
    uint32_t err_code;
    m_xfer_done = false;
    err_code = nrf_drv_twi_tx(&m_twi, dev_addr, &reg_addr, sizeof(reg_addr), true);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

    m_xfer_done = false;
    err_code = nrf_drv_twi_rx(&m_twi, dev_addr, data, length);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

    return err_code;

}

and obtain the data from the sensors registers.

BTW the library uses the i2c for the STM32 like this:

//STM32F specific I2C API call
#ifdef STM32F
	//All of the I2C API functions (For Example: HAL_I2C_Master_Transmit()) are being called from stm32f4xx_hal.h

	//hi2c1 - The variable to the I2C handler which is needed later in the Write and Read I2C function.
	//hi2c1 is defined in the stm32f4xx_hal.h and being called here via extern I2C_HandleTypeDef hi2c1;.
	extern I2C_HandleTypeDef hi2c1;

	//Master sends I2C write command via pointer *Data from the Sensor API.
	//The function returns HAL_OK (=0) when there is no error and -1 when there is an error.
	int WriteI2C_Bus(struct TransferData *Data)
	{
		//Initialization of intial Error = 0
		int Error = 0;

		//Define an array of 3 Bytes to be sent as I2C Write Command as shown in Fig. 10 in the Datasheet Page 7
		uint8_t WData[3]={Data->RegisterAddress, Data->WData[0], Data->WData[1]};

		//Send I2C Write Command as shown in Fig. 10 in the Datasheet Page 7 with Error checking.
		/*Format defined by STM:
		*HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout).
		*HAL_I2C_Master_Transmit() is used for transmitting data to the I2C device. It takes following arguments:
		*
		*I2C_HandleTypeDef *hi2c - is the pointer to the i2c handler. hi2c1 is defined in the stm32f4xx_hal.h and being called here via extern I2C_HandleTypeDef *hi2c1;.
		*uint16_t DevAddress - is the Address of the I2C device (Need to be shifted by 1 to left since the input of function expects 8 bits).
		*uint8_t *pData  - is the pointer to the data to be transmitted.
		*uint16_t Size  - is the size of the transmitted data in bytes.
		*uint32_t Timeout - timeout in millisecond in case of any error.
		*Return Error.
		*/
		Error = HAL_I2C_Master_Transmit(&hi2c1, (Data->Slave_Address)<<1, WData, 3, 100);

		//Return -1 when there is error and return HAL_OK (= 0) when no error
		if (Error != HAL_OK)
		{
			return -1;
		}
		else
		{
			return HAL_OK;
		}
	}

	//Master sends I2C Read command and save the read data via pointer *Data.
	//The function returns HAL_OK (=0) when no error and -1 when there is error.
	int ReadI2C_Bus (struct TransferData *Data)
	{
		//Initialization of intial Error = 0
		int Error = 0;

		//Send I2C Read Command as shown in Fig. 10 in the Datasheet Page 7 with Error checking.
		/*Format defined by STM:
		*HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c1, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout).
		*HAL_I2C_Mem_Read () is used for reading data from the I2C device. It has been used instead of HAL_I2C_Master_Receive() because it sends restart condition
		*while the latter which sends stop condition and thus not working. It takes following arguments:
		*
		*I2C_HandleTypeDef *hi2c - is the pointer to the i2c handler.
		*uint16_t DevAddress - is the Address of the I2C device (Need to be shifted by 1 to left since the input of function expects 8 bits).
		*uint16_t MemAddress - is the Internal memory address in the slave which is the register address.
		*uint16_t MemAddSize - the size of memory address (in Byte) which is the size of register address (In the case of Vishay's Sensor always 1 Byte).
		*uint8_t *pData  - is the pointer to the data to be received.
		*uint16_t Size  - is the size of the received data in bytes.
		*uint32_t Timeout - timeout in millisecond in case of any error.
		*Return Error.
		*
		*/
		Error = HAL_I2C_Mem_Read(&hi2c1, (Data->Slave_Address)<<1, Data->RegisterAddress, 1,Data->RData,2,100);

		//Return -1 when there is error and return HAL_OK (= 0) when no error
		if (Error !=HAL_OK)
		{
			return -1;
		}
		else
		{
			return HAL_OK;
		}
	}

	//Master sends I2C Gesture Read command and save the read data via pointer *Data.
	//The function returns HAL_OK (=0) when no error and -1 when there is error.
    int ReadI2C_Bus_Gesture_Mode(struct GestureTransferData *Data)
	{
		//Initialization of intial Error = 0
		int Error = 0;

		//Send I2C Gesture Read Command as shown in the Application Note Page 19 with Error checking.
		/*Format defined by STM:
		*HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout).
		*HAL_I2C_Master_Receive () is used for reading data from the I2C device. It has been used instead of HAL_I2C_Mem_Read() because no restart condition is *needed.
		*It takes following arguments:
		*
		*I2C_HandleTypeDef *hi2c - is the pointer to the i2c handler. hi2c1 is defined in the stm32f4xx_hal.h and being called here via extern I2C_HandleTypeDef *hi2c1;.
		*uint16_t DevAddress - is the Address of the I2C device (Need to be shifted by 1 to left since the input of function expects 8 bits).
		*uint8_t *pData  - is the pointer to the data to be received.
		*uint16_t Size  - is the size of the received data in bytes (For Gesture Stream 6 Bytes are needed).
		*uint32_t Timeout - timeout in millisecond in case of any error.
		*Return Error.
		*
		*/
		Error = HAL_I2C_Master_Receive(&hi2c1,(Data->Slave_Address)<<1,Data->RData,6,100);

		//Return -1 when there is error and return HAL_OK (= 0) when no error
		if (Error != HAL_OK)
		{
			return -1;
		}
		else
		{
			return HAL_OK;
		}
	}
#endif

So, I need to port the nrf twi and its sdk, right ? to eventually use the library with the nrf52dk?

In addition, I would like to use the pooling rather than interrupt. I guess as well this is done in the main() but within the while(true) loop?

Any ideas, example how to do, approach this?

Best.

PS yeah , I am new to this, just realized that I should write the code to read off the sensor in the while (true) loop :) where I am now printing text , juhej! 

Related