signal IntA.brk();
} else
signal IntA.rx(c);
- } else if (READ_FLAG(UC0IFG, UCB0RXIFG)) {
- volatile uint8_t c = UCB0RXBUF; /* read to clear UCB0RXIFG */
- if (READ_FLAG(UCB0CTL1, UCBRK)) {
- CLR_FLAG(UCB0CTL1, UCBRK);
- if (READ_FLAG(UCB0CTL0, UCMODE_3) == UCMODE_3)
- CLR_FLAG(UCB0CTL1, UCDORM);
- signal IntB.brk();
- } else
- signal IntB.rx(c);
- } else if (READ_FLAG(UCB0STAT, UCALIFG))
+ } else if (READ_FLAG(UC0IFG, UCB0RXIFG))
+ signal IntB.rx(UCB0RXBUF); /* read clears UCB0RXIFG */
+ else if (READ_FLAG(UCB0STAT, UCALIFG))
signal IntB.i2cCal();
else if (READ_FLAG(UCB0STAT, UCNACKIFG))
signal IntB.i2cNak();
signal IntA.brk();
} else
signal IntA.rx(c);
- } else if (READ_FLAG(UC1IFG, UCB1RXIFG)) {
- volatile uint8_t c = UCB1RXBUF; /* read to clear UCB1RXIFG */
- if (READ_FLAG(UCB1CTL1, UCBRK)) {
- CLR_FLAG(UCB1CTL1, UCBRK);
- if (READ_FLAG(UCB1CTL0, UCMODE_3) == UCMODE_3)
- CLR_FLAG(UCB1CTL1, UCDORM);
- signal IntB.brk();
- } else
- signal IntB.rx(c);
- } else if (READ_FLAG(UCB1STAT, UCALIFG))
+ } else if (READ_FLAG(UC1IFG, UCB1RXIFG))
+ signal IntB.rx(UCB1RXBUF); /* read clears UCB1RXIFG */
+ else if (READ_FLAG(UCB1STAT, UCALIFG))
signal IntB.i2cCal();
else if (READ_FLAG(UCB1STAT, UCNACKIFG))
signal IntB.i2cNak();
uint16_t I2Csa_addr, /* B devices only */
uint16_t Ie_addr,
uint16_t Ifg_addr,
- uint16_t UCAxRXIFG, /* We rely on xIE and xIFG at same bit positions */
- uint16_t UCAxTXIFG
+ uint16_t UCxxRXIFG, /* We rely on xIE and xIFG at same bit positions */
+ uint16_t UCxxTXIFG
) @safe() {
provides interface HplMsp430UsciReg as Registers;
}
/* RENDER(Ie); */
async command bool Registers.getIeRx()
{
- return READ_FLAG(UCxxIe, UCAxRXIFG);
+ return READ_FLAG(UCxxIe, UCxxRXIFG);
}
async command void Registers.setIeRx()
{
- SET_FLAG(UCxxIe, UCAxRXIFG);
+ SET_FLAG(UCxxIe, UCxxRXIFG);
}
async command void Registers.clrIeRx()
{
- CLR_FLAG(UCxxIe, UCAxRXIFG);
+ CLR_FLAG(UCxxIe, UCxxRXIFG);
}
async command bool Registers.getIeTx()
{
- return READ_FLAG(UCxxIe, UCAxTXIFG);
+ return READ_FLAG(UCxxIe, UCxxTXIFG);
}
async command void Registers.setIeTx()
{
- SET_FLAG(UCxxIe, UCAxTXIFG);
+ SET_FLAG(UCxxIe, UCxxTXIFG);
}
async command void Registers.clrIeTx()
{
- CLR_FLAG(UCxxIe, UCAxTXIFG);
+ CLR_FLAG(UCxxIe, UCxxTXIFG);
}
/* RENDER(Ifg); */
async command bool Registers.getIfgRx()
{
- return READ_FLAG(UCxxIfg, UCAxRXIFG);
+ return READ_FLAG(UCxxIfg, UCxxRXIFG);
}
async command void Registers.setIfgRx()
{
- SET_FLAG(UCxxIfg, UCAxRXIFG);
+ SET_FLAG(UCxxIfg, UCxxRXIFG);
}
async command void Registers.clrIfgRx()
{
- CLR_FLAG(UCxxIfg, UCAxRXIFG);
+ CLR_FLAG(UCxxIfg, UCxxRXIFG);
}
async command bool Registers.getIfgTx()
{
- return READ_FLAG(UCxxIfg, UCAxTXIFG);
+ return READ_FLAG(UCxxIfg, UCxxTXIFG);
}
async command void Registers.setIfgTx()
{
- SET_FLAG(UCxxIfg, UCAxTXIFG);
+ SET_FLAG(UCxxIfg, UCxxTXIFG);
}
async command void Registers.clrIfgTx()
{
- CLR_FLAG(UCxxIfg, UCAxTXIFG);
+ CLR_FLAG(UCxxIfg, UCxxTXIFG);
}
}
* This configuration provides the interface for using USCI_B1 in its SPI
* mode.
*
+ * The instantiator should set the blockSize, which represents the maximum
+ * number of bytes the underlying SPI stack will transmit or receive in a
+ * single interrupt service. Increasing the block size decreases SPI
+ * communications time at the expense of reducing system responsiveness to
+ * other events.
+ *
+ * The blockSize is best set by considering the maximum time the SPI stack
+ * should be able to delay other events. A rule of thumb formula would be:
+ *
+ * block_time = block_size / (spi_bitclock/8)
+ *
+ * For example, using a 500KHZ SPI bitclock, a block size of 64 bytes
+ * equates to a block time of 1 ms. Note that this calculation is rough
+ * because it does not take into account ISR overhead and other factors.
+ *
+ * The implementation will use a default blockSize if set to 0 here.
+ *
* @author R. Steve McKown <smckown@gmail.com>
*/
#include "Msp430Usci.h"
-generic configuration Msp430SpiB1C() {
+generic configuration Msp430SpiB1C(uint16_t blockSize) {
provides {
interface Resource;
interface ResourceRequested;
CLIENT_ID = unique(MSP430_USCIB1_RESOURCE)
};
- components new Msp430SpiP() as SpiP;
+ components new Msp430SpiP(blockSize) as SpiP;
SpiByte = SpiP;
SpiPacket = SpiP;
Configure = SpiP;
- components Msp430UsciA0C as UsciC;
+ components Msp430UsciB1C as UsciC;
Resource = UsciC.Resource[CLIENT_ID];
ResourceRequested = UsciC.ResourceRequested[CLIENT_ID];
ArbiterInfo = UsciC.ArbiterInfo;
SpiP.STE -> IOC.UCB1STE;
SpiP.SIMO -> IOC.UCB1SIMO;
SpiP.SOMI -> IOC.UCB1SOMI;
- SpiP.SCL -> IOC.UCB1SCL;
+ SpiP.CLK -> IOC.UCB1CLK;
}
/**
* Spi implementation using a USCI device.
*
+ * TODO: Implement error checking via UCxxSTAT
+ *
* @author R. Steve McKown <smckown@gmail.com>
*/
-generic module Msp430SpiP() {
+generic module Msp430SpiP(uint16_t blockSize) {
provides {
interface SpiByte;
interface SpiPacket;
interface HplMsp430GeneralIO as STE;
interface HplMsp430GeneralIO as SIMO;
interface HplMsp430GeneralIO as SOMI;
- interface HplMsp430GeneralIO as SCL;
+ interface HplMsp430GeneralIO as CLK;
interface AsyncConfigure<const msp430_usci_spi_t*> as Configure;
- interface Counter<T32khz,uint16_6>
interface ArbiterInfo;
}
}
implementation {
+ enum {
+ BLOCKSIZE_DEFAULT = 64
+ };
+
#define saveBits(pin, pos, dir, out, ren) { \
if (call pin.isOutput()) \
dir |= (1 << pos); \
call pin.makeInput(); \
}
- uint8_t dir; /* Pin state storage to allow for proper unconfiguration */
- uint8_t out;
- uint8_t ren;
- uint8_t* sobuf; /* Original buffer ptr from UartStream.send() */
- uint8_t solen; /* Original buffer len from UartStream.send() */
- uint8_t* sbuf; /* Position of next char to send */
- uint8_t slen; /* Len of chars in sbuf to send */
- bool rxie; /* Set if rxie has been enabled to UartStream.receive() */
- uint8_t* robuf; /* Original receive buffer */
- uint8_t rolen; /* Original (maximum) receive len */
- uint8_t* rbuf; /* Position of next byte in which to receive a char */
- uint8_t rlen; /* Remaining length in receive buffer */
+ /* Pin IO configuration storage for later restoration */
+ uint8_t m_dir;
+ uint8_t m_out;
+ uint8_t m_ren;
+
+ uint8_t* m_txBuf;
+ uint8_t* m_rxBuf;
+ uint16_t m_len;
+ uint16_t m_pos;
+
+ inline bool is4pin() /* true if the SPI bus is in 4-pin mode */
+ {
+ return (call Registers.getCtl0(UCMODE_3)) != UCMODE_0;
+ }
+
+ inline bool isBusy() /* true if a SPI transaction is in progress */
+ {
+ atomic return m_len != 0;
+ }
async command void ResourceConfigure.configure()
{
call Registers.setCtl1(UCSWRST);
- /* Force 3-pin SPI if config says I2C */
+ /* UCMODE_3 is invalid for SPI. Presume the configuration data
+ * are wrong and force 3-pin SPI as a minimially safe alternative.
+ */
ctl0 = config->ctl0 | UCSYNC;
if ((ctl0 & UCMODE_3) == UCMODE_3)
ctl0 &= ~(UCMODE_3);
call Registers.assignCtl1(config->ctl1 | UCSWRST);
call Registers.assignBr0(config->brx & 0xff);
call Registers.assignBr1(config->brx >> 8);
- call Registers.assignMctl(config->mctl); /* ??? */
- call Registers.clrStat(UCLISTEN);
+ call Registers.assignMctl(0);
+ if (config->uclisten)
+ call Registers.setStat(UCLISTEN);
+ else
+ call Registers.clrStat(UCLISTEN);
- /* Save pin IO states */
- dir = out = ren = 0;
- saveBits(RXD, 0, dir, out, ren);
- saveBits(TXD, 1, dir, out, ren);
+ /* Save pin IO configuration */
+ m_dir = m_out = m_ren = 0;
+ if (is4pin())
+ saveBits(STE, 0, m_dir, m_out, m_ren);
+ saveBits(SIMO, 1, m_dir, m_out, m_ren);
+ saveBits(SOMI, 2, m_dir, m_out, m_ren);
+ saveBits(CLK, 3, m_dir, m_out, m_ren);
- /* Configure RX pin for UART use */
- call RXD.makeInput();
- if (config->ren & USCI_REN_RX) {
- if (config->ren & USCI_REN_RX_PULLUP)
- call RXD.set();
+ /* Configure pins for SPI use */
+ if (is4pin()) {
+#if 0 /* Unsure if REN on STE is a valid configuration */
+ /* Configure STE pin for SPI use */
+ if (config->ren & USCI_REN_STE) {
+ if (config->ren & USCI_REN_STE_PULLUP)
+ call STE.set();
+ else
+ call STE.clr();
+ call STE.enableRen();
+ }
+#endif
+ call STE.selectModuleFunc();
+ }
+ call SOMI.makeInput();
+ if (config->ren & USCI_REN_SOMI) {
+ if (config->ren & USCI_REN_SOMI_PULLUP)
+ call SOMI.set();
else
- call RXD.clr();
- call RXD.enableRen();
+ call SOMI.clr();
+ call SOMI.enableRen();
}
- call RXD.selectModuleFunc();
-
-#if 0 /* pull-ups don't make sense on TXD, since it doesn't appear that
- * enabling an open-drain emulation mode via USCI is possible.
- */
-
- /* Configure TX pin for UART use */
- if (config->ren & USCI_REN_TX) {
- if (config->ren & USCI_REN_TX_PULLUP)
- call TXD.set();
+ call SOMI.selectModuleFunc();
+#if 0 /* Unsure if REN on SIMO is a valid configuration */
+ /* Configure SIMO pin for SPI use */
+ if (config->ren & USCI_REN_SIMO) {
+ if (config->ren & USCI_REN_SIMO_PULLUP)
+ call SIMO.set();
else
- call TXD.clr();
- call TXD.enableRen();
+ call SIMO.clr();
+ call SIMO.enableRen();
}
- call TXD.selectModuleFunc();
#endif
+ call SIMO.selectModuleFunc();
+#if 0 /* Unsure if REN on CLK is a valid configuration */
+ /* Configure CLK pin for SPI use */
+ if (config->ren & USCI_REN_CLK) {
+ if (config->ren & USCI_REN_CLK_PULLUP)
+ call CLK.set();
+ else
+ call CLK.clr();
+ call CLK.enableRen();
+ }
+#endif
+ call CLK.selectModuleFunc();
/* Clear interrupts; we'll add them as needed */
call Registers.clrIeRx();
/* Disable the device */
call Registers.setCtl1(UCSYNC);
- /* Clear interrupts and interrupt flags */
+ /* Clear interrupts and interrupt flags. We only used Rx */
call Registers.clrIeRx();
- call Registers.clrIeTx();
call Registers.clrIfgRx();
- call Registers.clrIfgTx();
/* Restore pins to their preconfigured state */
#if 0
- restoreBits(RXD, 0, dir, out, ren);
- restoreBits(TXD, 0, dir, out, ren);
+ if (is4pin())
+ restoreBits(STE, 0, m_dir, m_out, m_ren);
+ restoreBits(SIMO, 1, m_dir, m_out, m_ren);
+ restoreBits(SOMI, 1, m_dir, m_out, m_ren);
+ restoreBits(CLK, 1, m_dir, m_out, m_ren);
#endif
- call RXD.selectIOFunc();
- call TXD.selectIOFunc();
+ if (is4pin())
+ call STE.selectIOFunc();
+ call SIMO.selectIOFunc();
+ call SOMI.selectIOFunc();
+ call CLK.selectIOFunc();
}
}
- async command error_t UartByte.send(uint8_t byte)
+ async command uint8_t SpiByte.write(uint8_t byte)
{
- /* FIXME: race with UartStream.send() */
- atomic {
- if (sobuf)
- return FAIL;
- while (call Registers.getStat(UCBUSY));
+ if (isBusy())
+ return 0;
+ else {
+ while (!call Registers.getIfgTx());
call Registers.setTxbuf(byte);
- return SUCCESS;
+ while(!call Registers.getIfgRx());
+ return call Registers.getRxbuf();
}
}
- async command error_t UartStream.send(uint8_t* buf, uint16_t len)
+ void sendData()
{
- if (sobuf || !buf || !len)
- return FAIL;
- sobuf = buf;
- solen = len;
- call Registers.setIeTx();
- call Registers.setTxbuf(*sobuf);
- slen = solen - 1;
- if (slen)
- sbuf = sobuf + 1;
- return SUCCESS;
- }
+ /* We don't need to check Registers.getIfgTx() (aks UCxxTXIFG), as
+ * sendData() is only called after peripheral init or receipt of the rx()
+ * interrupt. SPI on msp430 guarantees UCxxTXIFG is asserted in both of
+ * these cases.
+ */
+ atomic {
+ uint16_t end = m_pos + (blockSize ? blockSize : BLOCKSIZE_DEFAULT);
+ uint8_t tmp;
- async event void Interrupts.tx()
- {
- while (slen && call Registers.getIfgTx()) {
- call Registers.setTxbuf(*sbuf);
- if (--slen)
- sbuf++;
- }
- if (slen == 0 && sobuf) {
- call Registers.clrIeTx();
- call Registers.clrIfgTx();
- sobuf = 0;
- signal UartStream.sendDone(sobuf, solen, SUCCESS);
+ if (end > m_len)
+ end = m_len;
+ call Registers.setTxbuf((m_txBuf) ? m_txBuf[m_pos] : 0);
+ while (++m_pos < end) {
+ while (!call Registers.getIfgRx());
+ if (m_rxBuf)
+ m_rxBuf[m_pos - 1] = call Registers.getRxbuf();
+ else
+ tmp = call Registers.getRxbuf();
+ call Registers.setTxbuf((m_txBuf) ? m_txBuf[m_pos] : 0);
+ }
}
}
- async command error_t UartStream.enableReceiveInterrupt()
- {
- if (!robuf)
- call Registers.clrIfgRx();
- call Registers.setIeRx();
- rxie = FALSE;
- return SUCCESS;
- }
-
- async command error_t UartStream.disableReceiveInterrupt()
+ async command error_t SpiPacket.send(uint8_t* txBuf, uint8_t* rxBuf,
+ uint16_t len)
{
- if (!robuf) {
- call Registers.clrIeRx();
- call Registers.clrIfgRx();
- } else
- rxie = TRUE;
- return SUCCESS;
- }
-
- async command error_t UartByte.receive(uint8_t* byte, uint8_t timeout)
- {
- uint16_t t;
-
- /* FIXME: race with UartStream.receive() */
- if (robuf || !byte)
+ if (isBusy() || (!txBuf && !rxBuf) || len == 0)
return FAIL;
- /* TODO: implement timeout, byte-time units. For now, 1-2 sec */
- t = TBR;
- while (t < TBR) {
- if (call Registers.getIfgRx()) {
- *byte = call Registers.getRxbuf();
+ else {
+ atomic {
+ m_txBuf = txBuf;
+ m_rxBuf = rxBuf;
+ m_len = len;
+ m_pos = 0;
+ call Registers.setIeRx();
+ sendData();
return SUCCESS;
}
}
- return FAIL;
}
- async command error_t UartStream.receive(uint8_t* buf, uint16_t len)
+ async event void Interrupts.tx() {}
+
+ task void signalSendDone()
{
- if (robuf || !buf || !len)
- return FAIL;
- robuf = rbuf = buf;
- rolen = rlen = len;
- if (!call Registers.getIeRx()) {
- call Registers.clrIfgRx();
- call Registers.setIeRx();
- rxie = TRUE;
- } else
- rxie = FALSE;
+ atomic {
+ signal SpiPacket.sendDone(m_txBuf, m_rxBuf, m_len, SUCCESS);
+ m_len = 0;
+ }
}
async event void Interrupts.rx(uint8_t byte)
{
- if (robuf) {
- /* receive() takes precedence if active */
- while (rlen && call Registers.getIfgRx()) {
- *rbuf = byte;
- if (--rlen)
- rbuf++;
- }
- if (rlen == 0 && robuf) {
- if (rxie) {
- call Registers.clrIeRx();
- call Registers.clrIfgRx();
- }
- robuf = 0;
- signal UartStream.receiveDone(robuf, rolen, SUCCESS);
- }
- } else
- signal UartStream.receivedByte(byte);
+ if (m_rxBuf)
+ m_rxBuf[m_pos - 1] = call Registers.getRxbuf();
+ else
+ call Registers.getRxbuf();
+
+ if (m_pos < m_len)
+ sendData();
+ else {
+ call Registers.clrIeRx();
+ post signalSendDone(); /* Don't signal from ISR context */
+ }
}
+ default async event void SpiPacket.sendDone(uint8_t*, uint8_t*, uint16_t,
+ error_t) {}
+
default async command const msp430_usci_spi_t* Configure.get()
{
const static msp430_usci_spi_t def = {
- ctl0: UCMODE_0, /* async, lsb first, 8N1 */
- ctl1: UCSWRST|UCSSEL_1, /* clock spi from SMCLK */
- brx: UBRX_32768HZ_9600,
- mctl: UMCTL_32768HZ_9600, /* ??? */
+ ctl0: UCSYNC | UCMODE_0 | UCMST, /* 3-pin SPI mode 0, LSB first */
+ ctl1: UCSWRST | UCSSEL_3, /* SPI clock source is SMCLK */
+ brx: 10, /* SPI clock=SMCLK/10; ~105KHz if SMCLK=1MHz */
+ uclisten: FALSE,
ren: USCI_REN_NONE
};
async event void Interrupts.i2cCal() {}
async event void Interrupts.brk() {}
async event void Interrupts.i2cNak() {}
- async event void Counter.overflow() {}
-
- default async event void UartStream.sendDone( uint8_t* buf, uint16_t len,
- error_t error ) {}
- default async event void UartStream.receivedByte( uint8_t byte ) {}
- default async event void UartStream.receiveDone( uint8_t* buf, uint16_t len,
- error_t error ) {}
}
/**
* Uart implementation using a USCI device.
*
+ * TODO: Implement blocking like in Msp430UartSpiP.nc.
+ * Implement error checking via UCAxSTAT.
+ *
* @author R. Steve McKown <smckown@gmail.com>
*/
call pin.makeInput(); \
}
- uint8_t dir; /* Pin state storage to allow for proper unconfiguration */
- uint8_t out;
- uint8_t ren;
- uint8_t* sobuf; /* Original buffer ptr from UartStream.send() */
- uint8_t solen; /* Original buffer len from UartStream.send() */
- uint8_t* sbuf; /* Position of next char to send */
- uint8_t slen; /* Len of chars in sbuf to send */
- bool rxie; /* Set if rxie has been enabled to UartStream.receive() */
- uint8_t* robuf; /* Original receive buffer */
- uint8_t rolen; /* Original (maximum) receive len */
- uint8_t* rbuf; /* Position of next byte in which to receive a char */
- uint8_t rlen; /* Remaining length in receive buffer */
+ /* Pin IO configuration storage for later restoration */
+ uint8_t m_dir;
+ uint8_t m_out;
+ uint8_t m_ren;
+
+ uint8_t* m_sobuf; /* Original buffer ptr from UartStream.send() */
+ uint8_t m_solen; /* Original buffer len from UartStream.send() */
+ uint8_t* m_sbuf; /* Position of next char to send */
+ uint8_t m_slen; /* Len of chars in m_sbuf to send */
+ bool m_rxie; /* Set if rxie has been enabled to UartStream.receive() */
+ uint8_t* m_robuf; /* Original receive buffer */
+ uint8_t m_rolen; /* Original (maximum) receive len */
+ uint8_t* m_rbuf; /* Position of next byte in which to receive a char */
+ uint8_t m_rlen; /* Remaining length in receive buffer */
+
+ sfrb(MYBRX, 219U);
async command void ResourceConfigure.configure()
{
call Registers.assignIrtctl(config->irtctl);
call Registers.assignIrrctl(config->irrctl);
call Registers.assignAbctl(config->abctl);
- call Registers.clrStat(UCLISTEN);
+ if (config->uclisten)
+ call Registers.setStat(UCLISTEN);
+ else
+ call Registers.clrStat(UCLISTEN);
- /* Save pin IO states */
- dir = out = ren = 0;
- saveBits(RXD, 0, dir, out, ren);
- saveBits(TXD, 1, dir, out, ren);
+ /* Save pin IO configuration */
+ m_dir = m_out = m_ren = 0;
+ saveBits(RXD, 0, m_dir, m_out, m_ren);
+ saveBits(TXD, 1, m_dir, m_out, m_ren);
/* Configure RX pin for UART use */
call RXD.makeInput();
call RXD.selectModuleFunc();
#if 0 /* pull-ups don't make sense on TXD, since it doesn't appear that
- * enabling an open-drain emulation mode via USCI is possible.
+ * enabling an open-drain emulation mode via USCI is not possible.
*/
/* Configure TX pin for UART use */
/* Restore pins to their preconfigured state */
#if 0
- restoreBits(RXD, 0, dir, out, ren);
- restoreBits(TXD, 0, dir, out, ren);
+ restoreBits(RXD, 0, m_dir, m_out, m_ren);
+ restoreBits(TXD, 0, m_dir, m_out, m_ren);
#endif
call RXD.selectIOFunc();
call TXD.selectIOFunc();
{
/* FIXME: race with UartStream.send() */
atomic {
- if (sobuf)
+ if (m_sobuf)
return FAIL;
- while (call Registers.getStat(UCBUSY));
+ while (!call Registers.getIfgTx());
call Registers.setTxbuf(byte);
return SUCCESS;
}
async command error_t UartStream.send(uint8_t* buf, uint16_t len)
{
- if (sobuf || !buf || !len)
- return FAIL;
- sobuf = buf;
- solen = len;
- call Registers.setIeTx();
- call Registers.setTxbuf(*sobuf);
- slen = solen - 1;
- if (slen)
- sbuf = sobuf + 1;
- return SUCCESS;
+ atomic {
+ if (m_sobuf || !buf || !len)
+ return FAIL;
+ m_sobuf = buf;
+ m_solen = len;
+ call Registers.setIeTx();
+ call Registers.setTxbuf(*m_sobuf);
+ m_slen = m_solen - 1;
+ if (m_slen)
+ m_sbuf = m_sobuf + 1;
+ return SUCCESS;
+ }
}
async event void Interrupts.tx()
{
- while (slen && call Registers.getIfgTx()) {
- call Registers.setTxbuf(*sbuf);
- if (--slen)
- sbuf++;
+ while (m_slen && call Registers.getIfgTx()) {
+ call Registers.setTxbuf(*m_sbuf);
+ if (--m_slen)
+ m_sbuf++;
}
- if (slen == 0 && sobuf) {
+ if (m_slen == 0 && m_sobuf) {
call Registers.clrIeTx();
call Registers.clrIfgTx();
- sobuf = 0;
- signal UartStream.sendDone(sobuf, solen, SUCCESS);
+ m_sobuf = 0;
+ signal UartStream.sendDone(m_sobuf, m_solen, SUCCESS);
}
}
async command error_t UartStream.enableReceiveInterrupt()
{
atomic {
- if (!robuf)
+ if (!m_robuf)
call Registers.clrIfgRx();
call Registers.setIeRx();
- rxie = FALSE;
+ m_rxie = FALSE;
return SUCCESS;
}
}
async command error_t UartStream.disableReceiveInterrupt()
{
atomic {
- if (!robuf) {
+ if (!m_robuf) {
call Registers.clrIeRx();
call Registers.clrIfgRx();
} else
- rxie = TRUE;
+ m_rxie = TRUE;
return SUCCESS;
}
}
uint16_t t;
/* FIXME: race with UartStream.receive() */
- if (robuf || !byte)
+ if (m_robuf || !byte)
return FAIL;
/* TODO: implement timeout, byte-time units. For now, 1-2 sec */
t = TBR;
async command error_t UartStream.receive(uint8_t* buf, uint16_t len)
{
atomic {
- if (robuf || !buf || !len)
+ if (m_robuf || !buf || !len)
return FAIL;
- robuf = rbuf = buf;
- rolen = rlen = len;
+ m_robuf = m_rbuf = buf;
+ m_rolen = m_rlen = len;
if (!call Registers.getIeRx()) {
call Registers.clrIfgRx();
call Registers.setIeRx();
- rxie = TRUE;
+ m_rxie = TRUE;
} else
- rxie = FALSE;
+ m_rxie = FALSE;
}
}
async event void Interrupts.rx(uint8_t byte)
{
atomic {
- if (robuf) {
+ if (m_robuf) {
/* receive() takes precedence if active */
- while (rlen && call Registers.getIfgRx()) {
- *rbuf = byte;
- if (--rlen)
- rbuf++;
+ while (m_rlen && call Registers.getIfgRx()) {
+ *m_rbuf = byte;
+ if (--m_rlen)
+ m_rbuf++;
}
- if (rlen == 0 && robuf) {
- if (rxie) {
+ if (m_rlen == 0 && m_robuf) {
+ if (m_rxie) {
call Registers.clrIeRx();
call Registers.clrIfgRx();
}
- robuf = 0;
- signal UartStream.receiveDone(robuf, rolen, SUCCESS);
+ m_robuf = 0;
+ signal UartStream.receiveDone(m_robuf, m_rolen, SUCCESS);
}
} else
signal UartStream.receivedByte(byte);
{
const static msp430_usci_uart_t def = {
ctl0: UCMODE_0, /* async, lsb first, 8N1 */
- ctl1: UCSWRST|UCSSEL_3, /* clock uart from SMCLK */
+ ctl1: UCSWRST | UCSSEL_3, /* clock uart from SMCLK */
brx: UBRX_1MHZ_115200,
mctl: UMCTL_1MHZ_115200,
irtctl: 0,
irrctl: 0,
abctl: 0,
+ uclisten: FALSE,
ren: USCI_REN_NONE
};
typedef enum {
USCI_REN_NONE = 0,
- USCI_REN_RX = 0x08,
- USCI_REN_RX_PULLUP = USCI_REN_RX + 0x01,
- USCI_REN_RX_PULLDOWN = USCI_REN_RX + 0x02,
+ /* For use in UART mode */
+ USCI_REN_TX = 0x03,
+ USCI_REN_TX_PULLUP = 0x01,
+ USCI_REN_TX_PULLDOWN = 0x02,
+ USCI_REN_RX = 0x0c,
+ USCI_REN_RX_PULLUP = 0x04,
+ USCI_REN_RX_PULLDOWN = 0x08,
- USCI_REN_TX = 0x80,
- USCI_REN_TX_PULLUP = USCI_REN_TX + 0x10,
- USCI_REN_TX_PULLDOWN = USCI_REN_TX + 0x20
+ /* For use in SPI mode */
+ USCI_REN_STE = 0x30,
+ USCI_REN_STE_PULLUP = 0x10,
+ USCI_REN_STE_PULLDOWN = 0x20,
+ USCI_REN_SIMO = USCI_REN_TX,
+ USCI_REN_SIMO_PULLUP = USCI_REN_TX_PULLUP,
+ USCI_REN_SIMO_PULLDOWN = USCI_REN_TX_PULLDOWN,
+ USCI_REN_SOMI = USCI_REN_RX,
+ USCI_REN_SOMI_PULLUP = USCI_REN_RX_PULLUP,
+ USCI_REN_SOMI_PULLDOWN = USCI_REN_RX_PULLDOWN,
+ USCI_REN_CLK = 0xc0,
+ USCI_REN_CLK_PULLUP = 0x40,
+ USCI_REN_CLK_PULLDOWN = 0x80,
+
+ /* For use in I2C mode */
+ USCI_REN_SDA = USCI_REN_TX,
+ USCI_REN_SDA_PULLUP = USCI_REN_TX_PULLUP,
+ USCI_REN_SDA_PULLDOWN = USCI_REN_TX_PULLDOWN,
+ USCI_REN_SCL = USCI_REN_RX,
+ USCI_REN_SCL_PULLUP = USCI_REN_RX_PULLUP,
+ USCI_REN_SCL_PULLDOWN = USCI_REN_RX_PULLDOWN
} msp430_ren_t;
/* Baud rates for UART mode. Only 32KHz modes work right now. */
uint8_t irtctl;
uint8_t irrctl;
uint8_t abctl;
+ bool uclisten;
msp430_ren_t ren;
-} __attribute__ ((packed)) msp430_usci_uart_t;
+} msp430_usci_uart_t;
typedef struct {
uint8_t ctl0;
uint8_t ctl1;
uint16_t brx;
- uint8_t mctl; /* ??? */
+ bool uclisten;
msp430_ren_t ren;
-} __attribute__ ((packed)) msp430_usci_spi_t;
+} msp430_usci_spi_t;
typedef struct {
uint8_t ctl0;
uint8_t i2cie;
uint8_t i2coa;
uint8_t i2csa;
+ bool uclisten;
msp430_ren_t ren;
-} __attribute__ ((packed)) msp430_usci_i2c_t;
+} msp430_usci_i2c_t;
#endif
interface ResourceRequested as ResourceRequested[uint8_t];
interface ArbiterInfo;
}
- uses interface ResourceConfig as ResourceConfig[uint8_t];
+ uses interface ResourceConfigure as ResourceConfigure[uint8_t];
}
implementation {
components new FcfsArbiterC(MSP430_USCIA0_RESOURCE) as ArbiterC;
interface ResourceRequested as ResourceRequested[uint8_t];
interface ArbiterInfo;
}
- uses interface ResourceConfig as ResourceConfig[uint8_t];
+ uses interface ResourceConfigure as ResourceConfigure[uint8_t];
}
implementation {
components new FcfsArbiterC(MSP430_USCIB0_RESOURCE) as ArbiterC;
interface ResourceRequested as ResourceRequested[uint8_t];
interface ArbiterInfo;
}
- uses interface ResourceConfig as ResourceConfig[uint8_t];
+ uses interface ResourceConfigure as ResourceConfigure[uint8_t];
}
implementation {
components new FcfsArbiterC(MSP430_USCIB1_RESOURCE) as ArbiterC;