Contiki 2.6

uart1.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, STMicroelectronics.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above
00011  *    copyright notice, this list of conditions and the following
00012  *    disclaimer in the documentation and/or other materials provided
00013  *    with the distribution.
00014  * 3. The name of the author may not be used to endorse or promote
00015  *    products derived from this software without specific prior
00016  *    written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00019  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00022  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00024  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * This file is part of the Contiki OS
00031  *
00032  */
00033 /*---------------------------------------------------------------------------*/
00034 /**
00035 * \file
00036 *                                       Machine dependent STM32W UART1 code.
00037 * \author
00038 *                                       Salvatore Pitrulli
00039 * \version
00040 *                                       0.1
00041 * \since
00042 *                                       03.04.2010
00043 */
00044 /*---------------------------------------------------------------------------*/
00045 
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 //#include <io.h>
00049 //#include <signal.h>
00050 
00051 #include "sys/energest.h"
00052 #include "dev/uart1.h"
00053 #include "dev/watchdog.h"
00054 
00055 #include "lib/ringbuf.h"
00056 
00057 #include "dev/leds.h"
00058 
00059 static int (*uart1_input_handler)(unsigned char c);
00060 
00061 static volatile uint8_t transmitting;
00062 
00063 #ifdef UART1_CONF_TX_WITH_INTERRUPT
00064 #define TX_WITH_INTERRUPT UART1_CONF_TX_WITH_INTERRUPT
00065 #else /* UART1_CONF_TX_WITH_INTERRUPT */
00066 #define TX_WITH_INTERRUPT 1
00067 #endif /* UART1_CONF_TX_WITH_INTERRUPT */
00068 
00069 
00070 #if TX_WITH_INTERRUPT
00071 
00072 #ifdef UART1_CONF_TX_BUFSIZE
00073 #define UART1_TX_BUFSIZE UART1_CONF_TX_BUFSIZE
00074 #else /* UART1_CONF_TX_BUFSIZE */
00075 #define UART1_TX_BUFSIZE 64
00076 #endif /* UART1_CONF_TX_BUFSIZE */
00077 
00078 static struct ringbuf txbuf;
00079 static uint8_t txbuf_data[UART1_TX_BUFSIZE];
00080 #endif /* TX_WITH_INTERRUPT */
00081 
00082 /*---------------------------------------------------------------------------*/
00083 //uint8_t
00084 //uart1_active(void)
00085 //{
00086 //  return ((~ UTCTL1) & TXEPT) | transmitting;
00087 //}
00088 /*---------------------------------------------------------------------------*/
00089 void
00090 uart1_set_input(int (*input)(unsigned char c))
00091 {
00092   uart1_input_handler = input;
00093 }
00094 /*---------------------------------------------------------------------------*/
00095 void
00096 uart1_writeb(unsigned char c)
00097 {
00098   watchdog_periodic();
00099 #if TX_WITH_INTERRUPT
00100 
00101   /* Put the outgoing byte on the transmission buffer. If the buffer
00102      is full, we just keep on trying to put the byte into the buffer
00103      until it is possible to put it there. */
00104   while(ringbuf_put(&txbuf, c) == 0);
00105 
00106   /* If there is no transmission going, we need to start it by putting
00107      the first byte into the UART. */
00108   if(transmitting == 0) {
00109     transmitting = 1; 
00110     SC1_DATA = ringbuf_get(&txbuf);
00111     INT_SC1FLAG = INT_SCTXFREE;
00112     INT_SC1CFG |= INT_SCTXFREE;
00113   }
00114 
00115 #else /* TX_WITH_INTERRUPT */
00116 
00117   /* Loop until the transmission buffer is available. */
00118   while((INT_SC1FLAG & INT_SCTXFREE) == 0);
00119 
00120   /* Transmit the data. */
00121   SC1_DATA = c;
00122   
00123   INT_SC1FLAG = INT_SCTXFREE;
00124 #endif /* TX_WITH_INTERRUPT */
00125 }
00126 /*---------------------------------------------------------------------------*/
00127 #if ! WITH_UIP /* If WITH_UIP is defined, putchar() is defined by the SLIP driver */
00128 #endif /* ! WITH_UIP */
00129 /*---------------------------------------------------------------------------*/
00130 /**
00131  * Initalize the RS232 port.
00132  *
00133  */
00134 void
00135 uart1_init(unsigned long ubr)
00136 {
00137   
00138   GPIO_PBCFGL &= 0xF00F;
00139   GPIO_PBCFGL |= 0x0490;  
00140   
00141   uint16_t uartper = (uint32_t)24e6/(2*ubr);
00142   uint32_t rest = (uint32_t)24e6%(2*ubr);
00143   
00144   SC1_UARTFRAC = 0;
00145   
00146   if(rest > (2*ubr)/4 && rest < (3*2*ubr)/4){
00147     SC1_UARTFRAC = 1;           // + 0.5
00148   }
00149   else if(rest >= (3*2*ubr)/4){
00150     uartper++;                  // + 1
00151   }
00152   
00153   SC1_UARTPER = uartper;
00154   
00155   SC1_UARTCFG = SC_UART8BIT;
00156   
00157   SC1_MODE = SC1_MODE_UART;
00158   
00159   SC1_INTMODE = SC_RXVALLEVEL | SC_TXFREELEVEL; // Receive buffer has data interrupt mode and Transmit buffer free interrupt mode: Level triggered.
00160   
00161   INT_SC1CFG = INT_SCRXVAL; // Receive buffer has data interrupt enable
00162 
00163   transmitting = 0;
00164   
00165 #if TX_WITH_INTERRUPT
00166   ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data));  
00167 #endif /* TX_WITH_INTERRUPT */ 
00168     
00169   
00170   INT_SC1FLAG = 0xFFFF;
00171   
00172   INT_CFGSET = INT_SC1;
00173 }
00174 /*---------------------------------------------------------------------------*/
00175 void uart1_rx_interrupt(void);
00176 void uart1_tx_interrupt(void);
00177 
00178 void halSc1Isr(void)
00179 {
00180   
00181   ENERGEST_ON(ENERGEST_TYPE_IRQ);
00182   
00183   if(INT_SC1FLAG & INT_SCRXVAL){
00184     uart1_rx_interrupt();
00185     INT_SC1FLAG = INT_SCRXVAL;    
00186   }
00187   #if TX_WITH_INTERRUPT
00188   else if(INT_SC1FLAG & INT_SCTXFREE){
00189     uart1_tx_interrupt();
00190     INT_SC1FLAG = INT_SCTXFREE;
00191   }  
00192   #endif /* TX_WITH_INTERRUPT */
00193   
00194 
00195   
00196   ENERGEST_OFF(ENERGEST_TYPE_IRQ);
00197 
00198 }
00199 
00200 void uart1_rx_interrupt(void)
00201 {
00202   uint8_t c;  
00203   
00204   c = SC1_DATA;
00205   
00206   if(uart1_input_handler != NULL) {
00207     uart1_input_handler(c);
00208   }  
00209 
00210 }
00211 /*---------------------------------------------------------------------------*/
00212 #if TX_WITH_INTERRUPT
00213 void uart1_tx_interrupt(void)
00214 {
00215 
00216   if(ringbuf_elements(&txbuf) == 0) {
00217     transmitting = 0;
00218     INT_SC1CFG &= ~INT_SCTXFREE;
00219   } else {
00220     SC1_DATA = ringbuf_get(&txbuf);
00221   }
00222   
00223 }
00224 #endif /* TX_WITH_INTERRUPT */
00225 /*---------------------------------------------------------------------------*/