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 "stm32l1xx.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 typedef struct
36 {
37 UART_HandleTypeDef UartHandle;
38 uint8_t RxData;
39 uint8_t TxData;
40 }UartContext_t;
41
42 UartContext_t UartContext[2];
43
44 extern Uart_t Uart1;
45 extern Uart_t Uart2;
46
UartMcuInit(Uart_t * obj,UartId_t uartId,PinNames tx,PinNames rx)47 void UartMcuInit( Uart_t *obj, UartId_t uartId, PinNames tx, PinNames rx )
48 {
49 if( uartId == UART_USB_CDC )
50 {
51 #if defined( USE_USB_CDC )
52 UartUsbInit( obj, uartId, NC, NC );
53 #endif
54 }
55 else
56 {
57 obj->UartId = uartId;
58
59 if( obj->UartId == UART_1 )
60 {
61 __HAL_RCC_USART1_FORCE_RESET( );
62 __HAL_RCC_USART1_RELEASE_RESET( );
63 __HAL_RCC_USART1_CLK_ENABLE( );
64
65 GpioInit( &obj->Tx, tx, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF7_USART1 );
66 GpioInit( &obj->Rx, rx, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF7_USART1 );
67 }
68 else if( obj->UartId == UART_2 )
69 {
70 __HAL_RCC_USART2_FORCE_RESET( );
71 __HAL_RCC_USART2_RELEASE_RESET( );
72 __HAL_RCC_USART2_CLK_ENABLE( );
73
74 GpioInit( &obj->Tx, tx, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF7_USART2 );
75 GpioInit( &obj->Rx, rx, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF7_USART2 );
76 }
77 }
78 }
79
UartMcuConfig(Uart_t * obj,UartMode_t mode,uint32_t baudrate,WordLength_t wordLength,StopBits_t stopBits,Parity_t parity,FlowCtrl_t flowCtrl)80 void UartMcuConfig( Uart_t *obj, UartMode_t mode, uint32_t baudrate, WordLength_t wordLength, StopBits_t stopBits, Parity_t parity, FlowCtrl_t flowCtrl )
81 {
82 if( obj->UartId == UART_USB_CDC )
83 {
84 #if defined( USE_USB_CDC )
85 UartUsbConfig( obj, mode, baudrate, wordLength, stopBits, parity, flowCtrl );
86 #endif
87 }
88 else
89 {
90 if( obj->UartId == UART_1 )
91 {
92 UartContext[obj->UartId].UartHandle.Instance = USART1;
93 }
94 else if( obj->UartId == UART_2 )
95 {
96 UartContext[obj->UartId].UartHandle.Instance = USART2;
97 }
98 UartContext[obj->UartId].UartHandle.Init.BaudRate = baudrate;
99
100 if( mode == TX_ONLY )
101 {
102 if( obj->FifoTx.Data == NULL )
103 {
104 assert_param( LMN_STATUS_ERROR );
105 }
106 UartContext[obj->UartId].UartHandle.Init.Mode = UART_MODE_TX;
107 }
108 else if( mode == RX_ONLY )
109 {
110 if( obj->FifoRx.Data == NULL )
111 {
112 assert_param( LMN_STATUS_ERROR );
113 }
114 UartContext[obj->UartId].UartHandle.Init.Mode = UART_MODE_RX;
115 }
116 else if( mode == RX_TX )
117 {
118 if( ( obj->FifoTx.Data == NULL ) || ( obj->FifoRx.Data == NULL ) )
119 {
120 assert_param( LMN_STATUS_ERROR );
121 }
122 UartContext[obj->UartId].UartHandle.Init.Mode = UART_MODE_TX_RX;
123 }
124 else
125 {
126 assert_param( LMN_STATUS_ERROR );
127 }
128
129 if( wordLength == UART_8_BIT )
130 {
131 UartContext[obj->UartId].UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
132 }
133 else if( wordLength == UART_9_BIT )
134 {
135 UartContext[obj->UartId].UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
136 }
137
138 switch( stopBits )
139 {
140 case UART_2_STOP_BIT:
141 UartContext[obj->UartId].UartHandle.Init.StopBits = UART_STOPBITS_2;
142 break;
143 case UART_1_STOP_BIT:
144 default:
145 UartContext[obj->UartId].UartHandle.Init.StopBits = UART_STOPBITS_1;
146 break;
147 }
148
149 if( parity == NO_PARITY )
150 {
151 UartContext[obj->UartId].UartHandle.Init.Parity = UART_PARITY_NONE;
152 }
153 else if( parity == EVEN_PARITY )
154 {
155 UartContext[obj->UartId].UartHandle.Init.Parity = UART_PARITY_EVEN;
156 }
157 else
158 {
159 UartContext[obj->UartId].UartHandle.Init.Parity = UART_PARITY_ODD;
160 }
161
162 if( flowCtrl == NO_FLOW_CTRL )
163 {
164 UartContext[obj->UartId].UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
165 }
166 else if( flowCtrl == RTS_FLOW_CTRL )
167 {
168 UartContext[obj->UartId].UartHandle.Init.HwFlowCtl = UART_HWCONTROL_RTS;
169 }
170 else if( flowCtrl == CTS_FLOW_CTRL )
171 {
172 UartContext[obj->UartId].UartHandle.Init.HwFlowCtl = UART_HWCONTROL_CTS;
173 }
174 else if( flowCtrl == RTS_CTS_FLOW_CTRL )
175 {
176 UartContext[obj->UartId].UartHandle.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
177 }
178
179 UartContext[obj->UartId].UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
180
181 if( HAL_UART_Init( &UartContext[obj->UartId].UartHandle ) != HAL_OK )
182 {
183 assert_param( LMN_STATUS_ERROR );
184 }
185
186 if( obj->UartId == UART_1 )
187 {
188 HAL_NVIC_SetPriority( USART1_IRQn, 1, 0 );
189 HAL_NVIC_EnableIRQ( USART1_IRQn );
190 }
191 else if( obj->UartId == UART_2 )
192 {
193 HAL_NVIC_SetPriority( USART2_IRQn, 1, 0 );
194 HAL_NVIC_EnableIRQ( USART2_IRQn );
195 }
196
197 /* Enable the UART Data Register not empty Interrupt */
198 HAL_UART_Receive_IT( &UartContext[obj->UartId].UartHandle, &UartContext[obj->UartId].RxData, 1 );
199 }
200 }
201
UartMcuDeInit(Uart_t * obj)202 void UartMcuDeInit( Uart_t *obj )
203 {
204 if( obj->UartId == UART_USB_CDC )
205 {
206 #if defined( USE_USB_CDC )
207 UartUsbDeInit( obj );
208 #endif
209 }
210 else
211 {
212 if( obj->UartId == UART_1 )
213 {
214 __HAL_RCC_USART1_FORCE_RESET( );
215 __HAL_RCC_USART1_RELEASE_RESET( );
216 __HAL_RCC_USART1_CLK_DISABLE( );
217 }
218 else if( obj->UartId == UART_2 )
219 {
220 __HAL_RCC_USART2_FORCE_RESET( );
221 __HAL_RCC_USART2_RELEASE_RESET( );
222 __HAL_RCC_USART2_CLK_DISABLE( );
223 }
224
225 GpioInit( &obj->Tx, obj->Tx.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
226 GpioInit( &obj->Rx, obj->Rx.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
227 }
228 }
229
UartMcuPutChar(Uart_t * obj,uint8_t data)230 uint8_t UartMcuPutChar( Uart_t *obj, uint8_t data )
231 {
232 if( obj->UartId == UART_USB_CDC )
233 {
234 #if defined( USE_USB_CDC )
235 return UartUsbPutChar( obj, data );
236 #else
237 return 255; // Not supported
238 #endif
239 }
240 else
241 {
242 CRITICAL_SECTION_BEGIN( );
243 UartContext[obj->UartId].TxData = data;
244
245 if( IsFifoFull( &obj->FifoTx ) == false )
246 {
247 FifoPush( &obj->FifoTx, UartContext[obj->UartId].TxData );
248
249 // Trig UART Tx interrupt to start sending the FIFO contents.
250 __HAL_UART_ENABLE_IT( &UartContext[obj->UartId].UartHandle, UART_IT_TC );
251
252 CRITICAL_SECTION_END( );
253 return 0; // OK
254 }
255 CRITICAL_SECTION_END( );
256 return 1; // Busy
257 }
258 }
259
UartMcuGetChar(Uart_t * obj,uint8_t * data)260 uint8_t UartMcuGetChar( Uart_t *obj, uint8_t *data )
261 {
262 if( obj->UartId == UART_USB_CDC )
263 {
264 #if defined( USE_USB_CDC )
265 return UartUsbGetChar( obj, data );
266 #else
267 return 255; // Not supported
268 #endif
269 }
270 else
271 {
272 CRITICAL_SECTION_BEGIN( );
273
274 if( IsFifoEmpty( &obj->FifoRx ) == false )
275 {
276 *data = FifoPop( &obj->FifoRx );
277 CRITICAL_SECTION_END( );
278 return 0;
279 }
280 CRITICAL_SECTION_END( );
281 return 1;
282 }
283 }
284
UartMcuPutBuffer(Uart_t * obj,uint8_t * buffer,uint16_t size)285 uint8_t UartMcuPutBuffer( Uart_t *obj, uint8_t *buffer, uint16_t size )
286 {
287 if( obj->UartId == UART_USB_CDC )
288 {
289 #if defined( USE_USB_CDC )
290 return UartUsbPutBuffer( obj, buffer, size );
291 #else
292 return 255; // Not supported
293 #endif
294 }
295 else
296 {
297 uint8_t retryCount;
298 uint16_t i;
299
300 for( i = 0; i < size; i++ )
301 {
302 retryCount = 0;
303 while( UartPutChar( obj, buffer[i] ) != 0 )
304 {
305 retryCount++;
306
307 // Exit if something goes terribly wrong
308 if( retryCount > TX_BUFFER_RETRY_COUNT )
309 {
310 return 1; // Error
311 }
312 }
313 }
314 return 0; // OK
315 }
316 }
317
UartMcuGetBuffer(Uart_t * obj,uint8_t * buffer,uint16_t size,uint16_t * nbReadBytes)318 uint8_t UartMcuGetBuffer( Uart_t *obj, uint8_t *buffer, uint16_t size, uint16_t *nbReadBytes )
319 {
320 uint16_t localSize = 0;
321
322 while( localSize < size )
323 {
324 if( UartGetChar( obj, buffer + localSize ) == 0 )
325 {
326 localSize++;
327 }
328 else
329 {
330 break;
331 }
332 }
333
334 *nbReadBytes = localSize;
335
336 if( localSize == 0 )
337 {
338 return 1; // Empty
339 }
340 return 0; // OK
341 }
342
HAL_UART_TxCpltCallback(UART_HandleTypeDef * handle)343 void HAL_UART_TxCpltCallback( UART_HandleTypeDef *handle )
344 {
345 Uart_t *uart = &Uart1;
346 UartId_t uartId = UART_1;
347
348 if( handle == &UartContext[UART_1].UartHandle )
349 {
350 uart = &Uart1;
351 uartId = UART_1;
352 }
353 else if( handle == &UartContext[UART_2].UartHandle )
354 {
355 uart = &Uart2;
356 uartId = UART_2;
357 }
358 else
359 {
360 // Unknown UART peripheral skip processing
361 return;
362 }
363 if( IsFifoEmpty( &uart->FifoTx ) == false )
364 {
365 UartContext[uartId].TxData = FifoPop( &uart->FifoTx );
366 // Write one byte to the transmit data register
367 HAL_UART_Transmit_IT( &UartContext[uartId].UartHandle, &UartContext[uartId].TxData, 1 );
368 }
369
370 if( uart->IrqNotify != NULL )
371 {
372 uart->IrqNotify( UART_NOTIFY_TX );
373 }
374 }
375
HAL_UART_RxCpltCallback(UART_HandleTypeDef * handle)376 void HAL_UART_RxCpltCallback( UART_HandleTypeDef *handle )
377 {
378 Uart_t *uart = &Uart1;
379 UartId_t uartId = UART_1;
380
381 if( handle == &UartContext[UART_1].UartHandle )
382 {
383 uart = &Uart1;
384 uartId = UART_1;
385 }
386 else if( handle == &UartContext[UART_2].UartHandle )
387 {
388 uart = &Uart2;
389 uartId = UART_2;
390 }
391 else
392 {
393 // Unknown UART peripheral skip processing
394 return;
395 }
396 if( IsFifoFull( &uart->FifoRx ) == false )
397 {
398 // Read one byte from the receive data register
399 FifoPush( &uart->FifoRx, UartContext[uartId].RxData );
400 }
401
402 if( uart->IrqNotify != NULL )
403 {
404 uart->IrqNotify( UART_NOTIFY_RX );
405 }
406
407 HAL_UART_Receive_IT( &UartContext[uartId].UartHandle, &UartContext[uartId].RxData, 1 );
408 }
409
HAL_UART_ErrorCallback(UART_HandleTypeDef * handle)410 void HAL_UART_ErrorCallback( UART_HandleTypeDef *handle )
411 {
412 UartId_t uartId = UART_1;
413
414 if( handle == &UartContext[UART_1].UartHandle )
415 {
416 uartId = UART_1;
417 }
418 else if( handle == &UartContext[UART_2].UartHandle )
419 {
420 uartId = UART_2;
421 }
422 else
423 {
424 // Unknown UART peripheral skip processing
425 return;
426 }
427 HAL_UART_Receive_IT( &UartContext[uartId].UartHandle, &UartContext[uartId].RxData, 1 );
428 }
429
USART1_IRQHandler(void)430 void USART1_IRQHandler( void )
431 {
432 // [BEGIN] Workaround to solve an issue with the HAL drivers not managing the uart state correctly.
433 uint32_t tmpFlag = 0, tmpItSource = 0;
434
435 tmpFlag = __HAL_UART_GET_FLAG( &UartContext[UART_1].UartHandle, UART_FLAG_TC );
436 tmpItSource = __HAL_UART_GET_IT_SOURCE( &UartContext[UART_1].UartHandle, UART_IT_TC );
437 // UART in mode Transmitter end
438 if( ( tmpFlag != RESET ) && ( tmpItSource != RESET ) )
439 {
440 if( ( UartContext[UART_1].UartHandle.State == HAL_UART_STATE_BUSY_RX ) || UartContext[UART_1].UartHandle.State == HAL_UART_STATE_BUSY_TX_RX )
441 {
442 UartContext[UART_1].UartHandle.State = HAL_UART_STATE_BUSY_TX_RX;
443 }
444 }
445 // [END] Workaround to solve an issue with the HAL drivers not managing the uart state correctly.
446
447 HAL_UART_IRQHandler( &UartContext[UART_1].UartHandle );
448 }
449
USART2_IRQHandler(void)450 void USART2_IRQHandler( void )
451 {
452 // [BEGIN] Workaround to solve an issue with the HAL drivers not managing the uart state correctly.
453 uint32_t tmpFlag = 0, tmpItSource = 0;
454
455 tmpFlag = __HAL_UART_GET_FLAG( &UartContext[UART_2].UartHandle, UART_FLAG_TC );
456 tmpItSource = __HAL_UART_GET_IT_SOURCE( &UartContext[UART_2].UartHandle, UART_IT_TC );
457 // UART in mode Transmitter end
458 if( ( tmpFlag != RESET ) && ( tmpItSource != RESET ) )
459 {
460 if( ( UartContext[UART_2].UartHandle.State == HAL_UART_STATE_BUSY_RX ) || UartContext[UART_2].UartHandle.State == HAL_UART_STATE_BUSY_TX_RX )
461 {
462 UartContext[UART_2].UartHandle.State = HAL_UART_STATE_BUSY_TX_RX;
463 }
464 }
465 // [END] Workaround to solve an issue with the HAL drivers not managing the uart state correctly.
466
467 HAL_UART_IRQHandler( &UartContext[UART_2].UartHandle );
468 }
469