|
@@ -32,564 +32,638 @@
|
|
#include "error.h"
|
|
#include "error.h"
|
|
#include "hw_uart_rom_api.h"
|
|
#include "hw_uart_rom_api.h"
|
|
|
|
|
|
-#define UART_IDLE_FIX /* Remove once IDLE problem is fixed */
|
|
|
|
|
|
+#define UART_IDLE_FIX /* Remove once IDLE problem is fixed */
|
|
|
|
|
|
/* UART Driver internal data structure */
|
|
/* UART Driver internal data structure */
|
|
typedef struct {
|
|
typedef struct {
|
|
- void *pUserData; /* Pointer to user data */
|
|
|
|
- UART_REGS_T *pREGS; /* Pointer to Registers */
|
|
|
|
- UART_DATA_T xfer[2]; /* TX/RX transfer data */
|
|
|
|
|
|
+ void *pUserData; /* Pointer to user data */
|
|
|
|
+ UART_REGS_T *pREGS; /* Pointer to Registers */
|
|
|
|
+ UART_DATA_T xfer[2]; /* TX/RX transfer data */
|
|
#ifdef UART_IDLE_FIX
|
|
#ifdef UART_IDLE_FIX
|
|
- uint32_t dly; /* Delay to count 1 bit time; REMOVE: when H/W is fixed */
|
|
|
|
|
|
+ uint32_t dly; /* Delay to count 1 bit time; REMOVE: when H/W is fixed */
|
|
#endif
|
|
#endif
|
|
- void(*cbTable[UART_CB_RESERVED]) (UART_HANDLE_T, UART_EVENT_T, void *); /* Call-back index table */
|
|
|
|
|
|
+ void(*cbTable[UART_CB_RESERVED]) (UART_HANDLE_T, UART_EVENT_T, void *); /* Call-back index table */
|
|
} UART_DRIVER_T;
|
|
} UART_DRIVER_T;
|
|
|
|
|
|
/* PRIVATE: Division logic to divide without integer overflow */
|
|
/* PRIVATE: Division logic to divide without integer overflow */
|
|
static uint32_t _UART_DivClk(uint32_t pclk, uint32_t m)
|
|
static uint32_t _UART_DivClk(uint32_t pclk, uint32_t m)
|
|
{
|
|
{
|
|
- uint32_t q, r, u = pclk >> 24, l = pclk << 8;
|
|
|
|
- m = m + 256;
|
|
|
|
- q = (1 << 24) / m;
|
|
|
|
- r = (1 << 24) - (q * m);
|
|
|
|
- return ((q * u) << 8) + (((r * u) << 8) + l) / m;
|
|
|
|
|
|
+ uint32_t q, r, u = pclk >> 24, l = pclk << 8;
|
|
|
|
+ m = m + 256;
|
|
|
|
+ q = (1 << 24) / m;
|
|
|
|
+ r = (1 << 24) - (q * m);
|
|
|
|
+ return ((q * u) << 8) + (((r * u) << 8) + l) / m;
|
|
}
|
|
}
|
|
|
|
|
|
/* PRIVATE: Get highest Over sampling value */
|
|
/* PRIVATE: Get highest Over sampling value */
|
|
static uint32_t _UART_GetHighDiv(uint32_t val, uint8_t strict)
|
|
static uint32_t _UART_GetHighDiv(uint32_t val, uint8_t strict)
|
|
{
|
|
{
|
|
- int32_t i, max = strict ? 16 : 5;
|
|
|
|
- for (i = 16; i >= max; i--) {
|
|
|
|
- if (!(val % i)) {
|
|
|
|
- return i;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return 0;
|
|
|
|
|
|
+ int32_t i, max = strict ? 16 : 5;
|
|
|
|
+ for (i = 16; i >= max; i--)
|
|
|
|
+ {
|
|
|
|
+ if (!(val % i))
|
|
|
|
+ {
|
|
|
|
+ return i;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* PRIVATE: Queue a transfer in UART */
|
|
/* PRIVATE: Queue a transfer in UART */
|
|
static ErrorCode_t _UART_Xfer(UART_DRIVER_T *pUART, void *buff, uint16_t len, uint8_t op)
|
|
static ErrorCode_t _UART_Xfer(UART_DRIVER_T *pUART, void *buff, uint16_t len, uint8_t op)
|
|
{
|
|
{
|
|
- UART_DATA_T *xfr = &pUART->xfer[op];
|
|
|
|
-
|
|
|
|
- /* Xfer of 0 bytes in a UART should always be successful */
|
|
|
|
- if (!len) {
|
|
|
|
- return LPC_OK;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Check if a Xfer is alredy in progress */
|
|
|
|
- if (xfr->count > xfr->offset) {
|
|
|
|
- return ERR_BUSY;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- xfr->buf = (void *) buff;
|
|
|
|
- xfr->count = len;
|
|
|
|
- xfr->offset = 0;
|
|
|
|
- xfr->state = UART_ST_BUSY;
|
|
|
|
- if (!op) {
|
|
|
|
- pUART->pREGS->INTENSET = UART_INT_TXRDY;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- pUART->pREGS->INTENSET = UART_INT_RXRDY | UART_INT_FRMERR | UART_INT_RXNOISE | UART_INT_START | UART_INT_OVR;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return LPC_OK;
|
|
|
|
|
|
+ UART_DATA_T *xfr = &pUART->xfer[op];
|
|
|
|
+
|
|
|
|
+ /* Xfer of 0 bytes in a UART should always be successful */
|
|
|
|
+ if (!len)
|
|
|
|
+ {
|
|
|
|
+ return LPC_OK;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Check if a Xfer is alredy in progress */
|
|
|
|
+ if (xfr->count > xfr->offset)
|
|
|
|
+ {
|
|
|
|
+ return ERR_BUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ xfr->buf = (void *) buff;
|
|
|
|
+ xfr->count = len;
|
|
|
|
+ xfr->offset = 0;
|
|
|
|
+ xfr->state = UART_ST_BUSY;
|
|
|
|
+ if (!op)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->INTENSET = UART_INT_TXRDY;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ pUART->pREGS->INTENSET = UART_INT_RXRDY | UART_INT_FRMERR | UART_INT_RXNOISE | UART_INT_START | UART_INT_OVR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return LPC_OK;
|
|
}
|
|
}
|
|
|
|
|
|
/* Calculate error difference */
|
|
/* Calculate error difference */
|
|
static int32_t _CalcErr(uint32_t n, uint32_t d, uint32_t *prev)
|
|
static int32_t _CalcErr(uint32_t n, uint32_t d, uint32_t *prev)
|
|
{
|
|
{
|
|
- uint32_t err = n - (n / d) * d;
|
|
|
|
- uint32_t herr = ((n / d) + 1) * d - n;
|
|
|
|
- if (herr < err) {
|
|
|
|
- err = herr;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (*prev <= err) {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- *prev = err;
|
|
|
|
- return (herr == err) + 1;
|
|
|
|
|
|
+ uint32_t err = n - (n / d) * d;
|
|
|
|
+ uint32_t herr = ((n / d) + 1) * d - n;
|
|
|
|
+ if (herr < err)
|
|
|
|
+ {
|
|
|
|
+ err = herr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (*prev <= err)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ *prev = err;
|
|
|
|
+ return (herr == err) + 1;
|
|
}
|
|
}
|
|
|
|
|
|
/* Calculate the base DIV value */
|
|
/* Calculate the base DIV value */
|
|
static ErrorCode_t _UART_CalcDiv(UART_BAUD_T *ub)
|
|
static ErrorCode_t _UART_CalcDiv(UART_BAUD_T *ub)
|
|
{
|
|
{
|
|
- int32_t i = 0;
|
|
|
|
- uint32_t perr = ~0UL;
|
|
|
|
-
|
|
|
|
- if (!ub->div) {
|
|
|
|
- i = ub->ovr ? ub->ovr : 16;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (; i > 4; i--) {
|
|
|
|
- int32_t tmp = _CalcErr(ub->clk, ub->baud * i, &perr);
|
|
|
|
-
|
|
|
|
- /* Continue when no improvement seen in err value */
|
|
|
|
- if (!tmp) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ub->div = tmp - 1;
|
|
|
|
- if (ub->ovr == i) {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- ub->ovr = i;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!ub->ovr) {
|
|
|
|
- return ERR_UART_BAUDRATE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ub->div += ub->clk / (ub->baud * ub->ovr);
|
|
|
|
- if (!ub->div) {
|
|
|
|
- return ERR_UART_BAUDRATE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ub->baud = ub->clk / (ub->div * ub->ovr);
|
|
|
|
- return LPC_OK;
|
|
|
|
|
|
+ int32_t i = 0;
|
|
|
|
+ uint32_t perr = ~0UL;
|
|
|
|
+
|
|
|
|
+ if (!ub->div)
|
|
|
|
+ {
|
|
|
|
+ i = ub->ovr ? ub->ovr : 16;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (; i > 4; i--)
|
|
|
|
+ {
|
|
|
|
+ int32_t tmp = _CalcErr(ub->clk, ub->baud * i, &perr);
|
|
|
|
+
|
|
|
|
+ /* Continue when no improvement seen in err value */
|
|
|
|
+ if (!tmp)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ub->div = tmp - 1;
|
|
|
|
+ if (ub->ovr == i)
|
|
|
|
+ {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ ub->ovr = i;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!ub->ovr)
|
|
|
|
+ {
|
|
|
|
+ return ERR_UART_BAUDRATE;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ub->div += ub->clk / (ub->baud * ub->ovr);
|
|
|
|
+ if (!ub->div)
|
|
|
|
+ {
|
|
|
|
+ return ERR_UART_BAUDRATE;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ub->baud = ub->clk / (ub->div * ub->ovr);
|
|
|
|
+ return LPC_OK;
|
|
}
|
|
}
|
|
|
|
|
|
/* Calculate the best MUL value */
|
|
/* Calculate the best MUL value */
|
|
static void _UART_CalcMul(UART_BAUD_T *ub)
|
|
static void _UART_CalcMul(UART_BAUD_T *ub)
|
|
{
|
|
{
|
|
- uint32_t m, perr = ~0UL, pclk = ub->clk, ovr = ub->ovr;
|
|
|
|
-
|
|
|
|
- /* If clock is UART's base clock calculate only the divider */
|
|
|
|
- for (m = 0; m < 256; m++) {
|
|
|
|
- uint32_t ov = ovr, x, v, tmp;
|
|
|
|
-
|
|
|
|
- /* Get clock and calculate error */
|
|
|
|
- x = _UART_DivClk(pclk, m);
|
|
|
|
- tmp = _CalcErr(x, ub->baud, &perr);
|
|
|
|
- v = (x / ub->baud) + tmp - 1;
|
|
|
|
-
|
|
|
|
- /* Update if new error is better than previous best */
|
|
|
|
- if (!tmp || (ovr && (v % ovr)) ||
|
|
|
|
- (!ovr && ((ov = _UART_GetHighDiv(v, ovr)) == 0))) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ub->ovr = ov;
|
|
|
|
- ub->mul = m;
|
|
|
|
- ub->clk = x;
|
|
|
|
- ub->div = tmp - 1;
|
|
|
|
- }
|
|
|
|
|
|
+ uint32_t m, perr = ~0UL, pclk = ub->clk, ovr = ub->ovr;
|
|
|
|
+
|
|
|
|
+ /* If clock is UART's base clock calculate only the divider */
|
|
|
|
+ for (m = 0; m < 256; m++)
|
|
|
|
+ {
|
|
|
|
+ uint32_t ov = ovr, x, v, tmp;
|
|
|
|
+
|
|
|
|
+ /* Get clock and calculate error */
|
|
|
|
+ x = _UART_DivClk(pclk, m);
|
|
|
|
+ tmp = _CalcErr(x, ub->baud, &perr);
|
|
|
|
+ v = (x / ub->baud) + tmp - 1;
|
|
|
|
+
|
|
|
|
+ /* Update if new error is better than previous best */
|
|
|
|
+ if (!tmp || (ovr && (v % ovr)) ||
|
|
|
|
+ (!ovr && ((ov = _UART_GetHighDiv(v, ovr)) == 0)))
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ub->ovr = ov;
|
|
|
|
+ ub->mul = m;
|
|
|
|
+ ub->clk = x;
|
|
|
|
+ ub->div = tmp - 1;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* PRIVATE: Invoke UART Call back functions */
|
|
/* PRIVATE: Invoke UART Call back functions */
|
|
static void _UART_InvokeCB(UART_DRIVER_T *pUART, UART_EVENT_T event, void *arg)
|
|
static void _UART_InvokeCB(UART_DRIVER_T *pUART, UART_EVENT_T event, void *arg)
|
|
{
|
|
{
|
|
- void (*cbfn)(UART_HANDLE_T, UART_EVENT_T, void *);
|
|
|
|
- cbfn = pUART->cbTable[(uint32_t) event >> 1];
|
|
|
|
- if (cbfn != NULL) {
|
|
|
|
- cbfn((UART_HANDLE_T) pUART, event, arg);
|
|
|
|
- }
|
|
|
|
|
|
+ void (*cbfn)(UART_HANDLE_T, UART_EVENT_T, void *);
|
|
|
|
+ cbfn = pUART->cbTable[(uint32_t) event >> 1];
|
|
|
|
+ if (cbfn != NULL)
|
|
|
|
+ {
|
|
|
|
+ cbfn((UART_HANDLE_T) pUART, event, arg);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* PRIVATE: Handler for data transfers */
|
|
/* PRIVATE: Handler for data transfers */
|
|
static void _UART_HandleTxRx(UART_HANDLE_T hUART, UART_EVENT_T event, void *arg)
|
|
static void _UART_HandleTxRx(UART_HANDLE_T hUART, UART_EVENT_T event, void *arg)
|
|
{
|
|
{
|
|
- UART_DATA_T *dat = (UART_DATA_T *) arg;
|
|
|
|
- UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
- uint16_t *buf16 = dat->buf;
|
|
|
|
- uint8_t *buf8 = dat->buf;
|
|
|
|
-
|
|
|
|
- /* Transmit data */
|
|
|
|
- if (event == UART_TX_DATA) {
|
|
|
|
- while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_TXRDY)) {
|
|
|
|
- if (dat->dwidth) {
|
|
|
|
- pUART->pREGS->TXDAT = *buf16++;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- pUART->pREGS->TXDAT = *buf8++;
|
|
|
|
- }
|
|
|
|
- dat->count--;
|
|
|
|
- }
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Receive data */
|
|
|
|
- while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_RXRDY)) {
|
|
|
|
- if (dat->dwidth) {
|
|
|
|
- *buf16++ = pUART->pREGS->RXDAT & 0x1FF;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- *buf8++ = pUART->pREGS->RXDAT & 0xFF;
|
|
|
|
- }
|
|
|
|
- dat->count--;
|
|
|
|
- }
|
|
|
|
|
|
+ UART_DATA_T *dat = (UART_DATA_T *) arg;
|
|
|
|
+ UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
+ uint16_t *buf16 = dat->buf;
|
|
|
|
+ uint8_t *buf8 = dat->buf;
|
|
|
|
+
|
|
|
|
+ /* Transmit data */
|
|
|
|
+ if (event == UART_TX_DATA)
|
|
|
|
+ {
|
|
|
|
+ while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_TXRDY))
|
|
|
|
+ {
|
|
|
|
+ if (dat->dwidth)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->TXDAT = *buf16++;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ pUART->pREGS->TXDAT = *buf8++;
|
|
|
|
+ }
|
|
|
|
+ dat->count--;
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Receive data */
|
|
|
|
+ while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_RXRDY))
|
|
|
|
+ {
|
|
|
|
+ if (dat->dwidth)
|
|
|
|
+ {
|
|
|
|
+ *buf16++ = pUART->pREGS->RXDAT & 0x1FF;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ *buf8++ = pUART->pREGS->RXDAT & 0xFF;
|
|
|
|
+ }
|
|
|
|
+ dat->count--;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* Handle UART Receive event */
|
|
/* Handle UART Receive event */
|
|
static int32_t _UART_HandleXfer(UART_DRIVER_T *pUART, uint8_t op)
|
|
static int32_t _UART_HandleXfer(UART_DRIVER_T *pUART, uint8_t op)
|
|
{
|
|
{
|
|
- UART_DATA_T dat;
|
|
|
|
- UART_DATA_T *xfr = &pUART->xfer[op];
|
|
|
|
-
|
|
|
|
- /* See if the transfer is already complete */
|
|
|
|
- if (xfr->offset >= xfr->count) {
|
|
|
|
- return 2;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Fill the buffer data structure */
|
|
|
|
- dat.count = xfr->count - xfr->offset;
|
|
|
|
- dat.dwidth = ((pUART->pREGS->CFG >> 2) & 3) > 1;
|
|
|
|
- if (dat.dwidth) {
|
|
|
|
- dat.buf = &((uint16_t *) xfr->buf)[xfr->offset];
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- dat.buf = &((uint8_t *) xfr->buf)[xfr->offset];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!xfr->offset && xfr->count) {
|
|
|
|
- _UART_InvokeCB(pUART, UART_TX_START, xfr);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pUART->cbTable[UART_CB_DATA]((UART_HANDLE_T) pUART, (UART_EVENT_T) (UART_TX_DATA + op), &dat);
|
|
|
|
- xfr->offset = (xfr->count - dat.count);
|
|
|
|
-
|
|
|
|
- if (xfr->offset >= xfr->count) {
|
|
|
|
- if (!op) {
|
|
|
|
- pUART->pREGS->INTENCLR = UART_INT_TXRDY;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- pUART->pREGS->INTENCLR = UART_INT_RXRDY;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_TX_DONE + op), xfr);
|
|
|
|
- if (xfr->state == UART_ST_BUSY) {
|
|
|
|
- xfr->state = UART_ST_DONE;
|
|
|
|
- }
|
|
|
|
- return 1;
|
|
|
|
- }
|
|
|
|
- return 0;
|
|
|
|
|
|
+ UART_DATA_T dat;
|
|
|
|
+ UART_DATA_T *xfr = &pUART->xfer[op];
|
|
|
|
+
|
|
|
|
+ /* See if the transfer is already complete */
|
|
|
|
+ if (xfr->offset >= xfr->count)
|
|
|
|
+ {
|
|
|
|
+ return 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Fill the buffer data structure */
|
|
|
|
+ dat.count = xfr->count - xfr->offset;
|
|
|
|
+ dat.dwidth = ((pUART->pREGS->CFG >> 2) & 3) > 1;
|
|
|
|
+ if (dat.dwidth)
|
|
|
|
+ {
|
|
|
|
+ dat.buf = &((uint16_t *) xfr->buf)[xfr->offset];
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ dat.buf = &((uint8_t *) xfr->buf)[xfr->offset];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!xfr->offset && xfr->count)
|
|
|
|
+ {
|
|
|
|
+ _UART_InvokeCB(pUART, UART_TX_START, xfr);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pUART->cbTable[UART_CB_DATA]((UART_HANDLE_T) pUART, (UART_EVENT_T) (UART_TX_DATA + op), &dat);
|
|
|
|
+ xfr->offset = (xfr->count - dat.count);
|
|
|
|
+
|
|
|
|
+ if (xfr->offset >= xfr->count)
|
|
|
|
+ {
|
|
|
|
+ if (!op)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->INTENCLR = UART_INT_TXRDY;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ pUART->pREGS->INTENCLR = UART_INT_RXRDY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_TX_DONE + op), xfr);
|
|
|
|
+ if (xfr->state == UART_ST_BUSY)
|
|
|
|
+ {
|
|
|
|
+ xfr->state = UART_ST_DONE;
|
|
|
|
+ }
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* STOP Receive under progress */
|
|
/* STOP Receive under progress */
|
|
static void _UART_StopRx(UART_HANDLE_T hUART)
|
|
static void _UART_StopRx(UART_HANDLE_T hUART)
|
|
{
|
|
{
|
|
- UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
- UART_DATA_T *rx = &pUART->xfer[1];
|
|
|
|
- volatile uint16_t *idx = (volatile uint16_t *) &rx->offset;
|
|
|
|
-
|
|
|
|
- if (*idx >= rx->count) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Disable further receive interrupts */
|
|
|
|
- pUART->pREGS->INTENCLR = UART_INT_RXRDY;
|
|
|
|
- rx->count = *idx;
|
|
|
|
- _UART_InvokeCB(pUART, UART_RX_DONE, rx);
|
|
|
|
|
|
+ UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
+ UART_DATA_T *rx = &pUART->xfer[1];
|
|
|
|
+ volatile uint16_t *idx = (volatile uint16_t *) &rx->offset;
|
|
|
|
+
|
|
|
|
+ if (*idx >= rx->count)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Disable further receive interrupts */
|
|
|
|
+ pUART->pREGS->INTENCLR = UART_INT_RXRDY;
|
|
|
|
+ rx->count = *idx;
|
|
|
|
+ _UART_InvokeCB(pUART, UART_RX_DONE, rx);
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPROTED API: Returns memory required for UART ROM driver */
|
|
/* EXPROTED API: Returns memory required for UART ROM driver */
|
|
uint32_t UART_GetMemSize(void)
|
|
uint32_t UART_GetMemSize(void)
|
|
{
|
|
{
|
|
- return sizeof(UART_DRIVER_T);
|
|
|
|
|
|
+ return sizeof(UART_DRIVER_T);
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: Calculate UART Baudrate divisors */
|
|
/* EXPORTED API: Calculate UART Baudrate divisors */
|
|
ErrorCode_t UART_CalculateBaud(UART_BAUD_T *ub)
|
|
ErrorCode_t UART_CalculateBaud(UART_BAUD_T *ub)
|
|
{
|
|
{
|
|
- if (!ub->mul) {
|
|
|
|
- _UART_CalcMul(ub);
|
|
|
|
- }
|
|
|
|
|
|
+ if (!ub->mul)
|
|
|
|
+ {
|
|
|
|
+ _UART_CalcMul(ub);
|
|
|
|
+ }
|
|
|
|
|
|
- return _UART_CalcDiv(ub);
|
|
|
|
|
|
+ return _UART_CalcDiv(ub);
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: UART Initialization function */
|
|
/* EXPORTED API: UART Initialization function */
|
|
UART_HANDLE_T UART_Init(void *mem, uint32_t base_addr, void *args)
|
|
UART_HANDLE_T UART_Init(void *mem, uint32_t base_addr, void *args)
|
|
{
|
|
{
|
|
- UART_DRIVER_T *pUART;
|
|
|
|
|
|
+ UART_DRIVER_T *pUART;
|
|
|
|
|
|
- /* Check if the memory is word aligned */
|
|
|
|
- if ((uint32_t) mem & 0x3) {
|
|
|
|
- return NULL;
|
|
|
|
- }
|
|
|
|
|
|
+ /* Check if the memory is word aligned */
|
|
|
|
+ if ((uint32_t) mem & 0x3)
|
|
|
|
+ {
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
|
|
- /* Assign memory provided by application */
|
|
|
|
- pUART = (UART_DRIVER_T *) mem;
|
|
|
|
- memset(pUART, 0, sizeof(UART_DRIVER_T));
|
|
|
|
|
|
+ /* Assign memory provided by application */
|
|
|
|
+ pUART = (UART_DRIVER_T *) mem;
|
|
|
|
+ memset(pUART, 0, sizeof(UART_DRIVER_T));
|
|
|
|
|
|
- /* Assign the base address */
|
|
|
|
- pUART->pREGS = (UART_REGS_T *) base_addr;
|
|
|
|
- pUART->pUserData = args;
|
|
|
|
|
|
+ /* Assign the base address */
|
|
|
|
+ pUART->pREGS = (UART_REGS_T *) base_addr;
|
|
|
|
+ pUART->pUserData = args;
|
|
|
|
|
|
- /* Set default handler for TX and RX */
|
|
|
|
- pUART->cbTable[UART_CB_DATA] = _UART_HandleTxRx;
|
|
|
|
- return (UART_HANDLE_T) pUART;
|
|
|
|
|
|
+ /* Set default handler for TX and RX */
|
|
|
|
+ pUART->cbTable[UART_CB_DATA] = _UART_HandleTxRx;
|
|
|
|
+ return (UART_HANDLE_T) pUART;
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: Configure UART parameters */
|
|
/* EXPORTED API: Configure UART parameters */
|
|
ErrorCode_t UART_Configure(UART_HANDLE_T hUART, const UART_CFG_T *cfg)
|
|
ErrorCode_t UART_Configure(UART_HANDLE_T hUART, const UART_CFG_T *cfg)
|
|
{
|
|
{
|
|
- UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
- UART_REGS_T *pREGS = pUART->pREGS;
|
|
|
|
-
|
|
|
|
- if (((cfg->cfg & UART_PAR_MASK) == (1 << 4)) ||
|
|
|
|
- ( (cfg->cfg & UART_DATA_MASK) == (3 << 2)) ) {
|
|
|
|
- return ERR_UART_PARAM;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Enable parity error when parity is enabled */
|
|
|
|
- if ((cfg->cfg & UART_PAR_MASK) >> 4) {
|
|
|
|
- pREGS->INTENSET = UART_INT_PARERR;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (((int32_t) cfg->div <= 0) || ((int32_t) cfg->ovr <= 0)) {
|
|
|
|
- return ERR_UART_PARAM;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pREGS->OSR = (cfg->ovr - 1) & 0x0F;
|
|
|
|
- pREGS->BRG = (cfg->div - 1) & 0xFFFF;
|
|
|
|
- pREGS->CFG = UART_CFG_ENABLE | (cfg->cfg & ~UART_CFG_RES);
|
|
|
|
-
|
|
|
|
- /* Enabled RX of BREAK event */
|
|
|
|
- if (cfg->cfg & UART_CFG_BRKRX) {
|
|
|
|
- pREGS->INTENSET = UART_INT_BREAK;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Enable CTS interrupt if requested */
|
|
|
|
- if (cfg->cfg & UART_CFG_CTSEV) {
|
|
|
|
- pREGS->INTENSET = UART_INT_CTS;
|
|
|
|
- }
|
|
|
|
|
|
+ UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
+ UART_REGS_T *pREGS = pUART->pREGS;
|
|
|
|
+
|
|
|
|
+ if (((cfg->cfg & UART_PAR_MASK) == (1 << 4)) ||
|
|
|
|
+ ( (cfg->cfg & UART_DATA_MASK) == (3 << 2)) )
|
|
|
|
+ {
|
|
|
|
+ return ERR_UART_PARAM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Enable parity error when parity is enabled */
|
|
|
|
+ if ((cfg->cfg & UART_PAR_MASK) >> 4)
|
|
|
|
+ {
|
|
|
|
+ pREGS->INTENSET = UART_INT_PARERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (((int32_t) cfg->div <= 0) || ((int32_t) cfg->ovr <= 0))
|
|
|
|
+ {
|
|
|
|
+ return ERR_UART_PARAM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pREGS->OSR = (cfg->ovr - 1) & 0x0F;
|
|
|
|
+ pREGS->BRG = (cfg->div - 1) & 0xFFFF;
|
|
|
|
+ pREGS->CFG = UART_CFG_ENABLE | (cfg->cfg & ~UART_CFG_RES);
|
|
|
|
+
|
|
|
|
+ /* Enabled RX of BREAK event */
|
|
|
|
+ if (cfg->cfg & UART_CFG_BRKRX)
|
|
|
|
+ {
|
|
|
|
+ pREGS->INTENSET = UART_INT_BREAK;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Enable CTS interrupt if requested */
|
|
|
|
+ if (cfg->cfg & UART_CFG_CTSEV)
|
|
|
|
+ {
|
|
|
|
+ pREGS->INTENSET = UART_INT_CTS;
|
|
|
|
+ }
|
|
|
|
|
|
#ifdef UART_IDLE_FIX
|
|
#ifdef UART_IDLE_FIX
|
|
- /* REMOVE: if/else block after H/W idle is fixed */
|
|
|
|
- if (cfg->res > 224) {
|
|
|
|
- pUART->dly = 3072 * (cfg->res - 224);
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- pUART->dly = cfg->res << 2;
|
|
|
|
- }
|
|
|
|
|
|
+ /* REMOVE: if/else block after H/W idle is fixed */
|
|
|
|
+ if (cfg->res > 224)
|
|
|
|
+ {
|
|
|
|
+ pUART->dly = 3072 * (cfg->res - 224);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ pUART->dly = cfg->res << 2;
|
|
|
|
+ }
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- return LPC_OK;
|
|
|
|
|
|
+ return LPC_OK;
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: UART setup special operation like BREAK etc. */
|
|
/* EXPORTED API: UART setup special operation like BREAK etc. */
|
|
void UART_SetControl(UART_HANDLE_T hUART, uint32_t cfg)
|
|
void UART_SetControl(UART_HANDLE_T hUART, uint32_t cfg)
|
|
{
|
|
{
|
|
- uint32_t en, dis;
|
|
|
|
- UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS;
|
|
|
|
-
|
|
|
|
- /* Get list of enabled and disabled options */
|
|
|
|
- en = ((cfg >> 16) & (cfg & 0xFFFF)) << 1;
|
|
|
|
- dis = ((cfg >> 16) & ~(cfg & 0xFFFF)) << 1;
|
|
|
|
-
|
|
|
|
- /* See if it is RX Stop request */
|
|
|
|
- if (cfg & UART_RX_STOP) {
|
|
|
|
- _UART_StopRx(hUART);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* See if any IDLEs are enabled */
|
|
|
|
- if (cfg & (UART_IDLE_MASK << 16)) {
|
|
|
|
- pREGS->INTENSET = (en >> 1) & UART_IDLE_MASK;
|
|
|
|
- pREGS->INTENCLR = (dis >> 1) & UART_IDLE_MASK;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* See if it is a request BREAK after TX */
|
|
|
|
- if (en & UART_CTL_TXDIS) {
|
|
|
|
- if (en & UART_CTL_TXBRKEN) {
|
|
|
|
- pREGS->CTL = (pREGS->CTL & ~UART_CTL_RES) | UART_CTL_TXDIS;
|
|
|
|
- while (!(pREGS->STAT & UART_INT_TXDIS)) {}
|
|
|
|
|
|
+ uint32_t en, dis;
|
|
|
|
+ UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS;
|
|
|
|
+
|
|
|
|
+ /* Get list of enabled and disabled options */
|
|
|
|
+ en = ((cfg >> 16) & (cfg & 0xFFFF)) << 1;
|
|
|
|
+ dis = ((cfg >> 16) & ~(cfg & 0xFFFF)) << 1;
|
|
|
|
+
|
|
|
|
+ /* See if it is RX Stop request */
|
|
|
|
+ if (cfg & UART_RX_STOP)
|
|
|
|
+ {
|
|
|
|
+ _UART_StopRx(hUART);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* See if any IDLEs are enabled */
|
|
|
|
+ if (cfg & (UART_IDLE_MASK << 16))
|
|
|
|
+ {
|
|
|
|
+ pREGS->INTENSET = (en >> 1) & UART_IDLE_MASK;
|
|
|
|
+ pREGS->INTENCLR = (dis >> 1) & UART_IDLE_MASK;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* See if it is a request BREAK after TX */
|
|
|
|
+ if (en & UART_CTL_TXDIS)
|
|
|
|
+ {
|
|
|
|
+ if (en & UART_CTL_TXBRKEN)
|
|
|
|
+ {
|
|
|
|
+ pREGS->CTL = (pREGS->CTL & ~UART_CTL_RES) | UART_CTL_TXDIS;
|
|
|
|
+ while (!(pREGS->STAT & UART_INT_TXDIS))
|
|
|
|
+ {}
|
|
#ifdef UART_IDLE_FIX
|
|
#ifdef UART_IDLE_FIX
|
|
- if (1) {
|
|
|
|
- volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
|
|
|
|
- while (dly--) {}/* Provide some idling time H/W does not do this */
|
|
|
|
- }
|
|
|
|
|
|
+ if (1)
|
|
|
|
+ {
|
|
|
|
+ volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
|
|
|
|
+ while (dly--)
|
|
|
|
+ {}/* Provide some idling time H/W does not do this */
|
|
|
|
+ }
|
|
#endif
|
|
#endif
|
|
- }
|
|
|
|
- else {
|
|
|
|
- pREGS->INTENSET = UART_INT_TXDIS;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* See if we are releasing break and resume TX operation */
|
|
|
|
- if ((dis & UART_CTL_TXDIS) && (dis & UART_CTL_TXBRKEN)) {
|
|
|
|
- pREGS->CTL = pREGS->CTL & ~(UART_CTL_RES | UART_CTL_TXBRKEN);
|
|
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ pREGS->INTENSET = UART_INT_TXDIS;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* See if we are releasing break and resume TX operation */
|
|
|
|
+ if ((dis & UART_CTL_TXDIS) && (dis & UART_CTL_TXBRKEN))
|
|
|
|
+ {
|
|
|
|
+ pREGS->CTL = pREGS->CTL & ~(UART_CTL_RES | UART_CTL_TXBRKEN);
|
|
#ifdef UART_IDLE_FIX
|
|
#ifdef UART_IDLE_FIX
|
|
- if (1) {
|
|
|
|
- volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
|
|
|
|
- while (dly--) {} /* Provide some idling time H/W does not do this */
|
|
|
|
- }
|
|
|
|
|
|
+ if (1)
|
|
|
|
+ {
|
|
|
|
+ volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
|
|
|
|
+ while (dly--)
|
|
|
|
+ {} /* Provide some idling time H/W does not do this */
|
|
|
|
+ }
|
|
#endif
|
|
#endif
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- /* Check for autobaud and enable autobaud err interrupt */
|
|
|
|
- if (en & UART_CTL_AUTOBAUD) {
|
|
|
|
- pREGS->INTENSET = UART_INT_ABAUDERR;
|
|
|
|
- }
|
|
|
|
|
|
+ /* Check for autobaud and enable autobaud err interrupt */
|
|
|
|
+ if (en & UART_CTL_AUTOBAUD)
|
|
|
|
+ {
|
|
|
|
+ pREGS->INTENSET = UART_INT_ABAUDERR;
|
|
|
|
+ }
|
|
|
|
|
|
- pREGS->CTL = ((pREGS->CTL | en) & ~dis) & ~UART_CTL_RES;
|
|
|
|
|
|
+ pREGS->CTL = ((pREGS->CTL | en) & ~dis) & ~UART_CTL_RES;
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: Register a call-back function */
|
|
/* EXPORTED API: Register a call-back function */
|
|
ErrorCode_t UART_RegisterCB(UART_HANDLE_T hUART,
|
|
ErrorCode_t UART_RegisterCB(UART_HANDLE_T hUART,
|
|
- UART_CBINDEX_T idx,
|
|
|
|
- void (*cb_func)(UART_HANDLE_T, UART_EVENT_T, void *))
|
|
|
|
|
|
+ UART_CBINDEX_T idx,
|
|
|
|
+ void (*cb_func)(UART_HANDLE_T, UART_EVENT_T, void *))
|
|
{
|
|
{
|
|
- if (idx < UART_CB_RESERVED) {
|
|
|
|
- ((UART_DRIVER_T *) hUART)->cbTable[idx] = cb_func;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- return ERR_UART_PARAM;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Restore internal data handlers when external ones are un-registered */
|
|
|
|
- if ((idx == UART_CB_DATA) && (cb_func == NULL)) {
|
|
|
|
- ((UART_DRIVER_T *) hUART)->cbTable[idx] = _UART_HandleTxRx;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return LPC_OK;
|
|
|
|
|
|
+ if (idx < UART_CB_RESERVED)
|
|
|
|
+ {
|
|
|
|
+ ((UART_DRIVER_T *) hUART)->cbTable[idx] = cb_func;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ return ERR_UART_PARAM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Restore internal data handlers when external ones are un-registered */
|
|
|
|
+ if ((idx == UART_CB_DATA) && (cb_func == NULL))
|
|
|
|
+ {
|
|
|
|
+ ((UART_DRIVER_T *) hUART)->cbTable[idx] = _UART_HandleTxRx;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return LPC_OK;
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: UART Event handler */
|
|
/* EXPORTED API: UART Event handler */
|
|
void UART_Handler(UART_HANDLE_T hUART)
|
|
void UART_Handler(UART_HANDLE_T hUART)
|
|
{
|
|
{
|
|
- UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
- uint32_t flags = pUART->pREGS->INTENSET & pUART->pREGS->INTSTAT;
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_TXRDY) {
|
|
|
|
- _UART_HandleXfer(pUART, 0);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_FRMERR) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_FRMERR;
|
|
|
|
- if (pUART->xfer[1].state == UART_ST_BUSY) {
|
|
|
|
- pUART->xfer[1].state = UART_ST_ERRFRM;
|
|
|
|
- }
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_FRAME);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_PARERR) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_PARERR;
|
|
|
|
- if (pUART->xfer[1].state == UART_ST_BUSY) {
|
|
|
|
- pUART->xfer[1].state = UART_ST_ERRPAR;
|
|
|
|
- }
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_PARITY);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_ABAUDERR) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_ABAUDERR;
|
|
|
|
- if (pUART->xfer[1].state == UART_ST_BUSY) {
|
|
|
|
- pUART->xfer[1].state = UART_ST_ERR;
|
|
|
|
- }
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_AUTOBAUD);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_RXNOISE) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_RXNOISE;
|
|
|
|
- if (pUART->xfer[1].state == UART_ST_BUSY) {
|
|
|
|
- pUART->xfer[1].state = UART_ST_ERRNOISE;
|
|
|
|
- }
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_RXNOISE);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_OVR) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_OVR;
|
|
|
|
- if (pUART->xfer[1].state == UART_ST_BUSY) {
|
|
|
|
- pUART->xfer[1].state = UART_ST_ERROVR;
|
|
|
|
- }
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_OVERRUN);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_RXRDY) {
|
|
|
|
- _UART_HandleXfer(pUART, 1);
|
|
|
|
|
|
+ UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
|
|
|
|
+ uint32_t flags = pUART->pREGS->INTENSET & pUART->pREGS->INTSTAT;
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_TXRDY)
|
|
|
|
+ {
|
|
|
|
+ _UART_HandleXfer(pUART, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_FRMERR)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_FRMERR;
|
|
|
|
+ if (pUART->xfer[1].state == UART_ST_BUSY)
|
|
|
|
+ {
|
|
|
|
+ pUART->xfer[1].state = UART_ST_ERRFRM;
|
|
|
|
+ }
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_FRAME);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_PARERR)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_PARERR;
|
|
|
|
+ if (pUART->xfer[1].state == UART_ST_BUSY)
|
|
|
|
+ {
|
|
|
|
+ pUART->xfer[1].state = UART_ST_ERRPAR;
|
|
|
|
+ }
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_PARITY);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_ABAUDERR)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_ABAUDERR;
|
|
|
|
+ if (pUART->xfer[1].state == UART_ST_BUSY)
|
|
|
|
+ {
|
|
|
|
+ pUART->xfer[1].state = UART_ST_ERR;
|
|
|
|
+ }
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_AUTOBAUD);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_RXNOISE)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_RXNOISE;
|
|
|
|
+ if (pUART->xfer[1].state == UART_ST_BUSY)
|
|
|
|
+ {
|
|
|
|
+ pUART->xfer[1].state = UART_ST_ERRNOISE;
|
|
|
|
+ }
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_RXNOISE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_OVR)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_OVR;
|
|
|
|
+ if (pUART->xfer[1].state == UART_ST_BUSY)
|
|
|
|
+ {
|
|
|
|
+ pUART->xfer[1].state = UART_ST_ERROVR;
|
|
|
|
+ }
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_OVERRUN);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_RXRDY)
|
|
|
|
+ {
|
|
|
|
+ _UART_HandleXfer(pUART, 1);
|
|
#ifdef UART_IDLE_FIX
|
|
#ifdef UART_IDLE_FIX
|
|
- if (1) {
|
|
|
|
- volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
|
|
|
|
- while ((pUART->pREGS->STAT & UART_STAT_RXIDLE) && dly--) {}
|
|
|
|
- }
|
|
|
|
|
|
+ if (1)
|
|
|
|
+ {
|
|
|
|
+ volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
|
|
|
|
+ while ((pUART->pREGS->STAT & UART_STAT_RXIDLE) && dly--)
|
|
|
|
+ {}
|
|
|
|
+ }
|
|
#else
|
|
#else
|
|
- while (pUART->pREGS->STAT & UART_STAT_RXIDLE) {}
|
|
|
|
|
|
+ while (pUART->pREGS->STAT & UART_STAT_RXIDLE)
|
|
|
|
+ {}
|
|
#endif
|
|
#endif
|
|
- _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_RX_INPROG + ((pUART->pREGS->STAT >> 1) & 1)), &pUART->xfer[1]);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_TXIDLE) {
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXIDLE);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_TXDIS) {
|
|
|
|
- pUART->pREGS->INTENCLR = UART_INT_TXDIS;/* Disable interrupt */
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXPAUSED);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_CTS) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_CTS;
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_EVENT,
|
|
|
|
- (void *) ((pUART->pREGS->STAT & UART_STAT_CTS) ? UART_EVENT_CTSHI : UART_EVENT_CTSLO));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_BREAK) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_BREAK | UART_INT_FRMERR;
|
|
|
|
- _UART_InvokeCB(pUART, UART_EV_EVENT,
|
|
|
|
- (void *) ((pUART->pREGS->STAT & UART_STAT_BREAK) ? UART_EVENT_BREAK : UART_EVENT_NOBREAK));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (flags & UART_INT_START) {
|
|
|
|
- pUART->pREGS->STAT = UART_INT_START;
|
|
|
|
- _UART_InvokeCB(pUART, UART_RX_START, &pUART->xfer[1]);
|
|
|
|
- }
|
|
|
|
|
|
+ _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_RX_INPROG + ((pUART->pREGS->STAT >> 1) & 1)), &pUART->xfer[1]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_TXIDLE)
|
|
|
|
+ {
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXIDLE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_TXDIS)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->INTENCLR = UART_INT_TXDIS;/* Disable interrupt */
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXPAUSED);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_CTS)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_CTS;
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_EVENT,
|
|
|
|
+ (void *) ((pUART->pREGS->STAT & UART_STAT_CTS) ? UART_EVENT_CTSHI : UART_EVENT_CTSLO));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_BREAK)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_BREAK | UART_INT_FRMERR;
|
|
|
|
+ _UART_InvokeCB(pUART, UART_EV_EVENT,
|
|
|
|
+ (void *) ((pUART->pREGS->STAT & UART_STAT_BREAK) ? UART_EVENT_BREAK : UART_EVENT_NOBREAK));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & UART_INT_START)
|
|
|
|
+ {
|
|
|
|
+ pUART->pREGS->STAT = UART_INT_START;
|
|
|
|
+ _UART_InvokeCB(pUART, UART_RX_START, &pUART->xfer[1]);
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: UART Transmit API */
|
|
/* EXPORTED API: UART Transmit API */
|
|
ErrorCode_t UART_Tx(UART_HANDLE_T hUART, const void *buff, uint16_t len)
|
|
ErrorCode_t UART_Tx(UART_HANDLE_T hUART, const void *buff, uint16_t len)
|
|
{
|
|
{
|
|
- return _UART_Xfer((UART_DRIVER_T *) hUART, (void *) buff, len, 0);
|
|
|
|
|
|
+ return _UART_Xfer((UART_DRIVER_T *) hUART, (void *) buff, len, 0);
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: UART Receive API */
|
|
/* EXPORTED API: UART Receive API */
|
|
ErrorCode_t UART_Rx(UART_HANDLE_T hUART, void *buff, uint16_t len)
|
|
ErrorCode_t UART_Rx(UART_HANDLE_T hUART, void *buff, uint16_t len)
|
|
{
|
|
{
|
|
- return _UART_Xfer((UART_DRIVER_T *) hUART, buff, len, 1);
|
|
|
|
|
|
+ return _UART_Xfer((UART_DRIVER_T *) hUART, buff, len, 1);
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: Flush the TX buffer */
|
|
/* EXPORTED API: Flush the TX buffer */
|
|
void UART_WaitTX(UART_HANDLE_T hUART)
|
|
void UART_WaitTX(UART_HANDLE_T hUART)
|
|
{
|
|
{
|
|
- while (!_UART_HandleXfer(hUART, 0)) {}
|
|
|
|
|
|
+ while (!_UART_HandleXfer(hUART, 0))
|
|
|
|
+ {}
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: Fetch the data from UART into RX buffer */
|
|
/* EXPORTED API: Fetch the data from UART into RX buffer */
|
|
void UART_WaitRX(UART_HANDLE_T hUART)
|
|
void UART_WaitRX(UART_HANDLE_T hUART)
|
|
{
|
|
{
|
|
- UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS;
|
|
|
|
- /* See if the data needs to be discarded */
|
|
|
|
- if (_UART_HandleXfer(hUART, 1) == 2) {
|
|
|
|
- volatile uint32_t dummy;
|
|
|
|
- while ((pREGS->STAT & UART_INT_RXRDY) || !(pREGS->STAT & UART_STAT_RXIDLE)) {
|
|
|
|
- dummy = pREGS->RXDAT;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- while (!_UART_HandleXfer(hUART, 1)) {}
|
|
|
|
|
|
+ UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS;
|
|
|
|
+ /* See if the data needs to be discarded */
|
|
|
|
+ if (_UART_HandleXfer(hUART, 1) == 2)
|
|
|
|
+ {
|
|
|
|
+ volatile uint32_t dummy;
|
|
|
|
+ while ((pREGS->STAT & UART_INT_RXRDY) || !(pREGS->STAT & UART_STAT_RXIDLE))
|
|
|
|
+ {
|
|
|
|
+ dummy = pREGS->RXDAT;
|
|
|
|
+ (void)dummy;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ while (!_UART_HandleXfer(hUART, 1))
|
|
|
|
+ {}
|
|
}
|
|
}
|
|
|
|
|
|
/* EXPORTED API: Function to Get the firmware Version */
|
|
/* EXPORTED API: Function to Get the firmware Version */
|
|
uint32_t UART_GetDriverVersion(void)
|
|
uint32_t UART_GetDriverVersion(void)
|
|
{
|
|
{
|
|
- return UART_DRIVER_VERSION;
|
|
|
|
|
|
+ return UART_DRIVER_VERSION;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * @brief Table of the addresses of all the UART ROM APIs
|
|
|
|
- * @note This table of function pointers is the API interface.
|
|
|
|
|
|
+ * @brief Table of the addresses of all the UART ROM APIs
|
|
|
|
+ * @note This table of function pointers is the API interface.
|
|
*/
|
|
*/
|
|
const ROM_UART_API_T uartrom_api = {
|
|
const ROM_UART_API_T uartrom_api = {
|
|
- UART_GetMemSize,
|
|
|
|
- UART_CalculateBaud,
|
|
|
|
- UART_Init,
|
|
|
|
- UART_Configure,
|
|
|
|
- UART_SetControl,
|
|
|
|
- UART_RegisterCB,
|
|
|
|
- UART_Handler,
|
|
|
|
- UART_Tx,
|
|
|
|
- UART_Rx,
|
|
|
|
- UART_WaitTX,
|
|
|
|
- UART_WaitRX,
|
|
|
|
- UART_GetDriverVersion,
|
|
|
|
|
|
+ UART_GetMemSize,
|
|
|
|
+ UART_CalculateBaud,
|
|
|
|
+ UART_Init,
|
|
|
|
+ UART_Configure,
|
|
|
|
+ UART_SetControl,
|
|
|
|
+ UART_RegisterCB,
|
|
|
|
+ UART_Handler,
|
|
|
|
+ UART_Tx,
|
|
|
|
+ UART_Rx,
|
|
|
|
+ UART_WaitTX,
|
|
|
|
+ UART_WaitRX,
|
|
|
|
+ UART_GetDriverVersion,
|
|
};
|
|
};
|