[En-Nut-Discussion] RE: UART_SETCLOCKMODE - UART_NSYNCSLAVE - found a bug in NutOs
Dave Smart
Dave at Smart-Family.net
Sun Sep 17 05:03:12 CEST 2006
I found a bug in the AVR usart driver.
I have a follow on issue with _ioctl(...) not behaving as I expected
======================= BUG Report =============================
In NutOs 4.0.3.2 of nut\arch\avr\dev\usartavr.c, line 1046,
and in the CVS tip [shown below] it is line 1050.
UCSRnA should be UCSRnC - which is the register where UMSEL appears.
1024 static int AvrUsartSetClockMode(u_char mode)
1025 {
1026 #ifdef __AVR_ENHANCED__
...
1047 /* Disable high speed. */
1048 cbi(UCSRnA, U2X);
1049 /* Enable synchronous mode. */
1050 sbi(UCSRnA, UMSEL);
...
1064 /* Disable negated clock. */
1065 cbi(UCSRnC, UCPOL);
1066 /* Disable synchronous mode. */
1067 cbi(UCSRnC, UMSEL);
I fixed this line, then used the configuration to rebuild, forced a build of
my code, and yet it didn't actually fix my problem, so there is something
I'm yet missing.
======================= Follow On Issue with _ioctl(...)
==========================
I tried some brute-force tests, but unexpectedly received error return
values as you see here. This sequence -
rlen = NutRegisterDevice(&devUart1, 0, 0); // open the UART as
a stream
uartkybd = fopen("uart1", "r+b");
_ioctlParam = 2; // 2 = even parity
rlen = _ioctl(_fileno(uartkybd), UART_SETPARITY, &_ioctlParam);
if (rlen)
puts_P(PSTR("***** error in SetParity()\n"));
_ioctlParam = 1;
rlen = _ioctl(_fileno(uartkybd), UART_SETSTOPBITS, &_ioctlParam);
if (rlen)
puts_P(PSTR("***** error in SetStop()\n"));
_ioctlParam = 8;
rlen = _ioctl(_fileno(uartkybd), UART_SETDATABITS, &_ioctlParam);
if (rlen)
puts_P(PSTR("***** error in SetData()\n"));
_ioctlParam = UART_SYNCSLAVE; // tx on rising edge, rx on falling
edge
rlen = _ioctl(_fileno(uartkybd), UART_SETCLOCKMODE, &_ioctlParam);
if (rlen)
puts_P(PSTR("***** error in
SetClockMode(UART_SYNCSLAVE)\n"));
_ioctlParam = UART_NSYNCSLAVE; // tx on rising edge, rx on falling
edge
rlen = _ioctl(_fileno(uartkybd), UART_SETCLOCKMODE, &_ioctlParam);
if (rlen)
puts_P(PSTR("***** error in
SetClockMode(UART_NSYNCSLAVE)\n"));
Printed -
***** error in SetParity()
***** error in SetClockMode(UART_SYNCSLAVE)
***** error in SetClockMode(UART_NSYNCSLAVE)
Just after these lines of code I put this into play.
UCSR1C |= 0x40; // Skip the driver and force Sync Mode
And did get sync mode to work as I wanted.
Regards,
Dave Smart
More information about the En-Nut-Discussion
mailing list