DMA для dsPIC. Контроллер Прямого доступа к памяти (DMA). DMA контроллер. Регистр Смещения Адреса Начала A DPSRAM Канала DMA x, страница 17

#define FCSCK 64*FS

#define BCGVAL (FCY/(2*FS))-1

DCICON1bits.CSCKD = 0;                  // Serial Bit Clock (CSCK pin) is output

DCICON1bits.CSCKE = 0;                  // Data sampled on falling edge of CSCK

DCICON1bits.COFSD = 0;                  // Frame Sync Signal is output

DCICON1bits.UNFM = 0;        // Transmit '0's on a transmit underflow

DCICON1bits.CSDOM = 0;     // CSDO pin drives '0's during disabled TX time slots

DCICON1bits.DJST = 0; // TX/RX starts 1 serial clock cycle after frame sync pulse

DCICON1bits.COFSM = 1;      // Frame Sync Signal set up for I2S mode

DCICON2bits.BLEN = 0;         // One data word will be buffered between interrupts

DCICON2bits.COFSG = 1;       // Data frame has 2 words: LEFT & RIGHT samples

DCICON2bits.WS = 15;           // Data word size is 16 bits

DCICON3 = BCG_VAL;          // Set up CSCK Bit Clock Frequency

TSCONbits.TSE0 = 1; // Transmit on Time Slot 0

TSCONbits.TSE1 = 1; // Transmit on Time Slot 1

RSCONbits.RSE0 = 1; // Receive on Time Slot 0

RSCONbits.RSE1 = 1; // Receive on Time Slot 1

Set up DMA Channel 0 for Transmit in Continuous Ping-Pong mode:

unsigned int TxBufferA[16] __attribute__((space(dma)));

unsigned int TxBufferB[16] __attribute__((space(dma)));

DMA0CON = 0x2002; // Ping-Pong, Continous, Post-Increment, RAM-to-Peripheral

DMA0CNT = 15;                                 // 15 DMA requests

DMA0REQ = 0x003C;             // Select DCI as DMA Request source

DMA0PAD = (volatile unsigned int) &TXBUF0;

DMA0STA = __builtin_dmaoffset(TxBufferA);

DMA0STB = __builtin_dmaoffset(TxBufferB);

IFS0bits.DMA0IF = 0;              // Clear DMA Interrupt Flag

IEC0bits.DMA0IE = 1;                         // Enable DMA interrupt

DMA0CONbits.CHEN = 1;                  // Enable DMA Channel

Set up DMA Channel 1 for Receive in Continuous Ping-Pong mode:

unsigned int RxBufferA[16] __attribute__((space(dma)));

unsigned int RxBufferB[16] __attribute__((space(dma)));

DMA1CON = 0x0002;             // Continuous, Ping-Pong, Post-Inc., Periph-RAM

DMA1CNT = 15;                                 // 16 DMA requests

DMA1REQ = 0x003C;             // Select DCI as DMA Request source

DMA1PAD = (volatile unsigned int) &RXBUF0;

DMA1STA = __builtin_dmaoffset(RxBufferA);

DMA1STB = __builtin_dmaoffset(RxBufferB);

IFS0bits.DMA1IF = 0;              // Clear DMA interrupt

IEC0bits.DMA1IE = 1;             // Enable DMA interrupt

DMA1CONbits.CHEN = 1;                  // Enable DMA Channel

Set up DMA Interrupt Handlers:

void __attribute__((__interrupt__)) _DMA0Interrupt(void)

{

static unsigned int TxBufferCount = 0;// Keep record of which buffer

// has Rx Data

if(BufferCount == 0)

{

/* Notify application that TxBufferA has been transmitted */

}

else

{

/* Notify application that TxBufferB has been transmitted */

}

BufferCount ^= 1;

IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag;

}

void __attribute__((__interrupt__)) _DMA1Interrupt(void)

{

static unsigned int RxBufferCount = 0;// Keep record of which buffer

// has Rx Data

if(BufferCount == 0)

{

/* Notify application that RxBufferA has been received */

}

else

{

/* Notify application that RxBufferB has been received */ }

BufferCount ^= 1;

IFS0bits.DMA1IF = 0; // Clear the DMA1 Interrupt Flag

}

Enable DCI:

/* Force First two words to fill-in Tx buffer/shift register */

DMA0REQbits.FORCE = 1;

while(DMA0REQbits.FORCE == 1);

DMA0REQbits.FORCE = 1;

while(DMA0REQbits.FORCE == 1);

DCICON1bits.DCIEN = 1; // Enable DCI

Если выбран режим One-Shot, в то время как DMA работает в режиме Ping-Pong, DMA отвечает, повторной инициализацией, чтобы указать на вторичный буфер после передачи первичного буфера и затем передает вторичный буфер. Последующие блочные пересылки не будут происходить, потому что канал DMA отключает себя. рисунок 22-18 иллюстрирует Однократную передачу данных в режиме Ping-Pong.