cancel
Showing results for 
Search instead for 
Did you mean: 

Connect to TLV493D-A1B6 over I2C

Jiimmy
Associate II

Hi folks

I am currently trying to communicate with the TLV493D-A1B6 3D hall sensor. As board, I'm using the NUCLEO-F103RB. To make sure I didn't mess up any connections or anything else, I verified my setup with an ADS1015 adc which I can read out over I2C. Unfortunately, I am not able to find a valid address whilst sweeping through all possible addresses. I always get "HAL_ERROR" after using the following routine. With my other I2C device, I get 3 valid addresses.

	for(i=1; i<255; i++)
    {
        ret = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i<<1), 3, 5);
        if (ret != HAL_OK) /* No ACK Received At That Address */
        {
            HAL_UART_Transmit(&huart1, Space, sizeof(Space), 10000);
        }
        else if(ret == HAL_OK)
        {
            sprintf(Buffer, "0x%X", i);
            HAL_UART_Transmit(&huart1, Buffer, sizeof(Buffer), 10000);
        }
    }

For further information, any data sheets are available here: https://www.infineon.com/cms/en/product/sensor/magnetic-sensors/magnetic-position-sensors/3d-magnetics/tlv493d-a1b6/

Thanks a lot for your help and best regards

1 ACCEPTED SOLUTION

Accepted Solutions
Jiimmy
Associate II

Here I am again. My code works now :D

As described in the data sheet, the I2C communication can only start after the SCL interrupt, driven by the slave, is over. I currently fixed this issue by starting the first read command after I receive an interrupt on the SCL line. After that, I disable the INT bit in the register 0x11. With this setting, I can receive data with the following command:

HAL_I2C_Master_Receive_IT(&hi2c1, ADDRESS, rbuffer, sizeof(rbuffer));

0693W00000KdZNmQAN.png

View solution in original post

5 REPLIES 5
Jiimmy
Associate II

It seems to be a hardware issue. I am currently working on it to figure out what exactly the problem is.

Jiimmy
Associate II

Unfortunately, I still did not figure out what exactly the error is. I managed to communicate with my sensor over I2C with an Arduino UNO board. Whilst using my ST Board, I observed that my sensor is pulling down the SCL line periodical. When I disconnect the SCL line to the sensor it, everything is fine, except the ACK is not sent, because my sensor has obviously no CLK.

I also try to change the GPIO mode, which did not realy help because it seems like the slave can not pull down the data line:

GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;	
 
// changed to
 
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;	

I would appreciate any help or hints.

Jiimmy
Associate II

Here I am again. My code works now :D

As described in the data sheet, the I2C communication can only start after the SCL interrupt, driven by the slave, is over. I currently fixed this issue by starting the first read command after I receive an interrupt on the SCL line. After that, I disable the INT bit in the register 0x11. With this setting, I can receive data with the following command:

HAL_I2C_Master_Receive_IT(&hi2c1, ADDRESS, rbuffer, sizeof(rbuffer));

0693W00000KdZNmQAN.png

Hi! I am relatively new to the stm32 world, and after making it through a few blinky exercises, I would like to try writing a driver for this sensor. 

Something that befuddles me about this particular sensor is its use of the SCL line as an interrupt line. I'm trying to figure out how to successfully read from the sensor, and I think I'm a few steps behind where you were at when you wrote this post. 

So far, I have set up my i2c SDA/SCL lines, and can successfully configure the sensor. But I think I need to also enable a GPIO exti interrupt on the SCL line, to trigger an interrupt on the falling edge before I initiate any i2c transactions to read sensor data.

CubeMX does not seem to allow me to set up the SCL pin as a GPIO interrupt as well (or, at least, I can't figure out how to do it), which I think means I need to be doing some hand-coding here, and this is where I'm getting a bit lost in understanding the NVIC table, the various exti lines, etc. 

Would you be able to offer some high-level tips on how you got this working? Like, so far I am trying to:

  • configure my SCL pin to also have exti interrupts, like so:

 

GPIO_InitTypeDef I2C_SCL_INTERRUPT_struct = {0};

// Configure I2C SCL pin for EXTI functionality
I2C_SCL_INTERRUPT_struct.Pin = I2C1_SCL_Pin; // our SCL pin
I2C_SCL_INTERRUPT_struct.Mode = GPIO_MODE_IT_FALLING; // Trigger on falling edge
I2C_SCL_INTERRUPT_struct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(I2C1_SCL_GPIO_Port, &I2C_SCL_INTERRUPT_struct);

 

  • Then, I think I need to configure the tvl493d sensor (enable temperature measurement, set parity bit, etc). 
  • After configuration, theoretically the sensor is now firing interrupts every so often, in which case I need to receive those, disable the interrupt (you mention doing this at the register level), read out data, then re-enable the interrupt. This part is where I'm getting lost. 

Is this in the right ballpark? I worry I'm overcomplicating things and missing something obvious here; cubeMX is so useful and nice, but it feels like I'm coloring a bit outside the lines with this sensor and am getting confused. 

 

sb_st
Associate III

It seems the above strategy doesn't work - when I initialize my i2c1 bus and then initialize my GPIO (PB6) as above, I get HAL_BUSY when trying to communicate with the sensor. Other posts on this forum suggest this is because I'm trying to use two peripherals on the same pin, and indeed when I remove the above GPIO init code, I can communicate with the sensor fine (which is to say: I can reset and initialize its registers; however it's still unclear to me how I can properly 'detect' the SCL line being pulled low by the sensor as an interrupt).