This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SSP1 communication through DMA

Hey everyone,

I've been trying to get the SSP1 port on the lpc2388 working to no avail. I have the SSP1 port working by itself but I want to be able to use the DMA. I've read over the manual and a few examples, but I still can't seem to get it to work.

The interrupts aren't firing and I don't see anything being transmitted from the SSP1 port. I know there are some messy parts, but I just want to get it working first and I'll put in error handling, etc. later. This is on a system using RTx by the way. Can anyone see any obvious errors that I have missed?

Here's how I'm configuring it:

SSP1 configuration (works when I don't use DMA):

void init_ssp1(void) {
    // Configure SSP1
    SSP1CR1     = 0x00;                     // Disable module
    SSP1CPSR    = 60000000/4/100000;        // Set 100KHz clock rate
    SSP1CR0     = 0xCF;                     // 16 bit transfers, SPI, CPOL=1, CPHA=1
    SSP1IMSC    = 0x0;                      // Disable all interrupts
    SSP1CR1     = 0x2;                      // Enable module

    // Enable SSP1 interrupt
    VICVectAddr11 = (unsigned long)ssp1_irq;
}

DMA configuration:

static U16      dma_rx_buf[128];
static U16      dma_tx_buf[128];

void init_dma(void) {
    U32 i;
    U16 *rx_address;
    U16 *tx_address;

    // Init buffers
    rx_address = dma_rx_buf;
    tx_address = dma_tx_buf;
    for (i=0; i<128;i++) {
        *tx_address++   = i;
        *rx_address++   = i;
    }

    // Clear DMA interrupts
    GPDMA_INT_TCCLR     = 0x3;          // TC interrupts
    GPDMA_INT_ERR_CLR   = 0x3;          // Err interrupts

    // Configure DMA ch0 for SSP1 send
    GPDMA_CH0_SRC       = (U32)&tx_address;
    GPDMA_CH0_DEST      = SSP1DR;

    // TX burst size of 128 x 16bits, source is incremented after each transfer
    GPDMA_CH0_CTRL      = (0x6<<12) | (0x6<<15) | SHIFT_ONE(18) | SHIFT_ONE(21) | SHIFT_ONE(26) | SHIFT_ONE(31);

    // Configure DMA ch1 for SSP1 receive
    GPDMA_CH1_SRC       = SSP1DR;
    GPDMA_CH1_DEST      = (U32)&rx_address;

    // RX burst size of 128 x 16bits, destination is incremented after each transfer
    GPDMA_CH1_CTRL      = (0x6<<12) | (0x6<<15) | SHIFT_ONE(18) | SHIFT_ONE(21) | SHIFT_ONE(27) | SHIFT_ONE(31);

    // Enable SSP1 interrupt
    VICVectAddr25 = (unsigned long)dma_irq;
}

When I send I use this code:

void comm_send(U16 *data, U16 length) {
    U32 i = 0;

    for (i=0; i<length; i++) dma_tx_buf[i] = data[i];

    // Enable SSP1 DMA access
    SSP1DMACR = 0x3;

    // Enable DMA ch0 for M2P to SSP1 with peripheral flow control and interrupts enabled
    GPDMA_CH0_CFG = SHIFT_ONE(0) | (0x2<<6) | (0x5<<11) | SHIFT_ONE(14) | SHIFT_ONE(15);

    // Enable DMA ch1 for P2M from SSP1 with peripheral flow control and interrupts enabled
    GPDMA_CH1_CFG = SHIFT_ONE(0) | (0x3<<1) | (0x6<<11) | SHIFT_ONE(14) | SHIFT_ONE(15);
}

Parents Reply Children
No data