Прочитал статью на этом сайте про 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 прекратилась. Что-то шлется и принимается - значения не понятные.
Где у меня косяк?
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 как вариант) и потом следующие циклы обмена запускать.
@aveal т.е. я так понял в основном цикле (main.c) использовать _DMA нельзя или не желательно? Из callback запускать снова запускать _DMA функции? Тогда логика работы этой программы измениться на 180 градусов. Но это не страшно, просто надо подумать.
Если оставить все как есть и убрать префикс _DMA, то все ОК.
Можно из основного, просто когда у тебя без _DMA, то программа висит на
HAL_SPI_TransmitReceive(hspi, &byte, &feedback, 1, 0x01f4)
пока не отправятся/придут ответные данные, и только потом начинает выполняться
HAL_SPI_Transmit(hspi, &_address, 1, 0x01f4)
А с _DMA у тебя грубо говоря функция кидает в буфер данные, запускает процесс передачи/приема и сразу выходит. И если сразу же вызывать следующую функцию, то она просто перепишет предыдущие данные, которые еще не успели улететь.
В этом в целом и смысл DMA - зарядил отправку, и контроллер не ждет в цикле, пока она завершится, а занимается другими вещами. Но соответственно следующие обменные операции надо запускать по событию завершения текущих.
В этом в целом и смысл DMA - зарядил отправку, и контроллер не ждет в цикле, пока она завершится, а занимается другими вещами. Но соответственно следующие обменные операции надо запускать по событию завершения текущих.
Уточняю:
HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) и
HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
вызываются по завершению передачи/приема данных или когда что либо пришло/отправилось (например 1 байт, вместо 16 отправленных/принятых)?
@mihayk когда все пришли/отправились, сколько было в аргументе функции указано.