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

 
 
> Использование SPI_DMA в AT91SAM9
PuHaT
сообщение May 14 2009, 05:28
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 4-05-06
Пользователь №: 16 758



Всем привет!
Написал работающий код (без использования DMA) для передачи блока данных из SDRAM в SPI - все работает исправно.
Решил использовать DMA - возникли проблемы. Использую следующий код (в котором вызываются функции из spi.c):

/******************* Инициализация модуля SPI *************************/
void InitSPI1 (void)
{
// Конфигурирование MISO, MOSI, SPCK, NPCS0
AT91C_BASE_PIOB->PIO_ASR =\
AT91C_BASE_PIOB->PIO_PDR =\
AT91C_BASE_PIOB->PIO_MDDR = 0x0000000F;


SPI_Configure(AT91C_BASE_SPI1, AT91C_ID_SPI1, AT91C_SPI_MSTR | AT91C_SPI_PS | AT91C_SPI_MODFDIS | (0x19UL << 24));
SPI_ConfigureNPCS(AT91C_BASE_SPI1, 0, (1 << 24)|(1 << 16)|(6UL << 8)|AT91C_SPI_BITS_16|AT91C_SPI_CSAAT|AT91C_SPI_NCPHA);

SPI_Enable(AT91C_BASE_SPI1);
}

unsigned int INIT1[] = {0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF, 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF};

/******************* Передача данных в SPI *****************************/
void SendData (void)
{
SPI_WriteBuffer(AT91C_BASE_SPI1, (void *)INIT1, 8);
mswait(10); // Задержка 10 мс
while(!SPI_IsFinished(AT91C_BASE_SPI1)); // Проверка окончания передачи данных
}

При вызове SendData () в регистр SPI1_TPR записывается адрес INIT1 (адрес SDRAM), в SPI1_TCR - длина блока. Проверил - все правильно. Но передается всего 4 байта вместо 48. Адрес увеличивается на 4 (SPI1_TPR), а SPI1_TCR уменьшается на единицу. И полный затык.
Ищу в гугле и на сайте атмела более подробную информацию, описывающую работу с SPI_DMA, но что-то ни наглядных примеров, ни каких-либо четких рекомендаций пока не нашел. Буду благодарен за любую информацию.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
defunct
сообщение May 14 2009, 21:26
Сообщение #2


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(PuHaT @ May 14 2009, 08:28) *
Буду благодарен за любую информацию.

Дык, а где код которым Вы собсно DMA инициализируете на передачу?

Код
xx_TPR = (U32)&pRing->storage[ pRing->CurrFrameHead ];
xx_TCR = pRing->CurrFrameSize;
xx_PTCR = AT91C_PDC_TXTEN; // enable transfer
Go to the top of the page
 
+Quote Post
PuHaT
сообщение May 15 2009, 03:59
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 4-05-06
Пользователь №: 16 758



Цитата(defunct @ May 15 2009, 01:26) *
Дык, а где код которым Вы собсно DMA инициализируете на передачу?

Код
xx_TPR = (U32)&pRing->storage[ pRing->CurrFrameHead ];
xx_TCR = pRing->CurrFrameSize;
xx_PTCR = AT91C_PDC_TXTEN; // enable transfer


Спасибо за ответ.
Извиняюсь за неполноту, привожу функцию (это код взятый из файла spi.c в примерах от атмела):

unsigned char SPI_WriteBuffer(AT91S_SPI *spi, void *buffer, unsigned int length)
{
// Check if first bank is free
if (spi->SPI_TCR == 0) {

spi->SPI_TPR = (unsigned int) buffer;
spi->SPI_TCR = length;
spi->SPI_PTCR = AT91C_PDC_TXTEN;
return 1;
}
// Check if second bank is free
else if (spi->SPI_TNCR == 0) {

spi->SPI_TNPR = (unsigned int) buffer;
spi->SPI_TNCR = length;
return 1;
}

// No free banks
return 0;
}

Есть значительное сходство с Вашим ответом. Порылся еще в поиске. В одном из сообщений говорилось, что при использовании DMA необходимо одновременно запускать процедуры для приема и передачи данных (в частности настраивать регистры SPI_TCR и SPI_TRCR на одинаковое количество). Сделал так - заработало, но нестабильно - данные передаются без остановки примерно до 500 байт, при заданной длине длине свыше примерно 500 передаются каждый раз разное количество байт (в диапазоне от 500 до 1000) причем количество переданных байт всегда равно количеству принятых. Мне же требуется передать блок данных от 10кБ до 50 кБ.
Работаю с JTAG-отладчиком (IAR+MT_Link) - может он как-то влиять на работу DMA?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 15 2009, 09:59
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(PuHaT @ May 15 2009, 07:59) *
В одном из сообщений говорилось, что при использовании DMA необходимо одновременно запускать процедуры для приема и передачи данных (в частности настраивать регистры SPI_TCR и SPI_TRCR на одинаковое количество).

Или сначала запустить прием, а затем передачу, что вполне логично.

Цитата(PuHaT @ May 15 2009, 07:59) *
Мне же требуется передать блок данных от 10кБ до 50 кБ.

Не знаю ваших причин, но, ИМХО, это не очень удачная идея - работать огромными блоками.

Цитата(PuHaT @ May 15 2009, 07:59) *
Работаю с JTAG-отладчиком (IAR+MT_Link) - может он как-то влиять на работу DMA?

Вполне вероятно, попробуйте без него.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 20:58
Рейтинг@Mail.ru


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