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
  • So I've narrowed down the problem with my code to memory access. The USB memory location is from 0x7FD00000 to 0x7FD03FFF. If I try to access anything outside of this from the DMA I get a channel error.

    When I kick off the DMA and SSP I configure the following:
    CH0 source is 0x7FD00000 (in USM memory location)
    CH0 destination is the SSP1 data register
    CH1 source is the SSP1 data register
    CH1 destination is 0x7FD02000 (in USM memory location)

    When I set the SSP to be the flow controller it tries to read as much data as possible and errors out when it hits 0x7FD04000. This happens with both the TX and RX SSP transfers. I understand why the error is happening but I don't understand how to configure it so it only fetches what I have set in the bust size and width registers.

    From my understanding I have set them as:
    CH0 Source Burst Size: 128 transfers
    CH0 Destination Burst Size: 128 transfers
    CH0 Source Width: 16bits
    CH0 Destination Width: 16bits
    CH1 Source Burst Size: 128 transfers
    CH1 Destination Burst Size: 128 transfers
    CH1 Source Width: 16bits
    CH1 Destination Width: 16bits

    My goal is to have 128 16bit registers transfered from the SSP and receive 128 16bit registers back. Am I misunderstanding anything here?

Reply
  • So I've narrowed down the problem with my code to memory access. The USB memory location is from 0x7FD00000 to 0x7FD03FFF. If I try to access anything outside of this from the DMA I get a channel error.

    When I kick off the DMA and SSP I configure the following:
    CH0 source is 0x7FD00000 (in USM memory location)
    CH0 destination is the SSP1 data register
    CH1 source is the SSP1 data register
    CH1 destination is 0x7FD02000 (in USM memory location)

    When I set the SSP to be the flow controller it tries to read as much data as possible and errors out when it hits 0x7FD04000. This happens with both the TX and RX SSP transfers. I understand why the error is happening but I don't understand how to configure it so it only fetches what I have set in the bust size and width registers.

    From my understanding I have set them as:
    CH0 Source Burst Size: 128 transfers
    CH0 Destination Burst Size: 128 transfers
    CH0 Source Width: 16bits
    CH0 Destination Width: 16bits
    CH1 Source Burst Size: 128 transfers
    CH1 Destination Burst Size: 128 transfers
    CH1 Source Width: 16bits
    CH1 Destination Width: 16bits

    My goal is to have 128 16bit registers transfered from the SSP and receive 128 16bit registers back. Am I misunderstanding anything here?

Children
No data