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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> SAM3U и SPI, Запуск SPI с DMA
*rust*
сообщение May 10 2011, 05:26
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Добрый день!

Кто-нибудь запускал SPI с DMA (прием\передача) на AT91SAM3U?
В даташите есть упоминание, что SPI может работать с DMA, в библиотеке от ATMEL есть специальные функции, реализующие эту работу:
Код
unsigned char SPI_WriteBuffer(AT91S_SPI *spi, void *buffer, unsigned int length)
запись
Код
unsigned char SPI_ReadBuffer(AT91S_SPI *spi, void *buffer, unsigned int length)
чтение

После инициализации SPI и запуска этих функций, ничего не происходит. Добавлю, что SPI по прерываниям у меня работает, но хотелось бы не занимать процессорное время и перейти на DMA.

Внутри этих функций (на примере SPI_ReadBuffer) инициализация и запуск DMA:
Код
#if !defined(CHIP_SPI_DMA)
    // Check if the first bank is free
    if (spi->SPI_RCR == 0) {

        spi->SPI_RPR = (unsigned int) buffer;
        spi->SPI_RCR = length;
        spi->SPI_PTCR = AT91C_PDC_RXTEN;
        return 1;
    }
    // Check if second bank is free
    else if (spi->SPI_RNCR == 0) {

        spi->SPI_RNPR = (unsigned int) buffer;
        spi->SPI_RNCR = length;
        return 1;
    }
#endif
    // No free bank
    return 0;
}


Сразу после записи в SPI_RCR(количество перемещаемых байт), проверяю этот регистр, а он равен 0.

Настораживает тот момент, что в ашнике на проц AT91SAM3U4.h нет адресов для регистров DMA работающих с SPI, хотя в структуре SPI эти регистры присутствуют.

Заранее благодарен за помощь!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 10 2011, 05:33
Сообщение #2


Гуру
******

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



А данные на передачу не забыли запустить? Чтобы что-то принимать по SPI, нужно обязательно что-то одновременно передавать.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 10 2011, 05:46
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Цитата
А данные на передачу не забыли запустить? Чтобы что-то принимать по SPI, нужно обязательно что-то одновременно передавать.

Нет, не забыл. Чтобы не наделать ошибок я для начала оставил передачу на прерывании. До прерывания DMA уже инициализирован.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение May 10 2011, 05:48
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



В аттачменте - тестовый проект c SPI на DMA (правда, с SAM3S) - возможно, поможет разобраться. Файл sdcard.c - работа с карточкой по SPI.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 10 2011, 05:54
Сообщение #5


Гуру
******

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



А, так это ж SAM3U. В нем PDC от SPI отломали, придется вам использовать "честный" DMA.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 10 2011, 06:28
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



aaarrr, т.е эти функции SPI_WriteBuffer и SPI_ReadBuffer в данном конкретном случае бесполезны?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 10 2011, 06:34
Сообщение #7


Гуру
******

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



Абсолютно бесполезны.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 10 2011, 07:49
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



У ATMELа имеются функции из библиотеки dma.c Как я понял с помощью них можно реализовать SPI с DMA.

aaarrr, это конечно крайняя наглость, но не могли бы Вы подсказать порядок вызова этих функций, если учесть что нужно реализовать и прием и передачу по SPI?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 10 2011, 08:10
Сообщение #9


Гуру
******

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



Цитата(*rust* @ May 10 2011, 11:49) *
aaarrr, это конечно крайняя наглость, но не могли бы Вы подсказать порядок вызова этих функций, если учесть что нужно реализовать и прием и передачу по SPI?

