Hi,
I need to use the USART in AT91SAM9260 working under Linux OS (quite
old 2.6.29.3 version, due to compatibility with some parts of the
system) to communicate with peripheral sending data in synchronous
mode with clock 6MHz. The peripheral provides clock.
The standard atmel_serial.c driver does not seem to support operation
with external clock neither the synchronous mode. (In fact it is still
valid for the newest version:
http://lxr.linux.no/linux+v3.0.4/driver ... al.c#L1106).
As the driver is quite complicated (especially considering the fact,
that I need to use DMA to leave CPU power for data processing), I'd
rather prefer modifying of the atmel_serial.c, than writing my own
driver.
My first idea is to simply modify the atmel_set_termios function
(
http://lxr.linux.no/linux+v2.6.29.3/dri ... al.c#L1015).
E.g. I can "steal" one value of c_ispeed, (let's take B460800, as it will be probably
not used by any USART in my system) to switch on the synchronous mode with external clock.
Below is the proposed modification, original code starts here:
http://lxr.linux.no/linux+v2.6.29.3/dri ... al.c#L1022 /* Get current mode register */
mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
| ATMEL_US_NBSTOP |
ATMEL_US_PAR | ATMEL_US_SYNC );
/* Added clearing of ATMEL_US_SYNC, not present before, as this bit was never set
in the original driver */
if(termios->c_ispeed != 460800) { /* Yes, I should check if c_ispeed is equal to 460800, even though the userspace program passes B460800 ! */
/* original code */
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
quot = uart_get_divisor(port, baud);
if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */
quot /= 8;
mode |= ATMEL_US_USCLKS_MCK_DIV8;
}
} else { /* my code, executed when c_ispeed==0 */
baud = 6000000 ; /* known in advance, set e.g. for calculation of timeouts */
/* may be it would be wise to allow setting of baud via c_ospeed? */
mode |= ATMEL_US_USCLKS_SCK | ATMEL_US_SYNC ;
}
I'd appreciate any suggestions regarding the proposed solution.
How should I manage the SCK pin? Is it enough to set its function in
direction in the board file (arch/arm/mach-at91/board-my-board.c )?
--
Regards,
Wojtek
SOLUTION:
I've managed to get the USART working in synchronous mode with the modification of atmel_serial.c shown in attached patch.