drv_usart.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. /******************************************************************//**
  2. * @file drv_usart.c
  3. * @brief USART driver of RT-Thread RTOS for EFM32
  4. * COPYRIGHT (C) 2011, RT-Thread Development Team
  5. * @author onelife
  6. * @version 0.4 beta
  7. **********************************************************************
  8. * @section License
  9. * The license and distribution terms for this file may be found in the file LICENSE in this
  10. * distribution or at http://www.rt-thread.org/license/LICENSE
  11. **********************************************************************
  12. * @section Change Logs
  13. * Date Author Notes
  14. * 2010-12-22 onelife Initial creation for EFM32
  15. * 2011-01-17 onelife Merge with serial.c
  16. * 2011-05-06 onelife Add sync mode (SPI) support
  17. *
  18. * @section Change Logs of serial.c
  19. * 2009-02-05 Bernard first version
  20. * 2009-10-25 Bernard fix rt_serial_read bug when there is no data in the buffer.
  21. * 2010-03-29 Bernard cleanup code.
  22. *********************************************************************/
  23. /******************************************************************//**
  24. * @addtogroup efm32
  25. * @{
  26. *********************************************************************/
  27. /* Includes -------------------------------------------------------------------*/
  28. #include "board.h"
  29. #include "hdl_interrupt.h"
  30. #include "drv_usart.h"
  31. /* Private typedef -------------------------------------------------------------*/
  32. union efm32_usart_init_t
  33. {
  34. USART_InitAsync_TypeDef async;
  35. USART_InitSync_TypeDef sync;
  36. };
  37. /* Private define --------------------------------------------------------------*/
  38. /* Private macro --------------------------------------------------------------*/
  39. #ifdef RT_USART_DEBUG
  40. #define usart_debug(format,args...) rt_kprintf(format, ##args)
  41. #else
  42. #define usart_debug(format,args...)
  43. #endif
  44. /* Private variables ------------------------------------------------------------*/
  45. #ifdef RT_USING_USART0
  46. #if (RT_USING_USART0 > 3)
  47. #error "The location number range of usart is 0~3"
  48. #endif
  49. struct rt_device usart0_device;
  50. #endif
  51. #ifdef RT_USING_USART1
  52. #if (RT_USING_USART1 > 3)
  53. #error "The location number range of usart is 0~3"
  54. #endif
  55. struct rt_device usart1_device;
  56. #endif
  57. #ifdef RT_USING_USART2
  58. #if (RT_USING_USART2 > 3)
  59. #error "The location number range of usart is 0~3"
  60. #endif
  61. struct rt_device usart2_device;
  62. #endif
  63. /* Private function prototypes ---------------------------------------------------*/
  64. /* Private functions ------------------------------------------------------------*/
  65. /******************************************************************//**
  66. * @brief
  67. * Initialize USART device
  68. *
  69. * @details
  70. *
  71. * @note
  72. *
  73. * @param[in] dev
  74. * Pointer to device descriptor
  75. *
  76. * @return
  77. * Error code
  78. *********************************************************************/
  79. static rt_err_t rt_usart_init (rt_device_t dev)
  80. {
  81. struct efm32_usart_device_t *usart;
  82. usart = (struct efm32_usart_device_t *)(dev->user_data);
  83. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  84. {
  85. if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
  86. {
  87. struct efm32_usart_dma_mode_t *dma_tx;
  88. dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
  89. usart->state |= USART_STATE_RX_BUSY;
  90. }
  91. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  92. {
  93. struct efm32_usart_int_mode_t *int_rx;
  94. int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
  95. int_rx->data_ptr = RT_NULL;
  96. }
  97. /* Enable USART */
  98. USART_Enable(usart->usart_device, usartEnable);
  99. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  100. }
  101. return RT_EOK;
  102. }
  103. /******************************************************************//**
  104. * @brief
  105. * Open USART device
  106. *
  107. * @details
  108. *
  109. * @note
  110. *
  111. * @param[in] dev
  112. * Pointer to device descriptor
  113. *
  114. * @param[in] oflag
  115. * Device open flag
  116. *
  117. * @return
  118. * Error code
  119. *********************************************************************/
  120. static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
  121. {
  122. RT_ASSERT(dev != RT_NULL);
  123. struct efm32_usart_device_t *usart;
  124. usart = (struct efm32_usart_device_t *)(dev->user_data);
  125. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  126. {
  127. IRQn_Type rxIrq;
  128. //if (usart->state & USART_STATE_CONSOLE)
  129. { /* Allocate new RX buffer */
  130. struct efm32_usart_int_mode_t *int_mode;
  131. int_mode = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
  132. if ((int_mode->data_ptr = rt_malloc(USART_RX_BUFFER_SIZE)) == RT_NULL)
  133. {
  134. usart_debug("USART: no memory for RX buffer\n");
  135. return -RT_ENOMEM;
  136. }
  137. rt_memset(int_mode->data_ptr, 0, USART_RX_BUFFER_SIZE);
  138. int_mode->data_size = USART_RX_BUFFER_SIZE;
  139. int_mode->read_index = 0;
  140. int_mode->save_index = 0;
  141. }
  142. /* Enable TX/RX interrupt */
  143. switch (usart->unit)
  144. {
  145. case 0:
  146. rxIrq = USART0_RX_IRQn;
  147. break;
  148. case 1:
  149. rxIrq = USART1_RX_IRQn;
  150. break;
  151. case 2:
  152. rxIrq = USART2_RX_IRQn;
  153. break;
  154. }
  155. /* Enable RX interrupts */
  156. usart->usart_device->IEN = USART_IEN_RXDATAV;
  157. /* Enable IRQ */
  158. if (oflag != RT_DEVICE_OFLAG_WRONLY)
  159. {
  160. NVIC_ClearPendingIRQ(rxIrq);
  161. NVIC_SetPriority(rxIrq, EFM32_IRQ_PRI_DEFAULT);
  162. NVIC_EnableIRQ(rxIrq);
  163. }
  164. }
  165. usart->usart_device->IFC = _USART_IFC_MASK;
  166. if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (oflag != RT_DEVICE_OFLAG_RDONLY))
  167. {
  168. /* DMA IRQ is enabled by DMA_Init() */
  169. NVIC_SetPriority(DMA_IRQn, EFM32_IRQ_PRI_DEFAULT);
  170. }
  171. usart_debug("USART%d: Open with flag %x\n", usart->unit, oflag);
  172. return RT_EOK;
  173. }
  174. /******************************************************************//**
  175. * @brief
  176. * Close USART device
  177. *
  178. * @details
  179. *
  180. * @note
  181. *
  182. * @param[in] dev
  183. * Pointer to device descriptor
  184. *
  185. * @return
  186. * Error code
  187. *********************************************************************/
  188. static rt_err_t rt_usart_close(rt_device_t dev)
  189. {
  190. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  191. {
  192. struct efm32_usart_int_mode_t *int_rx;
  193. int_rx = (struct efm32_usart_int_mode_t *)\
  194. (((struct efm32_usart_device_t *)(dev->user_data))->rx_mode);
  195. rt_free(int_rx->data_ptr);
  196. int_rx->data_ptr = RT_NULL;
  197. }
  198. return RT_EOK;
  199. }
  200. /******************************************************************//**
  201. * @brief
  202. * Read from USART device
  203. *
  204. * @details
  205. *
  206. * @note
  207. *
  208. * @param[in] dev
  209. * Pointer to device descriptor
  210. *
  211. * @param[in] pos
  212. * Offset
  213. *
  214. * @param[in] buffer
  215. * Poniter to the buffer
  216. *
  217. * @param[in] size
  218. * Buffer size in byte
  219. *
  220. * @return
  221. * Error code
  222. *********************************************************************/
  223. static rt_size_t rt_usart_read (
  224. rt_device_t dev,
  225. rt_off_t pos,
  226. void *buffer,
  227. rt_size_t size)
  228. {
  229. rt_uint8_t *ptr;
  230. rt_err_t err_code;
  231. rt_size_t read_len;
  232. err_code = RT_EOK;
  233. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  234. {
  235. ptr = buffer;
  236. /* interrupt mode Rx */
  237. while (size)
  238. {
  239. rt_base_t level;
  240. struct efm32_usart_int_mode_t *int_rx;
  241. int_rx = (struct efm32_usart_int_mode_t *)\
  242. (((struct efm32_usart_device_t *)(dev->user_data))->rx_mode);
  243. /* disable interrupt */
  244. level = rt_hw_interrupt_disable();
  245. if (int_rx->read_index != int_rx->save_index)
  246. {
  247. /* read a character */
  248. *ptr++ = int_rx->data_ptr[int_rx->read_index];
  249. size--;
  250. /* move to next position */
  251. int_rx->read_index ++;
  252. if (int_rx->read_index >= USART_RX_BUFFER_SIZE)
  253. {
  254. int_rx->read_index = 0;
  255. }
  256. }
  257. else
  258. {
  259. /* set error code */
  260. err_code = -RT_EEMPTY;
  261. /* enable interrupt */
  262. rt_hw_interrupt_enable(level);
  263. break;
  264. }
  265. /* enable interrupt */
  266. rt_hw_interrupt_enable(level);
  267. }
  268. read_len = (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  269. }
  270. else
  271. {
  272. RT_ASSERT(buffer != RT_NULL);
  273. struct efm32_usart_device_t *usart;
  274. USART_TypeDef *usart_device;
  275. usart = (struct efm32_usart_device_t *)(dev->user_data);
  276. usart_device = ((struct efm32_usart_device_t *)(dev->user_data))->usart_device;
  277. if (usart->state & USART_STATE_SYNC)
  278. {
  279. /* SPI read */
  280. rt_uint8_t inst_len = *((rt_uint8_t *)buffer);
  281. rt_uint8_t *inst_ptr = (rt_uint8_t *)(buffer + 1);
  282. rt_uint8_t *rx_buf = *((rt_uint8_t **)(buffer + inst_len + 1));
  283. ptr = rx_buf;
  284. /* write instruction */
  285. while (inst_len)
  286. {
  287. while (!(usart->usart_device->STATUS & USART_STATUS_TXBL));
  288. usart->usart_device->TXDATA = (rt_uint32_t)*inst_ptr;
  289. ++inst_ptr; --inst_len;
  290. }
  291. /* Flushing RX */
  292. usart_device->CMD = USART_CMD_CLEARRX;
  293. /* dummy write */
  294. while (!(usart_device->STATUS & USART_STATUS_TXBL));
  295. usart_device->TXDATA = (rt_uint32_t)0x00;
  296. /* dummy read */
  297. while (!(usart_device->STATUS & USART_STATUS_RXDATAV));
  298. *((rt_uint32_t *)0x00) = usart_device->RXDATA;
  299. while ((rt_uint32_t)ptr - (rt_uint32_t)rx_buf < size)
  300. {
  301. /* dummy write */
  302. while (!(usart_device->STATUS & USART_STATUS_TXBL));
  303. usart_device->TXDATA = (rt_uint32_t)0x00;
  304. /* read a byte of data */
  305. while (!(usart_device->STATUS & USART_STATUS_RXDATAV));
  306. *ptr = usart_device->RXDATA & 0xff;
  307. ptr ++;
  308. }
  309. }
  310. else
  311. {
  312. ptr = buffer;
  313. /* polling mode */
  314. while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
  315. {
  316. while (usart_device->STATUS & USART_STATUS_RXDATAV)
  317. {
  318. *ptr = usart_device->RXDATA & 0xff;
  319. ptr ++;
  320. }
  321. }
  322. }
  323. read_len = size;
  324. }
  325. /* set error code */
  326. rt_set_errno(err_code);
  327. return read_len;
  328. }
  329. /******************************************************************//**
  330. * @brief
  331. * Write to USART device
  332. *
  333. * @details
  334. *
  335. * @note
  336. *
  337. * @param[in] dev
  338. * Pointer to device descriptor
  339. *
  340. * @param[in] pos
  341. * Offset
  342. *
  343. * @param[in] buffer
  344. * Poniter to the buffer
  345. *
  346. * @param[in] size
  347. * Buffer size in byte
  348. *
  349. * @return
  350. * Number of written bytes
  351. *********************************************************************/
  352. static rt_size_t rt_usart_write (
  353. rt_device_t dev,
  354. rt_off_t pos,
  355. const void* buffer,
  356. rt_size_t size)
  357. {
  358. rt_err_t err_code;
  359. rt_size_t write_size;
  360. struct efm32_usart_device_t* usart;
  361. err_code = RT_EOK;
  362. write_size = 0;
  363. usart = (struct efm32_usart_device_t*)(dev->user_data);
  364. if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (size > 1))
  365. { /* DMA mode Tx */
  366. struct efm32_usart_dma_mode_t *dma_tx;
  367. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  368. {
  369. *((rt_uint8_t *)buffer + size++) = '\r';
  370. *((rt_uint8_t *)buffer + size) = 0x0;
  371. }
  372. dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
  373. dma_tx->data_ptr = (rt_uint32_t *)buffer;
  374. dma_tx->data_size = size;
  375. usart->state |= USART_STATE_TX_BUSY;
  376. DMA_ActivateBasic(
  377. dma_tx->dma_channel,
  378. true,
  379. false,
  380. (void *)&(usart->usart_device->TXDATA),
  381. buffer,
  382. size - 1);
  383. /* Wait, otherwise the TX buffer is overwrite */
  384. if (usart->state & USART_STATE_CONSOLE)
  385. {
  386. while(usart->state & USART_STATE_TX_BUSY);
  387. }
  388. else
  389. {
  390. while(usart->state & USART_STATE_TX_BUSY)
  391. {
  392. rt_thread_sleep(USART_WAIT_TIME_TX);
  393. }
  394. }
  395. write_size = size;
  396. }
  397. else
  398. { /* polling mode */
  399. rt_uint8_t *ptr = (rt_uint8_t *)buffer;
  400. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  401. {
  402. /* stream mode */
  403. while (size)
  404. {
  405. if (*ptr == '\n')
  406. {
  407. while (!(usart->usart_device->STATUS & USART_STATUS_TXBL));
  408. usart->usart_device->TXDATA = '\r';
  409. }
  410. while (!(usart->usart_device->STATUS & USART_STATUS_TXBL));
  411. usart->usart_device->TXDATA = (rt_uint32_t)*ptr;
  412. ++ptr; --size;
  413. }
  414. }
  415. else
  416. {
  417. /* write data directly */
  418. while (size)
  419. {
  420. while (!(usart->usart_device->STATUS & USART_STATUS_TXBL));
  421. usart->usart_device->TXDATA = (rt_uint32_t)*ptr;
  422. ++ptr; --size;
  423. }
  424. }
  425. write_size = (rt_size_t)ptr - (rt_size_t)buffer;
  426. }
  427. /* set error code */
  428. rt_set_errno(err_code);
  429. return write_size;
  430. }
  431. /******************************************************************//**
  432. * @brief
  433. * Configure USART device
  434. *
  435. * @details
  436. *
  437. * @note
  438. *
  439. * @param[in] dev
  440. * Pointer to device descriptor
  441. *
  442. * @param[in] cmd
  443. * IIC control command
  444. *
  445. * @param[in] args
  446. * Arguments
  447. *
  448. * @return
  449. * Error code
  450. *********************************************************************/
  451. static rt_err_t rt_usart_control (
  452. rt_device_t dev,
  453. rt_uint8_t cmd,
  454. void *args)
  455. {
  456. RT_ASSERT(dev != RT_NULL);
  457. struct efm32_usart_device_t *usart;
  458. usart = (struct efm32_usart_device_t *)(dev->user_data);
  459. switch (cmd)
  460. {
  461. case RT_DEVICE_CTRL_SUSPEND:
  462. /* Suspend device */
  463. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  464. USART_Enable(usart->usart_device, usartDisable);
  465. break;
  466. case RT_DEVICE_CTRL_RESUME:
  467. /* Resume device */
  468. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  469. USART_Enable(usart->usart_device, usartEnable);
  470. break;
  471. case RT_DEVICE_CTRL_USART_RBUFFER:
  472. /* Set RX buffer */
  473. {
  474. struct efm32_usart_int_mode_t *int_rx;
  475. rt_uint8_t size;
  476. int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
  477. size = (rt_uint8_t)((rt_uint32_t)args & 0xFFUL);
  478. /* Free previous RX buffer */
  479. if (int_rx->data_ptr != RT_NULL)
  480. {
  481. if (size == 0)
  482. { /* Free RX buffer */
  483. rt_free(int_rx->data_ptr);
  484. int_rx->data_ptr = RT_NULL;
  485. }
  486. else if (size != int_rx->data_size)
  487. {
  488. /* Re-allocate RX buffer */
  489. if ((int_rx->data_ptr = rt_realloc(int_rx->data_ptr, size)) \
  490. == RT_NULL)
  491. {
  492. usart_debug("USART: no memory for RX buffer\n");
  493. return -RT_ENOMEM;
  494. }
  495. // TODO: Is the following line necessary?
  496. //rt_memset(int_rx->data_ptr, 0, size);
  497. }
  498. }
  499. else
  500. {
  501. /* Allocate new RX buffer */
  502. if ((int_rx->data_ptr = rt_malloc(size)) == RT_NULL)
  503. {
  504. usart_debug("USART: no memory for RX buffer\n");
  505. return -RT_ENOMEM;
  506. }
  507. }
  508. int_rx->data_size = size;
  509. int_rx->read_index = 0;
  510. int_rx->save_index = 0;
  511. }
  512. break;
  513. }
  514. return RT_EOK;
  515. }
  516. /******************************************************************//**
  517. * @brief
  518. * USART RX data valid interrupt handler
  519. *
  520. * @details
  521. *
  522. * @note
  523. *
  524. * @param[in] dev
  525. * Pointer to device descriptor
  526. *********************************************************************/
  527. void rt_hw_usart_rx_isr(rt_device_t dev)
  528. {
  529. struct efm32_usart_device_t *usart;
  530. struct efm32_usart_int_mode_t *int_rx;
  531. /* interrupt mode receive */
  532. RT_ASSERT(dev->flag & RT_DEVICE_FLAG_INT_RX);
  533. usart = (struct efm32_usart_device_t *)(dev->user_data);
  534. int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
  535. RT_ASSERT(int_rx->data_ptr != RT_NULL);
  536. /* Set status */
  537. usart->state |= USART_STATE_RX_BUSY;
  538. /* save on rx buffer */
  539. while (usart->usart_device->STATUS & USART_STATUS_RXDATAV)
  540. {
  541. rt_base_t level;
  542. /* disable interrupt */
  543. level = rt_hw_interrupt_disable();
  544. /* save character */
  545. int_rx->data_ptr[int_rx->save_index] = \
  546. (rt_uint8_t)(usart->usart_device->RXDATA & 0xFFUL);
  547. int_rx->save_index ++;
  548. if (int_rx->save_index >= USART_RX_BUFFER_SIZE)
  549. int_rx->save_index = 0;
  550. /* if the next position is read index, discard this 'read char' */
  551. if (int_rx->save_index == int_rx->read_index)
  552. {
  553. int_rx->read_index ++;
  554. if (int_rx->read_index >= USART_RX_BUFFER_SIZE)
  555. {
  556. int_rx->read_index = 0;
  557. }
  558. }
  559. /* enable interrupt */
  560. rt_hw_interrupt_enable(level);
  561. }
  562. /* invoke callback */
  563. if (dev->rx_indicate != RT_NULL)
  564. {
  565. rt_size_t rx_length;
  566. /* get rx length */
  567. rx_length = int_rx->read_index > int_rx->save_index ?
  568. USART_RX_BUFFER_SIZE - int_rx->read_index + int_rx->save_index : \
  569. int_rx->save_index - int_rx->read_index;
  570. dev->rx_indicate(dev, rx_length);
  571. }
  572. }
  573. /******************************************************************//**
  574. * @brief
  575. * DMA for USART TX interrupt handler
  576. *
  577. * @details
  578. *
  579. * @note
  580. *
  581. * @param[in] dev
  582. * Pointer to device descriptor
  583. *********************************************************************/
  584. void rt_hw_usart_dma_tx_isr(rt_device_t dev)
  585. {
  586. /* DMA mode receive */
  587. struct efm32_usart_device_t *usart;
  588. struct efm32_usart_dma_mode_t *dma_tx;
  589. RT_ASSERT(dev->flag & RT_DEVICE_FLAG_DMA_TX);
  590. usart = (struct efm32_usart_device_t *)(dev->user_data);
  591. dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
  592. /* invoke call to notify tx complete */
  593. if (dev->tx_complete != RT_NULL)
  594. {
  595. dev->tx_complete(dev, dma_tx->data_ptr);
  596. }
  597. /* Set status */
  598. usart->state &= ~(rt_uint32_t)USART_STATE_TX_BUSY;
  599. }
  600. /******************************************************************//**
  601. * @brief
  602. * Register USART device
  603. *
  604. * @details
  605. *
  606. * @note
  607. *
  608. * @param[in] device
  609. * Pointer to device descriptor
  610. *
  611. * @param[in] name
  612. * Device name
  613. *
  614. * @param[in] flag
  615. * Configuration flags
  616. *
  617. * @param[in] usart
  618. * Pointer to USART device descriptor
  619. *
  620. * @return
  621. * Error code
  622. *********************************************************************/
  623. rt_err_t rt_hw_usart_register(
  624. rt_device_t device,
  625. const char *name,
  626. rt_uint32_t flag,
  627. struct efm32_usart_device_t *usart)
  628. {
  629. RT_ASSERT(device != RT_NULL);
  630. if ((flag & RT_DEVICE_FLAG_DMA_RX) ||
  631. (flag & RT_DEVICE_FLAG_INT_TX))
  632. {
  633. RT_ASSERT(0);
  634. }
  635. device->type = RT_Device_Class_Char;
  636. device->rx_indicate = RT_NULL;
  637. device->tx_complete = RT_NULL;
  638. device->init = rt_usart_init;
  639. device->open = rt_usart_open;
  640. device->close = rt_usart_close;
  641. device->read = rt_usart_read;
  642. device->write = rt_usart_write;
  643. device->control = rt_usart_control;
  644. device->user_data = usart;
  645. /* register a character device */
  646. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  647. }
  648. /******************************************************************//**
  649. * @brief
  650. * Initialize the specified USART unit
  651. *
  652. * @details
  653. *
  654. * @note
  655. *
  656. * @param[in] device
  657. * Pointer to device descriptor
  658. *
  659. * @param[in] unitNumber
  660. * Unit number
  661. *
  662. * @param[in] location
  663. * Pin location number
  664. *
  665. * @param[in] flag
  666. * Configuration flag
  667. *
  668. * @param[in] dmaChannel
  669. * DMA channel number for TX
  670. *
  671. * @param[in] console
  672. * Indicate if using as console
  673. *
  674. * @return
  675. * Pointer to USART device
  676. *********************************************************************/
  677. static struct efm32_usart_device_t *rt_hw_usart_unit_init(
  678. rt_device_t device,
  679. rt_uint8_t unitNumber,
  680. rt_uint8_t location,
  681. rt_uint32_t flag,
  682. rt_uint32_t dmaChannel,
  683. rt_uint8_t config)
  684. {
  685. struct efm32_usart_device_t *usart;
  686. struct efm32_usart_dma_mode_t *dma_mode;
  687. CMU_Clock_TypeDef usartClock;
  688. rt_uint32_t txDmaSelect;
  689. union efm32_usart_init_t init;
  690. efm32_irq_hook_init_t hook;
  691. /* Allocate device */
  692. usart = rt_malloc(sizeof(struct efm32_usart_device_t));
  693. if (usart == RT_NULL)
  694. {
  695. usart_debug("USART: no memory for device\n");
  696. return usart;
  697. }
  698. usart->unit = unitNumber;
  699. usart->state = config;
  700. usart->tx_mode = RT_NULL;
  701. usart->rx_mode = RT_NULL;
  702. /* Allocate TX */
  703. dma_mode = RT_NULL;
  704. if (flag & RT_DEVICE_FLAG_DMA_TX)
  705. {
  706. usart->tx_mode = dma_mode = rt_malloc(sizeof(struct efm32_usart_dma_mode_t));
  707. if (dma_mode == RT_NULL)
  708. {
  709. usart_debug("USART: no memory for DMA TX\n");
  710. rt_free(usart->rx_mode);
  711. rt_free(usart);
  712. usart = RT_NULL;
  713. return usart;
  714. }
  715. dma_mode->dma_channel = dmaChannel;
  716. }
  717. /* Allocate RX */
  718. if (flag & RT_DEVICE_FLAG_INT_RX)
  719. {
  720. usart->rx_mode = rt_malloc(sizeof(struct efm32_usart_int_mode_t));
  721. if (usart->rx_mode == RT_NULL)
  722. {
  723. usart_debug("USART: no memory for interrupt RX\n");
  724. rt_free(usart->tx_mode);
  725. rt_free(usart);
  726. usart = RT_NULL;
  727. return usart;
  728. }
  729. }
  730. /* Initialization */
  731. switch (unitNumber)
  732. {
  733. case 0:
  734. usart->usart_device = USART0;
  735. usartClock = (CMU_Clock_TypeDef)cmuClock_USART0;
  736. txDmaSelect = DMAREQ_USART0_TXBL;
  737. break;
  738. case 1:
  739. usart->usart_device = USART1;
  740. usartClock = (CMU_Clock_TypeDef)cmuClock_USART1;
  741. txDmaSelect = DMAREQ_USART1_TXBL;
  742. break;
  743. case 2:
  744. usart->usart_device = USART2;
  745. usartClock = (CMU_Clock_TypeDef)cmuClock_USART2;
  746. txDmaSelect = DMAREQ_USART2_TXBL;
  747. break;
  748. }
  749. /* Enable USART clock */
  750. CMU_ClockEnable(usartClock, true);
  751. /* Reset */
  752. USART_Reset(usart->usart_device);
  753. /* Config GPIO */
  754. GPIO_PinModeSet(
  755. (GPIO_Port_TypeDef)AF_PORT(AF_USART_TX(unitNumber), location),
  756. AF_PIN(AF_USART_TX(unitNumber), location),
  757. gpioModePushPull,
  758. 0);
  759. GPIO_PinModeSet(
  760. (GPIO_Port_TypeDef)AF_PORT(AF_USART_RX(unitNumber), location),
  761. AF_PIN(AF_USART_RX(unitNumber), location),
  762. gpioModeInputPull,
  763. 1);
  764. if (config & USART_STATE_SYNC)
  765. {
  766. GPIO_PinModeSet(
  767. (GPIO_Port_TypeDef)AF_PORT(AF_USART_CLK(unitNumber), location),
  768. AF_PIN(AF_USART_CLK(unitNumber), location),
  769. gpioModePushPull,
  770. 0);
  771. }
  772. if (config & USART_STATE_AUTOCS)
  773. {
  774. GPIO_PinModeSet(
  775. (GPIO_Port_TypeDef)AF_PORT(AF_USART_CS(unitNumber), location),
  776. AF_PIN(AF_USART_CS(unitNumber), location),
  777. gpioModePushPull,
  778. 1);
  779. }
  780. /* Config interrupt and NVIC */
  781. if (flag & RT_DEVICE_FLAG_INT_RX)
  782. {
  783. hook.type = efm32_irq_type_usart;
  784. hook.unit = unitNumber * 2 + 1;
  785. hook.cbFunc = rt_hw_usart_rx_isr;
  786. hook.userPtr = device;
  787. efm32_irq_hook_register(&hook);
  788. }
  789. /* Config DMA */
  790. if (flag & RT_DEVICE_FLAG_DMA_TX)
  791. {
  792. DMA_CB_TypeDef *callback;
  793. DMA_CfgChannel_TypeDef chnlCfg;
  794. DMA_CfgDescr_TypeDef descrCfg;
  795. hook.type = efm32_irq_type_dma;
  796. hook.unit = dmaChannel;
  797. hook.cbFunc = rt_hw_usart_dma_tx_isr;
  798. hook.userPtr = device;
  799. efm32_irq_hook_register(&hook);
  800. callback = (DMA_CB_TypeDef *)rt_malloc(sizeof(DMA_CB_TypeDef));
  801. callback->cbFunc = DMA_IRQHandler_All;
  802. callback->userPtr = RT_NULL;
  803. callback->primary = 0;
  804. /* Setting up DMA channel */
  805. chnlCfg.highPri = false; /* Can't use with peripherals */
  806. chnlCfg.enableInt = true; /* Interrupt for callback function */
  807. chnlCfg.select = txDmaSelect;
  808. chnlCfg.cb = callback;
  809. DMA_CfgChannel(dmaChannel, &chnlCfg);
  810. /* Setting up DMA channel descriptor */
  811. descrCfg.dstInc = dmaDataIncNone;
  812. descrCfg.srcInc = dmaDataInc1;
  813. descrCfg.size = dmaDataSize1;
  814. descrCfg.arbRate = dmaArbitrate1;
  815. descrCfg.hprot = 0;
  816. DMA_CfgDescr(dmaChannel, true, &descrCfg);
  817. }
  818. /* Enable RX and TX pins and set location */
  819. usart->usart_device->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | \
  820. (location << _USART_ROUTE_LOCATION_SHIFT);
  821. if (config & USART_STATE_SYNC)
  822. {
  823. usart->usart_device->ROUTE |= USART_ROUTE_CLKPEN;
  824. }
  825. if (config & USART_STATE_AUTOCS)
  826. {
  827. usart->usart_device->ROUTE |= USART_ROUTE_CSPEN;
  828. if (config & USART_STATE_MASTER)
  829. {
  830. usart->usart_device->CTRL |= USART_CTRL_AUTOCS;
  831. }
  832. }
  833. /* Init specified USART unit */
  834. if (config & USART_STATE_SYNC)
  835. {
  836. init.sync.enable = usartEnable;
  837. init.sync.refFreq = 0;
  838. init.sync.baudrate = SPI_BAUDRATE;
  839. init.sync.databits = usartDatabits8;
  840. if (config & USART_STATE_MASTER)
  841. {
  842. init.sync.master = true;
  843. }
  844. else
  845. {
  846. init.sync.master = false;
  847. }
  848. init.sync.msbf = true;
  849. init.sync.clockMode = usartClockMode0; /* Clock idle low, sample on rising edge. */
  850. USART_InitSync(usart->usart_device, &init.sync);
  851. }
  852. else
  853. {
  854. init.async.enable = usartEnable;
  855. init.async.refFreq = 0;
  856. init.async.baudrate = UART_BAUDRATE;
  857. init.async.oversampling = USART_CTRL_OVS_X4;
  858. init.async.databits = USART_FRAME_DATABITS_EIGHT;
  859. init.async.parity = USART_FRAME_PARITY_NONE;
  860. init.async.stopbits = USART_FRAME_STOPBITS_ONE;
  861. USART_InitAsync(usart->usart_device, &init.async);
  862. }
  863. /* Clear RX/TX buffers */
  864. usart->usart_device->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
  865. return usart;
  866. }
  867. /******************************************************************//**
  868. * @brief
  869. * Initialize all USART module related hardware and register USART device to kernel
  870. *
  871. * @details
  872. *
  873. * @note
  874. *********************************************************************/
  875. void rt_hw_usart_init(void)
  876. {
  877. struct efm32_usart_device_t *usart;
  878. rt_uint32_t flag;
  879. rt_uint8_t config;
  880. /* Register usart0 */
  881. #ifdef RT_USING_USART0
  882. config = 0x00;
  883. flag = RT_DEVICE_FLAG_RDWR;
  884. #ifdef RT_USART0_SYNC_MODE
  885. config |= USART_STATE_SYNC;
  886. #if (RT_USART0_SYNC_MODE != 0x0UL)
  887. config |= USART_STATE_MASTER;
  888. #else
  889. flag |= RT_DEVICE_FLAG_INT_RX;
  890. #endif
  891. #else
  892. flag |= RT_DEVICE_FLAG_INT_RX;
  893. #endif
  894. #if (SPI_AUTOCS_ENABLE & (1 << 0))
  895. config |= USART_STATE_AUTOCS;
  896. #endif
  897. #if (RT_CONSOLE_DEVICE == 0x0UL)
  898. config |= USART_STATE_CONSOLE;
  899. flag |= RT_DEVICE_FLAG_STREAM;
  900. #endif
  901. #ifdef RT_USART0_USING_DMA
  902. RT_ASSERT(RT_USART0_USING_DMA < DMA_CHAN_COUNT);
  903. flag |= RT_DEVICE_FLAG_DMA_TX;
  904. #else
  905. #define RT_USART0_USING_DMA EFM32_NO_DATA
  906. #endif
  907. usart = rt_hw_usart_unit_init(
  908. &usart0_device,
  909. 0,
  910. RT_USING_USART0,
  911. flag,
  912. RT_USART0_USING_DMA,
  913. config);
  914. rt_hw_usart_register(&usart0_device, RT_USART0_NAME, flag, usart);
  915. #endif
  916. /* Register usart1 */
  917. #ifdef RT_USING_USART1
  918. config = 0x00;
  919. flag = RT_DEVICE_FLAG_RDWR;
  920. #ifdef RT_USART1_SYNC_MODE
  921. config |= USART_STATE_SYNC;
  922. #if (RT_USART1_SYNC_MODE != 0x0UL)
  923. config |= USART_STATE_MASTER;
  924. #else
  925. flag |= RT_DEVICE_FLAG_INT_RX;
  926. #endif
  927. #else
  928. flag |= RT_DEVICE_FLAG_INT_RX;
  929. #endif
  930. #if (SPI_AUTOCS_ENABLE & (1 << 1))
  931. config |= USART_STATE_AUTOCS;
  932. #endif
  933. #if (RT_CONSOLE_DEVICE == 0x1UL)
  934. config |= USART_STATE_CONSOLE;
  935. flag |= RT_DEVICE_FLAG_STREAM;
  936. #endif
  937. #ifdef RT_USART1_USING_DMA
  938. RT_ASSERT(RT_USART1_USING_DMA < DMA_CHAN_COUNT);
  939. flag |= RT_DEVICE_FLAG_DMA_TX;
  940. #else
  941. #define RT_USART1_USING_DMA EFM32_NO_DATA
  942. #endif
  943. usart = rt_hw_usart_unit_init(
  944. &usart1_device,
  945. 1,
  946. RT_USING_USART1,
  947. flag,
  948. RT_USART1_USING_DMA,
  949. config);
  950. rt_hw_usart_register(&usart1_device, RT_USART1_NAME, flag, usart);
  951. #endif
  952. /* Register usart2 */
  953. #ifdef RT_USING_USART2
  954. config = 0x00;
  955. flag = RT_DEVICE_FLAG_RDWR;
  956. #ifdef RT_USART2_SYNC_MODE
  957. config |= USART_STATE_SYNC;
  958. #if (RT_USART2_SYNC_MODE != 0x0UL)
  959. config |= USART_STATE_MASTER;
  960. #else
  961. flag |= RT_DEVICE_FLAG_INT_RX;
  962. #endif
  963. #else
  964. flag |= RT_DEVICE_FLAG_INT_RX;
  965. #endif
  966. #if (SPI_AUTOCS_ENABLE & (1 << 2))
  967. config |= USART_STATE_AUTOCS;
  968. #endif
  969. #if (RT_CONSOLE_DEVICE == 0x2UL)
  970. config |= USART_STATE_CONSOLE;
  971. flag |= RT_DEVICE_FLAG_STREAM;
  972. #endif
  973. #ifdef RT_USART2_USING_DMA
  974. RT_ASSERT(RT_USART2_USING_DMA < DMA_CHAN_COUNT);
  975. flag |= RT_DEVICE_FLAG_DMA_TX;
  976. #else
  977. #define RT_USART2_USING_DMA EFM32_NO_DATA
  978. #endif
  979. usart = rt_hw_usart_unit_init(
  980. &usart2_device,
  981. 2,
  982. RT_USING_USART2,
  983. flag,
  984. RT_USART2_USING_DMA,
  985. config);
  986. rt_hw_usart_register(&usart2_device, RT_USART2_NAME, flag, usart);
  987. #endif
  988. }
  989. /******************************************************************//**
  990. * @}
  991. *********************************************************************/