Перейти к содержанию
    

UART передача по DMA

Здравствуйте!

У меня возникла следующая проблема при программировании BF534:

Необходимо сделать передачу массива по UART через DMA. По окончанию передачи надо запускать прерывание.

Как только инициализирую прерывания, процессор уходит в обработчик этого прерывания, и там и крутится :)

Подскажите, что мог сделать неправильно. Заранее спасибо за помощь.

 

Кусок кода:

 

void initUART()
{
            *pDMA9_X_COUNT   = 512 ; 
            *pDMA9_X_MODIFY  = 4 ; 
            *pDMA9_CONFIG      = 0x0080 ; 
//=============================
*pPORTF_FER = 0x3;           
*pUART0_GCTL = 0x0001;      
*pUART0_LCR = 0x0083 ;       
*pUART0_MCR = 0x0000 ;       
*pUART0_DLH = 0x0000 ;       
*pUART0_DLL = 0x002B ;     
*pUART0_LCR = 0x0003 ;       
*pUART0_IER = ERBFI | ETBEI; 
            } 
//-----------------------------------------------------------
void initIRQ(void)
{
*pSIC_IAR0 = 0xffffffff ;
*pSIC_IAR1 = 0xfff33fff ;
*pSIC_IAR2 = 0xffffffff ;
*pSIC_IAR3 = 0xffffffff ;
register_handler(ik_ivg10, UART0RxTx_ISR); // UART RX -> IVG 10
*pSIC_IMASK = 0x00001000;
} 
//-----------------------------------------------------------

 

Если прерывания не включать (маскировать), ПДП прекрасно срабатывает..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что же вы сам обработчик прерывания UART0RxTx_ISR не приложили? Наверно вы там не сбрасываете причину возникновения прерывания. Я не использовал DMA для UART. Работал только по прерывания по каждому байту. Там внутри прерывания вроде надо было читать регистр *pUART_IIR (это BF533). После этого бит прерывания сбрасывался. Если вы не делаете подобных действий, при выходе из прерывания остается установленный бит прерывания. Процессор выполняет несколько команд и снова заходит в обработчик прерывания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здраствуйте!

Наверно нужно сделать следующее в обработчике прерывания:

*pDMA9_IRQ_STATUS |= DMA_DONE;

 

 

Здравствуйте!

У меня возникла следующая проблема при программировании BF534:

Необходимо сделать передачу массива по UART через DMA. По окончанию передачи надо запускать прерывание.

Как только инициализирую прерывания, процессор уходит в обработчик этого прерывания, и там и крутится :)

Подскажите, что мог сделать неправильно. Заранее спасибо за помощь.

 

Кусок кода:

 

void initUART()
{
            *pDMA9_X_COUNT   = 512 ; 
            *pDMA9_X_MODIFY  = 4 ; 
            *pDMA9_CONFIG      = 0x0080 ; 
//=============================
*pPORTF_FER = 0x3;           
*pUART0_GCTL = 0x0001;      
*pUART0_LCR = 0x0083 ;       
*pUART0_MCR = 0x0000 ;       
*pUART0_DLH = 0x0000 ;       
*pUART0_DLL = 0x002B ;     
*pUART0_LCR = 0x0003 ;       
*pUART0_IER = ERBFI | ETBEI; 
            } 
//-----------------------------------------------------------
void initIRQ(void)
{
*pSIC_IAR0 = 0xffffffff ;
*pSIC_IAR1 = 0xfff33fff ;
*pSIC_IAR2 = 0xffffffff ;
*pSIC_IAR3 = 0xffffffff ;
register_handler(ik_ivg10, UART0RxTx_ISR); // UART RX -> IVG 10
*pSIC_IMASK = 0x00001000;
} 
//-----------------------------------------------------------

 

Если прерывания не включать (маскировать), ПДП прекрасно срабатывает..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за советы )

Прерывания я сбрасывал.

Раньше работал без ДМА, тогда считывал IIR регистр, прерывание сбрасывалось. Всё работало.

Теперь по ДМА в обработчике пишу

*pDMA9_IRQ_STATUS = 0x0001 ;//(сигнал W1C, запись 1 для сброса). Пробовал и IIR читать. Прерывание сбрасывается, но тут же снова устанавливается (смотрел в регистрах).

Просто у меня проблема вроде не в этом.

 

По идее, прерывание должно при моей инициализации возникнуть после ДМА (когда обнулиться счетчик и опустошится буфер), НО оно возникает сразу же после включения прерываний,

после исполнения этой строчки: *pSIC_IMASK = 0x00001000; Я ещё даже не успеваю запустить ДМА, и в итоге так и не запускаю, потому что программа начинает сразу же крутиться в обработчике.

Вот я и подумал, что или забыл что-то при инициализации или хитрость какая :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я делаю вот так:

 

//инициализация UART
void Init_UART(void)
{
    *pUART_LCR = 0x0003;                                        
    *pUART_IER = 0x0000;        
    *pUART_GCTL = 0x0030;        
}
void SetBaudRate(void)
{    
    *pUART_DLL = BAUDRATE_LOW;
    *pUART_DLH = BAUDRATE_HIGH;        
}
void On_UART_Clock(void)
{
    *pUART_GCTL |= 0x0001;    
}

