Atmel USART serial driver
This driver is a serial port driver using the Atmel USART module integrated in most AT32 and AT91 chips from Atmel. There are currently two drivers available for this module: The at91_serial/atmel_serial driver in the mainstream tree (available since 2.6.16, renamed "atmel_serial" in 2.6.19-rc1) and the serial_usart3 driver in the AT32STK1000 BSP. There are plans to merge these two drivers into one as part of the effort to push the AVR32/AT32AP7000/AT32STK1000 code into the mainstream kernel.
The at91_serial driver has just been renamed atmel_serial, and works fine with the AT32AP7000 chip. The old serial_usart3 driver should soon be obsoleted, but it still has a few advantages compared to the atmel_serial driver, like DMA support and break handling.
Chip Coldwell has implemented DMA support in the atmel_serial driver, but there are apparently some issues preventing it from being merged.
serial_usart3 implementation notes
The serial_usart3 driver uses DMA exclusively to transfer data.
The TX side is the easy part: simply adjust the PDC transmit counter until it covers whatever has been filled up until the end of the buffer, and start using the "next" set of pointer/counter registers whenever it wraps around. If this didn't make sense to you, please read up on the PeripheralDmaController.
On the RX side, the driver uses a pre-allocated ringbuffer. This buffer is split in half so that an interrupt fires when half the buffer has been filled up and the driver can start consuming the data and eventually re-use the buffer. In addition, the USART module is set up to fire an interrupt when there is data in the buffer, but no additional data has been received within a certain timeout. This is what makes the DMA-based implementation work for interactive terminals as well (imagine if you would have to type enough to fill half the buffer before the system would respond.)
Known issues with the serial_usart3 driver
Error handling
Because the serial_usart3 driver uses DMA to transfer data, it's difficult to insert error flags into the buffer at the correct position. Overruns are probably a non-issue, but framing errors, etc. should be flagged properly.
This all comes down to interrupt latency. When an error flag is set, we need to handle the interrupt and read out the DMA count register in less time than it takes to transfer one character. For example, when running at 115200 bps in 8N1 mode, the deadline becomes
1 / 115200 * 10 = 86.8 us
This deadline will probably be met in most cases, but making it a guarantee would require a lot more testing / analysis of the code.
The current driver simply doesn't insert any flags at all in the receive buffer.
Comments