Contiki 2.5
uart1.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, STMicroelectronics.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided
13  * with the distribution.
14  * 3. The name of the author may not be used to endorse or promote
15  * products derived from this software without specific prior
16  * written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This file is part of the Contiki OS
31  *
32  */
33 /*---------------------------------------------------------------------------*/
34 /**
35 * \file
36 * Machine dependent STM32W UART1 code.
37 * \author
38 * Salvatore Pitrulli
39 * \version
40 * 0.1
41 * \since
42 * 03.04.2010
43 */
44 /*---------------------------------------------------------------------------*/
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 //#include <io.h>
49 //#include <signal.h>
50 
51 #include "sys/energest.h"
52 #include "dev/uart1.h"
53 #include "dev/watchdog.h"
54 
55 #include "lib/ringbuf.h"
56 
57 #include "dev/leds.h"
58 
59 static int (*uart1_input_handler)(unsigned char c);
60 
61 static volatile uint8_t transmitting;
62 
63 #ifdef UART1_CONF_TX_WITH_INTERRUPT
64 #define TX_WITH_INTERRUPT UART1_CONF_TX_WITH_INTERRUPT
65 #else /* UART1_CONF_TX_WITH_INTERRUPT */
66 #define TX_WITH_INTERRUPT 1
67 #endif /* UART1_CONF_TX_WITH_INTERRUPT */
68 
69 
70 #if TX_WITH_INTERRUPT
71 
72 #ifdef UART1_CONF_TX_BUFSIZE
73 #define UART1_TX_BUFSIZE UART1_CONF_TX_BUFSIZE
74 #else /* UART1_CONF_TX_BUFSIZE */
75 #define UART1_TX_BUFSIZE 64
76 #endif /* UART1_CONF_TX_BUFSIZE */
77 
78 static struct ringbuf txbuf;
79 static uint8_t txbuf_data[UART1_TX_BUFSIZE];
80 #endif /* TX_WITH_INTERRUPT */
81 
82 /*---------------------------------------------------------------------------*/
83 //uint8_t
84 //uart1_active(void)
85 //{
86 // return ((~ UTCTL1) & TXEPT) | transmitting;
87 //}
88 /*---------------------------------------------------------------------------*/
89 void
90 uart1_set_input(int (*input)(unsigned char c))
91 {
92  uart1_input_handler = input;
93 }
94 /*---------------------------------------------------------------------------*/
95 void
96 uart1_writeb(unsigned char c)
97 {
98  watchdog_periodic();
99 #if TX_WITH_INTERRUPT
100 
101  /* Put the outgoing byte on the transmission buffer. If the buffer
102  is full, we just keep on trying to put the byte into the buffer
103  until it is possible to put it there. */
104  while(ringbuf_put(&txbuf, c) == 0);
105 
106  /* If there is no transmission going, we need to start it by putting
107  the first byte into the UART. */
108  if(transmitting == 0) {
109  transmitting = 1;
110  SC1_DATA = ringbuf_get(&txbuf);
111  INT_SC1FLAG = INT_SCTXFREE;
112  INT_SC1CFG |= INT_SCTXFREE;
113  }
114 
115 #else /* TX_WITH_INTERRUPT */
116 
117  /* Loop until the transmission buffer is available. */
118  while((INT_SC1FLAG & INT_SCTXFREE) == 0);
119 
120  /* Transmit the data. */
121  SC1_DATA = c;
122 
123  INT_SC1FLAG = INT_SCTXFREE;
124 #endif /* TX_WITH_INTERRUPT */
125 }
126 /*---------------------------------------------------------------------------*/
127 #if ! WITH_UIP /* If WITH_UIP is defined, putchar() is defined by the SLIP driver */
128 #endif /* ! WITH_UIP */
129 /*---------------------------------------------------------------------------*/
130 /**
131  * Initalize the RS232 port.
132  *
133  */
134 void
135 uart1_init(unsigned long ubr)
136 {
137 
138  GPIO_PBCFGL &= 0xF00F;
139  GPIO_PBCFGL |= 0x0490;
140 
141  u16_t uartper = (u32_t)24e6/(2*ubr);
142  u32_t rest = (u32_t)24e6%(2*ubr);
143 
144  SC1_UARTFRAC = 0;
145 
146  if(rest > (2*ubr)/4 && rest < (3*2*ubr)/4){
147  SC1_UARTFRAC = 1; // + 0.5
148  }
149  else if(rest >= (3*2*ubr)/4){
150  uartper++; // + 1
151  }
152 
153  SC1_UARTPER = uartper;
154 
155  SC1_UARTCFG = SC_UART8BIT;
156 
157  SC1_MODE = SC1_MODE_UART;
158 
159  SC1_INTMODE = SC_RXVALLEVEL | SC_TXFREELEVEL; // Receive buffer has data interrupt mode and Transmit buffer free interrupt mode: Level triggered.
160 
161  INT_SC1CFG = INT_SCRXVAL; // Receive buffer has data interrupt enable
162 
163  transmitting = 0;
164 
165 #if TX_WITH_INTERRUPT
166  ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data));
167 #endif /* TX_WITH_INTERRUPT */
168 
169 
170  INT_SC1FLAG = 0xFFFF;
171 
172  INT_CFGSET = INT_SC1;
173 }
174 /*---------------------------------------------------------------------------*/
175 void uart1_rx_interrupt(void);
176 void uart1_tx_interrupt(void);
177 
178 void halSc1Isr(void)
179 {
180 
181  ENERGEST_ON(ENERGEST_TYPE_IRQ);
182 
183  if(INT_SC1FLAG & INT_SCRXVAL){
184  uart1_rx_interrupt();
185  INT_SC1FLAG = INT_SCRXVAL;
186  }
187  #if TX_WITH_INTERRUPT
188  else if(INT_SC1FLAG & INT_SCTXFREE){
189  uart1_tx_interrupt();
190  INT_SC1FLAG = INT_SCTXFREE;
191  }
192  #endif /* TX_WITH_INTERRUPT */
193 
194 
195 
196  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
197 
198 }
199 
200 void uart1_rx_interrupt(void)
201 {
202  uint8_t c;
203 
204  c = SC1_DATA;
205 
206  if(uart1_input_handler != NULL) {
207  uart1_input_handler(c);
208  }
209 
210 }
211 /*---------------------------------------------------------------------------*/
212 #if TX_WITH_INTERRUPT
213 void uart1_tx_interrupt(void)
214 {
215 
216  if(ringbuf_elements(&txbuf) == 0) {
217  transmitting = 0;
218  INT_SC1CFG &= ~INT_SCTXFREE;
219  } else {
220  SC1_DATA = ringbuf_get(&txbuf);
221  }
222 
223 }
224 #endif /* TX_WITH_INTERRUPT */
225 /*---------------------------------------------------------------------------*/