1 /*!
2 * \file uart-board.c
3 *
4 * \brief Target board UART driver implementation
5 *
6 * \copyright Revised BSD License, see section \ref LICENSE.
7 *
8 * \code
9 * ______ _
10 * / _____) _ | |
11 * ( (____ _____ ____ _| |_ _____ ____| |__
12 * \____ \| ___ | (_ _) ___ |/ ___) _ \
13 * _____) ) ____| | | || |_| ____( (___| | | |
14 * (______/|_____)_|_|_| \__)_____)\____)_| |_|
15 * (C)2013-2017 Semtech
16 *
17 * \endcode
18 *
19 * \author Miguel Luis ( Semtech )
20 *
21 * \author Gregory Cristian ( Semtech )
22 */
23 #include "stm32l0xx.h"
24 #include "utilities.h"
25 #include "board.h"
26 #include "sysIrqHandlers.h"
27 #include "uart-board.h"
28
29 /*!
30 * Number of times the UartPutBuffer will try to send the buffer before
31 * returning ERROR
32 */
33 #define TX_BUFFER_RETRY_COUNT 10
34
35 static UART_HandleTypeDef UartHandle;
36 uint8_t RxData = 0;
37 uint8_t TxData = 0;
38
39 extern Uart_t Uart1;
40
UartMcuInit(Uart_t * obj,UartId_t uartId,PinNames tx,PinNames rx)41 void UartMcuInit( Uart_t *obj, UartId_t uartId, PinNames tx, PinNames rx )
42 {
43 obj->UartId = uartId;
44
45 if( uartId == UART_USB_CDC )
46 {
47 #if defined( USE_USB_CDC )
48 UartUsbInit( obj, uartId, NC, NC );
49 #endif
50 }
51 else
52 {
53 __HAL_RCC_USART1_FORCE_RESET( );
54 __HAL_RCC_USART1_RELEASE_RESET( );
55 __HAL_RCC_USART1_CLK_ENABLE( );
56
57 GpioInit( &obj->Tx, tx, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF4_USART1 );
58 GpioInit( &obj->Rx, rx, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF4_USART1 );
59 }
60 }
61
UartMcuConfig(Uart_t * obj,UartMode_t mode,uint32_t baudrate,WordLength_t wordLength,StopBits_t stopBits,Parity_t parity,FlowCtrl_t flowCtrl)62 void UartMcuConfig( Uart_t *obj, UartMode_t mode, uint32_t baudrate, WordLength_t wordLength, StopBits_t stopBits, Parity_t parity, FlowCtrl_t flowCtrl )
63 {
64 if( obj->UartId == UART_USB_CDC )
65 {
66 #if defined( USE_USB_CDC )
67 UartUsbConfig( obj, mode, baudrate, wordLength, stopBits, parity, flowCtrl );
68 #endif
69 }
70 else
71 {
72 UartHandle.Instance = USART1;
73 UartHandle.Init.BaudRate = baudrate;
74
75 if( mode == TX_ONLY )
76 {
77 if( obj->FifoTx.Data == NULL )
78 {
79 assert_param( LMN_STATUS_ERROR );
80 }
81 UartHandle.Init.Mode = UART_MODE_TX;
82 }
83 else if( mode == RX_ONLY )
84 {
85 if( obj->FifoRx.Data == NULL )
86 {
87 assert_param( LMN_STATUS_ERROR );
88 }
89 UartHandle.Init.Mode = UART_MODE_RX;
90 }
91 else if( mode == RX_TX )
92 {
93 if( ( obj->FifoTx.Data == NULL ) || ( obj->FifoRx.Data == NULL ) )
94 {
95 assert_param( LMN_STATUS_ERROR );
96 }
97 UartHandle.Init.Mode = UART_MODE_TX_RX;
98 }
99 else
100 {
101 assert_param( LMN_STATUS_ERROR );
102 }
103
104 if( wordLength == UART_8_BIT )
105 {
106 UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
107 }
108 else if( wordLength == UART_9_BIT )
109 {
110 UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
111 }
112
113 switch( stopBits )
114 {
115 case UART_2_STOP_BIT:
116 UartHandle.Init.StopBits = UART_STOPBITS_2;
117 break;
118 case UART_1_5_STOP_BIT:
119 UartHandle.Init.StopBits = UART_STOPBITS_1_5;
120 break;
121 case UART_1_STOP_BIT:
122 default:
123 UartHandle.Init.StopBits = UART_STOPBITS_1;
124 break;
125 }
126
127 if( parity == NO_PARITY )
128 {
129 UartHandle.Init.Parity = UART_PARITY_NONE;
130 }
131 else if( parity == EVEN_PARITY )
132 {
133 UartHandle.Init.Parity = UART_PARITY_EVEN;
134 }
135 else
136 {
137 UartHandle.Init.Parity = UART_PARITY_ODD;
138 }
139
140 if( flowCtrl == NO_FLOW_CTRL )
141 {
142 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
143 }
144 else if( flowCtrl == RTS_FLOW_CTRL )
145 {
146 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_RTS;
147 }
148 else if( flowCtrl == CTS_FLOW_CTRL )
149 {
150 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_CTS;
151 }
152 else if( flowCtrl == RTS_CTS_FLOW_CTRL )
153 {
154 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
155 }
156
157 UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
158
159 if( HAL_UART_Init( &UartHandle ) != HAL_OK )
160 {
161 assert_param( LMN_STATUS_ERROR );
162 }
163
164 HAL_NVIC_SetPriority( USART1_IRQn, 1, 0 );
165 HAL_NVIC_EnableIRQ( USART1_IRQn );
166
167 /* Enable the UART Data Register not empty Interrupt */
168 HAL_UART_Receive_IT( &UartHandle, &RxData, 1 );
169 }
170 }
171
UartMcuDeInit(Uart_t * obj)172 void UartMcuDeInit( Uart_t *obj )
173 {
174 if( obj->UartId == UART_USB_CDC )
175 {
176 #if defined( USE_USB_CDC )
177 UartUsbDeInit( obj );
178 #endif
179 }
180 else
181 {
182 __HAL_RCC_USART1_FORCE_RESET( );
183 __HAL_RCC_USART1_RELEASE_RESET( );
184 __HAL_RCC_USART1_CLK_DISABLE( );
185
186 GpioInit( &obj->Tx, obj->Tx.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
187 GpioInit( &obj->Rx, obj->Rx.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
188 }
189 }
190
UartMcuPutChar(Uart_t * obj,uint8_t data)191 uint8_t UartMcuPutChar( Uart_t *obj, uint8_t data )
192 {
193 if( obj->UartId == UART_USB_CDC )
194 {
195 #if defined( USE_USB_CDC )
196 return UartUsbPutChar( obj, data );
197 #else
198 return 255; // Not supported
199 #endif
200 }
201 else
202 {
203 CRITICAL_SECTION_BEGIN( );
204 TxData = data;
205
206 if( IsFifoFull( &obj->FifoTx ) == false )
207 {
208 FifoPush( &obj->FifoTx, TxData );
209
210 // Trig UART Tx interrupt to start sending the FIFO contents.
211 __HAL_UART_ENABLE_IT( &UartHandle, UART_IT_TC );
212
213 CRITICAL_SECTION_END( );
214 return 0; // OK
215 }
216 CRITICAL_SECTION_END( );
217 return 1; // Busy
218 }
219 }
220
UartMcuGetChar(Uart_t * obj,uint8_t * data)221 uint8_t UartMcuGetChar( Uart_t *obj, uint8_t *data )
222 {
223 if( obj->UartId == UART_USB_CDC )
224 {
225 #if defined( USE_USB_CDC )
226 return UartUsbGetChar( obj, data );
227 #else
228 return 255; // Not supported
229 #endif
230 }
231 else
232 {
233 CRITICAL_SECTION_BEGIN( );
234
235 if( IsFifoEmpty( &obj->FifoRx ) == false )
236 {
237 *data = FifoPop( &obj->FifoRx );
238 CRITICAL_SECTION_END( );
239 return 0;
240 }
241 CRITICAL_SECTION_END( );
242 return 1;
243 }
244 }
245
UartMcuPutBuffer(Uart_t * obj,uint8_t * buffer,uint16_t size)246 uint8_t UartMcuPutBuffer( Uart_t *obj, uint8_t *buffer, uint16_t size )
247 {
248 if( obj->UartId == UART_USB_CDC )
249 {
250 #if defined( USE_USB_CDC )
251 return UartUsbPutBuffer( obj, buffer, size );
252 #else
253 return 255; // Not supported
254 #endif
255 }
256 else
257 {
258 uint8_t retryCount;
259 uint16_t i;
260
261 for( i = 0; i < size; i++ )
262 {
263 retryCount = 0;
264 while( UartPutChar( obj, buffer[i] ) != 0 )
265 {
266 retryCount++;
267
268 // Exit if something goes terribly wrong
269 if( retryCount > TX_BUFFER_RETRY_COUNT )
270 {
271 return 1; // Error
272 }
273 }
274 }
275 return 0; // OK
276 }
277 }
278
UartMcuGetBuffer(Uart_t * obj,uint8_t * buffer,uint16_t size,uint16_t * nbReadBytes)279 uint8_t UartMcuGetBuffer( Uart_t *obj, uint8_t *buffer, uint16_t size, uint16_t *nbReadBytes )
280 {
281 uint16_t localSize = 0;
282
283 while( localSize < size )
284 {
285 if( UartGetChar( obj, buffer + localSize ) == 0 )
286 {
287 localSize++;
288 }
289 else
290 {
291 break;
292 }
293 }
294
295 *nbReadBytes = localSize;
296
297 if( localSize == 0 )
298 {
299 return 1; // Empty
300 }
301 return 0; // OK
302 }
303
HAL_UART_TxCpltCallback(UART_HandleTypeDef * handle)304 void HAL_UART_TxCpltCallback( UART_HandleTypeDef *handle )
305 {
306 if( IsFifoEmpty( &Uart1.FifoTx ) == false )
307 {
308 TxData = FifoPop( &Uart1.FifoTx );
309 // Write one byte to the transmit data register
310 HAL_UART_Transmit_IT( &UartHandle, &TxData, 1 );
311 }
312
313 if( Uart1.IrqNotify != NULL )
314 {
315 Uart1.IrqNotify( UART_NOTIFY_TX );
316 }
317 }
318
HAL_UART_RxCpltCallback(UART_HandleTypeDef * handle)319 void HAL_UART_RxCpltCallback( UART_HandleTypeDef *handle )
320 {
321 if( IsFifoFull( &Uart1.FifoRx ) == false )
322 {
323 // Read one byte from the receive data register
324 FifoPush( &Uart1.FifoRx, RxData );
325 }
326
327 if( Uart1.IrqNotify != NULL )
328 {
329 Uart1.IrqNotify( UART_NOTIFY_RX );
330 }
331
332 HAL_UART_Receive_IT( &UartHandle, &RxData, 1 );
333 }
334
HAL_UART_ErrorCallback(UART_HandleTypeDef * handle)335 void HAL_UART_ErrorCallback( UART_HandleTypeDef *handle )
336 {
337 HAL_UART_Receive_IT( &UartHandle, &RxData, 1 );
338 }
339
USART1_IRQHandler(void)340 void USART1_IRQHandler( void )
341 {
342 HAL_UART_IRQHandler( &UartHandle );
343 }
344