Порядок не подскажу, ибо не использовал (на дух не переношу все атмеловское софтверное творчество).
Но могу ответить на конкретные вопросы по DMAC. С SPI, правда, я его не использовал, зато использовал для SSC в режиме linked list и для MCI в single shot.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 10 2011, 11:09
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Вот нашел на одной сайте этот код. Попробую сделать нечто подобное. Посмотрите на него, правильной дорогой меня направили?
Код
I got it working... down here is the source code if someone is need of help..


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Config_DMA_SPI (void)
{
AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_HDMA;
AT91C_BASE_HDMA->HDMA_GCFG=0;

//SPI RX

AT91C_BASE_HDMA_CH_0->HDMA_CTRLB = AT91C_HDMA_SRC_DSCR_FETCH_DISABLE |
AT91C_HDMA_DST_DSCR_FETCH_DISABLE |
AT91C_HDMA_SRC_ADDRESS_MODE_FIXED |
AT91C_HDMA_DST_ADDRESS_MODE_INCR |
AT91C_HDMA_FC_PER2MEM;

AT91C_BASE_HDMA_CH_0->HDMA_CFG = AT91C_HDMA_SRC_PER_2 |
AT91C_HDMA_LOCK_IF_DISABLE |
AT91C_HDMA_LOCK_B_DISABLE |
AT91C_HDMA_SRC_H2SEL_HW |
AT91C_HDMA_DST_H2SEL_SW |
AT91C_HDMA_FIFOCFG_LARGESTBURST;

AT91C_BASE_HDMA_CH_0->HDMA_DSCR=0;
AT91C_BASE_HDMA_CH_0->HDMA_SADDR=(unsigned int)&AT91C_BASE_SPI0->SPI_RDR;
AT91C_BASE_HDMA_CH_0->HDMA_DADDR=(unsigned int)buff_in;

AT91C_BASE_HDMA_CH_0->HDMA_CTRLA = AT91C_HDMA_DCSIZE_1 |
AT91C_HDMA_SCSIZE_1 |
AT91C_HDMA_SRC_WIDTH_BYTE |
AT91C_HDMA_SRC_WIDTH_BYTE |
TRANSFER_SIZE;

// SPI TX

AT91C_BASE_HDMA_CH_1->HDMA_CTRLB = AT91C_HDMA_SRC_DSCR_FETCH_DISABLE |
AT91C_HDMA_DST_DSCR_FETCH_DISABLE |
AT91C_HDMA_SRC_ADDRESS_MODE_FIXED |
AT91C_HDMA_DST_ADDRESS_MODE_FIXED |
AT91C_HDMA_FC_MEM2PER;

AT91C_BASE_HDMA_CH_1->HDMA_CFG = AT91C_HDMA_DST_PER_1 |
AT91C_HDMA_SOD_DISABLE |
AT91C_HDMA_LOCK_IF_DISABLE |
AT91C_HDMA_LOCK_B_DISABLE |
AT91C_HDMA_SRC_H2SEL_SW |
AT91C_HDMA_DST_H2SEL_HW |
AT91C_HDMA_FIFOCFG_LARGESTBURST;

AT91C_BASE_HDMA_CH_1->HDMA_DSCR = 0;
AT91C_BASE_HDMA_CH_1->HDMA_SADDR=(unsigned int)&dummy_spi_byte;
AT91C_BASE_HDMA_CH_1->HDMA_DADDR=(unsigned int)&AT91C_BASE_SPI0->SPI_TDR;
AT91C_BASE_HDMA_CH_1->HDMA_CTRLA = AT91C_HDMA_DCSIZE_1 +
AT91C_HDMA_SCSIZE_1 +
AT91C_HDMA_SRC_WIDTH_BYTE +
AT91C_HDMA_DST_WIDTH_BYTE +
TRANSFER_SIZE;

//Interrupt
AT91C_BASE_HDMA->HDMA_EBCIER=AT91C_HDMA_BTC0+AT91C_HDMA_BTC1;
IRQ_ConfigureIT(AT91C_ID_HDMA, 0, HDMA_IrqHandler);


}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Enable_DMA_SPI(void)
{
AT91C_BASE_HDMA_CH_0->HDMA_DADDR=(unsigned int)buff_in; // RX
AT91C_BASE_HDMA_CH_0->HDMA_CTRLA |= TRANSFER_SIZE;
AT91C_BASE_HDMA_CH_1->HDMA_CTRLA |= TRANSFER_SIZE;
AT91C_BASE_HDMA->HDMA_EN = AT91C_HDMA_ENABLE;

AT91C_BASE_HDMA->HDMA_CHER = AT91C_HDMA_ENA0_1; //RX
AT91C_BASE_HDMA->HDMA_CHER = AT91C_HDMA_ENA1_1; //TX
IRQ_EnableIT(AT91C_ID_HDMA);
}
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 10 2011, 14:48
Сообщение #11


