Top.Mail.Ru
Уведомления
Очистить все

[Решено] SPI c DMA

(@mihayk)
Level 3

Прочитал статью на этом сайте про SPI и DMA. Решил попробовать. В CubeMX настроил. 

В коде заменил HAL-функции: 

HAL_SPI_TransmitReceive(hspi, &byte, &feedback, 1, 0x01f4)
HAL_SPI_Transmit(hspi, &_address, 1, 0x01f4)
HAL_SPI_Receive(hspi, dataBuf, num, 0x01f4)

на

HAL_SPI_TransmitReceive_DMA(hspi, &byte, &feedback, 1)
HAL_SPI_Transmit_DMA(hspi, &_address, 1)
HAL_SPI_Receive_DMA(hspi, dataBuf, num)

Callback-фунуции пока не использовал. 

Похоже где-то я что-то недопонял. Работа по SPI прекратилась. Что-то шлется и принимается - значения не понятные.

Где у меня косяк?

 

Цитата
Создатель темы Размещено : 18.10.2023 09:16
Aveal
(@aveal)
Top level Admin

HAL_SPI_TransmitReceive(hspi, &byte, &feedback, 1, 0x01f4);
HAL_SPI_Transmit(hspi, &_address, 1, 0x01f4);
HAL_SPI_Receive(hspi, dataBuf, num, 0x01f4);

А без DMA работает?

Вообще _DMA функции не блокирующие, то есть надо отслеживать, когда пришел ответ на первый запрос (через callback как вариант) и потом следующие циклы обмена запускать.

ОтветитьЦитата
Размещено : 19.10.2023 10:43
(@mihayk)
Level 3

@aveal т.е. я так понял в основном цикле (main.c) использовать _DMA нельзя или не желательно? Из callback запускать снова запускать _DMA функции? Тогда логика работы этой программы измениться на 180 градусов. Но это не страшно, просто надо подумать. 

Если оставить все как есть и убрать префикс _DMA, то все ОК.

ОтветитьЦитата
Создатель темы Размещено : 19.10.2023 11:38
Aveal
(@aveal)
Top level Admin

Можно из основного, просто когда у тебя без _DMA, то программа висит на

HAL_SPI_TransmitReceive(hspi, &byte, &feedback, 1, 0x01f4)

пока не отправятся/придут ответные данные, и только потом начинает выполняться

HAL_SPI_Transmit(hspi, &_address, 1, 0x01f4)

А  с _DMA у тебя грубо говоря функция кидает в буфер данные, запускает процесс передачи/приема и сразу выходит. И если сразу же вызывать следующую функцию, то она просто перепишет предыдущие данные, которые еще не успели улететь.

В этом в целом и смысл DMA - зарядил отправку, и контроллер не ждет в цикле, пока она завершится, а занимается другими вещами. Но соответственно следующие обменные операции надо запускать по событию завершения текущих.

ОтветитьЦитата
Размещено : 19.10.2023 12:06
(@mihayk)
Level 3
От: @aveal

 

В этом в целом и смысл DMA - зарядил отправку, и контроллер не ждет в цикле, пока она завершится, а занимается другими вещами. Но соответственно следующие обменные операции надо запускать по событию завершения текущих.

Уточняю: 

HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) и 

HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

вызываются по завершению передачи/приема данных или когда что либо пришло/отправилось (например 1 байт, вместо 16 отправленных/принятых)?

ОтветитьЦитата
Создатель темы Размещено : 19.10.2023 12:42
Aveal
(@aveal)
Top level Admin

@mihayk когда все пришли/отправились, сколько было в аргументе функции указано.

ОтветитьЦитата
Размещено : 19.10.2023 13:03
(@mihayk)
Level 3

@aveal Спасибо!

ОтветитьЦитата
Создатель темы Размещено : 19.10.2023 13:19
Aveal
(@aveal)
Top level Admin

@mihayk 👍😊 

ОтветитьЦитата
Размещено : 19.10.2023 13:26
Поделиться: