В течение нормальной операции в этом режиме, Нулевая Запись Данных может произойти только в ответ на запрос DMA периферийного устройства (то есть, после того, как данные были получены и доступны для передачи). Начальная запись CPU на периферийное устройство обязана запускать прием первого слова, после которого DMA заботится обо всех записях последующих периферийных (нулевых) данных. То есть запись пустого указателя CPU начинается, SPI (хозяин) посылает/получает данные, которые в свою очередь в конечном счете генерируют DMA, просят переместить недавно полученные данные.
Альтернативно, может использоваться принудительная передача DMA, чтобы ‘пнуть начало’ процесса. Однако, это будет также включать избыточное периферийное чтение (данные не правильны) и связанная настройка указателя DPSRAM, которая должна быть принята во внимание.
Figure 22-20: Data Transfer With Null Data Write Mode
Пример 22-10: SPI and DMA With Null Data Write Mode
Set up SPI for Master mode:
SPI1CON1bits.MODE16 = 1; //Communication is word-wide (16 bits)
SPI1CON1bits.MSTEN = 1; //Master Mode Enabled
SPI1STATbits.SPIEN = 1; //Enable SPI Module
Set up DMA Channel 1 for Null Data Write mode:
unsigned int BufferA[16] __attribute__((space(dma)));
unsigned int BufferB[16] __attribute__((space(dma)));
DMA1CON = 0x0802; // Null Write, Continuous, Ping-Pong,
// Post-Increment, Periph-to-RAM
DMA1CNT = 15; // Transfer 16 words at a time
DMA1REQ = 0x000A; // Select SPI1 as DMA request source
DMA1STA = __builtin_dmaoffset(BufferA);
DMA1STB = __builtin_dmaoffset(BufferB);
DMA1PAD = (volatile unsigned int) &SPI1BUF;
IFS0bits.DMA1IF = 0;
IEC0bits.DMA1IE = 1; // Enable DMA interrupt
DMA1CONbits.CHEN = 1; // Enable DMA Channel
DMA1REQbits.FORCE = 1; // Force First word after Enabling SPI
Set up DMA Interrupt Handler:
void __attribute__((__interrupt__)) _DMA1Interrupt(void)
{
static unsigned int BufferCount = 0; // Keep record of which buffer
// contains Rx Data
if(BufferCount == 0)
{
ProcessRxData(BufferA); // Process received SPI data in
// DMA RAM Primary buffer
}
else
{
ProcessRxData(BufferB); // Process received SPI data in
// DMA RAM Secondary buffer
}
BufferCount ^= 1;
IFS0bits.DMA1IF = 0; // Clear the DMA1 Interrupt Flag
}
22.7 ЗАПУСК DMA ПЕРЕДАЧ
Прежде, чем передачи DMA могут начаться, канал DMA нужно разрешить, устанавливая CHEN бит в ‘1’ в регистре DMAxCON. Когда канал DMA активен, он может быть повторно инициализирован, отключая этот канал (CHEN = 0), сопровождая последующим его разрешением (CHEN = 1). Этот процесс сбрасывает счетчик передачи DMA и устанавливает активный буфер DMA на первичный буфер.
Когда канал DMA и периферийное устройство должным образом инициализированы, передачи DMA стартуют, как только периферийное устройство готово переместить данные и выпускает запрос DMA. Однако, некоторые периферийные устройства не могут выпустить запрос DMA (и поэтому не будут запускать передачу DMA), пока некоторые условия не выполнены. В этих случаях, должна быть применена комбинация различных режимов DMA, чтобы инициализировать передачу DMA:
22.7.1 Старт DMA с Последовательным Периферийным Интерфейсом (SPI)
Старт передач DMA в\из SPI периферийного устройства зависит от SPI направления данных и ведущего или ведомого режима:
• только Tx в режиме ведущего - В этой конфигурации, запрос DMA не будет выпущен, пока не пошлют первый блок SPI данных. Для Инициализации передач DMA, пользовательское приложение должно сначала отправить данные, используя режим Manual Transfer DMA, или оно должно сначала записать данные в буфер SPI (SPIxBUF) независимо от DMA.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.