1

I'm tring to transmit as a slave to the master with I2C in a STM32F446RE but i can't get to it.

When there is no code running on the MCU i can see the master requesting me to write on the osciloscope. But when I use this code:

if(HAL_I2C_Slave_Receive_IT(&I2CxHandle, (uint8_t*)&T2, 1)!= HAL_OK);
  while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {    }
  while(HAL_I2C_Slave_Transmit_IT(&I2CxHandle, (uint8_t*)&T1, 1)!= HAL_OK);
  while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {    }

The SDA goes high and the SCL goes low.

Also when I remove the Recieve line and add a delay at the end of about 100ms the master recieves the messages but only during a limited time (not a constant time, sometimes 3-4s and sometimes almost a second) but it shouldn't do it because it does not consider the request from the master.

Any idea? I haven't checked any flag bacause I don't know how to.

Complete Code:

/* Includes ------------------------------------------------------------------*/
#include "main.h"



#define I2C_ADDRESS        0x2E



I2C_HandleTypeDef I2CxHandle;
static GPIO_InitTypeDef  GPIO_InitStruct;


static void SystemClock_Config(void);
static void Error_Handler(void);



int main(void)
{
  HAL_Init();
  /* Configure the system clock to 180 MHz */
  SystemClock_Config();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 

  GPIO_InitStruct.Pin = GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 

  GPIO_InitStruct.Pin = GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 

  /* Configure LED2 */
  BSP_LED_Init(LED2);

  /*##-1- Configure the I2C peripheral #######################################*/
  I2CxHandle.Instance             = I2Cx;
  I2CxHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
  I2CxHandle.Init.ClockSpeed      = 100000;
  I2CxHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  I2CxHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;
  I2CxHandle.Init.GeneralCallMode = I2C_GENERALCALL_ENABLE;
  I2CxHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
  I2CxHandle.Init.OwnAddress1     = I2C_ADDRESS;
  I2CxHandle.Init.OwnAddress2     = 0;

  if(HAL_I2C_Init(&I2CxHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }


HAL_Delay(100);

  while(1)
  {

    if(HAL_I2C_Slave_Receive_IT(&I2CxHandle, (uint8_t*)&T2, 1)!= HAL_OK);
      while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {   }
      while(HAL_I2C_Slave_Transmit_IT(&I2CxHandle, (uint8_t*)&T1, 1)!= HAL_OK);
      while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {   }
      T1++;

      //HAL_Delay(100);
    }
  }

static void Error_Handler(void)
{
  /* Turn LED2 ON if error */
  //BSP_LED_On(LED2);

  while(1)
  {
  }
}

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follows: 
  *            System Clock source            = PLL (HSI)
  *            SYSCLK(Hz)                     = 180000000
  *            HCLK(Hz)                       = 180000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSI Frequency(Hz)              = 16000000
  *            PLL_M                          = 16
  *            PLL_N                          = 360
  *            PLL_P                          = 2
  *            PLL_Q                          = 7
  *            PLL_R                          = 6
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 5
  * @param  None
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  HAL_StatusTypeDef ret = HAL_OK;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();

  /* The voltage scaling allows optimizing the power consumption when the device is 
     clocked below the maximum system frequency, to update the voltage scaling value 
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /* Enable HSI Oscillator and activate PLL with HSI as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 0x10;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 360;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  RCC_OscInitStruct.PLL.PLLR = 6;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

   /* Activate the OverDrive to reach the 180 MHz Frequency */  
  ret = HAL_PWREx_EnableOverDrive();
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }

}

/**
  * @brief  I2C error callbacks
  * @param  I2cHandle: I2C handle
  * @note   This example shows a simple way to report transfer error, and you can
  *         add your own implementation.
  * @retval None
  */
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle)
{
  /* Toggle LED2: error */

  while(1)
  {
   //     BSP_LED_On(LED2);
   // HAL_Delay(500);
    //BSP_LED_Off(LED2);
    //HAL_Delay(500);
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif
Manel Vilella
  • 31
  • 1
  • 7
  • When you're using the non-blocking, interrupt based HAL functions, I would define all the HAL_I2C_*() callback functions, in order to be able to react to the interrupts (you're polling the state right now to see when the operation is finished). And make sure the interrupts are enabled. - However, to test things out, it is often much easier to work with the blocking, non-interrupt based variants of the HAL functions (i.e. HAL_I2C_Slave_Receive()/_Transmit()). If you need faster non-blocking operation, you can set up your system to use the *_IT() or even *_DMA() functions later on... – rel Jun 28 '19 at 14:28
  • Which pins are connected? Where/how are they initialized? What is `I2Cx`? – followed Monica to Codidact Jun 29 '19 at 05:45
  • Some details on @berendi 's answer: The same pin can be connected to the multiple peripherals, you can route/multiplex them via your GPIO configuration. If you're using the HAL, HAL_GPIO_Init() is used for that (see also: 'alternate function mapping' in the datasheet). - STM32CubeMX can come in handy here. - I2Cx in your sample code stands for an "instance" (memory mapped registers) of the I2C peripheral used by your program, on the SMT32F446x there are 4 I2C peripherals -> I2C1, I2C2, I2C3, I2C4... - Have you copy/pasted the code from a tutorial? It needs to be adapted I think... – rel Jun 29 '19 at 16:31

0 Answers0