msb430-uart1.c

00001 /*
00002 Copyright 2007, Freie Universitaet Berlin. All rights reserved.
00003 
00004 These sources were developed at the Freie Universität Berlin, Computer
00005 Systems and Telematics group.
00006 
00007 Redistribution and use in source and binary forms, with or without
00008 modification, are permitted provided that the following conditions are
00009 met:
00010 
00011 - Redistributions of source code must retain the above copyright
00012 notice, this list of conditions and the following disclaimer.
00013 
00014 - Redistributions in binary form must reproduce the above copyright
00015 notice, this list of conditions and the following disclaimer in the
00016 documentation and/or other materials provided with the distribution.
00017  
00018 - Neither the name of Freie Universitaet Berlin (FUB) nor the names of its
00019 contributors may be used to endorse or promote products derived from
00020 this software without specific prior written permission.
00021 
00022 This software is provided by FUB and the contributors on an "as is"
00023 basis, without any representations or warranties of any kind, express
00024 or implied including, but not limited to, representations or
00025 warranties of non-infringement, merchantability or fitness for a
00026 particular purpose. In no event shall FUB or contributors be liable
00027 for any direct, indirect, incidental, special, exemplary, or
00028 consequential damages (including, but not limited to, procurement of
00029 substitute goods or services; loss of use, data, or profits; or
00030 business interruption) however caused and on any theory of liability,
00031 whether in contract, strict liability, or tort (including negligence
00032 or otherwise) arising in any way out of the use of this software, even
00033 if advised of the possibility of such damage.
00034 
00035 This implementation was developed by the CST group at the FUB.
00036 
00037 For documentation and questions please use the web site
00038 http://scatterweb.mi.fu-berlin.de and the mailinglist
00039 scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website).
00040 Berlin, 2007
00041 */
00042 
00043 /**
00044  * @file                ScatterWeb.Uart.c
00045  * @addtogroup  interfaces
00046  * @brief               UART interface
00047  * @author              Michael Baar    <baar@inf.fu-berlin.de>
00048  *
00049  * UART switch for RS232 and SPI protocols on UART1 written for
00050  * ScatterWeb MSB boards. Compatible to ScatterWeb EOS,
00051  * ScatterWeb Bootload and Contiki.
00052  */
00053 
00054 #include <io.h>
00055 #include <signal.h>
00056 #include <string.h>
00057 #include "dev/msb430-uart1.h"
00058 #include "msp430.h"
00059 #include "dev/lpm.h"
00060 
00061 #ifndef U1ME
00062 #define U1ME    ME2
00063 #endif
00064 
00065 volatile unsigned char uart_mode = UART_MODE_RESET;
00066 volatile unsigned char uart_lockcnt = 0;
00067 volatile uint8_t uart_edge = 0;
00068 
00069 static unsigned char uart_speed_br0[UART_NUM_MODES];
00070 static unsigned char uart_speed_br1[UART_NUM_MODES];
00071 static unsigned char uart_speed_bmn[UART_NUM_MODES];
00072 static uart_handler_t uart_handler[UART_NUM_MODES] = {NULL, NULL};
00073 
00074 /*---------------------------------------------------------------------------*/
00075 static void
00076 uart_configure(unsigned mode)
00077 {
00078   _DINT();              /* disable interrupts */
00079 
00080   UART_WAIT_TXDONE();   /* wait till all buffered data has been transmitted */
00081 
00082   if(mode == UART_MODE_RS232) {
00083     P5OUT |= 0x01;                                                      
00084     /* unselect SPI */
00085     P3SEL |= 0xC0;                                                      
00086     /* select rs232 */
00087     UCTL1 = SWRST | CHAR;               /* 8-bit character */
00088     UTCTL1 |= SSEL1;                    /* UCLK = MCLK */
00089     /* activate */
00090     U1ME |= UTXE1 | URXE1;              /* Enable USART1 TXD/RXD                 */
00091   } else if(mode == UART_MODE_SPI) {
00092     P3SEL &= ~0xC0;                     /* unselect RS232 */
00093     // to SPI mode
00094     UCTL1 = SWRST | CHAR | SYNC | MM;   /* 8-bit SPI Master */
00095     /*
00096      * SMCLK, 3-pin mode, clock idle low, data valid on
00097      * rising edge, UCLK delayed
00098      */
00099     UTCTL1 |= CKPH | SSEL1 | SSEL0 | STC;       /* activate */
00100     U1ME |= USPIE1;                             /* Enable USART1 SPI */
00101   }
00102 
00103   /* restore speed settings */
00104   UBR01  = uart_speed_br0[mode];        /* set baudrate */
00105   UBR11  = uart_speed_br1[mode];                        
00106   UMCTL1 = uart_speed_bmn[mode];        /* set modulation */
00107 
00108   UCTL1 &= ~SWRST;                      /* clear reset flag */
00109   _EINT();                              /* enable interrupts */
00110 }
00111 /*---------------------------------------------------------------------------*/
00112 void
00113 uart_set_speed(unsigned mode, unsigned ubr0,
00114                 unsigned ubr1, unsigned umctl)
00115 {
00116   /* store the setting */
00117   uart_speed_br0[mode] = ubr0;  /* baudrate */
00118   uart_speed_br1[mode] = ubr1;  /* baudrate */
00119   uart_speed_bmn[mode] = umctl; /* modulation */
00120 
00121   /* reconfigure, if mode active */
00122   if(uart_mode == mode) {
00123     uart_configure(mode);
00124   }
00125 }
00126 /*---------------------------------------------------------------------------*/
00127 void
00128 uart_set_handler(unsigned mode, uart_handler_t handler)
00129 {
00130   /* store the setting */
00131   uart_handler[mode] = handler;
00132   if(mode == uart_mode) {
00133     if(handler == NULL) {
00134       IE2 &= ~URXIE1;                   /* Disable USART1 RX interrupt */
00135     } else {
00136       IE2 |= URXIE1;                    /* Enable USART1 RX interrupt */
00137     }
00138   }
00139 }
00140 /*---------------------------------------------------------------------------*/
00141 int
00142 uart_lock(unsigned mode)
00143 {
00144   /* already locked? */
00145   if(uart_mode != mode && uart_lockcnt > 0) {
00146     return 0;
00147   }
00148 
00149   /* increase lock count */
00150   uart_lockcnt++;
00151   /* switch mode (if neccessary) */
00152   uart_set_mode(mode);
00153   return 1;
00154 }
00155 /*---------------------------------------------------------------------------*/
00156 int
00157 uart_lock_wait(unsigned mode)
00158 {
00159   while(UART_WAIT_LOCK(mode)) {
00160     _NOP();
00161   }
00162   return uart_lock(mode);
00163 }
00164 /*---------------------------------------------------------------------------*/
00165 int
00166 uart_unlock(unsigned mode)
00167 {
00168   if((uart_lockcnt == 0) || (mode != uart_mode)) {
00169     uart_lockcnt = 0;
00170     uart_set_mode(UART_MODE_DEFAULT);
00171     return 0;
00172   }
00173 
00174   /* decrement lock */
00175   if(uart_lockcnt > 0) {
00176     uart_lockcnt--;
00177     /* if no more locks, switch back to default mode */
00178     if(uart_lockcnt == 0) {
00179       uart_set_mode(UART_MODE_DEFAULT);
00180     }
00181     return 1;
00182   }
00183   return 0;
00184 }
00185 /*---------------------------------------------------------------------------*/
00186 void
00187 uart_set_mode(unsigned mode)
00188 {
00189   /* do nothing if the mode is already set */
00190   if(mode == uart_mode) {
00191     return;
00192   }
00193 
00194   IE2 &= ~(URXIE1 | UTXIE1);            /* disable irq */
00195   uart_configure(mode);                 /* configure uart parameters */
00196   uart_mode = mode;
00197         
00198   if(uart_handler[mode] != NULL) {
00199     IE2 |= URXIE1;                      /* Enable USART1 RX interrupt */
00200   }
00201 }
00202 /*---------------------------------------------------------------------------*/
00203 int
00204 uart_get_mode(void)
00205 {
00206   return uart_mode;
00207 }
00208 /*---------------------------------------------------------------------------*/
00209 interrupt(UART1RX_VECTOR)
00210 uart_rx(void)
00211 {
00212   uart_handler_t handler = uart_handler[uart_mode];
00213   int c;
00214         
00215   if(!(IFG2 & URXIFG1)) {
00216     /* If rising edge is detected, toggle & return */
00217     uart_edge = 1;
00218     U1TCTL &= ~URXSE;
00219     U1TCTL |= URXSE;
00220     _BIC_SR_IRQ(LPM3_bits);
00221     return;
00222   }
00223   uart_edge = 0;
00224   if(!(URCTL1 & RXERR)) {
00225     c = UART_RX;
00226     if(handler(c)) {
00227       _BIC_SR_IRQ(LPM3_bits);
00228     }
00229   } else {
00230     /* read out the char to clear the interrupt flags. */
00231     c = UART_RX;
00232   }
00233 }

Generated on Mon Apr 11 14:23:44 2011 for Contiki 2.5 by  doxygen 1.6.1