HAL_LPUART.c 15 KB

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