[Tinyos-devel] UartByte on Atm128
Jon Green
jgreen at certicom.com
Fri May 25 12:13:49 PDT 2007
I've created a patch against a copy of the source checked out of CVS
today to fix the UartByte implementation on the Atmel 128. The issue has
been discussed on the help list before:
http://mail.millennium.berkeley.edu/pipermail/tinyos-help/2006-December/021364.html
The patch fixes the following behaviour:
1) UartByte.send goes into an infinite loop when called.
2) UartByte.receive always times out.
3) HplAtm128Uart.disableRxIntr/disableTxIntr actually disable the rx/tx
module of the Uart, not just the interrupts.
4) HplAtm128Uart.enableRxIntr/enableTxIntr actually enable the rx/tx
module of the Uart, not just the interrupts.
5) UartStream.receivedByte can fire without calling
enableReceiveInterrupt.
In order to fix the above behaviour the following changes where made:
- HplAtm128UartP.nc
* StdControl.start no longer sets the TXCIE/RXCIE flag to enable
interrupts.
* HplAtm128Uart.enable/disableRxInter modifies the RXCIE flag
instead of the RXEN flag.
* HplAtm128Uart.enable/disableTxInter modifies the TXCIE flag
instead of the TXEN flag. HplAtm128Uart.enable writes a 1 to
the TXC register to clear the transmit complete flag before
enabling interrupts, to ensure that an interrupt is not
immediately fired.
Note: Info on the UART registers can be found on pg.190 of the atmel
atmega128 documentation.
- Atm128UartP.nc
* Added internal state to keep track of the interrupts.
* If interrupts are enabled UartByte.send/receive return failure
instead of going into infinite loops.
* When UartStream.send is called it enabled interrupts until it is
done sending and then disables them again.
* The UartStream.receivedByte event will now never fire unless the
user enables interrupts first by calling
UartStream.enableReceiveInterrupt().
* UartStream.receive will enable interrupts until it is done sending
and then disable them only if they haven't been enabled with
enableReceiveInterrupt().
I've included a simple test case that demonstrates the problems with the
existing interface and shows the new one works.
Cheers,
Jon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: uart.diff
Type: text/x-patch
Size: 7241 bytes
Desc: not available
Url : http://mail.millennium.berkeley.edu/pipermail/tinyos-devel/attachments/20070525/093e149a/uart.bin
-------------- next part --------------
configuration TestCase
{
}
implementation
{
components TestCaseC, PlatformSerialC, MainC;
TestCaseC.Boot -> MainC;
TestCaseC.UartControl -> PlatformSerialC;
TestCaseC.UartStream -> PlatformSerialC;
TestCaseC.UartByte -> PlatformSerialC;
}
-------------- next part --------------
module TestCaseC
{
uses interface Boot;
uses interface StdControl as UartControl;
uses interface UartByte;
uses interface UartStream;
}
implementation
{
char buffer[3];
event void Boot.booted()
{
/* initialize the Uart on boot */
call UartControl.start();
/* see if uartbyte.send works */
call UartByte.send('a');
call UartByte.send('b');
/* see if uartstream.send works */
call UartStream.send("cde",3);
/* see if uartbyte goes into an infinite loop with interrupts enabled*/
call UartByte.send('x');
/* make sure enable recieve interrupt persists when enabled by hand */
call UartStream.enableReceiveInterrupt();
/* see if uartbyte.recieve hangs if called with interrupts enabled */
call UartByte.receive(buffer,255);
/* test uartbyte functionality */
call UartStream.receive(buffer,3);
}
async event void UartStream.receivedByte(uint8_t byte)
{
char string[] = "ijk";
call UartStream.send(string,3);
call UartStream.disableReceiveInterrupt();
}
async event void
UartStream.receiveDone(uint8_t *buf, uint16_t len, error_t error)
{
call UartStream.send(buffer,3);
}
async event void
UartStream.sendDone(uint8_t *buf, uint16_t len, error_t error)
{
}
}
More information about the Tinyos-devel
mailing list