реклама на сайте
подробности

 
 
> Проблема с Link List в DMA
Novichok1
сообщение Aug 31 2009, 06:24
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



Доброго времени суток!

Нужно в LPC2478 копировать блоки данных из памяти в память через DMA контроллер.
Все делаю, как прописано в мануале:
- подаю питание на DMA
- енаблю сам DMA
- очищаю регистры запросов прерываний на нужном канале
- устанавливаю адреса исходных и целевых данных на нужном канале
- устанавливаю адрес заранее записанного на флэшку связанного списка
- устанавливаю необходимые параметры размеров трансферов
- енаблю канал

В результате, первый блок копируется нормально, но ко второму элементу связанного списка DMA почему-то не доходит. Я уже не знаю что курить, кто сталкивался с такой проблемой- пожалуйста,поделитесь опытом.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Quasar
сообщение Mar 1 2010, 19:44
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Столкнулся с проблемой, не получается запустить 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 );
}

}


Сообщение отредактировал IgorKossak - Mar 20 2011, 14:59
Причина редактирования: codebox тег для оформления длинного кода
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 07:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01389 секунд с 7
ELECTRONIX ©2004-2016