В настоящее время я работаю над проектом с использованием микроконтроллера STM32H723VE и столкнулся с проблемой с периферийными устройствами SAI1.
До сих пор SAI4 в режиме подчиненной передачи и I2S1 в режиме подчиненного приема работают правильно. SAI4 использует RAM D3, SAI1 и I2S используют RAM D2 через DMA. Однако когда я добавляю в код SAI1 в режиме подчиненной передачи, все операции DMA для SAI4 и I2S1 перестают работать. Когда я отключаю DMA для SAI1, все снова начинает работать. Для всех DMA ширина данных настроена на «слово», а их режим установлен на «циклический».
Я попытался отладить код и вот что я заметил:
Точный момент возникновения проблемы — это когда HAL_SAI_Transmit_DMA(&hsai_BlockA1...) : переключается с
/* Process Unlocked */
__HAL_UNLOCK(hsai);
к
return HAL_OK;
}
который находится в конце функции HAL_SAI_Transmit_DMA(&hsai_BlockA1...).
Фрагменты кода:
Ниже показано распределение оперативной памяти для DMA в файле .._FLASH.ld:
.dma_d2_buffer : /* Space before ':' is critical */
{
*(.dma_d2_buffer)
} >RAM_D2
.dma_d3_buffer : /* Space before ':' is critical */
{
*(.dma_d3_buffer)
} >RAM_D3
Важный код из main.c:
#if defined( __ICCARM__ )
#define DMA_D2_BUFFER \
_Pragma("location=\".dma_d2_buffer\"")
#else
#define DMA_D2_BUFFER \
__attribute__((section(".dma_d2_buffer"), used, aligned (4)))
#endif
#if defined( __ICCARM__ )
#define DMA_D3_BUFFER \
_Pragma("location=\".dma_d3_buffer\"")
#else
#define DMA_D3_BUFFER \
__attribute__((section(".dma_d3_buffer"), used, aligned (4)))
#endif
DMA_D2_BUFFER int32_t inDataI2s[BUFFER_SIZE];
DMA_D2_BUFFER int32_t outDataSai1[BUFFER_SIZE/2];
DMA_D3_BUFFER int32_t outDataSai4[BUFFER_SIZE/2];
int main(void)
{...
...
status = HAL_I2S_Receive_DMA(&hi2s1, (uint16_t *) inDataI2s, BUFFER_SIZE);
status = HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) outDataSai1, BUFFER_SIZE/2);
status = HAL_SAI_Transmit_DMA(&hsai_BlockB1, (uint8_t *) outDataSai1, BUFFER_SIZE/2);
status = HAL_SAI_Transmit_DMA(&hsai_BlockA4, (uint8_t *) outDataSai4, BUFFER_SIZE/2);
status = HAL_SAI_Transmit_DMA(&hsai_BlockB4, (uint8_t *) outDataSai4, BUFFER_SIZE/2);
while (1)
{
}
}
void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) {
bufferIndex = 0;
processData();
}
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) {
bufferIndex = BUFFER_SIZE/2;
processData();
}
void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai) {
saiCallback=1;
}
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai) {
saiCallback=2;
}
Да, я знаю о проблеме. Я внес изменения в файл .ld, рекомендованные в предоставленной вами ссылке. Используется последняя версия драйвера HAL.





Я нашел ошибку. Это был плохой STM32. Я провел A/B-тестирование и загрузил один и тот же код в два разных STM32H723VE, один вызвал функцию обратного вызова из SAI1, а другой просто перестал работать.
Мне это показалось очень интересным, поскольку я не ожидал, что это будет ошибка, поскольку все остальные периферийные устройства и даже оперативная память работали отлично. Как получается, что из-за аппаратной проблемы перестает работать только одно периферийное устройство?
Возможно, это не ваша проблема, но... Имейте в виду, что STM32H7 имеет проблему с DMA/кэшем. И еще предложение, проверьте, установлена ли у вас последняя версия драйвера HAL STM32H7xx (было обновление в марте 2024 года).