Полная процедура приема 8-битных данных SPI с использованием DMA показана в листингах ниже. Структура инициализации DMA настроена следующим образом:
static int dmaRcvBytes ( void *rbuf , unsigned count)
{
DMA_InitTypeDef DMA_InitStructure ;
uint16_t dummy [] = {0 xffff };
DMA_DeInit ( DMA1_Channel2 );
DMA_DeInit ( DMA1_CHannel3 );
// Common to both channels
DMA_InitStructure . DMA_PeripheralBaseAddr =
, !(uint32_t)(&( SPI1 ->DR));
DMA_InitStructure . DMA_PeripheralDataSize =
, !DMA_PeripheralDataSize_Byte ;
DMA_InitStructure . DMA_MemoryDataSize = DMA_MemoryDataSize_Byte ;
DMA_InitStructure . DMA_PeripheralInc = DMA_PeripheralInc_Disable ;
DMA_InitStructure . DMA_BufferSize = count;
DMA_InitStructure . DMA_Mode = DMA_Mode_Normal ;
DMA_InitStructure . DMA_Priority = DMA_Priority_VeryHigh ;
DMA_InitStructure .DMA_M2M = DMA_M2M_Disable ;
// Rx Channel
DMA_InitStructure . DMA_MemoryBaseAddr = (uint32_t)rbuf;
DMA_InitStructure . DMA_MemoryInc = DMA_MemoryInc_Enable ;
DMA_InitStructure .DMA_DIR = DMA_DIR_PeripheralSRC ;
DMA_Init(DMA1_Channel2 , & DMA_InitStructure );
// Tx channel
DMA_InitStructure . DMA_MemoryBaseAddr = (uint32_t) dummy;
DMA_InitStructure . DMA_MemoryInc = DMA_MemoryInc_Disable ;
DMA_InitStructure .DMA_DIR = DMA_DIR_PeripheralDST ;
DMA_Init(DMA1_channel3 , & DMA_InitStructure );
/* ... */
SPI DMA Receive (Part 1)
• Базовый адрес периферии установлен в регистр данных SPI.
• Размер данных периферии и памяти установлен на 8 бит (байт).
• Периферийное увеличение отключено — все данные считываются / записываются из одного регистра DR.
// Enable channels DMA_Cmd(rxChan , ENABLE); DMA_Cmd(txChan , ENABLE); // Enable SPI TX/RX request SPI_I2S_DMACmd (SPIx , SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx , , !ENABLE); // Wait for completion while ( DMA_GetFlagStatus ( DMA1_FLAG_TC2 ) == RESET); // Disable channels DMA_Cmd(rxChan , DISABLE); DMA_Cmd(txChan , DISABLE); SPI_I2S_DMACmd (SPIx , SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx , , !DISABLE); return count; }
SPI DMA Receive (Part 2)
• Размер буфера, установленный на количество данных для передачи (количество).
• Нормальный режим DMA
• Высокий приоритет
Затем код конфигурирует сторону памяти и инициализирует приемный канал, после чего реконфигурирует сторону памяти и конфигурирует канал передачи. Для однонаправленных операций чтения передаваемые данные предоставляются через «фиктивный» буфер, который многократно читается во время передачи (DMA_MemoryInc_Disable).
Как только оба канала настроены, они включены, выполняется запрос SPI DMA, и, наконец, код ожидает флага завершения. Обратите внимание, что в этой реализации процессор настраивает передачу, а затем ожидает завершения, но это все еще предполагает занятое ожидание. Альтернативный подход состоит в том, чтобы включить прерывание DMA и определить соответствующий обработчик (например, DM1_Channel1_IRQHandler). Основной код может затем вернуться и дождаться соответствующего события завершения.