KnightIgor 2 17 июля, 2012 Опубликовано 17 июля, 2012 · Жалоба Как-то сложновато... Если отказаться от счётчика (а зачем он нужен?) и оперировать только указателями на "голову" и "хвост" буфера, то и флаг не понадобиться, и прерывания можно не трогать, один раз только разрешить при инициализации и всё. Если оба указателя равны друг другу, буфер пуст или полон? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 17 июля, 2012 Опубликовано 17 июля, 2012 · Жалоба Если оба указателя равны друг другу, буфер пуст или полон?Принять на веру что пуст. Просто размер фифо нужно с запасом выбрать и выгребать его достаточно регулярно. По сути те же самые ограничения на производительность что и у вас, но у вас всё гавкнется гораздо раньше... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 28 сентября, 2012 Опубликовано 28 сентября, 2012 · Жалоба Я сделал драйвер для USART, который работает через DMA, может быть пригодится кому нибудь. Извлекал его потом из реального проекта, так что мог что то упустить, но надеюсь не упустил. Длайвер работает через USART1, адаприровать под другие порты, думаю не составит труда. Основной прием данных производится в буфер через DMA канал. По заполнению половинок буфера данные извлекаются и передаются в обработчик. В случае применения RTOS данные передаются в предусмотренный для данных queue (или в другой терминологии - в "message box"). Буфер может быть достаточно большого размера - 128 и более байт и в случае, если передача остановилась где то посередине и DMA прерывание не возникает, то через несколько пустых временных окон приема символов возникает прерывание "IDLE line" от USART, в данном прерывании вытаскивается хвост данных и DMA канал сбрасывается в стартовое состояние. Дан проект-пример. Основные файлы - main.c и STM32F10x_it.c. В main.c производится вся настрока периферии. В во втором прерывании все необходимые обработчики, а именно - от DMA и от USART. Ссылка Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rash 0 9 января, 2013 Опубликовано 9 января, 2013 · Жалоба А есть ли возможность аппаратно увидеть что начался приём данных?, что бы не начать новую передачу в случае RS-485 и не подгонять тайм ауты посылок. А то принимать всю посылку по IDLE удобно, но не знаешь есть она или нет в данный момент. Проверка флага RXNE в регистре USARTx_SR не помогла, этот флаг иногда ловится на несколько приходящих посылок, причём сбрасывался он сам, наверное DMA когда забирает байт данных очищает его. Мк ST32F407. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rash 0 23 января, 2013 Опубликовано 23 января, 2013 · Жалоба Отвечу сам на свой вопрос. Экспериментально проверил, если использовать режим IDLE и при этом DMA забирает всю посылку, то и флаг RXNE очищается когда его забрало DMA и прерывание по приёму USART_IT_RXNE никогда не произойдёт. Вижу только 2 выхода что бы определить старт приёма: Принять 1-ый байт и подключить потом DMA для приёма оставшейся посылки, 2-ой использовать ещё один бит порта как внешнее прерывание (поймать старт бит и отключить потом внешнее прерывания, до приёма полной посылки). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 27 января, 2013 Опубликовано 27 января, 2013 · Жалоба Если я правильно понимаю в чем проблема - то можно контроллировать счетчик передачи DMA. Если он не равен одному из 2 указателей, то передача в процессе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rash 0 27 января, 2013 Опубликовано 27 января, 2013 · Жалоба Задача такая: хотелось бы контролировать что начался приём. Как я понял вы предлагаете периодически опрашивать счётчик байтов DMA, и если он не равен 0, то значит идёт прём данных. Как то не подумал о таком, попробую при случае, спасибо за идею. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 28 января, 2013 Опубликовано 28 января, 2013 · Жалоба В этой идее есть недостаток. Счётчик ДМА может ещё не измениться а приём байта быть в процессе. Байты же не мгновенно принимаются, а по-битно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 3 февраля, 2013 Опубликовано 3 февраля, 2013 (изменено) · Жалоба В этой идее есть недостаток. Счётчик ДМА может ещё не измениться а приём байта быть в процессе. Байты же не мгновенно принимаются, а по-битно... Вероятность потери байта предельно низка, так как сначала достаются все байты из массива ДМА, затем еще раз проверяется счетчик ДМА и если он не изменился за время вытаскивания данных, то ДМА ресетится. Процедура сброса ДМА занимает доли микросекунды. В принципе, можно на время сброса ДМА переключать прием на прерывание, а затем назад. Но как показывает практика, и без этого все хорошо. По крайней мере через GPRS модем на 115200 (при скорости HCLK всего лишь 4МГц) удается принимать массивы несколько сот кБ без потерь (больше просто не пробовал). При этом контроллер под управлением freertos обслуживает около 10 задач и еще эпизодически работают 4 канала того же ДМА. Изменено 3 февраля, 2013 пользователем kan35 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 3 февраля, 2013 Опубликовано 3 февраля, 2013 · Жалоба А зачем вообще что-то ресетить? Ведь у дма есть циркулярный режим... //============================================================================= int uart_getc(uart_t* const uart) { dma_t* const dma = &uart->dma.rx; if (dma->size - dma->sfr->CNDTR != dma->idx) { int x = dma->buf[dma->idx]; if (++dma->idx >= dma->size) { dma->idx = 0; } return (x); } return (-1); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 4 февраля, 2013 Опубликовано 4 февраля, 2013 · Жалоба Он итак в циркулярном режиме. Вы просто проверяете наличие данных в ДМА памяти, но не это цель. А цель сделать все максимально аппаратно. То есть без участия процессора. В моем варианте при зполнении половинок буфера ДМА (или как вариант разных буферов в процессорах F2 и F4) возникают прерывания, в которых данные забираются. При паузе в передаче - данные так же успешно забираются из прерывания IDLE line. Никаких поллингов! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 5 февраля, 2013 Опубликовано 5 февраля, 2013 · Жалоба Понятно. У вас под ОС видимо заточка, а у меня под луп. Вы просто проверяете наличие данных в ДМА памятиДа. Я ДМА как фифо использую. Кстати, на передачу у вас тоже ДМА задействовано? У меня нет. Красивого решения не придумалось... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 6 февраля, 2013 Опубликовано 6 февраля, 2013 · Жалоба Понятно. У вас под ОС видимо заточка, а у меня под луп.Да. Я ДМА как фифо использую. Кстати, на передачу у вас тоже ДМА задействовано? У меня нет. Красивого решения не придумалось... Да, под ОСь. На передачу не сделал, но надо бы, руки не дошли пока. Для Оси передача получится просто красиво: задача уснет до окончания выполнения передачи. Для лупа не так просто будет, придумывать надо что то... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 7 февраля, 2013 Опубликовано 7 февраля, 2013 · Жалоба А есть ли возможность аппаратно увидеть что начался приём данных?, что бы не начать новую передачу в случае RS-485 и не подгонять тайм ауты посылокОт коллизий в RS485 вы так не защититесь. Это поможет сделать только протокол обмена. Когда вы проверяете идёт-ли у вас приём данных, в этот момент байт может только ещё начать приниматься, или на удалённой стороне аппаратура передатчика может только переключить выход в TX с последующей паузой для устаканивания канала в режиме передачи. Вероятность потери байта предельно низка, так как сначала достаются все байты из массива ДМА, затем еще раз проверяется счетчик ДМА и если он не изменился за время вытаскивания данных, то ДМА ресетится. Процедура сброса ДМА занимает доли микросекунды.Если вероятность потери !=0, то на помойку такое ПО. Которое может работать с некоторой вероятностью в зависимости от фазы луны. А если между проверкой и сбросом DMA как раз и придёт байт? И что значит "ресет DMA"? Это именно сброс канала или запрет его работы? Есть-ли у DMA каналов в STM32 FIFO? Знаю что у многих других контроллеров - есть, что будет приводить к потерям байт (при сбросе DMA) или появлению лишних байт (при его запрете) - сам лично сталкивался с такой проблемой. Должен быть алгоритм, позволяющий работать с 100% вероятностью. Иначе - зачем нужен STM32 если есть другие процессоры (например LPC или от TI) где есть нормальное FIFO на UARTах работающее со 100% вероятностью и не нужны пляски с бубном с DMA? Пишу не с целью разжигания религиозной войны STM vs LPC, а с целью понять плюсы и минусы STM32, как замены хорошо знакомым ядрам от NXP. Мои задачи подразумевают интенсивное использование UART-ов (несколько одновременно, до 5и) под ОС. Я пытаюсь понять во что это выльется при переходе с LPC на STM32? Очень настораживает сложность работы с UART на STM32 через DMA. Работа с частотами прерываний от одного UART порядка 11кГц/11кГц (TX/RX) на 115200 и суммарной эквивалентной частотой от 5-ти UART на 115200 порядка 110кГц очень напрягает, особенно под ОС. Прочитал сообщения этой ветки и возникли у меня большие сомнения в целесообразности использования STM32 вообще при работе с UART... В частности вопрос: если работать на приём так: Получаю IDLE-прерывание, в его обработчике запрещаю канал DMA, копирую данные из буфера DMA в программное FIFO, настраиваю канал DMA заново на приём в буфер DMA, разрешаю DMA, выхожу из ISR. Могут-ли в таком алгоритме быть потери байт или другие проблемы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 7 февраля, 2013 Опубликовано 7 февраля, 2013 · Жалоба Всё прекрасно работает на stm32. Не паникуйте!:) Кстати, у stm32f0 много вкусностей в модуле uart появилось относительно stm32f1. Так-что не надо всех под одну гребёнку.... Вы всё равно не составите адекватного мнения, пока не попробуете лично. ИМХО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться