drv_usart.c 30 KB

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