We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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); }
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?