Contiki 2.6
|
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 /*---------------------------------------------------------------------------*/