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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> DMA - для чего он и как его использовать
Kitsok
сообщение Feb 1 2007, 14:08
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Цитата(Karl @ Feb 1 2007, 13:26) *
Спасибо, вроде все понятно. А с приемом Вы не разбирались?

Нет, мне пока без надобности. Я на прием PDC использую с ADC. Код надо?
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Feb 1 2007, 14:53
Сообщение #17


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

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Цитата(Kitsok @ Feb 1 2007, 14:08) *
Нет, мне пока без надобности. Я на прием PDC использую с ADC. Код надо?


Мне надо. smile.gif Если не затруднит.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
Karl
сообщение Feb 1 2007, 16:47
Сообщение #18


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

Группа: Свой
Сообщений: 179
Регистрация: 4-02-05
Пользователь №: 2 429



Цитата(Kitsok @ Feb 1 2007, 16:08) *
Цитата(Karl @ Feb 1 2007, 13:26) *

Спасибо, вроде все понятно. А с приемом Вы не разбирались?

Нет, мне пока без надобности. Я на прием PDC использую с ADC. Код надо?


Да, пригодится. Кстати, передача заработала сразу smile.gif Спасибо!

У меня на SPI АЦП сидит. Так что надо и передачу и прием.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 1 2007, 19:38
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sonycman @ Jan 31 2007, 23:40) *
The Memory Controller has a simple, hard-wired priority bus arbiter that gives the control of the
bus to one of the two masters. The Peripheral DMA Controller has the highest priority; the ARM
processor has the lowest one.
[AT91SAM7S.pdf, 6175G–ATARM–22-Nov-06, page 120]

Действительно, курить в сторонке будет процессор, а не DMA...

Причем по другому для периферийного железа которое не имеет своих буферов и быть не может,
например, летит в 100 Mbit интерфейс 1500 байтовый пакет. Куда ему прикажете его девать?
Тут уж или терять, или процессор идет на перекур. Без вариантов.



Цитата(ASN @ Jan 31 2007, 22:05) *
zltigo
Режим работы контроллера DMA определяется в первую очередь типом используемой накристальной шины.

Определяется, например, свежие LPC23xx имеют два банка памяти и соответственно две шины,
что позволяет достаточно независимо работать DMA (в своих 8K) и CPU каждому в своем банке большую часть времени. Обычные ARM7 такого не имеют.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 2 2007, 01:46
Сообщение #20


кекс
******

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



Цитата(zltigo @ Feb 1 2007, 18:38) *
Причем по другому для периферийного железа которое не имеет своих буферов и быть не может,
например, летит в 100 Mbit интерфейс 1500 байтовый пакет. Куда ему прикажете его девать?
Тут уж или терять, или процессор идет на перекур. Без вариантов.

Действительно.
My bad..
Go to the top of the page
 
+Quote Post
Kitsok
сообщение Feb 2 2007, 11:48
Сообщение #21


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Это инициализация

Код
#define NCHANNELS 8

extern volatile unsigned portSHORT sADC_RAW[NCHANNELS*2];
#define   TRGEN    (0x0)    // Hardware triggering
#define   TRGSEL   (0x0)    // Use a Timer output signal (on rising edge) from TIOA0 (for this example)
#define   LOWRES   (0x0)    // 8-bit result output
#define   SLEEP    (0x0)    // Normal Mode
#define   PRESCAL  (0x0f)    // Max value
#define   STARTUP  (0xc)    // This time period must be higher than 20 ╣s and not 20 ms
#define   SHTIM    (0x2)    // Must be higher than 3 ADC clock cycles but depends on output
                            // impedance of the analog driver to the ADC input

void InitADC(void) {

  // Reset ADC
  AT91F_ADC_SoftReset (AT91C_BASE_ADC);

  // Open PDC for ADC
  AT91F_PDC_Open (AT91C_BASE_PDC_ADC);

  // Configure PDC for 2 buffers NCHANNELS bytes long each (Warning! Depends on LOWRES bit)
  AT91F_PDC_ReceiveFrame ( AT91C_BASE_PDC_ADC ,
                                (char *) &sADC_RAW[0], NCHANNELS,
                                (char *) &sADC_RAW[NCHANNELS], NCHANNELS);

  // Configure ADC
  AT91F_ADC_CfgModeReg (AT91C_BASE_ADC, (SHTIM << 24) | (STARTUP << 16) | (PRESCAL << 8) |
                             (SLEEP << 5) | (LOWRES <<4) | (TRGSEL << 1) | (TRGEN ) );

  // Enable all 8 channes
  AT91F_ADC_EnableChannel(AT91C_BASE_ADC, (1<<NCHANNELS) - 1);

  // Fire conversion
  AT91F_ADC_StartConversion(AT91C_BASE_ADC);
}