Гуру
******

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



Код
AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_HDMA;

После этой строчки можно не смотреть, ибо бангалор. Но вполне возможно, что работает.

Почитайте документацию, DMAC достаточно простая вещь. Всего-то записать дюжину регистров.
Go to the top of the page
 
+Quote Post
DmitryM
сообщение May 10 2011, 17:01
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(aaarrr @ May 10 2011, 18:48) *
Код
AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_HDMA;

После этой строчки можно не смотреть, ибо бангалор. Но вполне возможно, что работает.

Нда уж, и возможно будет зависеть от ревизии кристала biggrin.gif
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 11 2011, 06:05
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Код
Код
AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_HDMA;

После этой строчки можно не смотреть, ибо бангалор. Но вполне возможно, что работает.


А в чем проблема?
Go to the top of the page
 
+Quote Post
DmitryM
сообщение May 11 2011, 08:58
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(*rust* @ May 11 2011, 10:05) *
Код
Код
AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_HDMA;

После этой строчки можно не смотреть, ибо бангалор. Но вполне возможно, что работает.


А в чем проблема?

В том что PMC_PCER write only.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 11 2011, 10:26
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Цитата
В том что PMC_PCER write only.

так команда
Код
AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_HDMA;

это же не чтение.

Вот функция от атмела
Код
void PMC_EnablePeripheral(unsigned int id)
{
    SANITY_CHECK(id < 32);

    if ((AT91C_BASE_PMC->PMC_PCSR & (1 << id)) == (1 << id)) {

        TRACE_INFO("PMC_EnablePeripheral: clock of peripheral"
                   " %u is already enabled\n\r",
                   id);
    }
    else {

        AT91C_BASE_PMC->PMC_PCER = 1 << id;
    }
}


где unsigned int id в данной случае будет AT91C_ID_HDMA


В чем проблема?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 11 2011, 10:28
Сообщение #16


Гуру
******

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



Цитата(*rust* @ May 11 2011, 14:26) *
так команда
Код
AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_HDMA;

это же не чтение.

Это не только чтение, это чтение-модификация-запись.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 11 2011, 12:12
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Все понятно, sm.gif Вы правы. Я сначала подумал вообще о записи в целом в этот регистр, о том, что не нужно туда писать.
Постараюсь подчистить код.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 24 2011, 12:15
Сообщение #18


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



После небольшого перерыва опять вернулся к решению проблемы с DMA и SPI
Оставил передачу SPI работать по прерываниям, настроил прием в буфер через DMA.

Предварительно не один из каналов DMA не работает.
CODE
//----
#define buffer_size 10
unsigned char DMA_BUFFER_1[buffer_size], *prt_DMA;
//----

настройка DMA на прием:

AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_HDMA; //тактирование DMA
AT91C_BASE_HDMA->HDMA_EN = AT91C_HDMA_ENABLE; //Вкл DMA

DMA_SetSourceAddr(0,(unsigned int)&AT91C_BASE_SPI0->SPI_RDR); //Установка адреса источника, в данном случае регистр приемника SPI
DMA_SetDestinationAddr(0,(unsigned int)prt_DMA); //Установка адреса буфера, куда данные складываются
DMA_SetSourceBufferSize(0, buffer_size, 0, 0, 1);
//Конф рег HDMA_CTRLA_0:номерканала,размер перемещаемых данных, формат данных ист(байт),
//формат данных прием(байт),done(почему-то стоит 1)

