usart rx dma

Сообщение от

j0rи4mm3

У DMA канала есть регистр, который задает количество транзакций (байт на передачу для USORT) и уменьшается с кажой передачей байта. Количество принятых/переданых байт равно первоначальное значение минус текущее.

Сообщение от

j0rи4mm3

Зачем тогда DMA?

Сообщение от

j0rи4mm3

Когда размер посылки фиксирован и известен, то все просто: выделяется буфер нужного размера, задается количество транзакций для DMA и по окончанию (прерывание TC DMA) анализируется.

Если размер посылки неизвестен, то удобнее завести два буфера: маленький FIFO и большой для хранения самой посылки. Я делал примерно так:

- настраивал DMA в кольцевом режиме на размер FIFO и включал прерывания DMA TC и HT (окончание и половина передачи), также стартовал таймер для таймаута (интервал срабатывания такой, чтобы он был больше времени передачи как минимум одного байта).

- в обработчике прерывания DMA: если HT, то копируется первая половина FIFO буфера в большой буфер, если TC, то копируется вторая половина FIFO.

- в обработчике прерывания таймера: если счетчик DMA изменился с предыдущего раза, то значит прием идет, если нет - значит передача завершилась и можно обработать принятые данные в большом буфере.

Еще у USORT есть полезная штука IDLE detect, которая срабатывает, если за время, нужное на передачу одного байта (вместе со старт-стоп битами), не было активности на линии. Ее можно использовать вместо таймера, но это сработает не всегда, т.к. порой передачи идут с небольшими задержками (зависит от передатчика), тогда надо пользовать таймер.