А это собственно работа
Код
        // Check what buffer to use from ADC
        if (AT91C_BASE_PDC_ADC->PDC_RCR == 0)
         {
          ptrADC_RAW=NCHANNELS;
          AT91F_PDC_ReceiveFrame ( AT91C_BASE_PDC_ADC ,
                                (char *) &sADC_RAW[0], NCHANNELS,
                                (char *) &sADC_RAW[NCHANNELS], NCHANNELS);
         }
        else
         {
          ptrADC_RAW=0;
         }

        // Re-fire conversion
        AT91F_ADC_StartConversion(AT91C_BASE_ADC);


Тут возможно следовало бы использовать библиотечные функции, но я не запарился и читаю напрямую PDC_RCR.
ptrADC_RAW нужен для того, чтобы знать, в какой части буфера лежат свежие данные:

Код
// Convert 10-bit wide ADC results into 8-bit wide
          // Clean target array
          for(i=0;i<(NCHANNELS*10/8);i++) ucAxes[i]=0;

          // Do bit manipulations
          // The trick with +0x0200 & 0x03ff is - we need negative 10-bit wide number
          for(i=0;i<(NCHANNELS*10);i++)
           {
            ucAxes[i/8] += (((((sADC_RAW[ptrADC_RAW+(i/10)] + 0x0200)&0x03ff)>> (i%10))  & 0x01) << (i%8));
           }


Сообщение отредактировал Kitsok - Feb 2 2007, 11:51
Go to the top of the page
 
+Quote Post
Karl
сообщение Feb 6 2007, 13:16
Сообщение #22


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

Группа: Свой
Сообщений: 179
Регистрация: 4-02-05
Пользователь №: 2 429



Можно ли одновременно передавать массив данных в SPI через ДМА и получать данные из SPI через тот же ДМА? Что-то у меня не получается такой обмен... Передача идет, а прием - нет.
Go to the top of the page
 
+Quote Post
Kitsok
сообщение Feb 6 2007, 15:28
Сообщение #23


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Цитата(Karl @ Feb 6 2007, 13:16) *
Можно ли одновременно передавать массив данных в SPI через ДМА и получать данные из SPI через тот же ДМА? Что-то у меня не получается такой обмен... Передача идет, а прием - нет.


Ну вообще, PDA - штука двунаправленная, но конкретику надо смотреть в даташите и всяких примерах. Я не реализовывал двунаправленную передачу по SPI.
Go to the top of the page
 
+Quote Post
Karl
сообщение Feb 7 2007, 08:44
Сообщение #24


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

Группа: Свой
Сообщений: 179
Регистрация: 4-02-05
Пользователь №: 2 429



Цитата(Kitsok @ Feb 6 2007, 17:28) *
Цитата(Karl @ Feb 6 2007, 13:16) *

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


Ну вообще, PDA - штука двунаправленная, но конкретику надо смотреть в даташите и всяких примерах. Я не реализовывал двунаправленную передачу по SPI.


Спасибо, вроде разобрался. Заработало.
Go to the top of the page
 
+Quote Post
Kitsok
сообщение Feb 12 2007, 19:01
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Цитата(Karl @ Feb 7 2007, 08:44) *
Спасибо, вроде разобрался. Заработало.

Добрый день!

А можете код показать? Удалось ли принимать данные с использованием PDC?
Go to the top of the page
 
+Quote Post
Karl
сообщение Feb 15 2007, 07:26
Сообщение #26


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

Группа: Свой
Сообщений: 179
Регистрация: 4-02-05
Пользователь №: 2 429



Цитата(Kitsok @ Feb 12 2007, 21:01) *
Цитата(Karl @ Feb 7 2007, 08:44) *

Спасибо, вроде разобрался. Заработало.

Добрый день!

А можете код показать? Удалось ли принимать данные с использованием PDC?


Да, передачу и прием по PDC организовать удалось. Проблемы, как оказалось, были не с PDC, а с некорректной работой с SPI.
Инициализация SPI:
Код
void SPI_ini(void)
{

    AT91F_SPI_Reset(AT91C_BASE_SPI);
    //delay_ms(5);
    // Инициализация SPI. Запустим на работу с частотой примерно 2,5 МГц
    // Конфигурация канала АЦП (2 канал)
    AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_SPI);        // Тактирование на SPI
    
    AT91F_SPI_CfgMode(AT91C_BASE_SPI,
                    1<<0|                //Интерфейс работает в режиме ведущего.
                    0<<1|                //Фиксированный выбор корпуса внешнего периферийного устройства.
                    0<<2|                //PCSDEC: Декодирование выбора корпуса 0 = Периферийные устройства непосредственно подключены к выводам выбора корпуса.
                    0<<4|                //MODFDIS: Определение ошибки режима работы 0 =Определение ошибки режима работы запрещено.
                    0<<7|                // Зацикливание 0 - отключено
                    0xb<<16);                // PCS: Выбор корпуса периферии  Корпус 3
        
    AT91F_SPI_CfgCs(AT91C_BASE_SPI,2,
                    AT91C_SPI_BITS_8|            // 8 бит в пакете
                    400<<8|                        // Частота SPI в 20 наза меньше MCK    (необходимо не более 2,5 МГц)
                    2<<16|                        // Задержка перед выдачей тактовой частоты
                    0<<24|                        // Задержка между последовательными передачами данных
                    1<<1);


    AT91F_SPI_Enable(AT91C_BASE_SPI);
    AT91F_PDC_Open(AT91C_BASE_PDC_SPI);
}