AT91C_BASE_HDMA_CH_0->HDMA_CTRLB = (AT91C_HDMA_SRC_DSCR_FETCH_DISABLE | //Конф рег HDMA_CTRLB_0
AT91C_HDMA_DST_DSCR_FETCH_DISABLE | //хз, в даташите для этого случая нужно откл
AT91C_HDMA_SRC_ADDRESS_MODE_FIXED | //режим фиксированного адреса для истрочника, т.к это регистр SPI
AT91C_HDMA_DST_ADDRESS_MODE_INCR | //режим инкремента для памяти
AT91C_HDMA_FC_PER2MEM); //направление периферия->память

AT91C_BASE_HDMA_CH_0->HDMA_CFG = (AT91C_HDMA_SRC_PER_2 | AT91C_HDMA_SRC_H2SEL_HW); //Hardware handshaking interface

//-----
ConfigureSPI();
//-----


//-----
Start_spi();
//-----

Start_DMA_RX()
{
DMA_SetSourceAddr(0,(unsigned int)&AT91C_BASE_SPI0->SPI_RDR);
DMA_SetDestinationAddr(0,(unsigned int)prt_DMA);
DMA_SetSourceBufferSize(0, buffer_size, 0, 0, 1);
DMA_EnableChannel(0);
}


В общем-то сие работает после каждого заполнения буфера перед след. итерацией нужно опять взводить DMA: Start_DMA_RX()


Очень интересует вопрос, что такое Hardware handshaking interface и Software handshaking interface и для чего они нужны?
Многократно прочитав DMA в даташите так и не смог добиться полного понимания.

Сообщение отредактировал IgorKossak - May 26 2011, 14:32
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 24 2011, 12:35
Сообщение #19


Гуру
******

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



Цитата(*rust* @ May 24 2011, 16:15) *
Очень интересует вопрос, что такое Hardware handshaking interface и Software handshaking interface и для чего они нужны?

В случае Hardware handshaking interface порция данных передается по сигналу запроса от периферии, в случае Software handshaking interface процессор должен для этого пнуть DMAC.
"Полезность" последнего режима вызывает некоторые сомнения.

P.S. хз в ваших комментариях - это бит, запрещающий считывание нового дескриптора из памяти. Устанавливается в "0" в режимах Multi Buffer Transfer.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 24 2011, 17:04
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Спасибо за ответ.
Цитата
В случае Hardware handshaking interface порция данных передается по сигналу запроса от периферии

Как я понял это штука работает без участия процессора?
Цитата
Устанавливается в "0" в режимах Multi Buffer Transfer.

У меня режим Single Buffer и вроде бы по описанию на 1021стр DST_DSCR and SRC_DSCR должны быть 1. Исправлю.

Забегая немного вперед:
Когда DMA передает в SPI на что должен ориентироваться DMA? Нужно ли конфигурировать SPI каким-то специальным образом? Я пытался запустить передачу через DMA но пока никак.
Многовато вопросовsm.gif)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 24 2011, 19:49
Сообщение #21


Гуру
******

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



Цитата(*rust* @ May 24 2011, 21:04) *
Как я понял это штука работает без участия процессора?

Именно.

Цитата(*rust* @ May 24 2011, 21:04) *
У меня режим Single Buffer и вроде бы по описанию на 1021стр DST_DSCR and SRC_DSCR должны быть 1. Исправлю.

Так в коде же все правильно - чтения дескрипторов запрещены.

Цитата(*rust* @ May 24 2011, 21:04) *
Забегая немного вперед:
Когда DMA передает в SPI на что должен ориентироваться DMA? Нужно ли конфигурировать SPI каким-то специальным образом? Я пытался запустить передачу через DMA но пока никак.

Специально конфигурировать не нужно. Разумеется, не нужно задействовать прерывания SPI и трогать регистр данных. Просмотрите код внимательно, скорее всего, где-нибудь допустили опечатку.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 25 2011, 05:43
Сообщение #22


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Цитата
Так в коде же все правильно - чтения дескрипторов запрещены.

