|
|
  |
Прикрутить программный FIFO для UART LPC17XX, Как лаконично организовать? |
|
|
|
Oct 11 2013, 21:11
|
Местный
  
Группа: Свой
Сообщений: 454
Регистрация: 13-10-10
Из: Киев
Пользователь №: 60 135

|
Здравствуйте! Вывожу в UART с помощью printf(), предварительно подправив Retarget.c, в функцию fputc() внес следующее: Код int fputc(int c, FILE *f) { UART_SendByte(LPC_UART0, c); return (c);} Когда я предаю по UART длинные строки при помощи printf, то реально передаётся только первая часть строки, это по-идее происходит из-за наличия в модуле UART 16-и байтового аппаратного FIFO. Хочу подправить функцию fputc(), введя в неё программный FIFO, дабы иметь возможность передавать одной командой printf() большие строки. Можно, конечно, ввести в fputc() проверку освобождения аппаратного FIFO, но тогда процессор будет тратить такты впустую, чего не хочется. Подскажите, как бы его так сделать, чтобы между printf() и модулем UART'a был программный FIFO, и в то же время этот FIFO со как-то освобождался, то-ли по прерыванию от таймера, то-ли ... Как правильнее это реализовать?
|
|
|
|
|
Oct 11 2013, 21:30
|
Местный
  
Группа: Свой
Сообщений: 454
Регистрация: 13-10-10
Из: Киев
Пользователь №: 60 135

|
Не до конца объяснил. printf действительно про фифо ничего не знает, вот и гонит в UART_SendByte() по байтику всю строку, а UART_SendByte() вот такая: Код void UART_SendByte(LPC_UART_TypeDef* UARTx, uint8_t Data) { UARTx->THR = Data & UART_THR_MASKBIT; } То есть эта функция просто вносит в регистр передаваемых данных ещё один байт, не проверяя есть ли свободная ячейка в аппаратном фифо. ....Хм, пересмотрел код, у меня, кажется, аппаратный фифо был выключен. Попробую его включить, завтра получу доступ к железу - протестирую как теперь будет работать printf() с большими строками и отпишусь.
|
|
|
|
|
Oct 11 2013, 21:36
|
Знающий
   
Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245

|
Цитата(kt368 @ Oct 12 2013, 01:30)  Не до конца объяснил. printf действительно про фифо ничего не знает, вот и гонит в UART_SendByte() по байтику всю строку, а UART_SendByte() вот такая: Код void UART_SendByte(LPC_UART_TypeDef* UARTx, uint8_t Data) { UARTx->THR = Data & UART_THR_MASKBIT; } То есть эта функция просто вносит в регистр передаваемых данных ещё один байт, не проверяя есть ли свободная ячейка в аппаратном фифо. ....Хм, пересмотрел код, у меня, кажется, аппаратный фифо был выключен. Попробую его включить, завтра получу доступ к железу - протестирую как теперь будет работать printf() с большими строками и отпишусь. Так в этом случае не то что длинные строки, любая строка должна выводиться абракадаброй т.к. THR постоянно перезаписывается новыми данными, а что в сдивговый регистр попадет никто не узнает пока не увидит результат вывода на экран. (общий рецепт может не иметь ничего общего с LPC17XX)
|
|
|
|
|
Oct 11 2013, 22:42
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Код #ifndef __FIFO_H_ #define __FIFO_H_
#include "type.h"
template <u8 size, typename T = u8> class Fifo{ T buf[size]; u8 _count; u8 _first; u8 _last; public: Fifo(){ _count = _last = _first = 0; } void clear(){ _count = _last = _first = 0; } u8 count(){ return _count; } u8 free(){ return size - _count; }
void push(T item){ if(_count == size) return; _count++; buf[_last++] = item; if(_last >= size) _last = 0; }
T pop(){ if(_count == 0) return 0; _count--; T item = buf[_first++]; if(_first == size) _first = 0; return item; }
u8 write(T * data, u8 num){ if (num > (size - _count)) num = size - _count; u8 n = num; while (num--) push(*data++); return n; }
u8 read(T * data, u8 num){ if (num > _count) num = _count; u8 n = num; while (num--) *data++ = pop(); return n; }
T at(s16 index){ s16 i = index + (index < 0) ? _last : _first; while (i < 0) i += size; while (i >= size) i -= size; return buf[i]; } };
#endif /* __FIFO_H_ */ Fifo <64> txFifo; соответственно в UART_SendByte(char data){ txFifo.push(data); __UART_TX_INTERRUPT_ENABLE(); } а в прерывании передатчика if (txFifo.count()) UARTx->THR = txFifo.pop(); else __UART_TX_INTERRUPT_DISABLE();
|
|
|
|
|
Oct 12 2013, 19:11
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(_pv @ Oct 12 2013, 02:42)  [code] template <u8 size, typename T = u8> class Fifo{ ... } Уважаемый _pv, с какой целью жестко ограничена глубина FIFO 255 элементами? Пакеты могут быть и длиннее, чем 255 байт (протокол WAKE, например). Уважаемый kt368, пример кольцевого буфера можно найти в usrlib.* из scmRTOS. И смотрите внимательно на умолчания шаблона.
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Oct 12 2013, 20:41
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(mdmitry @ Oct 13 2013, 01:11)  Уважаемый _pv, с какой целью жестко ограничена глубина FIFO 255 элементами? Пакеты могут быть и длиннее, чем 255 байт (протокол WAKE, например). скопировано оттуда где пакетов больше 255 быть не может, а делать еще и задание типа для хранения индексов было лень. кому сильно надо может поменять на template <int size, typename idxT = u8, typename T = char> жаль нельзя сделать template <idxT size, typename idxT = u8, typename T = char>. было бы совсем красиво.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|