cancel
Showing results for 
Search instead for 
Did you mean: 

HAL I2C Interrupt code does not work on STM32F072

Mike Panetta
Associate II
Posted on October 09, 2017 at 19:27

I have been trying to get this to work for a few days now, read over several topics here and nothing I have tried has worked...

I tried all the suggestions here as well

https://community.st.com/0D50X00009XkXWwSAN

nothing helps.

I am trying to use the I2C HAL in slave mode, and none of the callbacks get called.  I turn an LED on in I2C1_IRQHandler but none of the callbacks seem to get called.  Also, even after resetting the CPU the code acts as if there is data ready to be read even before I start a transaction.

Start.

Get Data? 0, 2

WHILE: Wait for I2C: 22

WHILE: Wait for I2C: 22

WHILE: Wait for I2C: 22

Code below:

/**

* @brief This function handles I2C1 event global interrupt / I2C1 wake-up interrupt through EXTI line 23.

*/

void I2C1_IRQHandler(void)

{

  /* USER CODE BEGIN I2C1_IRQn 0 */

  HAL_GPIO_WritePin(PWR_LED_GPIO_Port, PWR_LED_Pin, 1);  // LED Turns on here - as expected

  /* USER CODE END I2C1_IRQn 0 */

  if (hi2c1.Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {

    HAL_I2C_ER_IRQHandler(&hi2c1);

    HAL_GPIO_WritePin(PWR_LED_GPIO_Port, PWR_LED_Pin, 0); // NO errors so LED stays on.

  } else {

    HAL_I2C_EV_IRQHandler(&hi2c1);

  }

  /* USER CODE BEGIN I2C1_IRQn 1 */

  /* USER CODE END I2C1_IRQn 1 */

}

int main(void)

{

  /* USER CODE BEGIN 1 */

  char buf[64];

  int ret;

  char buffer[128];

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */

  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_I2C1_Init();

  MX_USART2_UART_Init();

  /* Initialize interrupts */

  MX_NVIC_Init();

  /* USER CODE BEGIN 2 */

  snprintf(buffer, 128, 'Start.\r\n');

  HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000);

  while ((ret = HAL_I2C_GetState(&hi2c1)) != HAL_I2C_STATE_READY)

  {

    snprintf(buffer, 128, 'Wait for I2C: %x\r\n', ret);

    HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000);

    HAL_Delay(1000);

  }

  //ret = HAL_I2C_Slave_Receive_IT(&hi2c1, buf, sizeof(buf));

  /* USER CODE END 2 */

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

    HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);

    HAL_Delay(100);

    ret = HAL_I2C_Slave_Receive_IT(&hi2c1, buf, 1); // Always returns data even if I never did an I2C transcation.

    snprintf(buffer, 128, 'Get Data? %d, %x\r\n', ret, buf[0]);

    HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000);

    while ((ret = HAL_I2C_GetState(&hi2c1)) != HAL_I2C_STATE_READY)

    { // code gets stuck here forever

      snprintf(buffer, 128, 'WHILE: Wait for I2C: %x\r\n', ret);

      HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000);

      HAL_Delay(1000);

    }

    //ret = HAL_I2C_Slave_Receive(&hi2c1, buf, sizeof(buf), 100);

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }

  /* USER CODE END 3 */

}

Has anyone got Interrupt driven I2C Slave to work with STM32Cube?  Most of the questions/discussions I have read here seem to have not been solved...  Should I just switch to another serial interface, or processor?

Any help greatly appreciated.

Thanks,

Mike

null
5 REPLIES 5
Posted on October 09, 2017 at 20:03

>>Should I just switch to another serial interface, or processor?

Depends on what problem is being solved, and why I2C is the right answer.

A board-to-board messaging protocol might be better using something less archaic, like CAN

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 09, 2017 at 20:54

Hello Mike.

ret = HAL_I2C_Slave_Receive_IT(&hi2c1, buf, 1); // Always returns data even if I never did an I2C transcation.

HAL_I2C_Slave_Receive_IT, returns immediately with no valid data. When data received, the weak function HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) called .

So you can define your HAL_I2C_SlaveRxCpltCallback function and wait to be called when slave address transmitted from master mached and data received succesfully.

HAL_I2C_Slave_Receive, in opposite, waits(not returns) until data received.

Posted on October 09, 2017 at 20:09

In this case it is for communication between a Hikey ARM SBC running AOSP and an I/O board with the STM32 processor.  My available choices would be I2C/SMBUS, SPI and U(S)ART.  I was hoping I2C would work, was going to treat the I/O processor like an EEPROM/RAM.  I've never had these kinds of issues before with I2C, I think they are specific to either the STM32 chip or the HAL...

Thanks,

Mike

Posted on October 09, 2017 at 20:47

The ST I2C peripheral implementation is an overly complicated monster, that's for sure.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 09, 2017 at 21:32

Thanks for the reply.

I didn't paste it above, but I do have that routine.  It never gets called though

:(

/* USER CODE BEGIN 0 */

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef * hi2c)

{

  char buffer[128];

  snprintf(buffer, 128, 'HAL_I2C_SlaveRxCpltCallback(%p)\r\n', hi2c);

  HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000);

}

/* USER CODE END 0 */

I never see that print message.  Quite frustrating...

Thanks,

Mike