I2C Slave clock stretching not working using HAL
Hello, I am using an STM32F103CBT as an I2C slave.
A memory buffer is to be transferred via the interface. Although hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; is set, I cannot measure clock stretching and the first byte transferred is always 0xff.
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c){
HAL_I2C_EnableListen_IT(hi2c);
}
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode){
HAL_StatusTypeDef hal_i2c_status = HAL_ERROR;
if(TransferDirection == I2C_DIRECTION_TRANSMIT){
hal_i2c_status = HAL_I2C_Slave_Sequential_Receive_IT(hi2c, i2c_rx_buffer, 1, I2C_NEXT_FRAME);
if(hal_i2c_status != HAL_OK)printf("AC Receive IT error\r\n");
}else if(TransferDirection == I2C_DIRECTION_RECEIVE){
i2c_tx_tf_cnt = 0;
hal_i2c_status = HAL_I2C_Slave_Seq_Transmit_IT(hi2c, &i2c_tx_buffer[i2c_rx_offset], 1, I2C_NEXT_FRAME);// << this always sends 0xff
if(hal_i2c_status != HAL_OK)printf("AC Transmit IT error\r\n");
}
}
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c){
i2c_rx_offset = i2c_rx_buffer[0];
}
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c){
i2c_tx_tf_cnt++;
HAL_I2C_Slave_Seq_Transmit_IT(hi2c, &i2c_tx_buffer[(i2c_rx_offset+i2c_tx_tf_cnt)], 1, I2C_NEXT_FRAME);
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){
uint32_t errorcode = HAL_I2C_GetError(hi2c);
printf("HAL_I2C_ErrorCallback: %lu\r\n",errorcode);
SET_BIT(hi2c1.Instance->CR1, I2C_CR1_SWRST);
HAL_I2C_DeInit(hi2c);
HAL_I2C_Init(hi2c);
HAL_I2C_EnableListen_IT(hi2c);
}
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c){
printf("aborted\n" ); // never seen...
}I2C Init:
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 16;
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();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
} Did I miss something?
Screenshot from Logic Analyzer. After Address read there should be clock streching until the data register ist ready and first byte should be 30 instead of FF.
