📄 uart_drv.c
字号:
/*****************************************************************************
* All the SCI hardware related functions are implemented in this file
*
*
* (c) Copyright 2006, Freescale, Inc. All rights reserved.
*
* Freescale Confidential Proprietary
*
* No part of this document must be reproduced in any form - including copied,
* transcribed, printed or by any electronic means - without specific written
* permission from Freescale Semiconductor Danmark A/S.
*****************************************************************************/
#include "UART_Interface.h"
#include "TMR_Interface.h"
#if (gUART_Enabled_d == 1)
#if ((gUART_OnSCI1_d == 1) || (gUART_OnSCI2_d == 1))
/*****************************************************************************
******************************************************************************
* Private macros
******************************************************************************
*****************************************************************************/
/* Enable / disable Tx interrupt */
#define SCIx_EnableTxInts() { SCIxC2 |= gUART_TxInterrupt_c; }
#define SCIx_DisableTxInts() { SCIxC2 &= ~gUART_TxInterrupt_c; }
/* Enable / disable Rx interrupt */
#define SCIx_EnableRxInts() { SCIxC2 |= 0x20; }
#define SCIx_DisableRxInts() { SCIxC2 &= 0xDF; }
/* The UART task handles the following events: */
enum {
mTxSuccessEvent_c = 0x01,
mRxSuccessEvent_c = 0x02,
mRxTimeoutEvent_c = 0x04,
mRxWaterMarkEvent_c = 0x08,
};
/*****************************************************************************
******************************************************************************
* Private prototypes
******************************************************************************
*****************************************************************************/
/* Timeout handler for the UART */
void UART_Timeout(uint8_t timerId);
/*****************************************************************************
******************************************************************************
* Private type definitions
******************************************************************************
*****************************************************************************/
/*****************************************************************************
******************************************************************************
* Private memory declarations
******************************************************************************
*****************************************************************************/
/* FIFO (implemented as circular buffer) */
static uint8_t maFIFO[gUART_FIFOLen_c];
static uint8_t mhFIFO = 0, mtFIFO = 0; /* Head and tail in FIFO */
/* For backup until request is complete */
static irp_t *mpRxIrp = NULL, *mpTxIrp = NULL;
/* Counts the transmit data */
static uint8_t mcTx;
/* Counts the receiving data */
static uint8_t mcRx;
/* Dynamic water mark */
static uint8_t mFIFOWaterMark;
/*****************************************************************************
******************************************************************************
* Public function definitions
******************************************************************************
*****************************************************************************/
/*****************************************************************************
* The callback function that handle the timeout.
*
* Interface assumptions:
* Arguments:
* taskId - ID of receiving task
*
* Return value:
* None
*
* Revision history:
* date Author Comments
* ------ ------ --------
* 240406 AL,FSL Updated
*****************************************************************************/
void UART_Timeout(uint8_t timerId)
{
(void)timerId; /* To avoid compiler warning */
/* Signal to UART task that a timeout happened */
TS_SendEvent(gUartTaskID_c, mRxTimeoutEvent_c);
}
/****************************************************************************
* The UART task that copies data, manages timeouts, notifies the application
* callback function etc.
*
* Interface assumptions:
*
* Arguments:
* events - Bit mask.
*
* Return value:
* None
*
* Revision history:
* date Author Comments
* ------ ------ --------
* 240406 AL,FSL Updated
*****************************************************************************/
void UART_Main(event_t events)
{
uint8_t cHead; /* Backup of head pointer in FIFO */
#if (gUART_ReinitEnabled_d == 1)
irp_t *pIrp;
#endif
/* Check why the task is run */
/*--------------------------------------------------------------------------*/
if (events & mTxSuccessEvent_c) {
/* Call the users callback function with gUartTxSuccess_c response */
mpTxIrp->returnValue = gUartTxSuccess_c;
#if (gUART_ReinitEnabled_d == 1)
pIrp = mpTxIrp;
mpTxIrp = NULL; /* No Tx IRP pending anymore */
pIrp->reqData.rxtxParams.pfCallback(pIrp);
#else
pIrp->reqData.rxtxParams.pfCallback(mpTxIrp);
#endif
}
/*--------------------------------------------------------------------------*/
if (events & mRxWaterMarkEvent_c) {
/* We need to continue receiving in the FIFO instead of disabling the */
/* interrupt. If not, we may get data loss in between the application */
/* processing a completed Rx Irp and sending a new Rx Irp */
/* Check if we have an Irp for receiving */
if (NULL == mpRxIrp) {
/* No Irp for receiving, throw away data from FIFO: Data loss! */
mhFIFO = mtFIFO = 0; /* Head and tail in FIFO */
return;
}
/* Stop the timer */
TMR_StopTimer(gUART_TimerID_c);
cHead = mhFIFO;
/* Copy all the data from the buffer */
while ((cHead != mtFIFO) && (mcRx < mpRxIrp->reqData.rxtxParams.len)) {
mpRxIrp->reqData.rxtxParams.pBuffer[mcRx++]= maFIFO[mtFIFO++];
if (mtFIFO == gUART_FIFOLen_c) {
mtFIFO = 0;
}
} /* End while */
/* if the user buffer is full send a mRxSuccessEvent_c event */
if ( mcRx == mpRxIrp->reqData.rxtxParams.len ) {
TS_SendEvent(gUartTaskID_c, mRxSuccessEvent_c);
}
else {
/* Change the water mark */
if (( mpRxIrp->reqData.rxtxParams.len - mcRx ) < gUART_FIFOWaterMark_c) {
mFIFOWaterMark = mpRxIrp->reqData.rxtxParams.len - mcRx;
}
/* Restart the timer */
TMR_StartTimer(gUART_TimerID_c, gUART_RxTimeout_c, UART_Timeout);
/* Enable the Rx interrupt and enable the flow control */
EnableFlow();
}
}
/*--------------------------------------------------------------------------*/
if (events & mRxSuccessEvent_c) {
TMR_StopTimer(gUART_TimerID_c);
/* Call the Callback function with gUartRxSuccess_c response */
mpRxIrp->returnValue = gUartRxSuccess_c;
pIrp = mpRxIrp;
mpRxIrp = NULL; /* No Rx IRP pending anymore */
pIrp->reqData.rxtxParams.pfCallback( pIrp );
}
/*--------------------------------------------------------------------------*/
if (events & mRxTimeoutEvent_c) {
/* Is the FIFO empty? */
if ( mhFIFO == mtFIFO ) {
/* Yes, give the application whatever has already been received */
DisableFlow();
TMR_StopTimer(gUART_TimerID_c);
/* Call the Callback function with gUartRxTimeout_c response
and return the length */
mpRxIrp->reqData.rxtxParams.len = mcRx;
mpRxIrp->returnValue = gUartRxTimeout_c;
pIrp = mpRxIrp;
mpRxIrp = NULL; /* No Rx IRP pending anymore */
pIrp->reqData.rxtxParams.pfCallback( pIrp );
}
else {
/* Empty the buffer */
while (( mhFIFO != mtFIFO ) &&
( mcRx < mpRxIrp->reqData.rxtxParams.len )) {
mpRxIrp->reqData.rxtxParams.pBuffer[mcRx++]= maFIFO[mtFIFO++];
if ( mtFIFO == gUART_FIFOLen_c ) {
mtFIFO = 0;
}
} /* End while */
/* If the user buffer is full send a mRxSuccessEvent_c event */
if ( mcRx == mpRxIrp->reqData.rxtxParams.len ) {
TS_SendEvent(gUartTaskID_c, mRxSuccessEvent_c);
/* Disable the flow control */
DisableFlow();
}
else {
/* Restart the timer */
TMR_StartTimer(gUART_TimerID_c, gUART_RxTimeout_c, UART_Timeout);
}
} /* End else */
}
}
/*****************************************************************************
* Handles the application requests. Requests are submitted using Irp's (IO
* request packets). The Irp's can be allocated on the stack or on the heap,
* however, when the Irp contains a request of the types gRxUart_c or gTxUart_c
* the Irp must be allocated on the heap as the Irp is later returned to the
* application.
*
* Interface assumptions:
* The parameters are placed on the heap for gTxUart_c and gRxUart_c requests.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -