1 /*
2 ******************************************************************************
3 * @file HAL_LPUART.c
4 * @version V1.0.0
5 * @date 2020
6 * @brief LPUART HAL module driver.
7 * This file provides firmware functions to manage the following
8 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (LPUART).
9 * @ Initialization and de-initialization functions
10 * @ IO operation functions
11 * @ Peripheral Control functions
12 ******************************************************************************
13 */
14 #include "ACM32Fxx_HAL.h"
15
16 /*********************************************************************************
17 * Function : HAL_LPUART_IRQHander
18 * Description : LPUART IRQHander
19 * Input :
20 * Outpu :
21 * Author : CWT Data : 2020年
22 **********************************************************************************/
HAL_LPUART_IRQHander(LPUART_HandleTypeDef * hlpuart)23 void HAL_LPUART_IRQHander(LPUART_HandleTypeDef *hlpuart)
24 {
25 while ( (hlpuart->Instance->SR) & (1U << LPUART_SR_RX_INDEX))
26 {
27 if(hlpuart->rx_read_index != (((hlpuart->rx_write_index) + 1)% (hlpuart->rx_buffer_size) ) )
28 {
29 hlpuart->rx_buffer[hlpuart->rx_write_index] = hlpuart->Instance->RXDR;
30 hlpuart->rx_write_index = ((hlpuart->rx_write_index + 1)%(hlpuart->rx_buffer_size) );
31 }
32 else
33 {
34 hlpuart->Instance->SR = (1U << LPUART_SR_RX_INDEX); // buffer overflow
35 return;
36 }
37 }
38 }
39 /************************************************************************
40 * function : HAL_UART_Buffer_Init
41 * Description: uart buffer initiation.
42 * input :
43 * UART_HandleTypeDef *huart: pointer to uart handle structure
44 * return: 0: FAIL; 1: SUCCESS
45 ************************************************************************/
HAL_LPUART_Buffer_Init(LPUART_HandleTypeDef * hlpuart)46 HAL_StatusTypeDef HAL_LPUART_Buffer_Init(LPUART_HandleTypeDef *hlpuart)
47 {
48 if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
49 {
50 return HAL_ERROR;
51 }
52 hlpuart->rx_read_index = 0;
53 hlpuart->rx_write_index = 0;
54 hlpuart->tx_busy = 0;
55 return HAL_OK;
56 }
57
58 /**********************************************************************************
59 * function : HAL_LPUART_MSPInit
60 * Description: UART MCU specific initiation, such as IO share, module clock, ...
61 * input :
62 * UART_HandleTypeDef *huart: pointer to uart handle structure
63 * return: 0: FAIL; 1: SUCCESS
64 ***************************************************************************************/
65
HAL_LPUART_MSPInit(LPUART_HandleTypeDef * hlpuart)66 __weak void HAL_LPUART_MSPInit(LPUART_HandleTypeDef *hlpuart)
67 {
68 GPIO_InitTypeDef gpio_init;
69
70 System_Module_Reset(RST_LPUART);
71 gpio_init.Pin = GPIO_PIN_2|GPIO_PIN_3; // TX PA2 RX PA3
72 gpio_init.Mode = GPIO_MODE_AF_PP;
73 gpio_init.Pull = GPIO_PULLUP;
74 gpio_init.Alternate = GPIO_FUNCTION_6;
75 HAL_GPIO_Init(GPIOA,&gpio_init);
76 System_Module_Enable(EN_LPUART);
77 }
78
79 /*********************************************************************************
80 * Function : HAL_LPUART_MspDeInit
81 * Description : LPUART MSP De-Initialization
82 * This function frees the hardware resources used in this example:
83 * - Disable the Peripheral's clock
84 * - Revert GPIO configuration to their default state
85 * Input : hcan : pointer to a CAN_HandleTypeDef structure that contains
86 * the configuration information for CAN module
87 * Output :
88 * Author : CWT Data : 2020年
89 **********************************************************************************/
HAL_LPUART_MspDeInit(LPUART_HandleTypeDef * hlpuart)90 void HAL_LPUART_MspDeInit(LPUART_HandleTypeDef *hlpuart)
91 {
92 /* Initialization GPIO */
93 /* // TX PA2 RX PA3 */
94 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2);
95 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3);
96 }
97 /**********************************************************************************
98 * function : HAL_LPUART_Set_Baud_Rate
99 * Description: set uart module's baud rate. It should be set when UART is disabled.
100 * input :
101 * UART_HandleTypeDef *huart: pointer to uart handle structure
102 * return: 0: FAIL; 1: SUCCESS
103 ***************************************************************************************/
HAL_LPUART_Set_Baud_Rate(LPUART_HandleTypeDef * hlpuart,uint32_t lpuart_clk,uint32_t baud_rate)104 uint8_t HAL_LPUART_Set_Baud_Rate(LPUART_HandleTypeDef *hlpuart, uint32_t lpuart_clk, uint32_t baud_rate)
105 {
106 uint32_t ibaud, fbaud, rxsamp;
107
108 if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
109 {
110 return 0;
111 }
112 ibaud = 2;
113 fbaud = 0x952;
114 rxsamp = 1;
115 switch(lpuart_clk)
116 {
117 case 32000:
118 case 32768:
119 switch(baud_rate)
120 {
121 case 9600:
122 ibaud = 2;
123 fbaud = 0x952;
124 // ibaud = 2;
125 // fbaud = 0xA44;
126 break;
127
128 case 4800:
129 ibaud = 5;
130 fbaud = 0xefb;
131 break;
132
133 case 2400:
134 ibaud = 12;
135 fbaud = 0x6db;
136 break;
137
138 case 1200:
139 ibaud = 26;
140 fbaud = 0x492;
141 break;
142 default:
143 ibaud = 2;
144 fbaud = 0x952;
145 break;
146 }
147 rxsamp = ibaud >> 1;
148 break;
149
150 default:
151 switch(baud_rate)
152 {
153 case 115200:
154 ibaud = 16;
155 fbaud = 0x924;
156 break;
157
158 case 9600:
159 ibaud = 203;
160 fbaud = 0x888;
161 break;
162 }
163 rxsamp = ibaud >> 1;
164 break;
165 }
166 hlpuart->Instance->IBAUD = ibaud | (rxsamp << 8);
167 hlpuart->Instance->FBAUD = fbaud;
168 return 1;
169 }
170
171 /************************************************************************
172 * function : HAL_LPUART_Config
173 * Description: Configure UART module parameters, such as baudrate, parity,
174 * stop bits, dataword.
175 * input :
176 * UART_HandleTypeDef *huart: pointer to uart handle structure
177 * return: 0: FAIL; 1: SUCCESS
178 ************************************************************************/
HAL_LPUART_Config(LPUART_HandleTypeDef * hlpuart)179 uint8_t HAL_LPUART_Config(LPUART_HandleTypeDef *hlpuart)
180 {
181 volatile uint32_t temp_reg;
182 if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
183 {
184 return 0;
185 }
186 temp_reg = 1U << 7; // default value
187 temp_reg |= ((hlpuart->ConfigParam.WordLength << 4) | (hlpuart->ConfigParam.StopBits << 3));
188 switch(hlpuart->ConfigParam.Parity)
189 {
190 case LPUART_PARITY_NONE:
191 break; // do nothing
192
193 case LPUART_PARITY_SELECT_ODD:
194 case LPUART_PARITY_SELECT_EVEN:
195 temp_reg |= (((hlpuart->ConfigParam.Parity - LPUART_PARITY_SELECT_ODD) << LPUART_EPS_INDEX) | (1 << LPUART_PEN_INDEX));
196 break;
197
198 case LPUART_PARITY_SELECT_ONE:
199 case LPUART_PARITY_SELECT_ZERO:
200 temp_reg |= (((hlpuart->ConfigParam.Parity - LPUART_PARITY_SELECT_ONE) << LPUART_EPS_INDEX) | (1 << LPUART_SPS_INDEX) | (1 << LPUART_PEN_INDEX) );
201 break;
202 }
203 hlpuart->Instance->LCR = temp_reg;
204 return 1;
205 }
206
207 /*********************************************************************************
208 * Function : LPUART_Clock_Select
209 * Description : Select the LPUART clock.
210 * Input : lpuart_clk_src:Could be LPUART_CLOCK_SOURCE_RC32K LPUART_CLOCK_SOURCE_XTAL LPUART_CLOCK_SOURCE_PLL_DIV
211 * Outpu :
212 * Author : CWT Data : 2020年
213 **********************************************************************************/
LPUART_Clock_Select(uint8_t lpuart_clk_src)214 void LPUART_Clock_Select(uint8_t lpuart_clk_src)
215 {
216 if (0 == lpuart_clk_src)
217 {
218 SCU->CCR2 &= (~(BIT13 | BIT14) ); // RC32K
219 }
220 else if (1 == lpuart_clk_src)
221 {
222 SCU->CCR2 = (SCU->CCR2 & (~(BIT13 | BIT14) )) | (BIT13); // XTAL
223 }
224 else
225 {
226 SCU->CCR2 = (SCU->CCR2 & (~(BIT11 | BIT12| BIT13 | BIT14) )) | (BIT11 | BIT12 | BIT14); // pclk/32
227 }
228 }
229 /************************************************************************
230 * function : HAL_LPUART_Init
231 * Description: uart initial with parameters.
232 * input :
233 * UART_HandleTypeDef *huart: pointer to uart handle structure
234 * return: 0: FAIL; 1: SUCCESS
235 ************************************************************************/
HAL_LPUART_Init(LPUART_HandleTypeDef * hlpuart)236 HAL_StatusTypeDef HAL_LPUART_Init(LPUART_HandleTypeDef *hlpuart)
237 {
238 uint32_t lpuart_clock;
239 if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
240 {
241 return HAL_ERROR;;
242 }
243
244 HAL_LPUART_Buffer_Init(hlpuart);
245 /*reset module, configure tx and rx, enable module clock*/
246 HAL_LPUART_MSPInit(hlpuart);
247
248 if (LPUART_CLOCK_SOURCE_RC32K == hlpuart->ConfigParam.ClockSrc)
249 {
250 lpuart_clock = 32000;
251 System_Module_Enable(EN_RTC);
252 System_Enable_Disable_RTC_Domain_Access(FUNC_ENABLE);
253 System_Enable_RC32K();
254 LPUART_Clock_Select(0);
255 }
256 else if (LPUART_CLOCK_SOURCE_XTAL == hlpuart->ConfigParam.ClockSrc)
257 {
258 lpuart_clock = 32768;
259 System_Module_Enable(EN_RTC);
260 System_Enable_Disable_RTC_Domain_Access(FUNC_ENABLE);
261 System_Enable_XTAL();
262 LPUART_Clock_Select(1);
263 }
264 else
265 {
266 lpuart_clock = System_Get_APBClock()/32;
267 LPUART_Clock_Select(2);
268 }
269 HAL_LPUART_Set_Baud_Rate(hlpuart, lpuart_clock, hlpuart->ConfigParam.BaudRate);
270
271 HAL_LPUART_Config(hlpuart);
272
273 hlpuart->Instance->SR = LPUART_SR_BITS_ALL;
274 hlpuart->Instance->IE = (1U << LPUART_IE_RX_INDEX);
275 hlpuart->Instance->CR = (1U << LPUART_CR_RXE_INDEX) | (1 << LPUART_CR_TXE_INDEX);
276 hlpuart->Instance->LCR=((hlpuart->StopWakeup.Wakeup_Source<<5)|(hlpuart->StopWakeup.Wakeup_Check<<7));
277 hlpuart->Instance->ADDR=(hlpuart->StopWakeup.Wakeup_Addr);
278 NVIC_ClearPendingIRQ(LPUART_IRQn);
279 NVIC_EnableIRQ(LPUART_IRQn);
280 return HAL_OK;;
281 }
HAL_LPUART_DeInit(LPUART_HandleTypeDef * hlpuart)282 HAL_StatusTypeDef HAL_LPUART_DeInit(LPUART_HandleTypeDef *hlpuart)
283 {
284 /* Check handle */
285 if(!IS_LPUART_INSTANCE(hlpuart->Instance)) return HAL_ERROR;
286 HAL_LPUART_MspDeInit(hlpuart);
287 /* Disable LPUART clock */
288 System_Module_Disable(EN_LPUART);
289 /* Return function status */
290 return HAL_OK;
291 }
292 /************************************************************************
293 * function : HAL_LPUART_Wait_TX_Done
294 * Description: wait uart not busy
295 * input :
296 * UART_HandleTypeDef *huart: pointer to uart handle structure
297 * return: 0: FAIL; 1: SUCCESS
298 ************************************************************************/
HAL_LPUART_Wait_TX_Done(LPUART_HandleTypeDef * hlpuart)299 HAL_StatusTypeDef HAL_LPUART_Wait_TX_Done(LPUART_HandleTypeDef *hlpuart)
300 {
301 while (0 == (hlpuart->Instance->SR & (1 << LPUART_SR_TX_FINISH_INDEX) ) ) {};
302 hlpuart->Instance->SR = (1 << LPUART_SR_TX_FINISH_INDEX);
303 return HAL_OK;
304 }
305
HAL_LPUART_Output(LPUART_HandleTypeDef * hlpuart,unsigned char c)306 void HAL_LPUART_Output(LPUART_HandleTypeDef *hlpuart, unsigned char c)
307 {
308 if ((hlpuart->Instance->SR) & (1U << LPUART_SR_TX_EMPTY_INDEX) )
309 {
310 hlpuart->Instance->TXDR = c;
311 }
312
313 HAL_LPUART_Wait_TX_Done(hlpuart);
314 }
315
316 /************************************************************************
317 * function : uart_send_bytes
318 * Description: uart send bytes
319 * input :
320 * UINT32 uart_index: Serial port number
321 * UINT8* buff: out buffer
322 * UINT32 length: buffer length
323 * return: none
324 ************************************************************************/
HAL_LPUART_Send_Bytes(LPUART_HandleTypeDef * hlpuart,uint8_t * buff,uint32_t length)325 void HAL_LPUART_Send_Bytes(LPUART_HandleTypeDef *hlpuart, uint8_t *buff, uint32_t length)
326 {
327 uint32_t i;
328 for (i = 0; i < length; i++)
329 {
330 HAL_LPUART_Output(hlpuart, *buff++);
331 }
332 }
333
334 /************************************************************************
335 * function : HAL_LPUART_Receive_Bytes_Timeout
336 * Description: uart receive bytes
337 * input :
338 * UART_HandleTypeDef *huart: pointer to uart handle structure
339 * UINT8* buff: out buffer
340 * UINT32 length: buffer length
341 * UINT32 ms: number of ms to delay one byte
342 * return: received bytes
343 ************************************************************************/
HAL_LPUART_Receive_Bytes_Timeout(LPUART_HandleTypeDef * hlpuart,uint8_t * rxbuff,uint32_t length,uint32_t ms)344 uint32_t HAL_LPUART_Receive_Bytes_Timeout(LPUART_HandleTypeDef *hlpuart, uint8_t * rxbuff, uint32_t length, uint32_t ms)
345 {
346 volatile uint32_t i, timeout, count;;
347 if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
348 {
349 return 0;
350 }
351 timeout = (System_Get_APBClock() >> 13) * ms;
352 count = timeout;
353 i = 0;
354 while(i < length)
355 {
356 if((hlpuart->rx_read_index) != (hlpuart->rx_write_index))
357 {
358 rxbuff[i] = hlpuart->rx_buffer[hlpuart->rx_read_index];
359 hlpuart->rx_read_index = (((hlpuart->rx_read_index) + 1)%(hlpuart->rx_buffer_size) );
360 count = timeout;
361 i++;
362 }
363 else
364 {
365 if (0 == count)//timeout
366 {
367 break;
368 }
369 else
370 {
371 count--;
372 }
373 }
374 }
375 return i;
376 }
377 /************************************************************************
378 * function : HAL_LPUART_Receive_Bytes
379 * Description: LPUART receive bytes.
380 * input :
381 * UART_HandleTypeDef *huart: pointer to uart handle structure
382 * buff:receive data buff
383 * length:length of buff
384 * return:length
385 ************************************************************************/
HAL_LPUART_Receive_Bytes(LPUART_HandleTypeDef * hlpuart,uint8_t * rxbuff,uint32_t length)386 uint32_t HAL_LPUART_Receive_Bytes(LPUART_HandleTypeDef *hlpuart, uint8_t * rxbuff, uint32_t length)
387 {
388 volatile uint32_t i, ie_backup;
389 if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
390 {
391 return 0;
392 }
393 ie_backup = hlpuart->Instance->IE;
394 hlpuart->Instance->IE = 0;
395 i = 0;
396 while(i < length)
397 {
398 if( (hlpuart->Instance->SR) & (1U << LPUART_SR_RX_INDEX) )
399 {
400 rxbuff[i] = hlpuart->Instance->RXDR;
401 i++;
402 }
403 }
404 hlpuart->Instance->IE = ie_backup;
405 return length;
406 }
407 /************************************************************************
408 * function : HAL_LPUART_DMA_Send_Bytes
409 * Description: LPUART send bytes by DMA.
410 * input :
411 * UART_HandleTypeDef *huart: pointer to uart handle structure
412 * buff:send data buff
413 * length:length of buff
414 * return:none
415 ************************************************************************/
HAL_LPUART_DMA_Send_Bytes(LPUART_HandleTypeDef * hlpuart,uint8_t * buff,uint32_t length)416 void HAL_LPUART_DMA_Send_Bytes(LPUART_HandleTypeDef *hlpuart, uint8_t *buff, uint32_t length)
417 {
418 hlpuart->Instance->CR |= (1U << LPUART_CR_DMA_EN_INDEX);
419 hlpuart->tx_busy = 1;
420 HAL_DMA_Start_IT(hlpuart->dma_tx_handler, (uint32_t)buff, (uint32_t)&hlpuart->Instance->TXDR, length);
421 }
422
423 /************************************************************************
424 * function : HAL_LPUART_Clear_Wakeup_Flags
425 * Description: Clear the LPUART STOP wake up flag.
426 * input :
427 * UART_HandleTypeDef *huart: pointer to uart handle structure
428 * Wakeup_Bits:LPUART wakeup flag,could be: LPUART_WAKEUP_RX_BIT LPUART_WAKEUP_MATCH_BIT LPUART_WAKEUP_START_BIT
429 * return:none
430 ************************************************************************/
431
HAL_LPUART_Clear_Wakeup_Flags(LPUART_HandleTypeDef * hlpuart,uint32_t Wakeup_Bits)432 void HAL_LPUART_Clear_Wakeup_Flags(LPUART_HandleTypeDef *hlpuart, uint32_t Wakeup_Bits)
433 {
434 hlpuart->Instance->SR = Wakeup_Bits;
435 }
436
437
438