cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_Slave_Receive_IT() only receives one data byte and then the slave helds the SCL line low

VRami.1
Associate III

Hi all, I'm trying to send a dat from master to a slave (the STM32F103C6) with HAL function for polling mode is working well and it is receiving all the data I send (I got all ACKs) but when I try to do the same with interrupt mode then it receives only the address and the first data byte, after that the stm32 gives me an ACK and then mantains the SCL and SDA line low, about this part after I read the I2C specification once more I noted that this behavior is normal if the slave is unable to receive more data because it is helding the SCL line low to force the master into wait state.

HAL_I2C_Slave_Receive_IT() is designed to receive the data without blocking the device as it can continue executing another piece of code while the rest of the data is being received in interruption mode but it didn't work to me.

I can see for some flags that I'm managing in the code that the functions is executing at least once and when I search for the peripheral state the I'm been notified that the I2C module is occupied by the HAL_I2C_STATE_BUSY_RX_LISTEN flag.

I've also put a function to light a led inside the isr routine but the led never lights so I suppose the interruption is never handled but I don't know what else to do here. Following is the code for the main function:

  int main(void)

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

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

  HAL_Init();

  /* Configure the system clock */

  SystemClock_Config();

  MX_GPIO_Init();

  MX_I2C1_Init();

  HAL_I2C_MspInit(&hi2c1);

  HAL_GPIO_WritePin(GPIOA,FASE6_ROJO_Pin,GPIO_PIN_SET);

  HAL_GPIO_WritePin(GPIOA,FASE6_ROJO_Pin,GPIO_PIN_SET);

  if(HAL_I2C_Slave_Receive_IT(&hi2c1, mensaje, 11) != HAL_OK)

  {

    HAL_GPIO_WritePin(GPIOA,FASE6_ROJO_Pin,GPIO_PIN_RESET);

  }

  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)

  {

  }

  switch(HAL_I2C_GetState(&hi2c1)) /* Para ver el estado del periférico I2C */

  { /* en cuando sale de las condiciones.  */

    case HAL_I2C_STATE_RESET:

    {

    HAL_GPIO_WritePin(GPIOB,FASE4_ROJO_Pin,GPIO_PIN_SET);

    } break;

    case HAL_I2C_STATE_READY:

    {

    HAL_GPIO_WritePin(GPIOB,FASE5_VERDE_Pin,GPIO_PIN_SET);

    } break;

    case HAL_I2C_STATE_BUSY:

    {

    HAL_GPIO_WritePin(GPIOB,FASE5_AMA_Pin,GPIO_PIN_SET);

    } break;

    case HAL_I2C_STATE_BUSY_TX:

    {

    HAL_GPIO_WritePin(GPIOB,FASE5_ROJO_Pin,GPIO_PIN_SET);

    } break;

    case HAL_I2C_STATE_BUSY_RX:

    {

    HAL_GPIO_WritePin(GPIOB,FASE3_AMA_Pin,GPIO_PIN_SET);

    } break;

    case HAL_I2C_STATE_LISTEN:

    {

    HAL_GPIO_WritePin(GPIOB,FASE6_VERDE_Pin,GPIO_PIN_SET);

    } break;

    case HAL_I2C_STATE_BUSY_TX_LISTEN:

    {

    HAL_GPIO_WritePin(GPIOB,FASE6_AMA_Pin,GPIO_PIN_SET);

    } break;

    default:

    {

   HAL_GPIO_WritePin(GPIOB,FASE1_VERDE_Pin,GPIO_PIN_SET);

    } break;

  }

  while (1)

  {

  }

  }

Following is the i2c initialization function:

  I2C_HandleTypeDef hi2c1;

  /* I2C1 init function */

  void MX_I2C1_Init(void)

  {

    hi2c1.Instance = I2C1;

    hi2c1.Init.ClockSpeed = 100000;

    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

    hi2c1.Init.OwnAddress1 = 34;

    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

    hi2c1.Init.OwnAddress2 = 0;

    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

    if (HAL_I2C_Init(&hi2c1) != HAL_OK)

    {

      Error_Handler();

    }

  }

Following is the i2c initialization function with the respective NVIC priority setting:

  void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)

  {

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    if(i2cHandle->Instance==I2C1)

    {  

      __HAL_RCC_GPIOB_CLK_ENABLE();

      GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

      GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

      GPIO_InitStruct.Pull = GPIO_PULLUP;

      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

      /* I2C1 clock enable */

      __HAL_RCC_I2C1_CLK_ENABLE();

      /* I2C1 interrupt Init */

      HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);

      HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);

      HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);

      HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);

    }

  }

In the HAL_Init function the group priority is set like follows to priority 4:

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

and momentarily I manually set the priority of the i2c to 5 but it doesn't worked neither.

So I need help, can anyone help me?.

Thanks in advance for the help.

0 REPLIES 0