[an error occurred while processing this directive]
Ответ: :)) (+)
(«Телесистемы»: Конференция «Цифровые сигнальные процессоры (DSP) и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Чайник 14 января 2004 г. 19:07
В ответ на: Ответ: (+) отправлено Kolja 14 января 2004 г. 18:15

Не все так просто: Канал DMA может либо принимать, либо передавать.
Из этого следует, что бит готовности приема в режиме передачи ничего не значит ... В режиме передачи - контроль завершения, это прерывание передачи по DMA, но !!! Поскольку контроллер DMA имеет на борту FIFO, то, прерывание генерится сразу после того, как последнее слово записано в FIFO. Другими словами - после поступления прерывания, требуется проконтролировать буфер канального передатчика на отсутсвие в FIFO слов на передачу. С приемом проще - прерывание генерится тогда, когда последнее слово размещено в памяти. Тоесть - там не требуется контроль FIFO.
Кроме того - мне не удалось передавать пакеты менее 4 слов (глубина FIFO), как - то там криво это было сделано ...

В общем ... ниже идет код - попробуйте разобраться, он 100% рабочий за исключением флагов естесноо ..


//========================================================================================================

IOPG = Timer_Page;
ar = 0x0015; io(CFGR0) = ar; // Конфигурация таймера ИКМ, активный - 1, непериодический,
// запрос на прерывание,

//===== Внимание ! Изменение конфигурации таймера в программе приводит к жестким "глюкам"


ar = 0xffff; io(PRDL0) = ar; // Период младшее слово
ar = 0x0000; io(PRDH0) = ar; // Период старшее слово
ar = 0x0000; io(WLR0) = ar; // Перезагружаемое значение счетчика младшее слово
ar = 0x0000; io(WHR0) = ar; // Перезагружаемое значение счетчика старшее слово


//================== Дескриптор обмена SPI по DMA =======================================================


ar = SPI0_BUF_IN; dm(SPI0_HEAD+2) = ar; // HEAD1[+2] - DMA START ADDRESS
ar = 0x0000; dm(SPI0_HEAD) = ar; // HEAD1[0] - DMA CONFIGURATION
dm(SPI0_HEAD+1) = ar; // HEAD1[+1] - DMA START PAGE
dm(SPI0_HEAD+3) = ar; // HEAD1[+3] - DMA WORD COUNT + 2
ar = SPI0_HEAD; dm(SPI0_HEAD+4) = ar; // HEAD1[+4] - NEXT DESCRIPTOR POINTER


//=================== Выводы флагов =====================================================================


IOPG=General_Purpose_IO;

ax0 = 0x0800;
io(FLAGC)= ax0; // Сброс P3
ax0 = 0x0400;
io(FLAGC)= ax0; // Сброс P2

ar = setbit 7 of ax1; // Демаскировать прерывание Таймера 0
ar = setbit 8 of ar; // Разрешить прерывание по P1
ar = setbit 9 of ar; // Разрешить прерывание по P4

ar = setbit 15 of ar; // Разрешить прерывание по P4

IMASK = ar;

//========================================================================================================
rts;


SPI0_TX:

dm(SPI0_HEAD+3) = mx0;

call Start_Timer_Reset_SPI;

si = 0x0080; io(SPI0D_CFG) = si; // Зачистить буфер контроллера DMA
si = 0x8001; dm(SPI0_HEAD) = si; // Конфигурация DMA в DM

// si = SPI0_BUF_IN+1; dm(SPI0_HEAD+2) = si; // HEAD1[+2] - DMA START ADDRESS
si = SPI0_HEAD; dm(SPI0_HEAD+4) = si; // Указатель следующего дескриптора в DM

// si = 0x0000; io(TDBR0) = si;

si = SPI0_HEAD; io(SPI0D_CP) = si; // Указатель дескриптора в IO
si = 0x5D1E; io(SPICTL0) = si; // SPI0 Control Register in DMA MODE wait until start
si = 0x8001; io(SPI0D_CFG) = si; // Старт !!!
nop;
si = 0xFC02; io(SPIFLG0) = si; // SPI0 Flag register


rts;

SPI0_RX:
// Счетчик передаваемых слов должен
// быть записан в mx0

dm(SPI0_HEAD+3) = mx0;

call Start_Timer_Reset_SPI;

si = 0x0080; io(SPI0D_CFG) = si; // зачистка буфера DMA
si = 0x0000; dm(SPI0_HEAD+4) = si; // HEAD1[+4] - NEXT DESCRIPTOR POINTER
si = 0x8003; dm(SPI0_HEAD) = si; // Конфигурация DMA

si = SPI0_HEAD; io(SPI0D_CP) = si; // точка след дескриптора
si = 0x511E; io(SPICTL0) = si; // Конфигурация порта на прием !!!
si = 0x8003; io(SPI0D_CFG) = si; // Старт !!!
nop;
si = 0xFC02; io(SPIFLG0) = si; // Разрешаем CLK в альтере SPI0SEL


rts;

Start_Timer_Reset_SPI: // Количество передаваемых слов должно быть в mx0

IOPG = Timer_Page;

my0 = 0x0066; // 204 такта на слово конец обмена определяется
mr = mx0*my0 (UU); // по таймеру
io(WLR0) = mr0;
io(WHR0) = mr1; // старшее слово
si = 0x0100; io(GSR0) = si; // Разрешить работу таймера 0

IOPG = SPI0_Controller_Page; // == 0x4

si = 0x0000; io(SPICTL0) = si; // Стоп канал SPI0
io(SPI0D_CFG) = si; // Стоп DMA SPI0
io(SPIBAUD0) = si; // Сброс регистра скорости
si = 0x0056; io(SPIST0) = si; // Сбросить статус
si = 6; io(SPIBAUD0) = si; // Загрузка регистра скорости

rts;


Timer_Stop_RST_PIO: // Этот кусок используется в обработчике
// прерываний обмена по SPI

IOPG = Timer_Page;

ar = 0x0300; io(GSR0) = ar; // Таймер стоп
ar = 0xffff; io(PRDL0) = ar; // Период младшее слово
ar = 0x0000; io(PRDH0) = ar; // Период старшее слово
io(WLR0) = ar; // Перезагружаемое значение счетчика младшее слово
io(WHR0) = ar; // Перезагружаемое значение счетчика старшее слово

IOPG=General_Purpose_IO;

ax0 = 0x0800;
io(FLAGC)= ax0; // Сброс P3 запрос на передачу
ax0 = 0x0400;
io(FLAGC)= ax0; // Сброс P2 строб контр. суммы

rts;



Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru