В общем раскурил я эту историю.... Работает. Но вопросов только прибавилось.
Нашел вот такую статью
https://community.st.com/s/article/how- ... be-libraryСобственно ей руководстовался....
Оказалось разрешать прерывания, т.е. вызывать
HAL_I2C_EnableListen_IT(&hi2c1) надо после каждого запроса на прием/передачу.
Что сделал что бы заработало:
1. Функция
HAL_I2C_AddrCallback выглядит вот так. Как я понял это call back котороя вызывается когда мастер на шине выставляет адрес ведомого
Код:
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {
uint8_t test_buf[] = "Hello ESP-12F";
if (TransferDirection == I2C_DIRECTION_RECEIVE) {
HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, (uint8_t *) test_buf, 13, I2C_FIRST_AND_LAST_FRAME);
} else {
HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, (uint8_t *) test_buf, 11, I2C_FIRST_AND_LAST_FRAME);
}
}
2. Вот так вылядит основной цикл main который по флагу завершения передачи разрешате прерывания Xfer_Complete
Код:
HAL_I2C_EnableListen_IT(&hi2c1);
while (1) {
if (Xfer_Complete == 1) {
HAL_Delay(1);
HAL_I2C_EnableListen_IT(&hi2c1);
Xfer_Complete = 0;
}
}
3. Еще две call back функции которые выставляют флаг окончания передачи
Код:
extern __IO uint32_t Xfer_Complete;
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) {
Xfer_Complete = 1;
}
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *I2cHandle) {
Xfer_Complete = 1;
}
Все этого достаточно что бы все заработало. Сейчас картинка обмена на шине с логического анализатора выглядит вот так:

Теперь чего я не понимаю и буду благодарен за подсказку куда смотреть.....
1. В главном цикле перед тем как разрешить прерывания (после того как call back функция об окончание передачи была вызвана) приходиться делать паузу 1 млс. Без этого не работает.... Почему? Из за этого ведущему приходиться делать паузу между запросами в 2млс. что бы все гарантировано работало....
2. Почему нельзя разрешить прерывания прямо в call back функции? Например вот так:
Код:
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) {
Xfer_Complete = 1;
HAL_Delay(1);
HAL_I2C_EnableListen_IT(&hi2c1);
}
Так не работает...
3. Ну и совсем не объясимо для меня...
Код:
uint8_t aTxBuffer[32];
uint8_t aRxBuffer[32];
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {
uint8_t test_buf[] = "Hello ESP-12F";
if (TransferDirection == I2C_DIRECTION_RECEIVE) {
HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, (uint8_t *) test_buf, 13, I2C_FIRST_AND_LAST_FRAME);
} else {
HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, (uint8_t *) test_buf, 11, I2C_FIRST_AND_LAST_FRAME);
}
}
Обратите внимание, что в функциях HAL_I2C_Slave_Seq_Transmit_IT и HAL_I2C_Slave_Seq_Receive_IT используется локально объявленная еремення test_buf.
Так работает.....
Если использовать глобальные переменные aTxBuffer и aRxBuffer то контроллер уходит в непрерывную перезагрузку.... Почему?