retargetserial.c

Go to the documentation of this file.
00001 /***************************************************************************/
00035 #include <stdio.h>
00036 #include "em_device.h"
00037 #include "em_cmu.h"
00038 #include "em_int.h"
00039 #include "em_gpio.h"
00040 #include "retargetserial.h"
00041 
00042 /***************************************************************************/
00047 #if defined(RETARGET_USART)
00048 #include "em_usart.h"
00049 #endif
00050 
00051 #if defined(RETARGET_LEUART)
00052 #include "em_leuart.h"
00053 #endif
00054 
00055 /* Receive buffer */
00056 #define RXBUFSIZE    8                          
00057 static volatile int     rxReadIndex  = 0;       
00058 static volatile int     rxWriteIndex = 0;       
00059 static volatile int     rxCount      = 0;       
00060 static volatile uint8_t rxBuffer[RXBUFSIZE];    
00061 static uint8_t          LFtoCRLF    = 0;        
00062 static bool             initialized = false;    
00064 /**************************************************************************/
00067 void RETARGET_IRQ_NAME(void)
00068 {
00069 #if defined(RETARGET_USART)
00070   if (RETARGET_UART->STATUS & USART_STATUS_RXDATAV)
00071   {
00072 #else
00073   if (RETARGET_UART->IF & LEUART_IF_RXDATAV)
00074   {
00075 #endif
00076 
00077     /* Store Data */
00078     rxBuffer[rxWriteIndex] = RETARGET_RX(RETARGET_UART);
00079     rxWriteIndex++;
00080     rxCount++;
00081     if (rxWriteIndex == RXBUFSIZE)
00082     {
00083       rxWriteIndex = 0;
00084     }
00085     /* Check for overflow - flush buffer */
00086     if (rxCount > RXBUFSIZE)
00087     {
00088       rxWriteIndex = 0;
00089       rxCount      = 0;
00090       rxReadIndex  = 0;
00091     }
00092   }
00093 }
00094 
00097 /**************************************************************************/
00101 void RETARGET_SerialCrLf(int on)
00102 {
00103   if (on)
00104     LFtoCRLF = 1;
00105   else
00106     LFtoCRLF = 0;
00107 }
00108 
00109 
00110 /**************************************************************************/
00113 void RETARGET_SerialInit(void)
00114 {
00115   /* Configure GPIO pins */
00116   CMU_ClockEnable(cmuClock_GPIO, true);
00117   /* To avoid false start, configure output as high */
00118   GPIO_PinModeSet(RETARGET_TXPORT, RETARGET_TXPIN, gpioModePushPull, 1);
00119   GPIO_PinModeSet(RETARGET_RXPORT, RETARGET_RXPIN, gpioModeInput, 0);
00120 
00121 #if defined(RETARGET_USART)
00122   USART_TypeDef           *usart = RETARGET_UART;
00123   USART_InitAsync_TypeDef init   = USART_INITASYNC_DEFAULT;
00124 
00125   /* Enable DK RS232/UART switch */
00126   RETARGET_PERIPHERAL_ENABLE();
00127 
00128   /* Enable peripheral clocks */
00129   CMU_ClockEnable(cmuClock_HFPER, true);
00130   CMU_ClockEnable(RETARGET_CLK, true);
00131 
00132   /* Configure USART for basic async operation */
00133   init.enable = usartDisable;
00134   USART_InitAsync(usart, &init);
00135 
00136   /* Enable pins at UART1 location #2 */
00137   usart->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | RETARGET_LOCATION;
00138 
00139   /* Clear previous RX interrupts */
00140   USART_IntClear(RETARGET_UART, USART_IF_RXDATAV);
00141   NVIC_ClearPendingIRQ(RETARGET_IRQn);
00142 
00143   /* Enable RX interrupts */
00144   USART_IntEnable(RETARGET_UART, USART_IF_RXDATAV);
00145   NVIC_EnableIRQ(RETARGET_IRQn);
00146 
00147   /* Finally enable it */
00148   USART_Enable(usart, usartEnable);
00149 
00150 #else
00151   LEUART_TypeDef      *leuart = RETARGET_UART;
00152   LEUART_Init_TypeDef init    = LEUART_INIT_DEFAULT;
00153 
00154   /* Enable DK LEUART/RS232 switch */
00155   RETARGET_PERIPHERAL_ENABLE();
00156 
00157   /* Enable CORE LE clock in order to access LE modules */
00158   CMU_ClockEnable(cmuClock_CORELE, true);
00159 
00160   /* Select LFXO for LEUARTs (and wait for it to stabilize) */
00161   CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
00162 
00163   CMU_ClockEnable(RETARGET_CLK, true);
00164 
00165   /* Do not prescale clock */
00166   CMU_ClockDivSet(RETARGET_CLK, cmuClkDiv_1);
00167 
00168   /* Configure LEUART */
00169   init.enable = leuartDisable;
00170   LEUART_Init(leuart, &init);
00171   /* Enable pins at default location */
00172   leuart->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | RETARGET_LOCATION;
00173 
00174   /* Clear previous RX interrupts */
00175   LEUART_IntClear(RETARGET_UART, LEUART_IF_RXDATAV);
00176   NVIC_ClearPendingIRQ(RETARGET_IRQn);
00177 
00178   /* Enable RX interrupts */
00179   LEUART_IntEnable(RETARGET_UART, LEUART_IF_RXDATAV);
00180   NVIC_EnableIRQ(RETARGET_IRQn);
00181 
00182   /* Finally enable it */
00183   LEUART_Enable(leuart, leuartEnable);
00184 #endif
00185 
00186 #if !defined(__CROSSWORKS_ARM) && defined(__GNUC__)
00187   setvbuf(stdout, NULL, _IONBF, 0);   /*Set unbuffered mode for stdout (newlib)*/
00188 #endif
00189 
00190   initialized = true;
00191 }
00192 
00193 
00194 /**************************************************************************/
00198 int RETARGET_ReadChar(void)
00199 {
00200   int c = -1;
00201 
00202   if (initialized == false)
00203   {
00204     RETARGET_SerialInit();
00205   }
00206 
00207   INT_Disable();
00208   if (rxCount > 0)
00209   {
00210     c = rxBuffer[rxReadIndex];
00211     rxReadIndex++;
00212     if (rxReadIndex == RXBUFSIZE)
00213     {
00214       rxReadIndex = 0;
00215     }
00216     rxCount--;
00217   }
00218   INT_Enable();
00219 
00220   return c;
00221 }
00222 
00223 /**************************************************************************/
00228 int RETARGET_WriteChar(char c)
00229 {
00230   if (initialized == false)
00231   {
00232     RETARGET_SerialInit();
00233   }
00234 
00235   /* Add CR or LF to CRLF if enabled */
00236   if (LFtoCRLF && (c == '\n'))
00237   {
00238     RETARGET_TX(RETARGET_UART, '\r');
00239   }
00240   RETARGET_TX(RETARGET_UART, c);
00241 
00242   if (LFtoCRLF && (c == '\r'))
00243   {
00244     RETARGET_TX(RETARGET_UART, '\n');
00245   }
00246 
00247   return c;
00248 }