//разрешаю прерывания по UART
VDK_SetInterruptMaskBits(IVG10);

//...

//настраиваю ДМА
void Init_TxUART_DMA(unsigned char *buff, unsigned int size)
{
    *pDMA7_CONFIG = 0x0080;        
    *pDMA7_START_ADDR = buff;
    *pDMA7_X_COUNT = size;
    *pDMA7_X_MODIFY = 1;        
}
//вкл передачу по ДМА
void TxUART_en(void)
{
    *pDMA7_CONFIG |= 0x0001;    
    *pUART_IER |= 0x0002;        

}

 

В обработчике прерывания

//выкл передачу по ДМА 
void TxUART_dis(void)
{
    *pUART_IER &= ~0x0002;        
    *pDMA7_CONFIG &= ~0x0001;        
}
//сбрасываю ист ДМА
*pDMA7_IRQ_STATUS = 0x0001;

 

Девятый канал ДМА это ДМА типа "память-память" насколько я помню :laughing:

 

В симуляторе прерывание возникает как и положено после передачи блока данных размером size.

 

Только у меня в другом проблема.

я передаю данные в файл. Так вот туда пишутся данные через один почему то.

Т.е. отправляю size, а в файле size/2 значений, причем 1,3,5,....

 

А принимает наоборот - каждое значение записывает по 2 раза, т.е. допустим хочу принять 4 байта: 1,2,3,4

А в память он записывает четыре байта: 1,1,2,2

 

Думаю может симулятор криво симулирует? Появится железяка проверю там

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

*pSIC_IAR0 = 0xffffffff ;

*pSIC_IAR1 = 0xfff33fff ;

*pSIC_IAR2 = 0xffffffff ;

*pSIC_IAR3 = 0xffffffff ;

А ничего что ff - некорректное значение для iar? Зачем вам вообще эти строки? uart ведь и так на 10-м ivg.

И где инициализация DMA_START_ADDR?

 

Девятый канал ДМА это ДМА типа "память-память" насколько я помню :laughing:

Да нет, вам память изменяет :laughing: Он как раз UART TX.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А ничего что ff - некорректное значение для iar? Зачем вам вообще эти строки? uart ведь и так на 10-м ivg.

И где инициализация DMA_START_ADDR?

ff убрал, правда это ничего не поменяло в моем случае. Но вы правы, некорректно. Откуда то с примеров на форуме скопипастил. )

Инициализация DMA_START_ADDR производится при запуске пдп в основной части программы, т.к. могут различные массивы передаваться.

Не все исходники выложил, вы уж извините )) Подумал, что слишком много кода получится.

Я делаю вот так:

.....

Сделал как у вас, всё заработало. То есть просто добавил разрешение прерываний по уарт при запуске и отключение в обработчике (а было разрешение при инициализации и никаких запрещений). Да, и ещё добавил *pDMA9_CONFIG &= ~0x0001; в обработчик. Почему то думал, что после завершения блока передачи этот бит сам сбрасывается (

запуск:

*pDMA9_START_ADDR = &buf_uart0; 
*pDMA9_CONFIG |= 0x0001;    
*pUART0_IER |= 0x0002;

обработчик:

*pUART0_IER &= ~0x0002;        
*pDMA9_CONFIG &= ~0x0001; 
*pDMA9_IRQ_STATUS = 0x0001;

Насчет того, что у вас символы пропадают, ничего сказать не могу, у меня всё корректно. Может и правда на железе у вас всё будет нормально.

 

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не все исходники выложил, вы уж извините )) Подумал, что слишком много кода получится.

 

А сервисами ("Services") не пробовали пользоваться ? Я работаю с EZ-Kit 537 , сервисы, по-моему, сокращают объём работы при программировании новых устройств/функций

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что это такое?

 

функции из <services/services.h>, оч удобная и полезная штука, и работает стабильно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что это такое?

http://www.analog.com/static/imported-file..._man.rev3.2.pdf :

The system services form a collection of functions that are commonly found in embedded systems. Each system service focuses on a specific set of functionality such as direct memory access (DMA), power management (PM), interrupt control (IC), and so on. Collectively, the system services provide a wealth of pre-built, optimized code that simplifies software development, allowing you to get Blackfin processor-based designs to market more quickly.

The device driver model provides a simple, clean and familiar interface into device drivers for Blackfin processors. The primary objective of the device driver model is to create a concise, effective, and easy-to-use interface through which applications can communicate with device drivers. Secondarily, the model and device manager software significantly simplifies the development of device drivers, making the development of new device drivers very straightforward

 

оч удобная и полезная штука, и работает стабильно...

В общем да. Только достаточно тяжелая (по объему кода).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем да. Только достаточно тяжелая (по объему кода).

 

ну, в условиях войны с UART'ом, - это можно сказать кавалерия... )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...