Собственно работа:
Код
for(;;)

{
while(AT91F_SPI_SendFrame(AT91C_BASE_SPI,(char*) &SPI_buf_TX[0],sizeof(SPI_buf_TX),0,0) == 0);
        u08 a = AT91F_SPI_ReceiveFrame(AT91C_BASE_SPI,(char*) &SPI_buf_RX[0],sizeof(SPI_buf_TX),0,0);
    // Ожидаем, пока приемный буфер заполнится. В дальнейшем включу на прерывание.
    while(!( a = AT91C_BASE_SPI->SPI_SR & AT91C_SPI_ENDRX));
    ...
    ...    
    ...    
}
Go to the top of the page
 
+Quote Post
Kitsok
сообщение Feb 15 2007, 18:55
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Спасибо большое!

Я так и думал, что в общем-то ничего сложного.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Feb 15 2007, 19:59
Сообщение #28


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

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
Собственно работа:
Код
for(;;)

{
while(AT91F_SPI_SendFrame(AT91C_BASE_SPI,(char*) &SPI_buf_TX[0],sizeof(SPI_buf_TX),0,0) == 0);
        u08 a = AT91F_SPI_ReceiveFrame(AT91C_BASE_SPI,(char*) &SPI_buf_RX[0],sizeof(SPI_buf_TX),0,0);
    // Ожидаем, пока приемный буфер заполнится. В дальнейшем включу на прерывание.
    while(!( a = AT91C_BASE_SPI->SPI_SR & AT91C_SPI_ENDRX));
    ...
    ...    
    ...    
}


Кстати абсолютно не вижу кайфа в такой конструкции.
ДМА гонит данные, ядро ожидает завершения. Точно так же можно использовать и программные счетчик и указатель.
Чтобы действительно получить выигрыш, флажок завершения приема/передачи надо прицепить к прерыванию. В таком случае действительно ДМА будет жить своей жизнью, а ядро отвлекаться на подготовку/обработку данных один раз на фрейм, а в остальное время заниматься чем-то полезным.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
Karl
сообщение Feb 16 2007, 09:29
Сообщение #29


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

Группа: Свой
Сообщений: 179
Регистрация: 4-02-05
Пользователь №: 2 429



Цитата(beer_warrior @ Feb 15 2007, 21:59) *
Цитата

Собственно работа:
Код
for(;;)

{
while(AT91F_SPI_SendFrame(AT91C_BASE_SPI,(char*) &SPI_buf_TX[0],sizeof(SPI_buf_TX),0,0) == 0);
        u08 a = AT91F_SPI_ReceiveFrame(AT91C_BASE_SPI,(char*) &SPI_buf_RX[0],sizeof(SPI_buf_TX),0,0);
    // Ожидаем, пока приемный буфер заполнится. В дальнейшем включу на прерывание.
    while(!( a = AT91C_BASE_SPI->SPI_SR & AT91C_SPI_ENDRX));
    ...
    ...    
    ...    
}


Кстати абсолютно не вижу кайфа в такой конструкции.
ДМА гонит данные, ядро ожидает завершения. Точно так же можно использовать и программные счетчик и указатель.
Чтобы действительно получить выигрыш, флажок завершения приема/передачи надо прицепить к прерыванию. В таком случае действительно ДМА будет жить своей жизнью, а ядро отвлекаться на подготовку/обработку данных один раз на фрейм, а в остальное время заниматься чем-то полезным.


А Вы прочитайте внимательнее комментарии. Я выложил кусок тестовой програмки. Так проще разобраться в коде тем, кто будет смотреть. Реально у меня все на прерываниях.
Go to the top of the page
 
+Quote Post
Kitsok
сообщение Feb 16 2007, 11:46
Сообщение #30


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Цитата(beer_warrior @ Feb 15 2007, 19:59) *
Кстати абсолютно не вижу кайфа в такой конструкции.
ДМА гонит данные, ядро ожидает завершения. Точно так же можно использовать и программные счетчик и указатель.
Чтобы действительно получить выигрыш, флажок завершения приема/передачи надо прицепить к прерыванию. В таком случае действительно ДМА будет жить своей жизнью, а ядро отвлекаться на подготовку/обработку данных один раз на фрейм, а в остальное время заниматься чем-то полезным.


Ну почему-же нету кайфа.

Я например под FreeRTOS клепаю, так у меня, пока данные не готовы, будет отдаваться выполнение другим задачам wink.gif

Другой вопрос меня интересует, может доку не внимательно читал.

Вот допустим, я так сделал железо, что один и тот-же ChipSelect у меня работает и на передачу и на прием (разнос по сигналами MOSI/MISO).
Запускаю я одновременно и передачу и прием.
SPI может дупелксно и передавать и принимать?
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 28th June 2025 - 12:56
Рейтинг@Mail.ru


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