Столкнулся с проблемой, не получается запустить DMA на LPC2478 и LPC2378. Не хочет работать с SSP1, хотя с SSP0 работает нормально. Причем ошибки в инициализации SSP нет, так как при работе SSP1 с такой же конфигурацией но без DMA, все ok.
CODE
char dma_src[SSP_BUFSIZE] __attribute__((at(0x7FD00000)));
char dma_dst[SSP_BUFSIZE] __attribute__((at(0x7FD01000)));
static DWORD SSP1Init( void )
{
BYTE i, Dummy = Dummy;
/* enable clock to SSP1 for security reason. By default, it's enabled already */
PCONP |= (1 << 10);
PINSEL0 &= !( 0xFF << 12 );
PINSEL0 |= ( 0xAA << 12 );
/* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
SSP1CR0 = 0x0707;
/* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
#if LOOPBACK_MODE
SSP1CPSR = 0x2;
#else
/* Much slower clock is needed in order to test serial EEPROM. */
SSP1CPSR = 0x40;
#endif
for ( i = 0; i < FIFOSIZE; i++ )
{
Dummy = SSP1DR; /* clear the RxFIFO */
}
if ( install_irq( SSP1_INT, (void *)SSP1Handler, HIGHEST_PRIORITY ) == FALSE )
{
return (FALSE);
}
/* Device select as master, SSP Enabled */
#if LOOPBACK_MODE
SSP1CR1 = SSPCR1_LBM | SSPCR1_SSE;
#else
SSP1CR1 = SSPCR1_SSE;
#endif
/* Set SSPINMS registers to enable interrupts */
/* enable all error related interrupts */
SSP1IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;
return( TRUE );
}
/*****************************************************************************
** Function name: LoopbackTest
**
** Descriptions: Loopback test
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void DMATest( void )
{
DWORD i;
volatile DWORD cnt;
PCONP |= (1 << 29); /* Enable GPDMA clock */
/* Ch0 set for M2P transfer from mempry to SSP1. */
GPDMA_CH0_SRC = (unsigned long)dma_src;
GPDMA_CH0_DEST = SSP1DR;
/* The burst size is set to 8, the size is 8 bit too. */
/* Terminal Count Int enable */
GPDMA_CH0_CTRL = (SSP_BUFSIZE & 0x0FFF)
| (0x02 << 12)
| (0x02 << 15)
| (0x01 << 26)
| 0x80000000;
GPDMA_CH0_CFG = (0x01 << 16) /* Lock bit */
| (0x01 << 15) /* Terminal count interrupt mask. */
| (0x05 << 11) /* Flow control and transfer type. M2P*/
| (0x00 << 6 ) /* Destination peripheral. */
| (0x02 << 1 ) /* SSP1 Tx. */
| (0x01 << 0 ); /* Channel enabled. */
/* Ch1 set for P2M transfer from SSP1 to memory. */
GPDMA_CH1_SRC = SSP1DR;
GPDMA_CH1_DEST = (unsigned long)dma_dst;
/* The burst size is set to 8, the size is 8 bit too. */
/* Terminal Count Int enable */
GPDMA_CH1_CTRL = (SSP_BUFSIZE & 0x0FFF)
| (0x02 << 12)
| (0x02 << 15)
| (0x01 << 27)
| 0x80000000;
GPDMA_CH1_CFG = (0x01 << 16) /* Lock bit */
| (0x01 << 15) /* Terminal count interrupt mask. */
| (0x06 << 11) /* Flow control and transfer type. P2M*/
| (0x00 << 6 ) /* Destination peripheral. */
| (0x03 << 1 ) /* SSP1 Rx. */
| (0x01 << 0 ); /* Channel enabled. */
GPDMA_CONFIG = 0x01; /* Enable DMA channels, little endian */
while ( !(GPDMA_CONFIG & 0x01) );
if ( install_irq( GPDMA_INT, (void *)DMAHandler, HIGHEST_PRIORITY ) == FALSE ) {
while (1)
/* PANIC */;
}
/* Enable DMA TX and RX on SSP1 */
SSP1DMACR = 0x03;
cnt = 0x10000;
while ( cnt-- )
;
/* verifying, ignore the difference in the first two bytes */
for ( i = 0; i < SSP_BUFSIZE; i++ ){
if ( dma_dst[i] != dma_src[i] ){
while (1)
/* PANIC */; /* Verification failed */
}
}
return;
}
void SSP1Send( BYTE *buf, DWORD Length )
{
DWORD i;
BYTE Dummy = Dummy;
for ( i = 0; i < Length; i++ )
{
/* Move on only if NOT busy and TX FIFO not full. */
while ( (SSP1SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF );
SSP1DR = *buf;
buf++;
#if !LOOPBACK_MODE
while ( (SSP1SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE );
/* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO
on MISO. Otherwise, when SSP0Receive() is called, previous data byte
is left in the FIFO. */
Dummy = SSP1DR;
#else
/* Wait until the Busy bit is cleared. */
while ( SSP1SR & SSPSR_BSY );
#endif
}
return;
}
/******************************************************************************
** Main Function main()
******************************************************************************/
int main (void)
{
DWORD i;
SSP1Init();
while (1) {
for ( i = 0; i < SSP_BUFSIZE; i++ ) {
dma_src[i] = 0xAA;
dma_dst[i] = 0x00;
}
DMATest();
//SSP1Send( ((BYTE *)DMA_SRC), SSP_BUFSIZE );
}
}