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

 
 
> Использование 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
Ответов
Albun
сообщение Jul 23 2009, 08:18
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 21-07-08
Пользователь №: 39 116



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


Странное замечание. Каналы приема и передачи не зависимы друг от друга, имеют разные регистры и могут по желанию использоваться либо нет. DMA трансфер будет осуществлен только в том случае если
соответствующий регистр счетчик (TCR/TNCR или RCR/RNCR) не нулевой и установлен бит присутствия данных в буффере перефирии (TDR/RDR) и естественно если DMA включен. Целиком от вас зависит хотите ли вы трансфер данных осуществлять вручную (записавая данные в TDR/читая из RDR) или возложить всю работу на DMA.
В одном из проектов по ходу создании прошивки я начал с передачи и приема - оба вручную по прерываниям (TDRE/RDRF & TMEMPTY). После того как был не удовлетворен этим перевел прием на работу через DMA в то время как передача по прежнему висела на прерывании - вручную записывая новые данные в TDR регистр. Никаких потерь не наблюдалось. Далее и передачу перевел на работу через DMA. Итого во всех трех случаях прием передача были без потерь.

Очень вероятно влияние кеширования данных (если оно у вас включено).
Либо обратите внимание на скорость работы - может быть у вас скорость передачи данных (частота SPI) граничат со скоростью с которой микроконтроллер способен обработать один трансфер (8-16 бит). Убедитесь что за целый промежуток времени когда у вас пересылаются 10-50к данных не произошла ни разу потеря (OVRES бит в регистре статуса SR должен быть постоянно 0)
Go to the top of the page
 
+Quote Post



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

 


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


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