Поторопился...

Вопрос по Hardware handshaking interface.
Как я понял для памяти этот интерфейс применять не нужно, т.к память всегда готова. Т.е HWI используется только для периферии, тогда как биты в полях SDC_PER, DST_PER регистра DMAC_CFG опознаватели того устройства с которым HWI работает.
Если все так для приема и передачи через DMA, дожны быть разные опознаватели.

Прием (SPI источник)
(AT91C_HDMA_SRC_PER_2 | AT91C_HDMA_SRC_H2SEL_HW)

Прием (SPI приемник)
(AT91C_HDMA_DST_PER_1 | AT91C_HDMA_DST_H2SEL_HW)

Правильно?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 25 2011, 09:36
Сообщение #23


Гуру
******

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



Все правильно. Только лучше номера идентификаторов периферии задать через дефайн, дабы не путаться.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 25 2011, 11:27
Сообщение #24


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



aaarrr, спасибо Вам за помощь!

Все получилось SPI через DMA заработал (прием и передача). Конечно очень помог пример с зарубежного сайта, который я приводил несколькими постами выше.
Для всех нуждающихся выкладываю код, сразу оговорюсь, что на оригинальность не претендую:

CODE
//настройка DMA от приемника SPI до буфера // RX

AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_HDMA;
AT91C_BASE_HDMA->HDMA_GCFG=0;
//
DMA_SetSourceAddr(0,(unsigned int)&AT91C_BASE_SPI0->SPI_RDR); //регист приемника SPI
DMA_SetDestinationAddr(0,(unsigned int)prt_DMA); //указатель на массив

DMA_SetSourceBufferSize(0, buffer_size, 0, 0, 1); // buffer_size-кол-во перемещаемых байт

AT91C_BASE_HDMA_CH_0->HDMA_CTRLB = (AT91C_HDMA_SRC_DSCR_FETCH_DISABLE |
AT91C_HDMA_DST_DSCR_FETCH_DISABLE |
AT91C_HDMA_SRC_ADDRESS_MODE_FIXED |
AT91C_HDMA_DST_ADDRESS_MODE_INCR |
AT91C_HDMA_FC_PER2MEM);

AT91C_BASE_HDMA_CH_0->HDMA_CFG = (AT91C_HDMA_SRC_PER_2 |
AT91C_HDMA_LOCK_IF_DISABLE |
AT91C_HDMA_LOCK_B_DISABLE |
AT91C_HDMA_SRC_H2SEL_HW |
AT91C_HDMA_DST_H2SEL_SW |
AT91C_HDMA_FIFOCFG_LARGESTBURST);

//настройка DMA в передатчик SPI с буфера памяти// ТX
//в моем случае я передаю одно и то же число, поэтому инкремента/декремента для памяти у меня нет.

DMA_SetSourceAddr(1,(unsigned int)prt_trr);
DMA_SetDestinationAddr(1,(unsigned int)&AT91C_BASE_SPI0->SPI_TDR);

DMA_SetSourceBufferSize(1, buffer_size, 0, 0, 1);

AT91C_BASE_HDMA_CH_1->HDMA_DSCR=0;
AT91C_BASE_HDMA_CH_1->HDMA_CTRLB = (AT91C_HDMA_SRC_DSCR_FETCH_DISABLE |
AT91C_HDMA_DST_DSCR_FETCH_DISABLE |
AT91C_HDMA_SRC_ADDRESS_MODE_FIXED|
AT91C_HDMA_DST_ADDRESS_MODE_FIXED|
AT91C_HDMA_FC_MEM2PER);

