uartdrv.c

Go to the documentation of this file.
00001 /***************************************************************************/
00016 #include <string.h>
00017 
00018 #include "em_device.h"
00019 #include "em_emu.h"
00020 #include "em_gpio.h"
00021 #include "em_int.h"
00022 #include "em_usart.h"
00023 #include "uartdrv.h"
00024 #if defined(EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00025 #include "gpiointerrupt.h"
00026 #endif
00027 
00029 
00030 #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00031 static bool uartdrvHandleIsInitialized = false;
00032 static UARTDRV_Handle_t uartdrvHandle[EMDRV_UARTDRV_MAX_DRIVER_INSTANCES];
00033 #endif
00034 
00035 static bool ReceiveDmaComplete(  unsigned int channel,
00036                                  unsigned int sequenceNo,
00037                                  void *userParam );
00038 static bool TransmitDmaComplete( unsigned int channel,
00039                                  unsigned int sequenceNo,
00040                                  void *userParam );
00041 
00042 /***************************************************************************/
00045 #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00046 static UARTDRV_Handle_t HwFcCtsIrqGetDrvHandle(uint32_t gpioPinNo)
00047 {
00048   uint32_t i;
00049 
00050   for(i = 0; i < EMDRV_UARTDRV_MAX_DRIVER_INSTANCES; i++)
00051   {
00052     if (uartdrvHandle[i]->initData.ctsPin == gpioPinNo)
00053     {
00054       return uartdrvHandle[i];
00055     }
00056   }
00057   return NULL;
00058 }
00059 
00060 
00061 /***************************************************************************/
00064 static UARTDRV_FlowControlState_t HwFcGetClearToSendPin(UARTDRV_Handle_t handle)
00065 {
00066   return (UARTDRV_FlowControlState_t)GPIO_PinInGet(handle->initData.ctsPort, handle->initData.ctsPin);
00067 }
00068 
00069 
00070 /***************************************************************************/
00073 static void HwFcManageClearToSend(uint8_t gpioPinNo)
00074 {
00075   UARTDRV_Handle_t handle = HwFcCtsIrqGetDrvHandle(gpioPinNo);
00076 
00077   if (handle->initData.fcType == uartdrvFlowControlHw)
00078   {
00079     // If not auto mode, just assign the CTS pin state to the self state
00080     // If auto mode, also control UART TX enable
00081     handle->fcSelfState = HwFcGetClearToSendPin(handle);
00082     if (handle->fcSelfCfg == uartdrvFlowControlAuto)
00083     {
00084      if ((HwFcGetClearToSendPin(handle) == uartdrvFlowControlOn) || handle->IgnoreRestrain)
00085       {
00086         handle->IgnoreRestrain = false;
00087         handle->initData.port->CMD = USART_CMD_TXEN;
00088       }
00089       else
00090       {
00091         handle->initData.port->CMD = USART_CMD_TXDIS;
00092       }
00093     }
00094   }
00095 }
00096 
00097 
00098 static Ecode_t FcApplyState(UARTDRV_Handle_t handle)
00099 {
00100   uint8_t FcSwCode;
00101 
00102   if (handle->initData.fcType == uartdrvFlowControlHw)
00103   {
00104     if (handle->fcSelfCfg == uartdrvFlowControlOn)
00105     {
00106       // Assert nRTS (application control)
00107       GPIO_PinOutClear(handle->initData.rtsPort, handle->initData.rtsPin);
00108     }
00109     else if (handle->fcSelfCfg == uartdrvFlowControlOff)
00110     {
00111       // Deassert nRTS (application control)
00112       GPIO_PinOutSet(handle->initData.rtsPort, handle->initData.rtsPin);
00113     }
00114     else // Auto mode
00115     {
00116       if (handle->fcSelfState == uartdrvFlowControlOn)
00117       {
00118         // Assert nRTS
00119         GPIO_PinOutClear(handle->initData.rtsPort, handle->initData.rtsPin);
00120       }
00121       else // Off
00122       {
00123         // Deassert nRTS
00124         GPIO_PinOutSet(handle->initData.rtsPort, handle->initData.rtsPin);
00125       }
00126     }
00127   }
00128   else if (handle->initData.fcType == uartdrvFlowControlSw)
00129   {
00130     if (handle->fcSelfState == uartdrvFlowControlOn)
00131     {
00132       FcSwCode = UARTDRV_FC_SW_XON;
00133       UARTDRV_ForceTransmit(handle, &FcSwCode, 1);
00134     }
00135     else
00136     {
00137       FcSwCode = UARTDRV_FC_SW_XOFF;
00138       UARTDRV_ForceTransmit(handle, &FcSwCode, 1);
00139     }
00140   }
00141   return ECODE_EMDRV_UARTDRV_OK;
00142 }
00143 #endif /* EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE */
00144 
00145 
00146 /***************************************************************************/
00149 static Ecode_t EnqueueBuffer(UARTDRV_Buffer_FifoQueue_t *queue,
00150                              UARTDRV_Buffer_t *inputBuffer,
00151                              UARTDRV_Buffer_t **queueBuffer)
00152 {
00153   INT_Disable();
00154   if (queue->used >= queue->size)
00155   {
00156     *queueBuffer = NULL;
00157     INT_Enable();
00158     return ECODE_EMDRV_UARTDRV_QUEUE_FULL;
00159   }
00160   memcpy((void *)&queue->fifo[queue->head], (const void *)inputBuffer, sizeof(UARTDRV_Buffer_t));
00161   *queueBuffer = &queue->fifo[queue->head];
00162   queue->head = (queue->head + 1) % queue->size;
00163   queue->used++;
00164   INT_Enable();
00165 
00166   return ECODE_EMDRV_UARTDRV_OK;
00167 }
00168 
00169 
00170 /***************************************************************************/
00173 static Ecode_t DequeueBuffer(UARTDRV_Buffer_FifoQueue_t *queue,
00174                              UARTDRV_Buffer_t **buffer)
00175 {
00176   INT_Disable();
00177   if (queue->used == 0)
00178   {
00179     *buffer = NULL;
00180     INT_Enable();
00181     return ECODE_EMDRV_UARTDRV_QUEUE_EMPTY;
00182   }
00183   *buffer = &queue->fifo[queue->tail];
00184   queue->tail = (queue->tail + 1) % queue->size;
00185   queue->used--;
00186   INT_Enable();
00187 
00188   return ECODE_EMDRV_UARTDRV_OK;
00189 }
00190 
00191 
00192 /***************************************************************************/
00195 static Ecode_t GetTailBuffer(UARTDRV_Buffer_FifoQueue_t *queue,
00196                              UARTDRV_Buffer_t **buffer)
00197 {
00198   INT_Disable();
00199   if (queue->used == 0)
00200   {
00201     *buffer = NULL;
00202     INT_Enable();
00203     return ECODE_EMDRV_UARTDRV_QUEUE_EMPTY;
00204   }
00205   *buffer = &queue->fifo[queue->tail];
00206 
00207   INT_Enable();
00208   return ECODE_EMDRV_UARTDRV_OK;
00209 }
00210 
00211 
00212 /***************************************************************************/
00215 static void EnableTransmitter(UARTDRV_Handle_t handle)
00216 {
00217   handle->initData.port->CMD = USART_CMD_TXEN;
00218   while (!(handle->initData.port->STATUS & USART_STATUS_TXENS));
00219   #if defined( USART_ROUTEPEN_TXPEN )
00220   handle->initData.port->ROUTEPEN |= USART_ROUTEPEN_TXPEN;
00221   #else
00222   handle->initData.port->ROUTE |= USART_ROUTE_TXPEN;
00223   #endif
00224 }
00225 
00226 
00227 /***************************************************************************/
00230 static void DisableTransmitter(UARTDRV_Handle_t handle)
00231 {
00232   #if defined( USART_ROUTEPEN_TXPEN )
00233   handle->initData.port->ROUTEPEN &= ~USART_ROUTEPEN_TXPEN;
00234   #else
00235   handle->initData.port->ROUTE &= ~USART_ROUTE_TXPEN;
00236   #endif
00237   handle->initData.port->CMD = USART_CMD_TXDIS;
00238 }
00239 
00240 
00241 /***************************************************************************/
00244 static void EnableReceiver(UARTDRV_Handle_t handle)
00245 {
00246   handle->initData.port->CMD = USART_CMD_RXEN;
00247   while (!(handle->initData.port->STATUS & USART_STATUS_RXENS));
00248   #if defined( USART_ROUTEPEN_RXPEN )
00249   handle->initData.port->ROUTEPEN |= USART_ROUTEPEN_RXPEN;
00250   #else
00251   handle->initData.port->ROUTE |= USART_ROUTE_RXPEN;
00252   #endif
00253 }
00254 
00255 
00256 /***************************************************************************/
00259 static void DisableReceiver(UARTDRV_Handle_t handle)
00260 {
00261   #if defined( USART_ROUTEPEN_RXPEN )
00262   handle->initData.port->ROUTEPEN &= ~USART_ROUTEPEN_RXPEN;
00263   #else
00264   handle->initData.port->ROUTE &= ~USART_ROUTE_RXPEN;
00265   #endif
00266   handle->initData.port->CMD = USART_CMD_RXDIS;
00267 }
00268 
00269 
00270 /***************************************************************************/
00273 static void StartReceiveDma(UARTDRV_Handle_t handle,
00274                             UARTDRV_Buffer_t *buffer)
00275 {
00276   void *rxPort;
00277 
00278   handle->rxDmaActive = true;
00279   rxPort = (void *)&(handle->initData.port->RXDATA);
00280 
00281   DMADRV_PeripheralMemory( handle->rxDmaCh,
00282                            handle->rxDmaSignal,
00283                            buffer->data,
00284                            rxPort,
00285                            true,
00286                            buffer->transferCount,
00287                            dmadrvDataSize1,
00288                            ReceiveDmaComplete,
00289                            handle );
00290 }
00291 
00292 
00293 /***************************************************************************/
00296 static void StartTransmitDma(UARTDRV_Handle_t handle,
00297                              UARTDRV_Buffer_t *buffer)
00298 {
00299   void *txPort;
00300 
00301   handle->txDmaActive = true;
00302   txPort = (void *)&(handle->initData.port->TXDATA);
00303 
00304   DMADRV_MemoryPeripheral( handle->txDmaCh,
00305                            handle->txDmaSignal,
00306                            txPort,
00307                            buffer->data,
00308                            true,
00309                            buffer->transferCount,
00310                            dmadrvDataSize1,
00311                            TransmitDmaComplete,
00312                            handle );
00313 }
00314 
00315 
00316 /***************************************************************************/
00319 static bool ReceiveDmaComplete( unsigned int channel,
00320                                 unsigned int sequenceNo,
00321                                 void *userParam )
00322 {
00323   UARTDRV_Handle_t handle;
00324   UARTDRV_Buffer_t *buffer;
00325   (void)channel;
00326   (void)sequenceNo;
00327 
00328   handle = (UARTDRV_Handle_t)userParam;
00329   GetTailBuffer(handle->rxQueue, &buffer);
00330 
00331   if (handle->initData.port->IF & USART_IF_FERR)
00332   {
00333     buffer->transferStatus = ECODE_EMDRV_UARTDRV_FRAME_ERROR;
00334     buffer->itemsRemaining = buffer->transferCount; // nothing received
00335     handle->initData.port->IFC = USART_IFC_FERR;
00336   }
00337   else if (handle->initData.port->IF & USART_IF_PERR)
00338   {
00339     buffer->transferStatus = ECODE_EMDRV_UARTDRV_PARITY_ERROR;
00340     buffer->itemsRemaining = buffer->transferCount; // nothing received
00341     handle->initData.port->IFC = USART_IFC_PERR;
00342   }
00343   else
00344   {
00345     buffer->transferStatus = ECODE_EMDRV_UARTDRV_OK;
00346     buffer->itemsRemaining = 0;
00347   }
00348 
00349   INT_Disable();
00350 
00351   if (buffer->callback != NULL)
00352   {
00353     buffer->callback(handle, buffer->transferStatus, buffer->data, buffer->transferCount - buffer->itemsRemaining);
00354   }
00355   // Dequeue the current tail RX operation, check if more in queue
00356   DequeueBuffer(handle->rxQueue, &buffer);
00357 
00358   if (handle->rxQueue->used > 0)
00359   {
00360     GetTailBuffer(handle->rxQueue, &buffer);
00361     StartReceiveDma(handle, buffer);
00362   }
00363   else
00364   {
00365     #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00366     handle->fcSelfState = uartdrvFlowControlOff;
00367     FcApplyState(handle);
00368     #endif
00369     handle->rxDmaActive = false;
00370     DisableReceiver(handle);
00371   }
00372   INT_Enable();
00373   return true;
00374 }
00375 
00376 
00377 /***************************************************************************/
00380 static bool TransmitDmaComplete( unsigned int channel,
00381                                  unsigned int sequenceNo,
00382                                  void *userParam )
00383 {
00384   UARTDRV_Handle_t handle;
00385   UARTDRV_Buffer_t *buffer;
00386   (void)channel;
00387   (void)sequenceNo;
00388 
00389   handle = (UARTDRV_Handle_t)userParam;
00390   GetTailBuffer(handle->txQueue, &buffer);
00391 
00392   buffer->transferStatus = ECODE_EMDRV_UARTDRV_OK;
00393   buffer->itemsRemaining = 0;
00394 
00395   INT_Disable();
00396 
00397   if (buffer->callback != NULL)
00398   {
00399     buffer->callback(handle, ECODE_EMDRV_UARTDRV_OK, buffer->data, buffer->transferCount);
00400   }
00401   // Dequeue the current tail TX operation, check if more in queue
00402   DequeueBuffer(handle->txQueue, &buffer);
00403 
00404   if (handle->txQueue->used > 0)
00405   {
00406     GetTailBuffer(handle->txQueue, &buffer);
00407     StartTransmitDma(handle, buffer);
00408   }
00409   else
00410   {
00411     handle->txDmaActive = false;
00412   }
00413   INT_Enable();
00414   return true;
00415 }
00416 
00417 
00418 /***************************************************************************/
00421 static Ecode_t CheckParams(UARTDRV_Handle_t handle, void *data, uint32_t count)
00422 {
00423   if (handle == NULL)
00424   {
00425     return ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE;
00426   }
00427   if ((data == NULL) || (count == 0) || (count > DMADRV_MAX_XFER_COUNT )) {
00428     return ECODE_EMDRV_UARTDRV_PARAM_ERROR;
00429   }
00430   return ECODE_EMDRV_UARTDRV_OK;
00431 }
00432 
00433 
00434 /***************************************************************************/
00437 static Ecode_t ConfigGPIO(UARTDRV_Handle_t handle, bool enable)
00438 {
00439 #if defined( _USART_ROUTELOC0_MASK )
00440   UARTDRV_Init_t *initData;
00441 #else
00442   uint32_t location;
00443 #endif
00444 
00445 #if defined( _USART_ROUTELOC0_MASK )
00446   initData = &handle->initData;
00447 
00448   if ( 0 ) {
00449   #if defined(USARTRF0)
00450   } else if (handle->initData.port == USARTRF0) {
00451     handle->txPort = (GPIO_Port_TypeDef)AF_USARTRF0_TX_PORT( initData->portLocationTx );
00452     handle->rxPort = (GPIO_Port_TypeDef)AF_USARTRF0_RX_PORT( initData->portLocationRx );
00453     handle->txPin  = AF_USARTRF0_TX_PIN( initData->portLocationTx );
00454     handle->rxPin  = AF_USARTRF0_RX_PIN( initData->portLocationRx );
00455   #endif
00456   #if defined(USART0)
00457   } else if (handle->initData.port == USART0) {
00458     handle->txPort = (GPIO_Port_TypeDef)AF_USART0_TX_PORT( initData->portLocationTx );
00459     handle->rxPort = (GPIO_Port_TypeDef)AF_USART0_RX_PORT( initData->portLocationRx );
00460     handle->txPin  = AF_USART0_TX_PIN( initData->portLocationTx );
00461     handle->rxPin  = AF_USART0_RX_PIN( initData->portLocationRx );
00462   #endif
00463   #if defined(USART1)
00464   } else if (handle->initData.port == USART1) {
00465     handle->txPort  = (GPIO_Port_TypeDef)AF_USART1_TX_PORT( initData->portLocationTx );
00466     handle->rxPort  = (GPIO_Port_TypeDef)AF_USART1_RX_PORT( initData->portLocationRx );
00467     handle->txPin   = AF_USART1_TX_PIN( initData->portLocationTx );
00468     handle->rxPin   = AF_USART1_RX_PIN( initData->portLocationRx );
00469   #endif
00470   #if defined(USART2)
00471   } else if (handle->initData.port == USART2) {
00472     handle->txPort  = (GPIO_Port_TypeDef)AF_USART2_TX_PORT( initData->portLocationTx );
00473     handle->rxPort  = (GPIO_Port_TypeDef)AF_USART2_RX_PORT( initData->portLocationRx );
00474     handle->txPin   = AF_USART2_TX_PIN( initData->portLocationTx );
00475     handle->rxPin   = AF_USART2_RX_PIN( initData->portLocationRx );
00476   #endif
00477   #if defined(UART0)
00478   } else if (handle->initData.port == UART0) {
00479     handle->txPort  = (GPIO_Port_TypeDef)AF_UART0_TX_PORT( initData->portLocationTx );
00480     handle->rxPort  = (GPIO_Port_TypeDef)AF_UART0_RX_PORT( initData->portLocationRx );
00481     handle->txPin   = AF_UART0_TX_PIN( initData->portLocationTx );
00482     handle->rxPin   = AF_UART0_RX_PIN( initData->portLocationRx );
00483   #endif
00484   #if defined(UART1)
00485   } else if (handle->initData.port == UART1) {
00486     handle->txPort  = (GPIO_Port_TypeDef)AF_UART1_TX_PORT( initData->portLocationTx );
00487     handle->rxPort  = (GPIO_Port_TypeDef)AF_UART1_RX_PORT( initData->portLocationRx );
00488     handle->txPin   = AF_UART1_TX_PIN( initData->portLocationTx );
00489     handle->rxPin   = AF_UART1_RX_PIN( initData->portLocationRx );
00490   #endif
00491   } else {
00492     return ECODE_EMDRV_UARTDRV_PARAM_ERROR;
00493   }
00494 #else
00495   location = handle->initData.portLocation;
00496 
00497   if ( 0 ) {
00498   #if defined(USART0)
00499   } else if (handle->initData.port == USART0) {
00500     handle->txPort  = (GPIO_Port_TypeDef)AF_USART0_TX_PORT(location);
00501     handle->rxPort  = (GPIO_Port_TypeDef)AF_USART0_RX_PORT(location);
00502     handle->txPin   = AF_USART0_TX_PIN(location);
00503     handle->rxPin   = AF_USART0_RX_PIN(location);
00504   #endif
00505   #if defined(USART1)
00506   } else if (handle->initData.port == USART1) {
00507     handle->txPort  = (GPIO_Port_TypeDef)AF_USART1_TX_PORT(location);
00508     handle->rxPort  = (GPIO_Port_TypeDef)AF_USART1_RX_PORT(location);
00509     handle->txPin   = AF_USART1_TX_PIN(location);
00510     handle->rxPin   = AF_USART1_RX_PIN(location);
00511   #endif
00512   #if defined(USART2)
00513   } else if (handle->initData.port == USART2) {
00514     handle->txPort  = (GPIO_Port_TypeDef)AF_USART2_TX_PORT(location);
00515     handle->rxPort  = (GPIO_Port_TypeDef)AF_USART2_RX_PORT(location);
00516     handle->txPin   = AF_USART2_TX_PIN(location);
00517     handle->rxPin   = AF_USART2_RX_PIN(location);
00518   #endif
00519   #if defined(UART0)
00520   } else if (handle->initData.port == UART0) {
00521     handle->txPort  = (GPIO_Port_TypeDef)AF_UART0_TX_PORT(location);
00522     handle->rxPort  = (GPIO_Port_TypeDef)AF_UART0_RX_PORT(location);
00523     handle->txPin   = AF_UART0_TX_PIN(location);
00524     handle->rxPin   = AF_UART0_RX_PIN(location);
00525   #endif
00526   #if defined(UART1)
00527   } else if (handle->initData.port == UART1) {
00528     handle->txPort  = (GPIO_Port_TypeDef)AF_UART1_TX_PORT(location);
00529     handle->rxPort  = (GPIO_Port_TypeDef)AF_UART1_RX_PORT(location);
00530     handle->txPin   = AF_UART1_TX_PIN(location);
00531     handle->rxPin   = AF_UART1_RX_PIN(location);
00532   #endif
00533   } else {
00534     return ECODE_EMDRV_UARTDRV_PARAM_ERROR;
00535   }
00536 #endif
00537 
00538   if (enable)
00539   {
00540     GPIO_PinModeSet(handle->txPort, handle->txPin, gpioModePushPull, 1);
00541     GPIO_PinModeSet(handle->rxPort, handle->rxPin, gpioModeInput, 0);
00542     #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00543     if (handle->initData.fcType == uartdrvFlowControlHw)
00544     {
00545       GPIO_PinModeSet(handle->initData.ctsPort, handle->initData.ctsPin, gpioModeInput, 0);
00546       GPIO_PinModeSet(handle->initData.rtsPort, handle->initData.rtsPin, gpioModePushPull, 0);
00547       GPIO_IntConfig(handle->initData.ctsPort, handle->initData.ctsPin, true, true, true);
00548     }
00549     #endif
00550   }
00551   else
00552   {
00553     GPIO_PinModeSet(handle->txPort, handle->txPin, gpioModeDisabled, 0);
00554     GPIO_PinModeSet(handle->rxPort, handle->rxPin, gpioModeDisabled, 0);
00555     #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00556     if (handle->initData.fcType == uartdrvFlowControlHw)
00557     {
00558       GPIO_PinModeSet(handle->initData.ctsPort, handle->initData.ctsPin, gpioModeDisabled, 0);
00559       GPIO_PinModeSet(handle->initData.rtsPort, handle->initData.rtsPin, gpioModeDisabled, 0);
00560       GPIO_IntConfig(handle->initData.ctsPort, handle->initData.ctsPin, true, true, false);
00561     }
00562     #endif
00563   }
00564   return ECODE_EMDRV_UARTDRV_OK;
00565 }
00566 
00568 
00569 
00570 /***************************************************************************/
00584 Ecode_t UARTDRV_Init(UARTDRV_Handle_t handle, UARTDRV_Init_t *initData)
00585 {
00586   Ecode_t retVal;
00587   #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00588   uint32_t handleIdx;
00589   bool handleIsSet;
00590   #endif
00591   USART_InitAsync_TypeDef usartInit = USART_INITASYNC_DEFAULT;
00592 
00593 
00594   if (handle == NULL)
00595   {
00596     return ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE;
00597   }
00598   if (initData == NULL)
00599   {
00600     return ECODE_EMDRV_UARTDRV_PARAM_ERROR;
00601   }
00602   memset(handle, 0, sizeof(UARTDRV_HandleData_t));
00603 
00604 
00605   #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00606   // Set handler pointer in handler array
00607   if (!uartdrvHandleIsInitialized)
00608   {
00609     for (handleIdx = 0; handleIdx < EMDRV_UARTDRV_MAX_DRIVER_INSTANCES; handleIdx++)
00610     {
00611       uartdrvHandle[handleIdx] = NULL;
00612     }
00613     uartdrvHandleIsInitialized = true;
00614   }
00615 
00616   handleIsSet = false;
00617   for (handleIdx = 0; handleIdx < EMDRV_UARTDRV_MAX_DRIVER_INSTANCES; handleIdx++)
00618   {
00619     if ((uartdrvHandle[handleIdx] == NULL) || (uartdrvHandle[handleIdx] == handle))
00620     {
00621       uartdrvHandle[handleIdx] = handle;
00622       handleIsSet = true;
00623       break;
00624     }
00625   }
00626 
00627   if (!handleIsSet)
00628   {
00629     return ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE;
00630   }
00631   #else
00632   // Force init data to uartdrvFlowControlNone if flow control is excluded by EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE
00633   handle->initData.fcType = uartdrvFlowControlNone;
00634   #endif
00635 
00636 
00637   // Set clocks and DMA requests according to available peripherals
00638   if (false)
00639   {
00640   #if defined(USART0)
00641   } else if (initData->port == USART0)
00642   {
00643     handle->uartClock   = cmuClock_USART0;
00644     handle->txDmaSignal = dmadrvPeripheralSignal_USART0_TXBL;
00645     handle->rxDmaSignal = dmadrvPeripheralSignal_USART0_RXDATAV;
00646   #endif
00647   #if defined(USART1)
00648   }
00649   else if (initData->port == USART1)
00650   {
00651     handle->uartClock   = cmuClock_USART1;
00652     handle->txDmaSignal = dmadrvPeripheralSignal_USART1_TXBL;
00653     handle->rxDmaSignal = dmadrvPeripheralSignal_USART1_RXDATAV;
00654   #endif
00655   #if defined(USART2)
00656   }
00657   else if (initData->port == USART2)
00658   {
00659     handle->uartClock   = cmuClock_USART2;
00660     handle->txDmaSignal = dmadrvPeripheralSignal_USART2_TXBL;
00661     handle->rxDmaSignal = dmadrvPeripheralSignal_USART2_RXDATAV;
00662   #endif
00663   #if defined(UART0)
00664   }
00665   else if (initData->port == UART0)
00666   {
00667     handle->uartClock   = cmuClock_UART0;
00668     handle->txDmaSignal = dmadrvPeripheralSignal_UART0_TXBL;
00669     handle->rxDmaSignal = dmadrvPeripheralSignal_UART0_RXDATAV;
00670   #endif
00671   #if defined(UART1)
00672   }
00673   else if (initData->port == UART1)
00674   {
00675     handle->uartClock   = cmuClock_UART1;
00676     handle->txDmaSignal = dmadrvPeripheralSignal_UART1_TXBL;
00677     handle->rxDmaSignal = dmadrvPeripheralSignal_UART1_RXDATAV;
00678   #endif
00679   #if defined(UART2)
00680   }
00681   else if (initData->port == UART2)
00682   {
00683     handle->uartClock   = cmuClock_UART2;
00684     handle->txDmaSignal = dmadrvPeripheralSignal_UART2_TXBL;
00685     handle->rxDmaSignal = dmadrvPeripheralSignal_UART2_RXDATAV;
00686   #endif
00687   }
00688   else
00689   {
00690     return ECODE_EMDRV_UARTDRV_PARAM_ERROR;
00691   }
00692 
00693   memcpy((void *)&handle->initData, (const void *)initData, sizeof(UARTDRV_Init_t));
00694   handle->rxQueue = initData->rxQueue;
00695   handle->rxQueue->head = 0;
00696   handle->rxQueue->tail = 0;
00697   handle->rxQueue->used = 0;
00698   handle->rxDmaActive = false;
00699 
00700   handle->txQueue = initData->txQueue;
00701   handle->txQueue->head = 0;
00702   handle->txQueue->tail = 0;
00703   handle->txQueue->used = 0;
00704   handle->txDmaActive = false;
00705 
00706   handle->IgnoreRestrain = false;
00707 
00708   usartInit.baudrate = initData->baudRate;
00709   usartInit.stopbits = initData->stopBits;
00710   usartInit.parity = initData->parity;
00711   usartInit.oversampling = initData->oversampling;
00712 #if defined(USART_CTRL_MVDIS)
00713   usartInit.mvdis = initData->mvdis;
00714 #endif
00715 
00716   // UARTDRV is fixed at 8 bit frames.
00717   usartInit.databits = (USART_Databits_TypeDef)USART_FRAME_DATABITS_EIGHT;
00718 
00719   // Enable clocks
00720   CMU_ClockEnable(cmuClock_HFPER, true);
00721   CMU_ClockEnable(cmuClock_GPIO, true);
00722   CMU_ClockEnable(handle->uartClock, true);
00723 
00724   // Init U(S)ART to default async config.
00725   // RX/TX enable is done on demand
00726   usartInit.enable = usartDisable;
00727   USART_InitAsync(initData->port, &usartInit);
00728 
00729   #if defined( USART_ROUTEPEN_TXPEN )
00730   initData->port->ROUTEPEN = USART_ROUTEPEN_TXPEN
00731                              | USART_ROUTEPEN_RXPEN;
00732   initData->port->ROUTELOC0 = ( initData->port->ROUTELOC0 &
00733                                 ~( _USART_ROUTELOC0_TXLOC_MASK
00734                                    | _USART_ROUTELOC0_RXLOC_MASK ) )
00735                               | ( initData->portLocationTx  << _USART_ROUTELOC0_TXLOC_SHIFT  )
00736                               | ( initData->portLocationRx  << _USART_ROUTELOC0_RXLOC_SHIFT  );
00737   #else
00738   initData->port->ROUTE = USART_ROUTE_TXPEN
00739                         | USART_ROUTE_RXPEN
00740                         | (initData->portLocation
00741                           << _USART_ROUTE_LOCATION_SHIFT);
00742   #endif
00743 
00744   if ((retVal = ConfigGPIO(handle, true)) != ECODE_EMDRV_UARTDRV_OK)
00745   {
00746     return retVal;
00747   }
00748 
00749   INT_Disable();
00750 
00751   // Configure hardware flow control pins and interrupt vectors
00752   #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00753   GPIOINT_Init();
00754   GPIOINT_CallbackRegister(initData->ctsPin, HwFcManageClearToSend);
00755   handle->fcPeerState = uartdrvFlowControlOn;
00756   handle->fcSelfState = uartdrvFlowControlOn;
00757   handle->fcSelfCfg = uartdrvFlowControlAuto;
00758   FcApplyState(handle);
00759   #endif
00760 
00761   // Clear any false IRQ/DMA request
00762   USART_IntClear(initData->port, ~0x0);
00763 
00764   // Enable TX permanently as the TX circuit consumes very little energy.
00765   // RX is enabled on demand as the RX circuit consumes some energy due to
00766   // continuous (over)sampling.
00767   USART_Enable(initData->port, usartEnableTx);
00768 
00769   // Discard false frames and/or IRQs
00770   initData->port->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
00771 
00772   // Initialize DMA.
00773   DMADRV_Init();
00774 
00775   if ( DMADRV_AllocateChannel(&handle->txDmaCh,NULL) != ECODE_EMDRV_DMADRV_OK )
00776   {
00777     INT_Enable();
00778     return ECODE_EMDRV_UARTDRV_DMA_ALLOC_ERROR;
00779   }
00780 
00781   if ( DMADRV_AllocateChannel(&handle->rxDmaCh,NULL) != ECODE_EMDRV_DMADRV_OK )
00782   {
00783     INT_Enable();
00784     return ECODE_EMDRV_UARTDRV_DMA_ALLOC_ERROR;
00785   }
00786 
00787   INT_Enable();
00788   return ECODE_EMDRV_UARTDRV_OK;
00789 }
00790 
00791 
00792 /***************************************************************************/
00802 Ecode_t UARTDRV_DeInit(UARTDRV_Handle_t handle)
00803 {
00804   if (handle == NULL)
00805   {
00806     return ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE;
00807   }
00808   // Stop DMA's.
00809   DMADRV_StopTransfer( handle->rxDmaCh );
00810   DMADRV_StopTransfer( handle->txDmaCh );
00811 
00812   // Do not leave any peer restrained on DeInit
00813   UARTDRV_FlowControlSet(handle, uartdrvFlowControlOn);
00814 
00815   ConfigGPIO(handle, false);
00816 
00817   USART_Reset(handle->initData.port);
00818   handle->initData.port->CMD = USART_CMD_RXDIS;
00819   handle->initData.port->CMD = USART_CMD_TXDIS;
00820 
00821   CMU_ClockEnable(handle->uartClock, false);
00822 
00823   #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
00824   GPIOINT_CallbackRegister(handle->initData.ctsPin, NULL);
00825   #endif
00826 
00827   DMADRV_FreeChannel( handle->txDmaCh );
00828   DMADRV_FreeChannel( handle->rxDmaCh );
00829   DMADRV_DeInit();
00830 
00831   handle->rxQueue->head = 0;
00832   handle->rxQueue->tail = 0;
00833   handle->rxQueue->used = 0;
00834 
00835   handle->txQueue->head = 0;
00836   handle->txQueue->tail = 0;
00837   handle->txQueue->used = 0;
00838 
00839   return ECODE_EMDRV_UARTDRV_OK;
00840 }
00841 
00842 
00843 /***************************************************************************/
00855 Ecode_t UARTDRV_Abort(UARTDRV_Handle_t handle, UARTDRV_AbortType_t type)
00856 {
00857   UARTDRV_Buffer_t *rxBuffer, *txBuffer;
00858 
00859   if (handle == NULL) {
00860     return ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE;
00861   }
00862 
00863   INT_Disable();
00864   if ((type == uartdrvAbortTransmit) && (handle->txQueue->used == 0))
00865   {
00866     INT_Enable();
00867     return ECODE_EMDRV_UARTDRV_IDLE;
00868   }
00869   else if ((type == uartdrvAbortReceive) && (handle->rxQueue->used == 0))
00870   {
00871     INT_Enable();
00872     return ECODE_EMDRV_UARTDRV_IDLE;
00873   }
00874   else if ((type == uartdrvAbortAll) && (handle->txQueue->used == 0)
00875                                      && (handle->rxQueue->used == 0))
00876   {
00877     INT_Enable();
00878     return ECODE_EMDRV_UARTDRV_IDLE;
00879   }
00880 
00881   // Stop DMA's.
00882   if ((type == uartdrvAbortTransmit) || (type == uartdrvAbortAll))
00883   {
00884     GetTailBuffer(handle->txQueue, &txBuffer);
00885     DMADRV_StopTransfer( handle->txDmaCh );
00886     DMADRV_TransferRemainingCount( handle->txDmaCh,
00887                                    (int*)&txBuffer->itemsRemaining );
00888     txBuffer->transferStatus = ECODE_EMDRV_UARTDRV_ABORTED;
00889     if (txBuffer->callback != NULL)
00890     {
00891       txBuffer->callback(handle,
00892                          ECODE_EMDRV_UARTDRV_ABORTED,
00893                          NULL,
00894                          txBuffer->itemsRemaining);
00895     }
00896   }
00897   if ((type == uartdrvAbortReceive) || (type == uartdrvAbortAll))
00898   {
00899     GetTailBuffer(handle->rxQueue, &rxBuffer);
00900     DMADRV_StopTransfer( handle->rxDmaCh );
00901     DMADRV_TransferRemainingCount( handle->rxDmaCh,
00902                                    (int*)&rxBuffer->itemsRemaining );
00903     rxBuffer->transferStatus = ECODE_EMDRV_UARTDRV_ABORTED;
00904     if (rxBuffer->callback != NULL)
00905     {
00906       rxBuffer->callback(handle,
00907                          ECODE_EMDRV_UARTDRV_ABORTED,
00908                          NULL,
00909                          rxBuffer->itemsRemaining);
00910     }
00911   }
00912   INT_Enable();
00913 
00914   return ECODE_EMDRV_UARTDRV_OK;
00915 }
00916 
00917 
00918 /***************************************************************************/
00927 uint8_t UARTDRV_GetReceiveDepth(UARTDRV_Handle_t handle)
00928 {
00929   return (uint8_t)handle->rxQueue->used;
00930 }
00931 
00932 
00933 /***************************************************************************/
00949 UARTDRV_Status_t UARTDRV_GetReceiveStatus(UARTDRV_Handle_t handle,
00950                                           uint8_t **buffer,
00951                                           UARTDRV_Count_t *itemsReceived,
00952                                           UARTDRV_Count_t *itemsRemaining)
00953 {
00954   UARTDRV_Buffer_t *rxBuffer;
00955   uint32_t remaining;
00956 
00957   if (handle->rxQueue->used > 0)
00958   {
00959     GetTailBuffer(handle->rxQueue, &rxBuffer);
00960     DMADRV_TransferRemainingCount( handle->rxDmaCh,
00961                                    (int*)&remaining );
00962 
00963     *itemsReceived = rxBuffer->transferCount - remaining;
00964     *itemsRemaining = remaining;
00965     *buffer = rxBuffer->data;
00966   }
00967   else
00968   {
00969     *itemsRemaining = 0;
00970     *itemsReceived = 0;
00971     *buffer = NULL;
00972   }
00973   return handle->initData.port->STATUS;
00974 }
00975 
00976 
00977 /***************************************************************************/
00986 uint8_t UARTDRV_GetTransmitDepth(UARTDRV_Handle_t handle)
00987 {
00988   return (uint8_t)handle->txQueue->used;
00989 }
00990 
00991 
00992 /***************************************************************************/
01008 UARTDRV_Status_t UARTDRV_GetTransmitStatus(UARTDRV_Handle_t handle,
01009                                            uint8_t **buffer,
01010                                            UARTDRV_Count_t *itemsSent,
01011                                            UARTDRV_Count_t *itemsRemaining)
01012 {
01013   UARTDRV_Buffer_t *txBuffer;
01014   uint32_t remaining;
01015 
01016   if (handle->txQueue->used > 0)
01017   {
01018     GetTailBuffer(handle->txQueue, &txBuffer);
01019     DMADRV_TransferRemainingCount( handle->txDmaCh,
01020                                    (int*)&remaining );
01021 
01022     *itemsSent = txBuffer->transferCount - remaining;
01023     *itemsRemaining = remaining;
01024     *buffer = txBuffer->data;
01025   }
01026   else
01027   {
01028     *itemsRemaining = 0;
01029     *itemsSent = 0;
01030     *buffer = NULL;
01031   }
01032   return handle->initData.port->STATUS;
01033 }
01034 
01035 
01036 /***************************************************************************/
01048 Ecode_t UARTDRV_FlowControlSet(UARTDRV_Handle_t handle, UARTDRV_FlowControlState_t state)
01049 {
01050   #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
01051   handle->fcSelfCfg = state;
01052   if (state != uartdrvFlowControlAuto)
01053   {
01054     handle->fcSelfState = state;
01055   }
01056   return FcApplyState(handle);
01057   #else
01058   return ECODE_EMDRV_UARTDRV_OK;
01059   #endif
01060 }
01061 
01062 
01063 /***************************************************************************/
01072 UARTDRV_FlowControlState_t UARTDRV_FlowControlGetPeerStatus(UARTDRV_Handle_t handle)
01073 {
01074   return handle->fcPeerState;
01075 }
01076 
01077 
01078 /***************************************************************************/
01087 UARTDRV_FlowControlState_t UARTDRV_FlowControlGetSelfStatus(UARTDRV_Handle_t handle)
01088 {
01089   return handle->fcSelfState;
01090 }
01091 
01092 
01093 /***************************************************************************/
01102 Ecode_t UARTDRV_FlowControlIgnoreRestrain(UARTDRV_Handle_t handle)
01103 {
01104   handle->IgnoreRestrain = true;
01105 
01106   return ECODE_EMDRV_UARTDRV_OK;
01107 }
01108 
01109 
01110 /***************************************************************************/
01123 UARTDRV_Count_t UARTDRV_ForceReceive(UARTDRV_Handle_t handle,
01124                                       uint8_t *data,
01125                                       UARTDRV_Count_t maxCount)
01126 {
01127   Ecode_t retVal;
01128   uint32_t rxState;
01129   UARTDRV_Count_t i = 0;
01130 
01131   retVal = CheckParams(handle, data, maxCount);
01132   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01133   {
01134     return 0;
01135   }
01136 
01137   // Wait for DMA receive to complete and clear
01138   while(handle->rxQueue->used > 0);
01139 
01140   rxState = (handle->initData.port->STATUS & USART_STATUS_RXENS);
01141   if (!rxState)
01142   {
01143     EnableReceiver(handle);
01144   }
01145 
01146   while ((handle->initData.port->STATUS & USART_STATUS_RXDATAV))
01147   {
01148     *data = (uint8_t)handle->initData.port->RXDATA;
01149     data++;
01150     i++;
01151     if (i >= maxCount)
01152     {
01153       break;
01154     }
01155   }
01156   data -= i;
01157 
01158   if (!rxState)
01159   {
01160     DisableReceiver(handle);
01161   }
01162   return i;
01163 }
01164 
01165 
01166 /***************************************************************************/
01180 Ecode_t  UARTDRV_ForceTransmit(UARTDRV_Handle_t handle,
01181                                uint8_t *data,
01182                                UARTDRV_Count_t count)
01183 {
01184   Ecode_t retVal;
01185   uint32_t txState;
01186 
01187   retVal = CheckParams(handle, data, count);
01188   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01189   {
01190     return retVal;
01191   }
01192 
01193   // Wait for DMA transmit to complete and clear
01194   while(handle->txQueue->used > 0);
01195 
01196   txState = (handle->initData.port->STATUS & USART_STATUS_TXENS);
01197   if (!txState)
01198   {
01199     EnableTransmitter(handle);
01200   }
01201 
01202   while (count--)
01203   {
01204     while (!(handle->initData.port->STATUS & USART_STATUS_TXBL));
01205     handle->initData.port->TXDATA = *data;
01206     data++;
01207   }
01208   while (!(handle->initData.port->STATUS & USART_STATUS_TXC));
01209 
01210   if (!txState)
01211   {
01212     DisableTransmitter(handle);
01213   }
01214 
01215   return ECODE_EMDRV_UARTDRV_OK;
01216 }
01217 
01218 
01219 /***************************************************************************/
01234 Ecode_t UARTDRV_Receive(UARTDRV_Handle_t handle,
01235                         uint8_t *data,
01236                         UARTDRV_Count_t count,
01237                         UARTDRV_Callback_t callback)
01238 {
01239   Ecode_t retVal;
01240   UARTDRV_Buffer_t outputBuffer;
01241   UARTDRV_Buffer_t *queueBuffer;
01242 
01243   retVal = CheckParams(handle, data, count);
01244   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01245   {
01246     return retVal;
01247   }
01248   outputBuffer.data = data;
01249   outputBuffer.transferCount = count;
01250   outputBuffer.itemsRemaining = count;
01251   outputBuffer.callback = callback;
01252   outputBuffer.transferStatus = ECODE_EMDRV_UARTDRV_WAITING;
01253 
01254   retVal = EnqueueBuffer(handle->rxQueue, &outputBuffer, &queueBuffer);
01255   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01256   {
01257     return retVal;
01258   }
01259   if (!(handle->rxDmaActive))
01260   {
01261     EnableReceiver(handle);
01262     StartReceiveDma(handle, queueBuffer);
01263     #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
01264     handle->fcSelfState = uartdrvFlowControlOn;
01265     FcApplyState(handle);
01266     #endif
01267   } // else: started by ReceiveDmaComplete
01268 
01269   return ECODE_EMDRV_UARTDRV_OK;
01270 }
01271 
01272 
01273 /***************************************************************************/
01286 Ecode_t UARTDRV_ReceiveB(UARTDRV_Handle_t handle,
01287                    uint8_t *data,
01288                    UARTDRV_Count_t count)
01289 {
01290   Ecode_t retVal;
01291   UARTDRV_Buffer_t inputBuffer;
01292   UARTDRV_Buffer_t *queueBuffer;
01293 
01294   retVal = CheckParams(handle, data, count);
01295   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01296   {
01297     return retVal;
01298   }
01299   inputBuffer.data = data;
01300   inputBuffer.transferCount = count;
01301   inputBuffer.itemsRemaining = count;
01302   inputBuffer.callback = NULL;
01303   inputBuffer.transferStatus = ECODE_EMDRV_UARTDRV_WAITING;
01304 
01305   retVal = EnqueueBuffer(handle->rxQueue, &inputBuffer, &queueBuffer);
01306   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01307   {
01308     return retVal;
01309   }
01310   while(handle->rxQueue->used > 1)
01311   {
01312     EMU_EnterEM1();
01313   }
01314   EnableReceiver(handle);
01315   #if (EMDRV_UARTDRV_HW_FLOW_CONTROL_ENABLE)
01316   handle->fcSelfState = uartdrvFlowControlOn;
01317   FcApplyState(handle);
01318   #endif
01319   StartReceiveDma(handle, queueBuffer);
01320   while(handle->rxDmaActive)
01321   {
01322     EMU_EnterEM1();
01323   }
01324   return queueBuffer->transferStatus;
01325 }
01326 
01327 
01328 /***************************************************************************/
01343 Ecode_t UARTDRV_Transmit(UARTDRV_Handle_t handle,
01344                          uint8_t *data,
01345                          UARTDRV_Count_t count,
01346                          UARTDRV_Callback_t callback)
01347 {
01348   Ecode_t retVal;
01349   UARTDRV_Buffer_t inputBuffer;
01350   UARTDRV_Buffer_t *queueBuffer;
01351 
01352   retVal = CheckParams(handle, data, count);
01353   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01354   {
01355     return retVal;
01356   }
01357   inputBuffer.data = data;
01358   inputBuffer.transferCount = count;
01359   inputBuffer.itemsRemaining = count;
01360   inputBuffer.callback = callback;
01361   inputBuffer.transferStatus = ECODE_EMDRV_UARTDRV_WAITING;
01362 
01363   retVal = EnqueueBuffer(handle->txQueue, &inputBuffer, &queueBuffer);
01364   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01365   {
01366     return retVal;
01367   }
01368   if (!(handle->txDmaActive))
01369   {
01370     StartTransmitDma(handle, queueBuffer);
01371   } // else: started by TransmitDmaComplete
01372 
01373   return ECODE_EMDRV_UARTDRV_OK;
01374 }
01375 
01376 
01377 /***************************************************************************/
01390 Ecode_t UARTDRV_TransmitB(UARTDRV_Handle_t handle,
01391                           uint8_t *data,
01392                           UARTDRV_Count_t count)
01393 {
01394   Ecode_t retVal;
01395   UARTDRV_Buffer_t outputBuffer;
01396   UARTDRV_Buffer_t *queueBuffer;
01397 
01398   retVal = CheckParams(handle, data, count);
01399   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01400   {
01401     return retVal;
01402   }
01403   outputBuffer.data = data;
01404   outputBuffer.transferCount = count;
01405   outputBuffer.itemsRemaining = count;
01406   outputBuffer.callback = NULL;
01407   outputBuffer.transferStatus = ECODE_EMDRV_UARTDRV_WAITING;
01408 
01409   retVal = EnqueueBuffer(handle->txQueue, &outputBuffer, &queueBuffer);
01410   if (retVal != ECODE_EMDRV_UARTDRV_OK)
01411   {
01412     return retVal;
01413   }
01414   while(handle->txQueue->used > 1)
01415   {
01416     EMU_EnterEM1();
01417   }
01418   StartTransmitDma(handle, queueBuffer);
01419   while(handle->txDmaActive)
01420   {
01421     EMU_EnterEM1();
01422   }
01423   return queueBuffer->transferStatus;
01424 }
01425 
01426 
01427 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/