From b054fbe2a8deacc35f0067deb15274da53d96984 Mon Sep 17 00:00:00 2001 From: smckown Date: Mon, 8 Sep 2008 21:35:08 +0000 Subject: [PATCH] USCI UART output on USCI_A1 is working, using ACLK as BRCLK. Baud rate problems using SMCLK, suggesting that SMCLK is not the frequency we expect. --- tos/chips/msp430/usci/HplMsp430UsciC.nc | 33 ++-- ...sp430UsciIntP.nc => HplMsp430UsciInt0P.nc} | 99 +++++----- tos/chips/msp430/usci/HplMsp430UsciInt1P.nc | 118 ++++++++++++ tos/chips/msp430/usci/HplMsp430UsciReg.nc | 170 ++++++++++-------- tos/chips/msp430/usci/HplMsp430UsciRegP.nc | 86 +++++---- tos/chips/msp430/usci/Msp430SpiB1C.nc | 6 +- tos/chips/msp430/usci/Msp430UartA0C.nc | 6 +- tos/chips/msp430/usci/Msp430UartA1C.nc | 4 +- tos/chips/msp430/usci/Msp430UartP.nc | 129 ++++++++----- tos/chips/msp430/usci/Msp430Usci.h | 87 ++------- 10 files changed, 415 insertions(+), 323 deletions(-) rename tos/chips/msp430/usci/{HplMsp430UsciIntP.nc => HplMsp430UsciInt0P.nc} (56%) create mode 100644 tos/chips/msp430/usci/HplMsp430UsciInt1P.nc diff --git a/tos/chips/msp430/usci/HplMsp430UsciC.nc b/tos/chips/msp430/usci/HplMsp430UsciC.nc index f8f84a9e..051e6546 100644 --- a/tos/chips/msp430/usci/HplMsp430UsciC.nc +++ b/tos/chips/msp430/usci/HplMsp430UsciC.nc @@ -53,7 +53,7 @@ configuration HplMsp430UsciC { interface HplMsp430UsciReg as RegB0; interface HplMsp430UsciInt as IntB0; #endif -#if defined(__MSP430_HAS_USCIAB1__) +#if defined(__MSP430_HAS_USCI_AB1__) interface HplMsp430UsciReg as RegA1; interface HplMsp430UsciInt as IntA1; interface HplMsp430UsciReg as RegB1; @@ -68,17 +68,15 @@ implementation { UCA0IRTCTL_, UCA0IRRCTL_, 0/*UCA0I2COA_*/, 0/*UCA0I2CSA_*/, IE2_, IFG2_, UCA0RXIFG, UCA0TXIFG) as RegA0P; - RegA0 = RegA0P.Reg; + RegA0 = RegA0P.Registers; components new HplMsp430UsciRegP(UCB0CTL0_, UCB0CTL1_, UCB0BR0_, UCB0BR1_, 0/*UCB0MCTL_*/, UCB0I2CIE_, UCB0STAT_, UCB0RXBUF_, UCB0TXBUF_, 0/*UCB0ABCTL_*/, 0/*UCB0IRTCTL_*/, 0/*UCB0IRRCTL_*/, UCB0I2COA_, UCB0I2CSA_, IE2_, IFG2_, UCB0RXIFG, UCB0TXIFG) as RegB0P; - RegB0 = RegB0P.Reg; + RegB0 = RegB0P.Registers; - components new HplMsp430UsciIntP(USCIAB0RX_VECTOR, USCIAB0TX_VECTOR, - UCA0RXIFG, UCA0TXIFG, UCB0RXIFG, UCB0TXIFG, UCA0CTL0_, UCA0CTL1_, - UCA0RXBUF_, UCB0CTL0_, UCB0CTL1_, UCB0RXBUF_, IFG2_) as Int0P; + components HplMsp430UsciInt0P as Int0P; IntA0 = Int0P.IntA; IntB0 = Int0P.IntB; #elif defined(__MSP430_HAS_USCI__) @@ -86,17 +84,15 @@ implementation { UCA0MCTL_, 0/*UCA0I2CIE_*/, UCA0STAT_, UCA0RXBUF_, UCA0TXBUF_, UCA0ABCTL_, UCA0IRTCTL_, UCA0IRRCTL_, 0/*UCA0I2COA_*/, 0/*UCA0I2CSA_*/, IE2_, IFG2_, UCA0RXIFG, UCA0TXIFG) as RegA0P; - RegA0 = RegA0P.Reg; + RegA0 = RegA0P.Registers; components new HplMsp430UsciRegP(UCB0CTL0_, UCB0CTL1_, UCB0BR0_, UCB0BR1_, 0/*UCB0MCTL_*/, UCB0I2CIE_, UCB0STAT_, UCB0RXBUF_, UCB0TXBUF_, 0/*UCB0ABCTL_*/, 0/*UCB0IRTCTL_*/, 0/*UCB0IRRCTL_*/, UCB0I2COA_, UCB0I2CSA_, IE2_, IFG2_, UCB0RXIFG, UCB0TXIFG) as RegB0P; - RegB0 = RegB0P.Reg; + RegB0 = RegB0P.Registers; - components new HplMsp430UsciIntP(USCIRX_VECTOR, USCITX_VECTOR, UCA0RXIFG, - UCA0TXIFG, UCB0RXIFG, UCB0TXIFG, UCA0CTL0_, UCA0CTL1_, UCA0RXBUF_, - UCB0CTL0_, UCB0CTL1_, UCB0RXBUF_, IFG2_) as Int0P; + components HplMsp430UsciInt0P as Int0P; IntA0 = Int0P.IntA; IntB0 = Int0P.IntB; #endif @@ -104,21 +100,18 @@ implementation { #if defined(__MSP430_HAS_USCI_AB1__) components new HplMsp430UsciRegP(UCA1CTL0_, UCA1CTL1_, UCA1BR0_, UCA1BR1_, UCA1MCTL_, 0/*UCA1I2CIE_*/, UCA1STAT_, UCA1RXBUF_, UCA1TXBUF_, UCA1ABCTL_, - UCA1IRTCTL_, UCA1IRRCTL_, 0/*UCA1I2COA_*/, 0/*UCA1I2CSA_*/, IE2_, IFG2_, - UCA1RXIFG, UCA1TXIFG) as RegA1P; - RegA1 = RegA1P.Reg; + UCA1IRTCTL_, UCA1IRRCTL_, 0/*UCA1I2COA_*/, 0/*UCA1I2CSA_*/, UC1IE_, + UC1IFG_, UCA1RXIFG, UCA1TXIFG) as RegA1P; + RegA1 = RegA1P.Registers; components new HplMsp430UsciRegP(UCB1CTL0_, UCB1CTL1_, UCB1BR0_, UCB1BR1_, 0/*UCB1MCTL_*/, UCB1I2CIE_, UCB1STAT_, UCB1RXBUF_, UCB1TXBUF_, 0/*UCB1ABCTL_*/, 0/*UCB1IRTCTL_*/, 0/*UCB1IRRCTL_*/, UCB1I2COA_, - UCB1I2CSA_, IE2_, IFG2_, UCB1RXIFG, UCB1TXIFG) as RegB1P; - RegB1 = RegB1P.Reg; + UCB1I2CSA_, UC1IE_, UC1IFG_, UCB1RXIFG, UCB1TXIFG) as RegB1P; + RegB1 = RegB1P.Registers; - components new HplMsp430UsciIntP(USCIAB1RX_VECTOR, USCIAB1TX_VECTOR, - UCA1RXIFG, UCA1TXIFG, UCB1RXIFG, UCB1TXIFG, UCA1CTL0_, UCA1CTL1_, - UCA1RXBUF_, UCB1CTL0_, UCB1CTL1_, UCB1RXBUF_, UC1IFG_) as Int1P; + components HplMsp430UsciInt1P as Int1P; IntA1 = Int1P.IntA; IntB1 = Int1P.IntB; #endif -#endif } diff --git a/tos/chips/msp430/usci/HplMsp430UsciIntP.nc b/tos/chips/msp430/usci/HplMsp430UsciInt0P.nc similarity index 56% rename from tos/chips/msp430/usci/HplMsp430UsciIntP.nc rename to tos/chips/msp430/usci/HplMsp430UsciInt0P.nc index a418bb27..8c3a3451 100644 --- a/tos/chips/msp430/usci/HplMsp430UsciIntP.nc +++ b/tos/chips/msp430/usci/HplMsp430UsciInt0P.nc @@ -28,7 +28,7 @@ */ /** - * HPL interrupt interface for a given USCI's Ax and Bx devices. + * HPL interrupt interface for the USCI0 peripheral. * * @author R. Steve McKown */ @@ -36,93 +36,78 @@ #include "Msp430Usci.h" #include "msp430hardware.h" -module HplMsp430UsciInt0P( - uint8_t USCIABxRX_VECTOR, - uint8_t USCIABxTX_VECTOR, - uint8_t UCAxRXIFG, - uint8_t UCAxTXIFG, - uint8_t UCBxRXIFG, - uint8_t UCBxTXIFG, - uint8_t Ucaxctl0_addr, - uint8_t Ucaxctl1_addr, - uint8_t Ucaxrxbuf_addr, - uint8_t Ucbxctl0_addr, - uint8_t Ucbxctl1_addr, - uint8_t Ucbxrxbuf_addr, - uint8_t Ucxifg_addr - ) @safe() { +#if defined(USCIRX_VECTOR) /* odd def for MSP430G461 */ +#define USCIAB0RX_VECTOR USCIRX_VECTOR +#endif +#if defined(USCITX_VECTOR) /* odd def for MSP430G461 */ +#define USCIAB0TX_VECTOR USCITX_VECTOR +#endif + +module HplMsp430UsciInt0P @safe() { provides { - interface HplMsp430UsciInt as IntA; /* Interrupts for USCI_A0 */ - interface HplMsp430UsciInt as IntB; /* Interrupts for USCI_B0 */ + interface HplMsp430UsciInt as IntA; + interface HplMsp430UsciInt as IntB; } } implementation { - #define UCxIFG (*TCAST(volatile uint8_t* ONE, Ucxifg_addr)) - #define UCAxCTL0 (*TCAST(volatile uint8_t* ONE, Ucaxctl0_addr)) - #define UCAxCTL1 (*TCAST(volatile uint8_t* ONE, Ucaxctl1_addr)) - #define UCAxRXBUF (*TCAST(volatile uint8_t* ONE, Ucaxrxbuf_addr)) - #define UCBxCTL0 (*TCAST(volatile uint8_t* ONE, Ucbxctl0_addr)) - #define UCBxCTL1 (*TCAST(volatile uint8_t* ONE, Ucbxctl1_addr)) - #define UCBxRXBUF (*TCAST(volatile uint8_t* ONE, Ucbxrxbuf_addr)) - #if 0 - MSP430REG_NORACE(UCxIFG); - MSP430REG_NORACE(UCAxCTL0); - MSP430REG_NORACE(UCAxCTL1); - MSP430REG_NORACE(UCAxRXBUF); - MSP430REG_NORACE(UCBxCTL0); - MSP430REG_NORACE(UCBxCTL1); - MSP430REG_NORACE(UCBxRXBUF); + MSP430REG_NORACE(UC0IFG); + MSP430REG_NORACE(UCA0CTL0); + MSP430REG_NORACE(UCA0CTL1); + MSP430REG_NORACE(UCA0RXBUF); + MSP430REG_NORACE(UCB0CTL0); + MSP430REG_NORACE(UCB0CTL1); + MSP430REG_NORACE(UCB0RXBUF); #endif /* This USCI_Ax and USCI_Bx interrupt vector signals receive events for UART * and SPI modes, and status events for I2C modes. Only Bx can do I2C. */ - TOSH_SIGNAL(USCIABxRX_VECTOR) { - if (READ_FLAG(UCxIFG, UCAxRXIFG)) { - volatile uint8_t c = UCAxRXBUF; /* read to clear UCAxRXIFG */ - if (READ_FLAG(UCAxCTL1, UCBRK)) { - UCAxCTL1 &= ~UCBRK; - if (READ_FLAG(UCAxCTL0, UCMODE_3) == UCMODE_3) - UCAxCTL1 &= ~UCDORM; + TOSH_SIGNAL(USCIAB0RX_VECTOR) { + if (READ_FLAG(UC0IFG, UCA0RXIFG)) { + volatile uint8_t c = UCA0RXBUF; /* read to clear UCA0RXIFG */ + if (READ_FLAG(UCA0CTL1, UCBRK)) { + UCA0CTL1 &= ~UCBRK; + if (READ_FLAG(UCA0CTL0, UCMODE_3) == UCMODE_3) + UCA0CTL1 &= ~UCDORM; signal IntA.brk(); } else signal IntA.rx(c); - } else if (READ_FLAG(UCxIFG, UCBxRXIFG)) { - volatile uint8_t c = UCBxRXBUF; /* read to clear UCBxRXIFG */ - if (READ_FLAG(UCBxCTL1, UCBRK)) { - CLR_FLAG(UCBxCTL1, UCBRK); - if (READ_FLAG(UCBxCTL0, UCMODE_3) == UCMODE_3) - CLR_FLAG(UCBxCTL1, UCDORM); + } 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(UCBxSTAT & UCALIFG)) + } else if (READ_FLAG(UCB0STAT, UCALIFG)) signal IntB.i2cCal(); - else if (READ_FLAG(UCBxSTAT, UCNAKIFG)) + else if (READ_FLAG(UCB0STAT, UCNACKIFG)) signal IntB.i2cNak(); - else if (READ_FLAG(UCBxSTAT, UCSTTIFG)) + else if (READ_FLAG(UCB0STAT, UCSTTIFG)) signal IntB.i2cStart(); - else if (READ_FLAG(UCBxSTAT, UCSTPIFG)) + else if (READ_FLAG(UCB0STAT, UCSTPIFG)) signal IntB.i2cStop(); } /* This USCI_Ax and USCI_Bx interrupt vector signals transmit events for UART * and SPI modes, and rx/tx events for I2C modes. Only Bx can do I2C. */ - TOSH_SIGNAL(USCIABxTX_VECTOR) { - if (READ_FLAG(UCxIFG, UCBxRXIFG)) - signal IntB.rx(UCBxRXBUF); /* I2C receive */ - else if (READ_FLAG(UCxIFG, UCAxTXIFG)) + TOSH_SIGNAL(USCIAB0TX_VECTOR) { + if (READ_FLAG(UC0IFG, UCB0RXIFG)) + signal IntB.rx(UCB0RXBUF); /* I2C receive */ + else if (READ_FLAG(UC0IFG, UCA0TXIFG)) signal IntA.tx(); - else if (READ_FLAG(UCxIFG, UCBxTXIFG)) + else if (READ_FLAG(UC0IFG, UCB0TXIFG)) signal IntB.tx(); } default async event void IntA.brk() {} - default async event void IntA.rx(char c) {} + default async event void IntA.rx(uint8_t byte) {} default async event void IntA.tx() {} /* i2c is not available for A devices, so the below are never signalled */ default async event void IntA.i2cCal() {} @@ -131,7 +116,7 @@ implementation default async event void IntA.i2cStop() {} default async event void IntB.brk() {} - default async event void IntB.rx(char c) {} + default async event void IntB.rx(uint8_t byte) {} default async event void IntB.tx() {} default async event void IntB.i2cCal() {} default async event void IntB.i2cNak() {} diff --git a/tos/chips/msp430/usci/HplMsp430UsciInt1P.nc b/tos/chips/msp430/usci/HplMsp430UsciInt1P.nc new file mode 100644 index 00000000..e6a79a14 --- /dev/null +++ b/tos/chips/msp430/usci/HplMsp430UsciInt1P.nc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2008, Titanium Mirror, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the Technische Universität Berlin nor the names + * of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * HPL interrupt interface for the USCI1 peripheral. + * + * @author R. Steve McKown + */ + +#include "Msp430Usci.h" +#include "msp430hardware.h" + +module HplMsp430UsciInt1P @safe() { + provides { + interface HplMsp430UsciInt as IntA; + interface HplMsp430UsciInt as IntB; + } +} + +implementation +{ +#if 0 + MSP430REG_NORACE(UC1IFG); + MSP430REG_NORACE(UCA1CTL0); + MSP430REG_NORACE(UCA1CTL1); + MSP430REG_NORACE(UCA1RXBUF); + MSP430REG_NORACE(UCB1CTL0); + MSP430REG_NORACE(UCB1CTL1); + MSP430REG_NORACE(UCB1RXBUF); +#endif + + /* This USCI_Ax and USCI_Bx interrupt vector signals receive events for UART + * and SPI modes, and status events for I2C modes. Only Bx can do I2C. + */ + TOSH_SIGNAL(USCIAB1RX_VECTOR) { + if (READ_FLAG(UC1IFG, UCA1RXIFG)) { + volatile uint8_t c = UCA1RXBUF; /* read to clear UCA1RXIFG */ + if (READ_FLAG(UCA1CTL1, UCBRK)) { + UCA1CTL1 &= ~UCBRK; + if (READ_FLAG(UCA1CTL0, UCMODE_3) == UCMODE_3) + UCA1CTL1 &= ~UCDORM; + 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)) + signal IntB.i2cCal(); + else if (READ_FLAG(UCB1STAT, UCNACKIFG)) + signal IntB.i2cNak(); + else if (READ_FLAG(UCB1STAT, UCSTTIFG)) + signal IntB.i2cStart(); + else if (READ_FLAG(UCB1STAT, UCSTPIFG)) + signal IntB.i2cStop(); + } + + /* This USCI_Ax and USCI_Bx interrupt vector signals transmit events for UART + * and SPI modes, and rx/tx events for I2C modes. Only Bx can do I2C. + */ + TOSH_SIGNAL(USCIAB1TX_VECTOR) { + if (READ_FLAG(UC1IFG, UCB1RXIFG)) + signal IntB.rx(UCB1RXBUF); /* I2C receive */ + else if (READ_FLAG(UC1IFG, UCA1TXIFG)) + signal IntA.tx(); + else if (READ_FLAG(UC1IFG, UCB1TXIFG)) + signal IntB.tx(); + } + + default async event void IntA.brk() {} + default async event void IntA.rx(uint8_t byte) {} + default async event void IntA.tx() {} + /* i2c is not available for A devices, so the below are never signalled */ + default async event void IntA.i2cCal() {} + default async event void IntA.i2cNak() {} + default async event void IntA.i2cStart() {} + default async event void IntA.i2cStop() {} + + default async event void IntB.brk() {} + default async event void IntB.rx(uint8_t byte) {} + default async event void IntB.tx() {} + default async event void IntB.i2cCal() {} + default async event void IntB.i2cNak() {} + default async event void IntB.i2cStart() {} + default async event void IntB.i2cStop() {} +} diff --git a/tos/chips/msp430/usci/HplMsp430UsciReg.nc b/tos/chips/msp430/usci/HplMsp430UsciReg.nc index 3f4536c8..ed296771 100644 --- a/tos/chips/msp430/usci/HplMsp430UsciReg.nc +++ b/tos/chips/msp430/usci/HplMsp430UsciReg.nc @@ -39,7 +39,7 @@ interface HplMsp430UsciReg { /** * Return the current mode. */ - command msp430_usci_mode_t getMode(); + async command msp430_usci_mode_t getMode(); /** * Prepare to set the mode. If the device supports the requested mode, its @@ -50,14 +50,14 @@ interface HplMsp430UsciReg { * @param msp430usci_mode_t The desired USCI mode. * @return bool TRUE if the device supports the requested mode, else FALSE. */ - command bool setMode(msp430_usci_mode_t mode); + async command bool setMode(msp430_usci_mode_t mode); /** * Get pointer to the UCxxCTL0 register associated with the USCI device. * * @return The pointer to the device's UCxxCTL0 register. */ - command volatile uint8_t* ptrCtl0(); + async command volatile uint8_t* ptrCtl0(); /** * Get bits from the UCxxCTL0 register associated with the USCI device. @@ -67,7 +67,7 @@ interface HplMsp430UsciReg { * @return The value of the device's UCxxCTL0 register ANDed with * mask. */ - command uint8_t getCtl0(uint8_t mask); + async command uint8_t getCtl0(uint8_t mask); /** * Set bits in the UCxxCTL0 register associated with the USCI device. @@ -75,7 +75,7 @@ interface HplMsp430UsciReg { * * @parm mask The bits in set in mask to set in UCxxCTL0. */ - command void setCtl0(uint8_t mask); + async command void setCtl0(uint8_t mask); /** * Clear bits in the UCxxCTL0 register associated with the USCI device. @@ -83,178 +83,190 @@ interface HplMsp430UsciReg { * * @parm mask The bits in set in mask to clear in UCxxCTL0. */ - command void clrCtl0(uint8_t mask); + async command void clrCtl0(uint8_t mask); /** * Assign the values of the bits in value, whose corresponding bits in * mask are set, in the UCxxCTL0 register. The operation is * equivalent to: UCxxCTL0 = (UCxxCTL0 & ~mask) | (value & mask). */ - command void assignCtl0(uint8_t mask, uint8_t value); + //async command void assignCtl0(uint8_t mask, uint8_t value); + async command void assignCtl0(uint8_t value); /** * Manipulate bits in the UCxxCTL1 register. See the methods that manipulate * UCxxCTL0 for more information. */ - command volatile uint8_t* ptrCtl1(); - command uint8_t getCtl1(uint8_t mask); - command void setCtl1(uint8_t mask); - command void clrCtl1(uint8_t mask); - command void assignCtl1(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrCtl1(); + async command uint8_t getCtl1(uint8_t mask); + async command void setCtl1(uint8_t mask); + async command void clrCtl1(uint8_t mask); + //async command void assignCtl1(uint8_t mask, uint8_t value); + async command void assignCtl1(uint8_t value); /** * Manipulate bits in the UCxxBR0 register. See the methods that manipulate * UCxxCTL0 for more information. */ - command volatile uint8_t* ptrBr0(); - command uint8_t getBr0(uint8_t mask); - command void setBr0(uint8_t mask); - command void clrBr0(uint8_t mask); - command void assignBr0(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrBr0(); + async command uint8_t getBr0(uint8_t mask); + async command void setBr0(uint8_t mask); + async command void clrBr0(uint8_t mask); + //async command void assignBr0(uint8_t mask, uint8_t value); + async command void assignBr0(uint8_t value); /** * Manipulate bits in the UCxxBR1 register. See the methods that manipulate * UCxxCTL0 for more information. */ - command volatile uint8_t* ptrBr1(); - command uint8_t getBr1(uint8_t mask); - command void setBr1(uint8_t mask); - command void clrBr1(uint8_t mask); - command void assignBr1(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrBr1(); + async command uint8_t getBr1(uint8_t mask); + async command void setBr1(uint8_t mask); + async command void clrBr1(uint8_t mask); + //async command void assignBr1(uint8_t mask, uint8_t value); + async command void assignBr1(uint8_t value); /** * Manipulate bits in the UCxxMCTL register. See the methods that manipulate * UCxxCTL0 for more information. These methods perform no operation on * providers implementing a USCI_Bx device. */ - command volatile uint8_t* ptrMctl(); - command uint8_t getMctl(uint8_t mask); - command void setMctl(uint8_t mask); - command void clrMctl(uint8_t mask); - command void assignMctl(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrMctl(); + async command uint8_t getMctl(uint8_t mask); + async command void setMctl(uint8_t mask); + async command void clrMctl(uint8_t mask); + //async command void assignMctl(uint8_t mask, uint8_t value); + async command void assignMctl(uint8_t value); /** * Manipulate bits in the UCxxI2CIE register. See the methods that * manipulate UCxxCTL0 for more information. These methods perform no * operation on providers implementing a USCI_Ax device. */ - command volatile uint8_t* ptrI2Cie(); - command uint8_t getI2Cie(uint8_t mask); - command void setI2Cie(uint8_t mask); - command void clrI2Cie(uint8_t mask); - command void assignI2Cie(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrI2Cie(); + async command uint8_t getI2Cie(uint8_t mask); + async command void setI2Cie(uint8_t mask); + async command void clrI2Cie(uint8_t mask); + //async command void assignI2Cie(uint8_t mask, uint8_t value); + async command void assignI2Cie(uint8_t value); /** * Manipulate bits in the UCxxSTAT register. See the methods that manipulate * UCxxCTL0 for more information. */ - command volatile uint8_t* ptrStat(); - command uint8_t getStat(uint8_t mask); - command void setStat(uint8_t mask); - command void clrStat(uint8_t mask); - command void assignStat(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrStat(); + async command uint8_t getStat(uint8_t mask); + async command void setStat(uint8_t mask); + async command void clrStat(uint8_t mask); + //async command void assignStat(uint8_t mask, uint8_t value); + async command void assignStat(uint8_t value); /** * Return pointer to the UCAxxRXBUF register used by the USCI device. */ - command volatile uint8_t* ptrRxbuf(); + async command volatile uint8_t* ptrRxbuf(); /** * Read the contents of the UCAxxRXBUF register. This register cannot be * written. */ - command uint8_t getRxbuf(); + async command uint8_t getRxbuf(); /** * Return pointer to the UCAxxTXBUF register used by the USCI device. */ - command volatile uint8_t* ptrTxbuf(); + async command volatile uint8_t* ptrTxbuf(); /** * Read the contents of the UCAxxTXBUF register. */ - command uint8_t getTxbuf(); + async command uint8_t getTxbuf(); /** * Write a byte to the UCAxxTXBUF register. */ - command void setTxbuf(uint8_t byte); + async command void setTxbuf(uint8_t byte); /** * Manipulate bits in the UCxxABCTL register. See the methods that * manipulate UCxxCTL0 for more information. These methods perform no * operation on providers implementing a USCI_Bx device. */ - command volatile uint8_t* ptrAbctl(); - command uint8_t getAbctl(uint8_t mask); - command void setAbctl(uint8_t mask); - command void clrAbctl(uint8_t mask); - command void assignAbctl(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrAbctl(); + async command uint8_t getAbctl(uint8_t mask); + async command void setAbctl(uint8_t mask); + async command void clrAbctl(uint8_t mask); + //async command void assignAbctl(uint8_t mask, uint8_t value); + async command void assignAbctl(uint8_t value); /** * Manipulate bits in the UCxxIRTCTL register. See the methods that * manipulate UCxxCTL0 for more information. These methods perform no * operation on providers implementing a USCI_Bx device. */ - command volatile uint8_t* ptrIrtctl(); - command uint8_t getIrtctl(uint8_t mask); - command void setIrtctl(uint8_t mask); - command void clrIrtctl(uint8_t mask); - command void assignIrtctl(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrIrtctl(); + async command uint8_t getIrtctl(uint8_t mask); + async command void setIrtctl(uint8_t mask); + async command void clrIrtctl(uint8_t mask); + //async command void assignIrtctl(uint8_t mask, uint8_t value); + async command void assignIrtctl(uint8_t value); /** * Manipulate bits in the UCxxIRRCTL register. See the methods that * manipulate UCxxCTL0 for more information. These methods perform no * operation on providers implementing a USCI_Bx device. */ - command volatile uint8_t* ptrIrrctl(); - command uint8_t getIrrctl(uint8_t mask); - command void setIrrctl(uint8_t mask); - command void clrIrrctl(uint8_t mask); - command void assignIrrctl(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrIrrctl(); + async command uint8_t getIrrctl(uint8_t mask); + async command void setIrrctl(uint8_t mask); + async command void clrIrrctl(uint8_t mask); + //async command void assignIrrctl(uint8_t mask, uint8_t value); + async command void assignIrrctl(uint8_t value); /** * Manipulate bits in the UCxxI2COA register. See the methods that * manipulate UCxxCTL0 for more information. These methods perform no * operation on providers implementing a USCI_Ax device. */ - command volatile uint8_t* ptrI2Coa(); - command uint8_t getI2Coa(uint8_t mask); - command void setI2Coa(uint8_t mask); - command void clrI2Coa(uint8_t mask); - command void assignI2Coa(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrI2Coa(); + async command uint8_t getI2Coa(uint8_t mask); + async command void setI2Coa(uint8_t mask); + async command void clrI2Coa(uint8_t mask); + //async command void assignI2Coa(uint8_t mask, uint8_t value); + async command void assignI2Coa(uint8_t value); /** * Manipulate bits in the UCxxI2COA register. See the methods that * manipulate UCxxCTL0 for more information. These methods perform no * operation on providers implementing a USCI_Ax device. */ - command volatile uint8_t* ptrI2Csa(); - command uint8_t getI2Csa(uint8_t mask); - command void setI2Csa(uint8_t mask); - command void clrI2Csa(uint8_t mask); - command void assignI2Csa(uint8_t mask, uint8_t value); + async command volatile uint8_t* ptrI2Csa(); + async command uint8_t getI2Csa(uint8_t mask); + async command void setI2Csa(uint8_t mask); + async command void clrI2Csa(uint8_t mask); + //async command void assignI2Csa(uint8_t mask, uint8_t value); + async command void assignI2Csa(uint8_t value); /** * Manipulate bits in the UCxxIE register. See the methods that manipulate * UCxxCTL0 for more information. */ - command bool getIeRx(); - command void setIeRx(); - command void clrIeRx(); - command bool getIeTx(); - command void setIeTx(); - command void clrIeTx(); + async command bool getIeRx(); + async command void setIeRx(); + async command void clrIeRx(); + async command bool getIeTx(); + async command void setIeTx(); + async command void clrIeTx(); /** * Manipulate bits in the UCxxIFG register. See the methods that manipulate * UCxxCTL0 for more information. */ - command bool getIfgRx(); - command void setIfgRx(); - command void clrIfgRx(); - command bool getIfgTx(); - command void setIfgTx(); - command void clrIfgTx(); + async command bool getIfgRx(); + async command void setIfgRx(); + async command void clrIfgRx(); + async command bool getIfgTx(); + async command void setIfgTx(); + async command void clrIfgTx(); } diff --git a/tos/chips/msp430/usci/HplMsp430UsciRegP.nc b/tos/chips/msp430/usci/HplMsp430UsciRegP.nc index cde8ae1a..67f650a7 100644 --- a/tos/chips/msp430/usci/HplMsp430UsciRegP.nc +++ b/tos/chips/msp430/usci/HplMsp430UsciRegP.nc @@ -85,66 +85,72 @@ implementation #define UCxxIe (*TCAST(volatile uint8_t* ONE, Ie_addr)) #define UCxxIfg (*TCAST(volatile uint8_t* ONE, Ifg_addr)) +#if 0 #define ASSIGNBITS(reg, mask, value) \ (reg = ((reg) & ~(mask)) | ((value) & (mask))) +#endif #define RENDER(name) \ - command volatile uint8_t* Registers.ptr##name() { \ + async command volatile uint8_t* Registers.ptr##name() { \ return &UCxx##name; \ } \ - command uint8_t Registers.get##name(uint8_t mask) { \ + async command uint8_t Registers.get##name(uint8_t mask) { \ return READ_FLAG(UCxx##name, mask); \ } \ - command void Registers.set##name(uint8_t mask) { \ + async command void Registers.set##name(uint8_t mask) { \ SET_FLAG(UCxx##name, mask); \ } \ - command void Registers.clr##name(uint8_t mask) { \ + async command void Registers.clr##name(uint8_t mask) { \ CLR_FLAG(UCxx##name, mask); \ } \ - command void Registers.assign##name(uint8_t mask, uint8_t value) { \ - ASSIGNBITS(UCxx##name, mask, value); \ + async command void Registers.assign##name(uint8_t value) { \ + UCxx##name = value; \ } #define RENDER_A(name) \ - command volatile uint8_t* Registers.ptr##name() { \ + async command volatile uint8_t* Registers.ptr##name() { \ return &UCAx##name; \ } \ - command uint8_t Registers.get##name(uint8_t mask) { \ + async command uint8_t Registers.get##name(uint8_t mask) { \ if (IS_USCI_Ax) \ return READ_FLAG(UCAx##name, mask); \ + else \ + return 0; \ } \ - command void Registers.set##name(uint8_t mask) { \ + async command void Registers.set##name(uint8_t mask) { \ if (IS_USCI_Ax) \ SET_FLAG(UCAx##name, mask); \ } \ - command void Registers.clr##name(uint8_t mask) { \ + async command void Registers.clr##name(uint8_t mask) { \ if (IS_USCI_Ax) \ CLR_FLAG(UCAx##name, mask); \ } \ - command void Registers.assign##name(uint8_t mask, uint8_t value) { \ + async command void Registers.assign##name(uint8_t value) { \ if (IS_USCI_Ax) \ - ASSIGNBITS(UCAx##name, mask, value); \ + UCAx##name = value; \ } #define RENDER_B(name) \ - command volatile uint8_t* Registers.ptr##name() { \ + async command volatile uint8_t* Registers.ptr##name() { \ return &UCBx##name; \ } \ - command uint8_t Registers.get##name(uint8_t mask) { \ + async command uint8_t Registers.get##name(uint8_t mask) { \ if (IS_USCI_Bx) \ return READ_FLAG(UCBx##name, mask); \ + else \ + return 0; \ } \ - command void Registers.set##name(uint8_t mask) { \ + async command void Registers.set##name(uint8_t mask) { \ if (IS_USCI_Bx) \ SET_FLAG(UCBx##name, mask); \ } \ - command void Registers.clr##name(uint8_t mask) { \ + async command void Registers.clr##name(uint8_t mask) { \ if (IS_USCI_Bx) \ CLR_FLAG(UCBx##name, mask); \ } \ - command void Registers.assign##name(uint8_t mask, uint8_t value) { \ + async command void Registers.assign##name(uint8_t value) { \ if (IS_USCI_Bx) \ - ASSIGNBITS(UCBx##name, mask, value); \ + UCBx##name = value; \ } #if 0 @@ -167,7 +173,7 @@ implementation MSP430REG_NORACE(UCxIfg); #endif - command msp430_usci_mode_t Registers.getMode() + async command msp430_usci_mode_t Registers.getMode() { if (READ_FLAG(UCxxCtl0, UCSYNC)) { if (READ_FLAG(UCxxCtl0, UCMODE_3) == UCMODE_3) @@ -179,13 +185,17 @@ implementation } } - command bool Registers.setMode(msp430_usci_mode_t mode) + /* Doesn't really set the mode, but checks the most for the device and inits + * the device. + */ + async command bool Registers.setMode(msp430_usci_mode_t mode) { if (mode == USCI_UART && IS_USCI_Bx) return FALSE; if (mode == USCI_I2C && IS_USCI_Ax) return FALSE; - SET_FLAG(UCxxCtl0, UCSYNC); + SET_FLAG(UCxxCtl1, UCSWRST); + return TRUE; } RENDER(Ctl0); @@ -197,28 +207,28 @@ implementation RENDER(Stat); /* RENDER(Rxbuf); */ - command volatile uint8_t* Registers.ptrRxbuf() + async command volatile uint8_t* Registers.ptrRxbuf() { return &UCxxRxbuf; } - command uint8_t Registers.getRxbuf() + async command uint8_t Registers.getRxbuf() { return UCxxRxbuf; } /* RENDER(Txbuf); */ - command volatile uint8_t* Registers.ptrTxbuf() + async command volatile uint8_t* Registers.ptrTxbuf() { return &UCxxTxbuf; } - command uint8_t Registers.getTxbuf() + async command uint8_t Registers.getTxbuf() { return UCxxTxbuf; } - command void Registers.setTxbuf(uint8_t byte) + async command void Registers.setTxbuf(uint8_t byte) { UCxxTxbuf = byte; } @@ -230,63 +240,63 @@ implementation RENDER_B(I2Csa); /* RENDER(Ie); */ - command bool Registers.getIeRx() + async command bool Registers.getIeRx() { return READ_FLAG(UCxxIe, UCAxRXIFG); } - command void Registers.setIeRx() + async command void Registers.setIeRx() { SET_FLAG(UCxxIe, UCAxRXIFG); } - command void Registers.clrIeRx() + async command void Registers.clrIeRx() { CLR_FLAG(UCxxIe, UCAxRXIFG); } - command bool Registers.getIeTx() + async command bool Registers.getIeTx() { return READ_FLAG(UCxxIe, UCAxTXIFG); } - command void Registers.setIeTx() + async command void Registers.setIeTx() { SET_FLAG(UCxxIe, UCAxTXIFG); } - command void Registers.clrIeTx() + async command void Registers.clrIeTx() { CLR_FLAG(UCxxIe, UCAxTXIFG); } /* RENDER(Ifg); */ - command bool Registers.getIfgRx() + async command bool Registers.getIfgRx() { return READ_FLAG(UCxxIfg, UCAxRXIFG); } - command void Registers.setIfgRx() + async command void Registers.setIfgRx() { SET_FLAG(UCxxIfg, UCAxRXIFG); } - command void Registers.clrIfgRx() + async command void Registers.clrIfgRx() { CLR_FLAG(UCxxIfg, UCAxRXIFG); } - command bool Registers.getIfgTx() + async command bool Registers.getIfgTx() { return READ_FLAG(UCxxIfg, UCAxTXIFG); } - command void Registers.setIfgTx() + async command void Registers.setIfgTx() { SET_FLAG(UCxxIfg, UCAxTXIFG); } - command void Registers.clrIfgTx() + async command void Registers.clrIfgTx() { CLR_FLAG(UCxxIfg, UCAxTXIFG); } diff --git a/tos/chips/msp430/usci/Msp430SpiB1C.nc b/tos/chips/msp430/usci/Msp430SpiB1C.nc index 0e20f519..ad0997a4 100644 --- a/tos/chips/msp430/usci/Msp430SpiB1C.nc +++ b/tos/chips/msp430/usci/Msp430SpiB1C.nc @@ -40,7 +40,7 @@ #include "Msp430Usci.h" -configuration Msp430SpiB1C { +generic configuration Msp430SpiB1C() { provides { interface Resource; interface ResourceRequested; @@ -55,12 +55,12 @@ implementation { CLIENT_ID = unique(MSP430_USCIB1_RESOURCE) }; - components Msp430SpiP as SpiP; + components new Msp430SpiP() as SpiP; SpiByte = SpiP; SpiPacket = SpiP; Msp430UsciSpiConfigure = SpiP; - components new Msp430UsciA0C() as UsciC; + components Msp430UsciA0C as UsciC; Resource = UsciC.Resource[CLIENT_ID]; ResourceRequested = UsciC.ResourceRequested[CLIENT_ID]; ArbiterInfo = UsciC.ArbiterInfo; diff --git a/tos/chips/msp430/usci/Msp430UartA0C.nc b/tos/chips/msp430/usci/Msp430UartA0C.nc index b9e6073c..39b2e43b 100644 --- a/tos/chips/msp430/usci/Msp430UartA0C.nc +++ b/tos/chips/msp430/usci/Msp430UartA0C.nc @@ -40,7 +40,7 @@ #include "Msp430Usci.h" -configuration Msp430UartA0C { +generic configuration Msp430UartA0C() { provides { interface Resource; interface ResourceRequested; @@ -55,12 +55,12 @@ implementation { CLIENT_ID = unique(MSP430_USCIA0_RESOURCE) }; - components Msp430UartP as UartP; + components new Msp430UartP() as UartP; UartStream = UartP; UartByte = UartP; Msp430UsciUartConfigure = UartP; - components new Msp430UsciA0C() as UsciC; + components Msp430UsciA0C as UsciC; Resource = UsciC.Resource[CLIENT_ID]; ResourceRequested = UsciC.ResourceRequested[CLIENT_ID]; ArbiterInfo = UsciC.ArbiterInfo; diff --git a/tos/chips/msp430/usci/Msp430UartA1C.nc b/tos/chips/msp430/usci/Msp430UartA1C.nc index 558a29b5..dd680564 100644 --- a/tos/chips/msp430/usci/Msp430UartA1C.nc +++ b/tos/chips/msp430/usci/Msp430UartA1C.nc @@ -40,7 +40,7 @@ #include "Msp430Usci.h" -configuration Msp430UartA1C { +generic configuration Msp430UartA1C() { provides { interface Resource; interface ResourceRequested; @@ -60,7 +60,7 @@ implementation { UartByte = UartP; Msp430UsciConfigure = UartP; - components new Msp430UsciA1C() as UsciC; + components Msp430UsciA1C as UsciC; Resource = UsciC.Resource[CLIENT_ID]; ResourceRequested = UsciC.ResourceRequested[CLIENT_ID]; ArbiterInfo = UsciC.ArbiterInfo; diff --git a/tos/chips/msp430/usci/Msp430UartP.nc b/tos/chips/msp430/usci/Msp430UartP.nc index 550b1623..ad919b82 100644 --- a/tos/chips/msp430/usci/Msp430UartP.nc +++ b/tos/chips/msp430/usci/Msp430UartP.nc @@ -89,63 +89,94 @@ implementation { async command void ResourceConfigure.configure() { - msp430_usci_config_t* config = call Msp430UsciConfigure.get(); + atomic { + msp430_usci_config_t* config = call Msp430UsciConfigure.get(); - call Registers.setCtl0(UCSYNC); - /* Save pin states */ - dir = out = ren = 0; - saveBits(RXD, 0, dir, out, ren); - saveBits(TXD, 1, dir, out, ren); + call Registers.setCtl1(UCSWRST); - /* Configure USCI registers */ - call Registers.assignCtl0(0xff, config->uart.ctl0); - call Registers.assignCtl1(0xff, config->uart.ctl1|UCSWRST); - call Registers.assignBr0(0xff, config->uart.brx & 0xff); - call Registers.assignBr1(0xff, config->uart.brx >> 8); - call Registers.assignMctl(0xff, config->uart.mctl); - call Registers.assignIrtctl(0xff, config->uart.irtctl); - call Registers.assignIrrctl(0xff, config->uart.irrctl); - call Registers.assignAbctl(0xff, config->uart.abctl); - /* FIXME: we may need to have REN/DIR stuff in the configuration... */ + /* Configure USCI registers */ + call Registers.assignCtl0(config->uart.ctl0); + call Registers.assignCtl1(config->uart.ctl1|UCSWRST); + call Registers.assignBr0(config->uart.brx & 0xff); + call Registers.assignBr1(config->uart.brx >> 8); + call Registers.assignMctl(config->uart.mctl); + call Registers.assignIrtctl(config->uart.irtctl); + call Registers.assignIrrctl(config->uart.irrctl); + call Registers.assignAbctl(config->uart.abctl); + call Registers.clrStat(UCLISTEN); - /* Configure pins for module function */ - call RXD.selectModuleFunc(); - call TXD.selectModuleFunc(); + /* Save pin IO states */ + dir = out = ren = 0; + saveBits(RXD, 0, dir, out, ren); + saveBits(TXD, 1, dir, out, ren); - /* Clear interrupts; we'll add them as needed */ - call Registers.clrCtl1(UCRXEIE|UCBRKIE); - call Registers.clrIeRx(); - call Registers.clrIeTx(); + /* Configure RX pin for UART use */ + call RXD.makeInput(); + if (config->uart.ren & USCI_REN_RX) { + if (config->uart.ren & USCI_REN_RX_PULLUP) + call RXD.set(); + else + call RXD.clr(); + call RXD.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. + */ - /* Enable the device */ - call Registers.clrCtl0(UCSYNC); + /* Configure TX pin for UART use */ + if (config->uart.ren & USCI_REN_TX) { + if (config->uart.ren & USCI_REN_TX_PULLUP) + call TXD.set(); + else + call TXD.clr(); + call TXD.enableRen(); + } + call TXD.selectModuleFunc(); +#endif + + /* Clear interrupts; we'll add them as needed */ + call Registers.clrIeRx(); + call Registers.clrIeTx(); + + /* Enable the device */ + call Registers.clrCtl1(UCSWRST); + } } async command void ResourceConfigure.unconfigure() { - /* Disable the device */ - call Registers.setCtl0(UCSYNC); + atomic { + /* Disable the device */ + call Registers.setCtl1(UCSYNC); - /* Clear interrupts and interrupt flags */ - call Registers.clrIeRx(); - call Registers.clrIeTx(); - call Registers.clrIfgRx(); - call Registers.clrIfgTx(); + /* Clear interrupts and interrupt flags */ + call Registers.clrIeRx(); + call Registers.clrIeTx(); + call Registers.clrIfgRx(); + call Registers.clrIfgTx(); - /* Restore pins to their preconfigured state */ - restoreBits(RXD, 0, dir, out, ren); - restoreBits(TXD, 0, dir, out, ren); - call RXD.selectIOFunc(); - call TXD.selectIOFunc(); + /* Restore pins to their preconfigured state */ +#if 0 + restoreBits(RXD, 0, dir, out, ren); + restoreBits(TXD, 0, dir, out, ren); +#endif + call RXD.selectIOFunc(); + call TXD.selectIOFunc(); + } } async command error_t UartByte.send(uint8_t byte) { /* FIXME: race with UartStream.send() */ - if (sobuf) - return FAIL; - call Registers.setTxbuf(byte); - return SUCCESS; + atomic { + if (sobuf) + return FAIL; + while (call Registers.getStat(UCBUSY)); + call Registers.setTxbuf(byte); + return SUCCESS; + } } async command error_t UartStream.send(uint8_t* buf, uint16_t len) @@ -254,13 +285,13 @@ implementation { static msp430_usci_config_t def = { uart: { ctl0: UCMODE_0, /* async, lsb first, 8N1 */ - ctl1: UCSWRST|UCSSEL_3, /* clock uart from SMCLK */ - brx: UBRX_1MHZ_9600, - mctl: UMCTL_1MHZ_9600, + ctl1: UCSWRST|UCSSEL_1, /* clock uart from SMCLK */ + brx: UBRX_32768HZ_9600, + mctl: UMCTL_32768HZ_9600, irtctl: 0, irrctl: 0, - abctl: 0 - /* FIXME: pullup/pulldown configuration... */ + abctl: 0, + ren: USCI_REN_NONE } }; @@ -273,4 +304,10 @@ implementation { 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 ) {} } diff --git a/tos/chips/msp430/usci/Msp430Usci.h b/tos/chips/msp430/usci/Msp430Usci.h index 4d0a2cd7..880a92da 100644 --- a/tos/chips/msp430/usci/Msp430Usci.h +++ b/tos/chips/msp430/usci/Msp430Usci.h @@ -50,7 +50,6 @@ #define MSP430_USCIA1_RESOURCE "Msp430UsciA1.Resource" #define MSP430_USCIB1_RESOURCE "Msp430UsciB1.Resource" -/* Values of UCAxCTL0 only looking at the UCMODEx bits */ typedef enum { USCI_UART = 0, @@ -58,80 +57,18 @@ typedef enum USCI_I2C } msp430_usci_mode_t; -#if 0 -/* FIXME - * There are different meanings to these fields based upon the mode - * (uart/spi/etc) and the device (USCI_x0 or USCI_x1). - */ - -/* Packed bitfields are lsb first */ - -typedef struct { - unsigned int ucsync: 1; /* Synchronous mode enable. 0=async, 1=sync */ - unsigned int ucmodex: 2; /* USCI mode. 00=uart, 01=idle-line, 10=addr-bit, 11=autobaud */ - unsigned int ucspb: 1; /* Stop bit select. 0=one bit, 1=two bits */ - unsigned int uc7bit: 1; /* Character length. 0=8 bits, 1=7 bits */ - unsigned int ucmsb: 1; /* MSB first select. 0=LSB(it) first, 1=MSB(it) first */ - unsigned int ucpar: 1; /* Parity select. 0=odd parity, 1=even parity */ - unsigned int ucpen: 1; /* Parity enable. 0=parity disabled, 1=parity enabled */ -} __attribute__ ((packed)) msp430_usci_uart_ctl0_t ; - -typedef struct { - unsigned int ucswrst: 1; // Software resent enable. 0=disabled (operational), 1=enabled (reset) */ - unsigned int uctxbrk:1; // Next frame is a break or break/sync: 0=no, 1=yes */ - unsigned int uctxaddr:1; // Next transmit frame is an address. 0=no, 1=yes */ - unsigned int ucdorm: 1; // Dormant; USCI in sleep. 0=!dormant, 1=dormant */ - unsigned int ucbrkie: 1; // Receive break sets UCAxRXIFG interrupt. 0=no, 1=yes */ - unsigned int ucrxeie: 1; // Receive erroneous char sets UCAxRXIFG interrupt. 0=no, 1=yes */ - unsigned int uccsselx: 2; // USCI clock source (BRCLK). 00=UCLK, 01=ACLK, 10=SMCLK, 11=SMCLK */ -} __attribute__ ((packed)) msp430_usci_uart_ctl1_t; - -typedef struct { - unsigned int ucbusy:1; /* USCI busy; tx or rx in process. 0=no, 1=yes */ - unsigned int ucidleaddr:1; /* In idle-line mode: Idle line detected. 0=no, 1=yes */ - /* In addr-bit mode: Last char rx is addr. 0=no, 1=yes */ - unsigned int ucrxerr:1; /* Receive error flag. 0=none, 1=(ucfe|ucpe|ucoe) */ - unsigned int ucbrk:1; /* Break detection flag. 0=no, 1=yes */ - unsigned int ucpe:1; /* Parity error flag. 0=no or ucaxctl0.ucpen=0, 1=yes */ - unsigned int ucoe:1; /* Overrun error flag. 0=no, 1=yes */ - unsigned int ucfe:1; /* Framing error flag. 0=no, 1=yes */ - unsigned int uclisten:1; /* Listen enable (loopback). 0=disabled, 1=enabled */ -} __attribute__ ((packed)) msp430_usci_uart_stat_t; +typedef enum { + USCI_REN_NONE = 0, -typdef struct { - unsigned int uciren:1; /* IrDA decoder. 0=disabled, 1=enabled */ - unsigned int ucirtxclk:1; /* IrDA transmit pulse clock select. 0=BRCLK, 1=BRCLK16 if ucos16=1 else BRCLK */ - unsigned ucirtxplx:6; /* Pulse length. t(pulse) = (ucirtxplx + 1)/(2 * f(irtxclk)) */ -} __attribute__ ((packed)) msp430_usci_uart_irtctl_t; + USCI_REN_RX = 0x08, + USCI_REN_RX_PULLUP = USCI_REN_RX + 0x01, + USCI_REN_RX_PULLDOWN = USCI_REN_RX + 0x02, -typedef struct { - unsigned int ucirrxfe:1; /* IrDA recv filter. 0=disabled, 1=enabled */ - unsigned int ucirrxpl:1; /* IrDA recv input ucaxrxd polarity. 0=high w/light pulse, 1=low */ - unsigned int ucirrxflx:6; /* IrDA recv filter len. t(min) = (ucirrxflx + 4)/(2 * f(irtxclk)) */ -} __attribute__ ((packed)) msp430_usci_uart_irrctl_t; + USCI_REN_TX = 0x80, + USCI_REN_TX_PULLUP = USCI_REN_TX + 0x10, + USCI_REN_TX_PULLDOWN = USCI_REN_TX + 0x20 +} msp430_ren_t; -typdef struct { - unsigned int ucabden:1; /* Auto baud rate detect enable. 0=no, 1=yes (baud calc from break/sync) */ - unsigned int reserved:1; /* Reserved */ - unsigned int ucbtoe:1; /* Break time out error. 0=no, 1=yes: break len > 22 bit times */ - unsigned int ucstoe:1; /* Synch field timeout error. 0=no, 1=yes: sync len > measurable time */ - unsigned int ucdelimx:1; /* Break/synch delimiter length in bit times. 00=1, 01=2, 10=3, 11=4 */ - unsigned int reserved2:2; /* Reserved */ -} __attribute__ ((packed)) msp430_usci_uart_abctl_t; -#endif - -#if 0 /* We aren't using individual fields, but rather leveraging the defs - * provided by the compiler. Hence, bit fields aren't all that useful. - */ -typdef struct { - msp430_usci_uart_ctl0_t ctl0; - msp430_usci_uart_ctl0_t ctl1; - msp430_usci_uart_stat_t stat; - msp430_usci_uart_irtctl_t irtctl; - msp430_usci_uart_irrctl_t irrctl; - msp430_usci_uart_abctl_t abctl; -} __attribute__ ((packed)) msp430_usci_uart_t; -#else typedef struct { uint8_t ctl0; uint8_t ctl1; @@ -140,13 +77,13 @@ typedef struct { uint8_t irtctl; uint8_t irrctl; uint8_t abctl; - /* FIXME: add support for configuring internal pull-up or pull-down on RXD pin */ + msp430_ren_t ren; } __attribute__ ((packed)) msp430_usci_uart_t; -#endif -/* Baud rates for UART mode */ +/* Baud rates for UART mode. Only 32KHz modes work right now. */ typedef enum { /* UCOS16=0. UMCTL = UCBRFx << 4 + UCBRSx << 1 + UCOS16. */ + UBRX_32768HZ_9600=3, UMCTL_32768HZ_9600=(0 << 4) + (3 << 1) + 0, UBRX_1MHZ_9600=109, UMCTL_1MHZ_9600=(0 << 4) + (2 << 1) + 0, UBRX_1MHZ_115200=9, UMCTL_1MHZ_115200=(0 << 4) + (1 << 1) + 0, } msp430_usci_uart_rate_t; -- 2.39.2