AT91C_BASE_HDMA_CH_1->HDMA_CFG = (AT91C_HDMA_DST_PER_1 |
AT91C_HDMA_SOD_DISABLE |
AT91C_HDMA_LOCK_IF_DISABLE |
AT91C_HDMA_LOCK_B_DISABLE |
AT91C_HDMA_SRC_H2SEL_SW |
AT91C_HDMA_DST_H2SEL_HW |
AT91C_HDMA_FIFOCFG_LARGESTBURST);
//В даташите написано, что нужно с начало запустить DMA, а потом периферию, если используете Flow controller
//поэтому:
void start_DMA(void)
{
DMA_SetSourceAddr(0,(unsigned int)&AT91C_BASE_SPI0->SPI_RDR);
DMA_SetDestinationAddr(0,(unsigned int)prt_DMA);
DMA_SetSourceBufferSize(0, buffer_size, 0, 0, 1);

DMA_SetSourceAddr(1,(unsigned int)prt_trr);
DMA_SetDestinationAddr(1,(unsigned int)&AT91C_BASE_SPI0->SPI_TDR);
DMA_SetSourceBufferSize(1, buffer_size, 0, 0, 1);

DMA_EnableChannel(0);
DMA_EnableChannel(1);
}

//Configure pins for SPI
PIO_Configure(pinsSPI, PIO_LISTSIZE(pinsSPI));
ConfigureSPI();// and Enable SPI



После каждого прохода DMA нужно не забывать делать переинициализацию DMA: void start_DMA(void)


Если заметите ошибки, пишите. Думаю, что это будет полезно всем.

Еще раз спасибо за помощь!

Сообщение отредактировал IgorKossak - May 26 2011, 14:33
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 26 2011, 09:44
Сообщение #25


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



aaarrr, такой вопрос: Можно ли сделать CS(чип-селект) байт-ориентированным, т.е после каждого переданного байта CS подымается, при работе SPI через DMA? В документации я читал что, SPI with DMAC, CS опускает перед передачей и подымает его только когда передал весь указанный в настройках массив.
И второй вопрос: Куда смотрит DMA когда выбирает каким CS дергать? CS у меня два, когда все работало по прерываниям, я сам указывал, при необходимости, каким CS нужно дергать а тут как?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 26 2011, 10:20
Сообщение #26


Гуру
******

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



Цитата(*rust* @ May 26 2011, 13:44) *
aaarrr, такой вопрос: Можно ли сделать CS(чип-селект) байт-ориентированным, т.е после каждого переданного байта CS подымается, при работе SPI через DMA? В документации я читал что, SPI with DMAC, CS опускает перед передачей и подымает его только когда передал весь указанный в настройках массив.

На SAM7 для этого нужно было использовать "левые" передачи с фиктивным CS. Подозреваю, что и здесь нужен такой же финт.

Цитата(*rust* @ May 26 2011, 13:44) *
И второй вопрос: Куда смотрит DMA когда выбирает каким CS дергать? CS у меня два, когда все работало по прерываниям, я сам указывал, при необходимости, каким CS нужно дергать а тут как?

Тут все точно так же. Если работаете в режиме Fixed Peripheral, то CS выбирается в SPI_MR, в случае Variable Peripheral CS указывается в регистре данных.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 26 2011, 10:43
Сообщение #27


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Спасибо за ответ!
Цитата
На SAM7 для этого нужно было использовать "левые" передачи с фиктивным CS. Подозреваю, что и здесь нужен такой же финт.

По подробнее можно? sm.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 26 2011, 10:54
Сообщение #28


Гуру
******

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



Цитата(*rust* @ May 26 2011, 14:43) *
По подробнее можно? sm.gif

Заводится некий фиктивный CS из неиспользуемых (скажем, NPCS3), для него выставляется режим с максимально коротким временем передачи - 8 бит, MCK/2. Физически этот сигнал никуда не выводится, т.е. ногу можно использовать под PIO. Для обмена отдельными словами с периферией на другом CS (например, NPCS0), используем такую последовательность:
Передача NPCS0
Передача NPCS3
Передача NPCS0
Передача NPCS3
...
Выглядит коряво, конечно, но другого способа не предусмотрено.
Go to the top of the page
 
+Quote Post
*rust*
сообщение May 26 2011, 11:44
Сообщение #29


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



понятно. Спасибо
Go to the top of the page
 
+Quote Post

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

 


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


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