12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670 |
- /***************************************************************************//**
- * @file drv_usart.c
- * @brief USART driver of RT-Thread RTOS for EFM32
- * COPYRIGHT (C) 2012, RT-Thread Development Team
- * @author onelife
- * @version 1.0
- *******************************************************************************
- * @section License
- * The license and distribution terms for this file may be found in the file
- * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE
- *******************************************************************************
- * @section Change Logs of serial.c
- * Date Author Notes
- * 2009-02-05 Bernard first version
- * 2009-10-25 Bernard fix rt_serial_read bug when there is no data in the
- * buffer.
- * 2010-03-29 Bernard cleanup code.
- *
- * @section Change Logs
- * Date Author Notes
- * 2010-12-22 onelife Initial creation for EFM32
- * 2011-01-17 onelife Merge with serial.c
- * 2011-05-06 onelife Add sync mode (SPI) support
- * 2011-06-14 onelife Fix a bug of TX by DMA
- * 2011-06-16 onelife Modify init function for EFM32 library v2.0.0
- * upgrading
- * 2011-07-07 onelife Modify write function to avoid sleep in ISR
- * 2011-07-26 onelife Add lock (semaphore) to prevent simultaneously
- * access
- * 2011-11-29 onelife Modify init function for EFM32 library v2.2.2
- * upgrading
- * 2011-12-09 onelife Add giant gecko support
- * 2011-12-09 onelife Add UART module support
- * 2011-12-20 onelife Add 9-bit SPI mode support
- * 2011-12-20 onelife Change SPI write format (same as SPI read)
- * 2011-12-20 onelife Change USART status format
- * 2011-12-27 onelife Utilize "USART_PRESENT", "USART_COUNT",
- * "UART_PRESENT" and "UART_COUNT"
- * 2012-05-16 onelife Fix a bug in rt_hw_usart_init()
- ******************************************************************************/
- /***************************************************************************//**
- * @addtogroup efm32
- * @{
- ******************************************************************************/
- /* Includes ------------------------------------------------------------------*/
- #include "board.h"
- #include "hdl_interrupt.h"
- #include "drv_usart.h"
- #if (defined(RT_USING_USART0) || defined(RT_USING_USART1) || \
- defined(RT_USING_USART2) || defined(RT_USING_UART0) || \
- defined(RT_USING_UART1))
- #if ((defined(RT_USING_USART0) || defined(RT_USING_USART1) || \
- defined(RT_USING_USART2)) && !defined(USART_PRESENT))
- #error "USART module is not available"
- #endif
- #if ((defined(RT_USING_UART0) || defined(RT_USING_UART1)) && \
- !defined(UART_PRESENT))
- #error "UART module is not available"
- #endif
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- #ifdef RT_USART_DEBUG
- #define usart_debug(format,args...) rt_kprintf(format, ##args)
- #else
- #define usart_debug(format,args...)
- #endif
- /* Private variables ---------------------------------------------------------*/
- #ifdef RT_USING_USART0
- #if (RT_USING_USART0 >= EFM32_USART_LOCATION_COUNT)
- #error "Wrong location number"
- #endif
- struct rt_device usart0_device;
- static struct rt_semaphore usart0_lock;
- #endif
- #ifdef RT_USING_USART1
- #if (USART_COUNT <= 1)
- #error "Wrong unit number"
- #endif
- #if (RT_USING_USART1 >= EFM32_USART_LOCATION_COUNT)
- #error "Wrong location number"
- #endif
- struct rt_device usart1_device;
- static struct rt_semaphore usart1_lock;
- #endif
- #ifdef RT_USING_USART2
- #if (USART_COUNT <= 2)
- #error "Wrong unit number"
- #endif
- #if (RT_USING_USART2 >= EFM32_USART_LOCATION_COUNT)
- #error "Wrong location number"
- #endif
- struct rt_device usart2_device;
- static struct rt_semaphore usart2_lock;
- #endif
- #ifdef RT_USING_UART0
- #if (RT_USING_UART0 >= EFM32_UART_LOCATION_COUNT)
- #error "Wrong location number"
- #endif
- struct rt_device uart0_device;
- static struct rt_semaphore uart0_lock;
- #endif
- #ifdef RT_USING_UART1
- #if (UART_COUNT <= 1)
- #error "Wrong unit number"
- #endif
- #if (RT_USING_UART1 >= EFM32_UART_LOCATION_COUNT)
- #error "Wrong location number"
- #endif
- struct rt_device uart1_device;
- static struct rt_semaphore uart1_lock;
- #endif
- /* Private function prototypes -----------------------------------------------*/
- /* Private functions ---------------------------------------------------------*/
- /***************************************************************************//**
- * @brief
- * Initialize USART device
- *
- * @details
- *
- * @note
- *
- * @param[in] dev
- * Pointer to device descriptor
- *
- * @return
- * Error code
- ******************************************************************************/
- static rt_err_t rt_usart_init (rt_device_t dev)
- {
- struct efm32_usart_device_t *usart;
- usart = (struct efm32_usart_device_t *)(dev->user_data);
- if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
- {
- if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
- {
- struct efm32_usart_dma_mode_t *dma_tx;
- dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
- usart->state |= USART_STATE_RX_BUSY;
- }
- if (dev->flag & RT_DEVICE_FLAG_INT_RX)
- {
- struct efm32_usart_int_mode_t *int_rx;
- int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
- int_rx->data_ptr = RT_NULL;
- }
- /* Enable USART */
- USART_Enable(usart->usart_device, usartEnable);
- dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
- }
- return RT_EOK;
- }
- /***************************************************************************//**
- * @brief
- * Open USART device
- *
- * @details
- *
- * @note
- *
- * @param[in] dev
- * Pointer to device descriptor
- *
- * @param[in] oflag
- * Device open flag
- *
- * @return
- * Error code
- ******************************************************************************/
- static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
- {
- RT_ASSERT(dev != RT_NULL);
- struct efm32_usart_device_t *usart;
- usart = (struct efm32_usart_device_t *)(dev->user_data);
- if (dev->flag & RT_DEVICE_FLAG_INT_RX)
- {
- IRQn_Type rxIrq;
- //if (usart->state & USART_STATE_CONSOLE)
- { /* Allocate new RX buffer */
- struct efm32_usart_int_mode_t *int_mode;
- int_mode = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
- if ((int_mode->data_ptr = rt_malloc(USART_RX_BUFFER_SIZE)) == RT_NULL)
- {
- usart_debug("USART%d err: no mem for RX BUF\n", usart->unit);
- return -RT_ENOMEM;
- }
- rt_memset(int_mode->data_ptr, 0, USART_RX_BUFFER_SIZE);
- int_mode->data_size = USART_RX_BUFFER_SIZE;
- int_mode->read_index = 0;
- int_mode->save_index = 0;
- }
- /* Enable RX interrupt */
- #if defined(UART_PRESENT)
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- usart->usart_device->IEN = UART_IEN_RXDATAV;
- }
- else
- #endif
- {
- usart->usart_device->IEN = USART_IEN_RXDATAV;
- }
- /* Enable IRQ */
- switch (usart->unit)
- {
- case 0:
- #if defined(UART_PRESENT)
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- rxIrq = UART0_RX_IRQn;
- }
- else
- #endif
- {
- rxIrq = USART0_RX_IRQn;
- }
- break;
- #if ((defined(USART_PRESENT) && (USART_COUNT > 1)) || \
- (defined(UART_PRESENT) && (UART_COUNT > 1)))
- case 1:
- #if (defined(UART_PRESENT) && (UART_COUNT > 1))
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- rxIrq = UART1_RX_IRQn;
- }
- else
- #endif
- {
- rxIrq = USART1_RX_IRQn;
- }
- break;
- #endif
- #if ((defined(USART_PRESENT) && (USART_COUNT > 2)) || \
- (defined(UART_PRESENT) && (UART_COUNT > 2)))
- case 2:
- #if (defined(UART_PRESENT) && (UART_COUNT > 2))
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- rxIrq = UART2_RX_IRQn;
- }
- else
- #endif
- {
- rxIrq = USART2_RX_IRQn;
- }
- break;
- #endif
- }
- if (oflag != RT_DEVICE_OFLAG_WRONLY)
- {
- NVIC_ClearPendingIRQ(rxIrq);
- NVIC_SetPriority(rxIrq, EFM32_IRQ_PRI_DEFAULT);
- NVIC_EnableIRQ(rxIrq);
- }
- }
- /* Clear Flag */
- #if defined(UART_PRESENT)
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- usart->usart_device->IFC = _UART_IFC_MASK;
- }
- else
- #endif
- {
- usart->usart_device->IFC = _USART_IFC_MASK;
- }
- if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (oflag != RT_DEVICE_OFLAG_RDONLY))
- {
- /* DMA IRQ is enabled by DMA_Init() */
- NVIC_SetPriority(DMA_IRQn, EFM32_IRQ_PRI_DEFAULT);
- }
- usart->counter++;
- usart_debug("USART%d: Open with flag %x\n", usart->unit, oflag);
- return RT_EOK;
- }
- /***************************************************************************//**
- * @brief
- * Close USART device
- *
- * @details
- *
- * @note
- *
- * @param[in] dev
- * Pointer to device descriptor
- *
- * @return
- * Error code
- ******************************************************************************/
- static rt_err_t rt_usart_close(rt_device_t dev)
- {
- RT_ASSERT(dev != RT_NULL);
- struct efm32_usart_device_t *usart;
- usart = (struct efm32_usart_device_t *)(dev->user_data);
- if (--usart->counter == 0)
- {
- if (dev->flag & RT_DEVICE_FLAG_INT_RX)
- {
- struct efm32_usart_int_mode_t *int_rx;
- int_rx = (struct efm32_usart_int_mode_t *)usart->rx_mode;
- rt_free(int_rx->data_ptr);
- int_rx->data_ptr = RT_NULL;
- }
- }
- return RT_EOK;
- }
- /***************************************************************************//**
- * @brief
- * Read from USART device
- *
- * @details
- *
- * @note
- * 9-bit SPI mode and SPI slave mode is untested
- *
- * @param[in] dev
- * Pointer to device descriptor
- *
- * @param[in] pos
- * Offset
- *
- * @param[in] buffer
- * Poniter to the buffer
- *
- * @param[in] size
- * Buffer size in byte
- *
- * @return
- * Number of read bytes
- ******************************************************************************/
- static rt_size_t rt_usart_read (
- rt_device_t dev,
- rt_off_t pos,
- void *buffer,
- rt_size_t size)
- {
- rt_err_t err_code;
- struct efm32_usart_device_t *usart;
- rt_size_t read_len, len;
- rt_uint8_t *ptr;
- rt_uint32_t rx_flag, tx_flag, b8_flag;
- usart = (struct efm32_usart_device_t *)(dev->user_data);
- #if defined(UART_PRESENT)
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- rx_flag = UART_STATUS_RXDATAV;
- tx_flag = UART_STATUS_TXBL;
- b8_flag = UART_CTRL_BIT8DV;
- }
- else
- #endif
- {
- rx_flag = USART_STATUS_RXDATAV;
- tx_flag = USART_STATUS_TXBL;
- b8_flag = USART_CTRL_BIT8DV;
- }
- /* Lock device */
- if (rt_hw_interrupt_check())
- {
- err_code = rt_sem_take(usart->lock, RT_WAITING_NO);
- }
- else
- {
- err_code = rt_sem_take(usart->lock, RT_WAITING_FOREVER);
- }
- if (err_code != RT_EOK)
- {
- rt_set_errno(err_code);
- return 0;
- }
- if (dev->flag & RT_DEVICE_FLAG_INT_RX)
- {
- len = size;
- ptr = buffer;
- /* interrupt mode Rx */
- while (len)
- {
- rt_base_t level;
- struct efm32_usart_int_mode_t *int_rx;
- int_rx = (struct efm32_usart_int_mode_t *)\
- (((struct efm32_usart_device_t *)(dev->user_data))->rx_mode);
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
- if (int_rx->read_index != int_rx->save_index)
- {
- /* read a character */
- *ptr++ = int_rx->data_ptr[int_rx->read_index];
- len--;
- /* move to next position */
- int_rx->read_index ++;
- if (int_rx->read_index >= USART_RX_BUFFER_SIZE)
- {
- int_rx->read_index = 0;
- }
- }
- else
- {
- /* set error code */
- err_code = -RT_EEMPTY;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
- break;
- }
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
- }
- read_len = (rt_uint32_t)ptr - (rt_uint32_t)buffer;
- }
- else
- {
- if (usart->state & USART_STATE_SYNC)
- {
- /* SPI read */
- rt_uint8_t inst_len = *((rt_uint8_t *)buffer);
- rt_uint8_t *inst_ptr = (rt_uint8_t *)(buffer + 1);
- rt_uint8_t *rx_buf = *((rt_uint8_t **)(buffer + inst_len + 1));
- rt_off_t i;
- ptr = inst_ptr;
- len = inst_len;
- /* Write instructions */
- if (len)
- {
- if (usart->state & USART_STATE_9BIT)
- {
- usart->usart_device->CTRL &= ~b8_flag;
- }
- while (len)
- {
- while (!(usart->usart_device->STATUS & tx_flag));
- usart->usart_device->TXDATA = (rt_uint32_t)*(ptr++);
- len--;
- }
- if (usart->state & USART_STATE_9BIT)
- {
- usart->usart_device->CTRL |= b8_flag;
- }
- }
- /* Flushing RX */
- usart->usart_device->CMD = USART_CMD_CLEARRX;
- /* Skip some bytes if necessary */
- for (i = 0; i < pos; i++)
- {
- /* dummy write */
- while (!(usart->usart_device->STATUS & tx_flag));
- usart->usart_device->TXDATA = (rt_uint32_t)0xff;
- /* dummy read */
- while (!(usart->usart_device->STATUS & rx_flag));
- *((rt_uint32_t *)0x00) = usart->usart_device->RXDATA;
- }
- ptr = rx_buf;
- len = size;
- /* Read data */
- while (len)
- {
- /* dummy write */
- while (!(usart->usart_device->STATUS & tx_flag));
- usart->usart_device->TXDATA = (rt_uint32_t)0xff;
- /* read a byte of data */
- while (!(usart->usart_device->STATUS & rx_flag));
- *(ptr++) = usart->usart_device->RXDATA & 0xff;
- len--;
- }
- }
- else
- {
- ptr = buffer;
- len = size;
- /* polling mode */
- while (len)
- {
- while (usart->usart_device->STATUS & rx_flag)
- {
- *(ptr++) = usart->usart_device->RXDATA & 0xff;
- }
- len--;
- }
- }
- read_len = size - len;
- }
- /* Unlock device */
- rt_sem_release(usart->lock);
- /* set error code */
- rt_set_errno(err_code);
- return read_len;
- }
- /***************************************************************************//**
- * @brief
- * Write to USART device
- *
- * @details
- *
- * @note
- *
- * @param[in] dev
- * Pointer to device descriptor
- *
- * @param[in] pos
- * Offset
- *
- * @param[in] buffer
- * Poniter to the buffer
- *
- * @param[in] size
- * Buffer size in byte
- *
- * @return
- * Number of written bytes
- ******************************************************************************/
- static rt_size_t rt_usart_write (
- rt_device_t dev,
- rt_off_t pos,
- const void* buffer,
- rt_size_t size)
- {
- rt_err_t err_code;
- struct efm32_usart_device_t* usart = (struct efm32_usart_device_t*)(dev->user_data);
- rt_size_t read_len, len;
- rt_uint8_t *ptr;
- rt_size_t write_size = 0;
- rt_uint32_t tx_flag, b8_flag;
- #if defined(UART_PRESENT)
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- tx_flag = UART_STATUS_TXBL;
- b8_flag = UART_CTRL_BIT8DV;
- }
- else
- #endif
- {
- tx_flag = USART_STATUS_TXBL;
- b8_flag = USART_CTRL_BIT8DV;
- }
- /* Lock device */
- if (rt_hw_interrupt_check())
- {
- err_code = rt_sem_take(usart->lock, RT_WAITING_NO);
- }
- else
- {
- err_code = rt_sem_take(usart->lock, RT_WAITING_FOREVER);
- }
- if (err_code != RT_EOK)
- {
- rt_set_errno(err_code);
- return 0;
- }
- if (usart->state & USART_STATE_SYNC)
- { /* SPI write */
- rt_uint8_t inst_len = *((rt_uint8_t *)buffer);
- rt_uint8_t *inst_ptr = (rt_uint8_t *)(buffer + 1);
- rt_uint8_t *tx_buf = *((rt_uint8_t **)(buffer + inst_len + 1));
- ptr = inst_ptr;
- len = inst_len;
- /* Write instructions */
- if (len)
- {
- if (usart->state & USART_STATE_9BIT)
- {
- usart->usart_device->CTRL &= ~b8_flag;
- }
- if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (len > 2))
- { /* DMA mode Tx */
- struct efm32_usart_dma_mode_t *dma_tx;
- usart_debug("USART: DMA TX INS (%d)\n", len);
- dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
- dma_tx->data_ptr = (rt_uint32_t *)ptr;
- dma_tx->data_size = len;
- usart->state |= USART_STATE_TX_BUSY;
- DMA_ActivateBasic(
- dma_tx->dma_channel,
- true,
- false,
- (void *)&(usart->usart_device->TXDATA),
- (void *)ptr,
- (rt_uint32_t)(len - 1));
- /* Wait, otherwise the TX buffer is overwrite */
- // TODO: This function blocks the process => goto low power mode?
- // if (usart->state & USART_STATE_CONSOLE)
- // {
- while(usart->state & USART_STATE_TX_BUSY);
- // }
- // else
- // {
- // while(usart->state & USART_STATE_TX_BUSY)
- // {
- // rt_thread_sleep(USART_WAIT_TIME_TX);
- // }
- // }
- }
- else
- { /* polling mode */
- usart_debug("USART: Polling TX INS (%d)\n", len);
- while (len)
- {
- while (!(usart->usart_device->STATUS & tx_flag));
- usart->usart_device->TXDATA = (rt_uint32_t)*(ptr++);
- len--;
- }
- }
- if (usart->state & USART_STATE_9BIT)
- {
- usart->usart_device->CTRL |= b8_flag;
- }
- }
- ptr = tx_buf;
- }
- else
- {
- ptr = (rt_uint8_t *)buffer;
- }
- len = size;
- /* Write data */
- if (dev->flag & RT_DEVICE_FLAG_STREAM)
- {
- if (*(ptr + len - 1) == '\n')
- {
- *(ptr + len - 1) = '\r';
- *(ptr + len++) = '\n';
- *(ptr + len) = 0;
- }
- }
- if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (len > 2))
- { /* DMA mode Tx */
- struct efm32_usart_dma_mode_t *dma_tx;
- usart_debug("USART: DMA TX data (%d)\n", len);
- dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
- dma_tx->data_ptr = (rt_uint32_t *)ptr;
- dma_tx->data_size = len;
- usart->state |= USART_STATE_TX_BUSY;
- DMA_ActivateBasic(
- dma_tx->dma_channel,
- true,
- false,
- (void *)&(usart->usart_device->TXDATA),
- (void *)ptr,
- (rt_uint32_t)(len - 1));
- /* Wait, otherwise the TX buffer is overwrite */
- // TODO: This function blocks the process => goto low power mode?
- // if (usart->state & USART_STATE_CONSOLE)
- // {
- while(usart->state & USART_STATE_TX_BUSY);
- // }
- // else
- // {
- // while(usart->state & USART_STATE_TX_BUSY)
- // {
- // rt_thread_sleep(USART_WAIT_TIME_TX);
- // }
- // }
- write_size = size;
- }
- else
- { /* polling mode */
- usart_debug("USART: Polling TX data (%d)\n", len);
- while (len)
- {
- while (!(usart->usart_device->STATUS & tx_flag));
- usart->usart_device->TXDATA = (rt_uint32_t)*(ptr++);
- len--;
- }
- write_size = size - len;
- }
- /* Unlock device */
- rt_sem_release(usart->lock);
- /* set error code */
- rt_set_errno(err_code);
- return write_size;
- }
- /***************************************************************************//**
- * @brief
- * Configure USART device
- *
- * @details
- *
- * @note
- *
- * @param[in] dev
- * Pointer to device descriptor
- *
- * @param[in] cmd
- * IIC control command
- *
- * @param[in] args
- * Arguments
- *
- * @return
- * Error code
- ******************************************************************************/
- static rt_err_t rt_usart_control (
- rt_device_t dev,
- rt_uint8_t cmd,
- void *args)
- {
- RT_ASSERT(dev != RT_NULL);
- rt_err_t err_code;
- struct efm32_usart_device_t *usart;
- usart = (struct efm32_usart_device_t *)(dev->user_data);
- /* Lock device */
- if (rt_hw_interrupt_check())
- {
- err_code = rt_sem_take(usart->lock, RT_WAITING_NO);
- }
- else
- {
- err_code = rt_sem_take(usart->lock, RT_WAITING_FOREVER);
- }
- if (err_code != RT_EOK)
- {
- return err_code;
- }
- switch (cmd)
- {
- case RT_DEVICE_CTRL_SUSPEND:
- /* Suspend device */
- dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
- USART_Enable(usart->usart_device, usartDisable);
- break;
- case RT_DEVICE_CTRL_RESUME:
- /* Resume device */
- dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
- USART_Enable(usart->usart_device, usartEnable);
- break;
- case RT_DEVICE_CTRL_USART_RBUFFER:
- /* Set RX buffer */
- {
- struct efm32_usart_int_mode_t *int_rx;
- rt_uint8_t size;
- int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
- size = (rt_uint8_t)((rt_uint32_t)args & 0xFFUL);
- /* Free previous RX buffer */
- if (int_rx->data_ptr != RT_NULL)
- {
- if (size == 0)
- { /* Free RX buffer */
- rt_free(int_rx->data_ptr);
- int_rx->data_ptr = RT_NULL;
- }
- else if (size != int_rx->data_size)
- {
- /* Re-allocate RX buffer */
- if ((int_rx->data_ptr = rt_realloc(int_rx->data_ptr, size)) \
- == RT_NULL)
- {
- usart_debug("USART%d err: no mem for RX BUF\n", usart->unit);
- err_code = -RT_ENOMEM;
- break;
- }
- // TODO: Is the following line necessary?
- //rt_memset(int_rx->data_ptr, 0, size);
- }
- }
- else
- {
- /* Allocate new RX buffer */
- if ((int_rx->data_ptr = rt_malloc(size)) == RT_NULL)
- {
- usart_debug("USART%d err: no mem for RX BUF\n", usart->unit);
- err_code = -RT_ENOMEM;
- break;
- }
- }
- int_rx->data_size = size;
- int_rx->read_index = 0;
- int_rx->save_index = 0;
- }
- break;
- }
- /* Unlock device */
- rt_sem_release(usart->lock);
- return err_code;
- }
- /***************************************************************************//**
- * @brief
- * USART RX data valid interrupt handler
- *
- * @details
- *
- * @note
- * 9-bit SPI mode has not implemented yet and SPI slave mode is untested
- *
- * @param[in] dev
- * Pointer to device descriptor
- ******************************************************************************/
- void rt_hw_usart_rx_isr(rt_device_t dev)
- {
- struct efm32_usart_device_t *usart;
- struct efm32_usart_int_mode_t *int_rx;
- rt_uint32_t flag;
- /* interrupt mode receive */
- RT_ASSERT(dev->flag & RT_DEVICE_FLAG_INT_RX);
- usart = (struct efm32_usart_device_t *)(dev->user_data);
- int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
- RT_ASSERT(int_rx->data_ptr != RT_NULL);
- #if defined(UART_PRESENT)
- if (usart->state & USART_STATE_ASYNC_ONLY)
- {
- flag = UART_STATUS_RXDATAV;
- }
- else
- #endif
- {
- flag = USART_STATUS_RXDATAV;
- }
- /* Set status */
- usart->state |= USART_STATE_RX_BUSY;
- /* save into rx buffer */
- while (usart->usart_device->STATUS & flag)
- {
- rt_base_t level;
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
- /* save character */
- int_rx->data_ptr[int_rx->save_index] = \
- (rt_uint8_t)(usart->usart_device->RXDATA & 0xFFUL);
- int_rx->save_index ++;
- if (int_rx->save_index >= USART_RX_BUFFER_SIZE)
- int_rx->save_index = 0;
- /* if the next position is read index, discard this 'read char' */
- if (int_rx->save_index == int_rx->read_index)
- {
- int_rx->read_index ++;
- if (int_rx->read_index >= USART_RX_BUFFER_SIZE)
- {
- int_rx->read_index = 0;
- }
- }
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
- }
- /* invoke callback */
- if (dev->rx_indicate != RT_NULL)
- {
- rt_size_t rx_length;
- /* get rx length */
- rx_length = int_rx->read_index > int_rx->save_index ?
- USART_RX_BUFFER_SIZE - int_rx->read_index + int_rx->save_index : \
- int_rx->save_index - int_rx->read_index;
- dev->rx_indicate(dev, rx_length);
- }
- }
- /***************************************************************************//**
- * @brief
- * DMA for USART TX interrupt handler
- *
- * @details
- *
- * @note
- *
- * @param[in] dev
- * Pointer to device descriptor
- ******************************************************************************/
- void rt_hw_usart_dma_tx_isr(rt_device_t dev)
- {
- /* DMA mode receive */
- struct efm32_usart_device_t *usart;
- struct efm32_usart_dma_mode_t *dma_tx;
- RT_ASSERT(dev->flag & RT_DEVICE_FLAG_DMA_TX);
- usart = (struct efm32_usart_device_t *)(dev->user_data);
- dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
- /* invoke call to notify tx complete */
- if (dev->tx_complete != RT_NULL)
- {
- dev->tx_complete(dev, dma_tx->data_ptr);
- }
- /* Set status */
- usart->state &= ~(rt_uint32_t)USART_STATE_TX_BUSY;
- }
- /***************************************************************************//**
- * @brief
- * Register USART device
- *
- * @details
- *
- * @note
- *
- * @param[in] device
- * Pointer to device descriptor
- *
- * @param[in] name
- * Device name
- *
- * @param[in] flag
- * Configuration flags
- *
- * @param[in] usart
- * Pointer to USART device descriptor
- *
- * @return
- * Error code
- ******************************************************************************/
- rt_err_t rt_hw_usart_register(
- rt_device_t device,
- const char *name,
- rt_uint32_t flag,
- struct efm32_usart_device_t *usart)
- {
- RT_ASSERT(device != RT_NULL);
- if ((flag & RT_DEVICE_FLAG_DMA_RX) ||
- (flag & RT_DEVICE_FLAG_INT_TX))
- {
- RT_ASSERT(0);
- }
- if (usart->state & USART_STATE_SYNC)
- {
- device->type = RT_Device_Class_SPIBUS;
- }
- else
- {
- device->type = RT_Device_Class_Char;
- }
- device->rx_indicate = RT_NULL;
- device->tx_complete = RT_NULL;
- device->init = rt_usart_init;
- device->open = rt_usart_open;
- device->close = rt_usart_close;
- device->read = rt_usart_read;
- device->write = rt_usart_write;
- device->control = rt_usart_control;
- device->user_data = usart;
- /* register a character device */
- return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
- }
- /***************************************************************************//**
- * @brief
- * Initialize the specified USART unit
- *
- * @details
- *
- * @note
- *
- * @param[in] device
- * Pointer to device descriptor
- *
- * @param[in] unitNumber
- * Unit number
- *
- * @param[in] location
- * Pin location number
- *
- * @param[in] flag
- * Configuration flag
- *
- * @param[in] dmaChannel
- * DMA channel number for TX
- *
- * @param[in] console
- * Indicate if using as console
- *
- * @return
- * Pointer to USART device
- ******************************************************************************/
- static struct efm32_usart_device_t *rt_hw_usart_unit_init(
- rt_device_t device,
- rt_uint8_t unitNumber,
- rt_uint8_t location,
- rt_uint32_t flag,
- rt_uint32_t dmaChannel,
- rt_uint8_t config)
- {
- struct efm32_usart_device_t *usart;
- struct efm32_usart_dma_mode_t *dma_mode;
- DMA_CB_TypeDef *callback;
- CMU_Clock_TypeDef usartClock;
- rt_uint32_t txDmaSelect;
- GPIO_Port_TypeDef port_tx, port_rx, port_clk, port_cs;
- rt_uint32_t pin_tx, pin_rx, pin_clk, pin_cs;
- efm32_irq_hook_init_t hook;
- do
- {
- /* Allocate device */
- usart = rt_malloc(sizeof(struct efm32_usart_device_t));
- if (usart == RT_NULL)
- {
- usart_debug("USART%d err: no mem\n", usart->unit);
- break;
- }
- usart->counter = 0;
- usart->unit = unitNumber;
- usart->state = config;
- usart->tx_mode = RT_NULL;
- usart->rx_mode = RT_NULL;
- /* Allocate TX */
- dma_mode = RT_NULL;
- if (flag & RT_DEVICE_FLAG_DMA_TX)
- {
- usart->tx_mode = dma_mode = rt_malloc(sizeof(struct efm32_usart_dma_mode_t));
- if (dma_mode == RT_NULL)
- {
- usart_debug("USART%d err: no mem for DMA TX\n", usart->unit);
- break;
- }
- dma_mode->dma_channel = dmaChannel;
- }
- /* Allocate RX */
- if (flag & RT_DEVICE_FLAG_INT_RX)
- {
- usart->rx_mode = rt_malloc(sizeof(struct efm32_usart_int_mode_t));
- if (usart->rx_mode == RT_NULL)
- {
- usart_debug("USART%d err: no mem for INT RX\n", usart->unit);
- break;
- }
- }
- /* Initialization */
- #if defined(UART_PRESENT)
- if ((!(config & USART_STATE_ASYNC_ONLY) && (unitNumber >= USART_COUNT)) || \
- ((config & USART_STATE_ASYNC_ONLY) && (unitNumber >= UART_COUNT)))
- #else
- if (unitNumber >= USART_COUNT)
- #endif
- {
- break;
- }
- switch (unitNumber)
- {
- case 0:
- #if defined(UART_PRESENT)
- if (config & USART_STATE_ASYNC_ONLY)
- {
- usart->usart_device = UART0;
- usartClock = (CMU_Clock_TypeDef)cmuClock_UART0;
- txDmaSelect = DMAREQ_UART0_TXBL;
- port_tx = AF_UART0_TX_PORT(location);
- pin_tx = AF_UART0_TX_PIN(location);
- port_rx = AF_UART0_RX_PORT(location);
- pin_rx = AF_UART0_RX_PIN(location);
- }
- else
- #endif
- {
- usart->usart_device = USART0;
- usartClock = (CMU_Clock_TypeDef)cmuClock_USART0;
- txDmaSelect = DMAREQ_USART0_TXBL;
- port_tx = AF_USART0_TX_PORT(location);
- pin_tx = AF_USART0_TX_PIN(location);
- port_rx = AF_USART0_RX_PORT(location);
- pin_rx = AF_USART0_RX_PIN(location);
- port_clk = AF_USART0_CLK_PORT(location);
- pin_clk = AF_USART0_CLK_PIN(location);
- port_cs = AF_USART0_CS_PORT(location);
- pin_cs = AF_USART0_CS_PIN(location);
- }
- break;
- #if ((defined(USART_PRESENT) && (USART_COUNT > 1)) || \
- (defined(UART_PRESENT) && (UART_COUNT > 1)))
- case 1:
- #if (defined(UART_PRESENT) && (UART_COUNT > 1))
- if (config & USART_STATE_ASYNC_ONLY)
- {
- usart->usart_device = UART1;
- usartClock = (CMU_Clock_TypeDef)cmuClock_UART1;
- txDmaSelect = DMAREQ_UART1_TXBL;
- port_tx = AF_UART1_TX_PORT(location);
- pin_tx = AF_UART1_TX_PIN(location);
- port_rx = AF_UART1_RX_PORT(location);
- pin_rx = AF_UART1_RX_PIN(location);
- }
- else
- #endif
- {
- usart->usart_device = USART1;
- usartClock = (CMU_Clock_TypeDef)cmuClock_USART1;
- txDmaSelect = DMAREQ_USART1_TXBL;
- port_tx = AF_USART1_TX_PORT(location);
- pin_tx = AF_USART1_TX_PIN(location);
- port_rx = AF_USART1_RX_PORT(location);
- pin_rx = AF_USART1_RX_PIN(location);
- port_clk = AF_USART1_CLK_PORT(location);
- pin_clk = AF_USART1_CLK_PIN(location);
- port_cs = AF_USART1_CS_PORT(location);
- pin_cs = AF_USART1_CS_PIN(location);
- }
- break;
- #endif
- #if ((defined(USART_PRESENT) && (USART_COUNT > 2)) || \
- (defined(UART_PRESENT) && (UART_COUNT > 2)))
- case 2:
- #if (defined(UART_PRESENT) && (UART_COUNT > 2))
- if (config & USART_STATE_ASYNC_ONLY)
- {
- usart->usart_device = UART2;
- usartClock = (CMU_Clock_TypeDef)cmuClock_UART2;
- txDmaSelect = DMAREQ_UART2_TXBL;
- port_tx = AF_UART2_TX_PORT(location);
- pin_tx = AF_UART2_TX_PIN(location);
- port_rx = AF_UART2_RX_PORT(location);
- pin_rx = AF_UART2_RX_PIN(location);
- }
- else
- #endif
- {
- usart->usart_device = USART2;
- usartClock = (CMU_Clock_TypeDef)cmuClock_USART2;
- txDmaSelect = DMAREQ_USART2_TXBL;
- port_tx = AF_USART2_TX_PORT(location);
- pin_tx = AF_USART2_TX_PIN(location);
- port_rx = AF_USART2_RX_PORT(location);
- pin_rx = AF_USART2_RX_PIN(location);
- port_clk = AF_USART2_CLK_PORT(location);
- pin_clk = AF_USART2_CLK_PIN(location);
- port_cs = AF_USART2_CS_PORT(location);
- pin_cs = AF_USART2_CS_PIN(location);
- }
- break;
- #endif
- default:
- break;
- }
- /* Enable USART clock */
- CMU_ClockEnable(usartClock, true);
- /* Config GPIO */
- GPIO_PinModeSet(
- port_tx,
- pin_tx,
- gpioModePushPull,
- 0);
- GPIO_PinModeSet(
- port_rx,
- pin_rx,
- gpioModeInputPull,
- 1);
- if (config & USART_STATE_SYNC)
- {
- GPIO_PinModeSet(
- port_clk,
- pin_clk,
- gpioModePushPull,
- 0);
- }
- if (config & USART_STATE_AUTOCS)
- {
- GPIO_PinModeSet(
- port_cs,
- pin_cs,
- gpioModePushPull,
- 1);
- }
- /* Config interrupt and NVIC */
- if (flag & RT_DEVICE_FLAG_INT_RX)
- {
- hook.type = efm32_irq_type_usart;
- hook.unit = unitNumber * 2 + 1;
- #if defined(UART_PRESENT)
- if (config & USART_STATE_ASYNC_ONLY)
- {
- hook.unit += USART_COUNT * 2;
- }
- #endif
- hook.cbFunc = rt_hw_usart_rx_isr;
- hook.userPtr = device;
- efm32_irq_hook_register(&hook);
- }
- /* Config DMA */
- if (flag & RT_DEVICE_FLAG_DMA_TX)
- {
- DMA_CfgChannel_TypeDef chnlCfg;
- DMA_CfgDescr_TypeDef descrCfg;
- hook.type = efm32_irq_type_dma;
- hook.unit = dmaChannel;
- hook.cbFunc = rt_hw_usart_dma_tx_isr;
- hook.userPtr = device;
- efm32_irq_hook_register(&hook);
- callback = (DMA_CB_TypeDef *)rt_malloc(sizeof(DMA_CB_TypeDef));
- if (callback == RT_NULL)
- {
- usart_debug("USART%d err: no mem for callback\n", usart->unit);
- break;
- }
- callback->cbFunc = DMA_IRQHandler_All;
- callback->userPtr = RT_NULL;
- callback->primary = 0;
- /* Setting up DMA channel */
- chnlCfg.highPri = false; /* Can't use with peripherals */
- chnlCfg.enableInt = true; /* Interrupt for callback function */
- chnlCfg.select = txDmaSelect;
- chnlCfg.cb = callback;
- DMA_CfgChannel(dmaChannel, &chnlCfg);
- /* Setting up DMA channel descriptor */
- descrCfg.dstInc = dmaDataIncNone;
- descrCfg.srcInc = dmaDataInc1;
- descrCfg.size = dmaDataSize1;
- descrCfg.arbRate = dmaArbitrate1;
- descrCfg.hprot = 0;
- DMA_CfgDescr(dmaChannel, true, &descrCfg);
- }
- /* Init specified USART unit */
- if (config & USART_STATE_SYNC)
- {
- USART_InitSync_TypeDef init_sync = USART_INITSYNC_DEFAULT;
- init_sync.enable = usartEnable;
- init_sync.refFreq = 0;
- init_sync.baudrate = SPI_BAUDRATE;
- if (config & USART_STATE_9BIT)
- {
- init_sync.databits = usartDatabits9;
- }
- else
- {
- init_sync.databits = usartDatabits8;
- }
- if (config & USART_STATE_MASTER)
- {
- init_sync.master = true;
- }
- else
- {
- init_sync.master = false;
- }
- init_sync.msbf = true;
- switch (USART_CLK_MODE_GET(config))
- {
- case 0:
- init_sync.clockMode = usartClockMode0;
- break;
- case 1:
- init_sync.clockMode = usartClockMode1;
- break;
- case 2:
- init_sync.clockMode = usartClockMode2;
- break;
- case 3:
- init_sync.clockMode = usartClockMode3;
- break;
- }
- USART_InitSync(usart->usart_device, &init_sync);
- }
- else
- {
- USART_InitAsync_TypeDef init_async = USART_INITASYNC_DEFAULT;
- init_async.enable = usartEnable;
- init_async.refFreq = 0;
- init_async.baudrate = UART_BAUDRATE;
- init_async.oversampling = USART_CTRL_OVS_X4;
- init_async.databits = USART_FRAME_DATABITS_EIGHT;
- init_async.parity = USART_FRAME_PARITY_NONE;
- init_async.stopbits = USART_FRAME_STOPBITS_ONE;
- USART_InitAsync(usart->usart_device, &init_async);
- }
- /* Enable RX and TX pins and set location */
- usart->usart_device->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | \
- (location << _USART_ROUTE_LOCATION_SHIFT);
- if (config & USART_STATE_SYNC)
- {
- usart->usart_device->ROUTE |= USART_ROUTE_CLKPEN;
- }
- if (config & USART_STATE_AUTOCS)
- {
- usart->usart_device->ROUTE |= USART_ROUTE_CSPEN;
- if (config & USART_STATE_MASTER)
- {
- usart->usart_device->CTRL |= USART_CTRL_AUTOCS;
- }
- }
- /* Clear RX/TX buffers */
- usart->usart_device->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
- return usart;
- } while(0);
- if (usart->rx_mode)
- {
- rt_free(usart->rx_mode);
- }
- if (usart->tx_mode)
- {
- rt_free(usart->tx_mode);
- }
- if (usart)
- {
- rt_free(usart);
- }
- if (callback)
- {
- rt_free(callback);
- }
- #if defined(UART_PRESENT)
- if (config & USART_STATE_ASYNC_ONLY)
- {
- usart_debug("UART%d err: init failed!\n", unitNumber);
- }
- else
- #endif
- {
- usart_debug("USART%d err: init failed!\n", unitNumber);
- }
- return RT_NULL;
- }
- /***************************************************************************//**
- * @brief
- * Initialize all USART module related hardware and register USART device to
- * kernel
- *
- * @details
- *
- * @note
- ******************************************************************************/
- void rt_hw_usart_init(void)
- {
- struct efm32_usart_device_t *usart;
- rt_uint32_t flag;
- rt_uint8_t config;
- do
- {
- #if (defined(USART_PRESENT) && defined(RT_USING_USART0))
- config = 0x00;
- flag = RT_DEVICE_FLAG_RDWR;
- #ifdef RT_USART0_SYNC_MODE
- config |= USART_STATE_SYNC;
- config |= (RT_USART0_SYNC_MODE & SYNC_SETTING_MASK) << SYNC_SETTING_SHIFT;
- #if (!((RT_USART0_SYNC_MODE << SYNC_SETTING_SHIFT) & USART_STATE_MASTER))
- flag |= RT_DEVICE_FLAG_INT_RX;
- #endif
- #else
- flag |= RT_DEVICE_FLAG_INT_RX;
- #endif
- #if (RT_CONSOLE_DEVICE == EFM_USART0)
- config |= USART_STATE_CONSOLE;
- flag |= RT_DEVICE_FLAG_STREAM;
- #endif
- #ifdef RT_USART0_USING_DMA
- RT_ASSERT(RT_USART0_USING_DMA < DMA_CHAN_COUNT);
- flag |= RT_DEVICE_FLAG_DMA_TX;
- #else
- #define RT_USART0_USING_DMA EFM32_NO_DMA
- #endif
- /* Initialize and Register usart0 */
- if ((usart = rt_hw_usart_unit_init(
- &usart0_device,
- 0,
- RT_USING_USART0,
- flag,
- RT_USART0_USING_DMA,
- config)) != RT_NULL)
- {
- rt_hw_usart_register(&usart0_device, RT_USART0_NAME, flag, usart);
- }
- else
- {
- break;
- }
- /* Initialize lock for usart0 */
- usart->lock = &usart0_lock;
- if (rt_sem_init(usart->lock, RT_USART0_NAME, 1, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- break;
- }
- #endif
- #if (defined(USART_PRESENT) && (USART_COUNT > 1) && defined(RT_USING_USART1))
- config = 0x00;
- flag = RT_DEVICE_FLAG_RDWR;
- #ifdef RT_USART1_SYNC_MODE
- config |= USART_STATE_SYNC;
- config |= (RT_USART1_SYNC_MODE & SYNC_SETTING_MASK) << SYNC_SETTING_SHIFT;
- #if (!((RT_USART1_SYNC_MODE << SYNC_SETTING_SHIFT) & USART_STATE_MASTER))
- flag |= RT_DEVICE_FLAG_INT_RX;
- #endif
- #else
- flag |= RT_DEVICE_FLAG_INT_RX;
- #endif
- #if (RT_CONSOLE_DEVICE == EFM_USART1)
- config |= USART_STATE_CONSOLE;
- flag |= RT_DEVICE_FLAG_STREAM;
- #endif
- #ifdef RT_USART1_USING_DMA
- RT_ASSERT(RT_USART1_USING_DMA < DMA_CHAN_COUNT);
- flag |= RT_DEVICE_FLAG_DMA_TX;
- #else
- #define RT_USART1_USING_DMA EFM32_NO_DMA
- #endif
- /* Initialize and Register usart1 */
- if ((usart = rt_hw_usart_unit_init(
- &usart1_device,
- 1,
- RT_USING_USART1,
- flag,
- RT_USART1_USING_DMA,
- config)) != RT_NULL)
- {
- rt_hw_usart_register(&usart1_device, RT_USART1_NAME, flag, usart);
- }
- else
- {
- break;
- }
- /* Initialize lock for usart1 */
- usart->lock = &usart1_lock;
- if (rt_sem_init(usart->lock, RT_USART1_NAME, 1, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- break;
- }
- #endif
- #if (defined(USART_PRESENT) && (USART_COUNT > 2) && defined(RT_USING_USART2))
- config = 0x00;
- flag = RT_DEVICE_FLAG_RDWR;
- #ifdef RT_USART2_SYNC_MODE
- config |= USART_STATE_SYNC;
- config |= (RT_USART2_SYNC_MODE & SYNC_SETTING_MASK) << SYNC_SETTING_SHIFT;
- #if (!((RT_USART2_SYNC_MODE << SYNC_SETTING_SHIFT) & USART_STATE_MASTER))
- flag |= RT_DEVICE_FLAG_INT_RX;
- #endif
- #else
- flag |= RT_DEVICE_FLAG_INT_RX;
- #endif
- #if (RT_CONSOLE_DEVICE == EFM_USART2)
- config |= USART_STATE_CONSOLE;
- flag |= RT_DEVICE_FLAG_STREAM;
- #endif
- #ifdef RT_USART2_USING_DMA
- RT_ASSERT(RT_USART2_USING_DMA < DMA_CHAN_COUNT);
- flag |= RT_DEVICE_FLAG_DMA_TX;
- #else
- #define RT_USART2_USING_DMA EFM32_NO_DMA
- #endif
- /* Initialize and Register usart2 */
- if ((usart = rt_hw_usart_unit_init(
- &usart2_device,
- 2,
- RT_USING_USART2,
- flag,
- RT_USART2_USING_DMA,
- config)) != RT_NULL)
- {
- rt_hw_usart_register(&usart2_device, RT_USART2_NAME, flag, usart);
- }
- else
- {
- break;
- }
- /* Initialize lock for usart2 */
- usart->lock = &usart2_lock;
- if (rt_sem_init(usart->lock, RT_USART2_NAME, 1, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- break;
- }
- #endif
- #if (defined(UART_PRESENT) && defined(RT_USING_UART0))
- config = USART_STATE_ASYNC_ONLY;
- flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
- #if (RT_CONSOLE_DEVICE == EFM_UART0)
- config |= USART_STATE_CONSOLE;
- flag |= RT_DEVICE_FLAG_STREAM;
- #endif
- #ifdef RT_UART0_USING_DMA
- RT_ASSERT(RT_UART0_USING_DMA < DMA_CHAN_COUNT);
- flag |= RT_DEVICE_FLAG_DMA_TX;
- #else
- #define RT_UART0_USING_DMA EFM32_NO_DMA
- #endif
- /* Initialize and Register uart0 */
- if ((usart = rt_hw_usart_unit_init(
- &uart0_device,
- 0,
- RT_USING_UART0,
- flag,
- RT_UART0_USING_DMA,
- config)) != RT_NULL)
- {
- rt_hw_usart_register(&uart0_device, RT_UART0_NAME, flag, usart);
- }
- else
- {
- break;
- }
- /* Initialize lock for uart0 */
- usart->lock = &uart0_lock;
- if (rt_sem_init(usart->lock, RT_UART0_NAME, 1, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- break;
- }
- #endif
- #if (defined(UART_PRESENT) && (UART_COUNT > 1) && defined(RT_USING_UART1))
- config = USART_STATE_ASYNC_ONLY;
- flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
- #if (RT_CONSOLE_DEVICE == EFM_UART1)
- config |= USART_STATE_CONSOLE;
- flag |= RT_DEVICE_FLAG_STREAM;
- #endif
- #ifdef RT_UART1_USING_DMA
- RT_ASSERT(RT_UART1_USING_DMA < DMA_CHAN_COUNT);
- flag |= RT_DEVICE_FLAG_DMA_TX;
- #else
- #define RT_UART1_USING_DMA EFM32_NO_DMA
- #endif
- /* Initialize and Register uart1 */
- if ((usart = rt_hw_usart_unit_init(
- &uart1_device,
- 1,
- RT_USING_UART1,
- flag,
- RT_UART1_USING_DMA,
- config)) != RT_NULL)
- {
- rt_hw_usart_register(&uart1_device, RT_UART1_NAME, flag, usart);
- }
- else
- {
- break;
- }
- /* Initialize lock for uart1 */
- usart->lock = &uart1_lock;
- if (rt_sem_init(usart->lock, RT_UART1_NAME, 1, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- break;
- }
- #endif
- usart_debug("USART: H/W init OK!\n");
- return;
- } while (0);
- rt_kprintf("USART: H/W init failed!\n");
- }
- #endif /* (defined(RT_USING_USART0) || defined(RT_USING_USART1) || \
- defined(RT_USING_USART2) || defined(RT_USING_UART0) || \
- defined(RT_USING_UART1)) */
- /***************************************************************************//**
- * @}
- ******************************************************************************/
|