AnsweredAssumed Answered

STM32F407VG I2C HAL_I2C_ERROR_AF Error but not in SPL?

Question asked by Jeremy Vance on Jan 13, 2016
Latest reply on Jan 20, 2016 by Amel N
So, I'm trying to take the plunge into HAL with my STM32F407VG to be more "future-proof" but HAL seems to fight me at every avenue.  Today's headache: I2C.  Something that is usually pretty trivial to do has turned into just frustration.  I have dumbed this down to a newly created project in STM32CubeMX with I2C1 being used.

I'm trying to write to device 0x94, address 0x2, value 0x1.  So I try to use the following:
1.uint8_t data[2] = { 2, 1 };
2.HAL_I2C_Master_Transmit(&hi2c1, 0x94, &data[0], 2, 100);

Here are the cube's generated files for I2C:
01./* I2C1 init function */
02.void MX_I2C1_Init(void)
03.{
04. 
05.  hi2c1.Instance = I2C1;
06.  hi2c1.Init.ClockSpeed = 400000;
07.  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
08.  hi2c1.Init.OwnAddress1 = 0;
09.  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
10.  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
11.  hi2c1.Init.OwnAddress2 = 0;
12.  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
13.  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
14.  HAL_I2C_Init(&hi2c1);
15. 
16.}

and low level initialization:
01.void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
02.{
03. 
04.  GPIO_InitTypeDef GPIO_InitStruct;
05.  if(hi2c->Instance==I2C1)
06.  {
07.  /* USER CODE BEGIN I2C1_MspInit 0 */
08. 
09.  /* USER CODE END I2C1_MspInit 0 */
10.   
11.    /**I2C1 GPIO Configuration   
12.    PB8     ------> I2C1_SCL
13.    PB9     ------> I2C1_SDA
14.    */
15.    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
16.    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
17.    GPIO_InitStruct.Pull = GPIO_PULLUP;
18.    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
19.    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
20.    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
21. 
22.    /* Peripheral clock enable */
23.    __I2C1_CLK_ENABLE();
24.  /* USER CODE BEGIN I2C1_MspInit 1 */
25. 
26.  /* USER CODE END I2C1_MspInit 1 */
27.  }
28.}

Here is the code from my std periph lib program using direct register changing:
01.// Configure I2C SCL and SDA pins.
02.GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
03.GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
04.GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
05.GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
06.GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
07.GPIO_Init(GPIOB, &GPIO_InitStructure);
08. 
09.GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
10.GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
11. 
12.// Configure I2C.
13.uint32_t pclk1 = 42000000;
14. 
15.I2C1 ->CR2 = pclk1 / 1000000; // Configure frequency and disable interrupts and DMA.
16.I2C1 ->OAR1 = I2C_OAR1_ADDMODE | 0x33;
17. 
18.// Configure I2C speed in standard mode.
19.const uint32_t i2c_speed = 100000;
20.int ccrspeed = pclk1 / (i2c_speed * 2);
21.if (ccrspeed < 4) {
22.    ccrspeed = 4;
23.}
24.I2C1 ->CCR = ccrspeed;
25.I2C1 ->TRISE = pclk1 / 1000000 + 1;
26. 
27.I2C1 ->CR1 = I2C_CR1_ACK | I2C_CR1_PE; // Enable and configure the I2C peripheral.

And here is the write function for the same command:
01.while (I2C1 ->SR2 & I2C_SR2_BUSY );
02.I2C1 ->CR1 |= I2C_CR1_START; // Start the transfer sequence.
03.while (!(I2C1 ->SR1 & I2C_SR1_SB )); // Wait for start bit.
04.I2C1 ->DR = 0x94;
05.while (!(I2C1 ->SR1 & I2C_SR1_ADDR )); // Wait for master transmitter mode.
06.I2C1 ->SR2;
07.I2C1 ->DR = 0x02; // Transmit the address to write to.
08.while (!(I2C1 ->SR1 & I2C_SR1_TXE )); // Wait for byte to move to shift register.
09.I2C1 ->DR = 0x01; // Transmit the value.
10.while (!(I2C1 ->SR1 & I2C_SR1_BTF )); // Wait for all bytes to finish.
11.I2C1 ->CR1 |= I2C_CR1_STOP; // End the transfer sequence.

The std periph works great everytime.  The HAL library fails with the same error after the device address is sent HAL_I2C_ERROR_AF everytime.  Can someone tell me what I'm doing wrong here?  

I have put the same device on the logic analyzer and I get 0x94+NAK on the HAL and 0x94+ACK, 0x2, 0x1 on the Std Periph.

Thanks for any help!

Outcomes