LPC2142 在keil RTX-ARM操作系统下 UART使用队列的方式。
#include "uart.h"
//#define uart0_unlock(); VICIntEnable = 1 << VIC_UART0
//#define uart0_lock(); VICIntEnClr= 1 << VIC_UART0
#define QueuePush(p)
//static
UartQueue_t UartQueue0;
UartQueue_t UartQueue1;
static void UartQueueInit(UartQueue_t* queue)
{
os_sem_init (queue->rxSem.sem, 0);
queue->rxPush = queue->rxBuf;
queue->rxPop= queue->rxBuf;
queue->rxTick = 0;
os_sem_init (queue->txSem.sem,UART_TX_SIZE);
queue->txPush = queue->txBuf;
queue->txPop= queue->txBuf;
queue->txTick = 0;
}
INT16U UartRead(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
INT16U n;
UartQueue_t *pqueue;
switch(port)
{
case PORT_UART0:
pqueue = &UartQueue0;
break;
case PORT_UART1:
pqueue = &UartQueue1;
break;
}
for(n=0;n<size;n++)
{
if(OS_R_TMO == os_sem_wait(pqueue->rxSem.sem,timeout))
{
break;
}
*buf = *pqueue->rxPop;
buf++;
pqueue->rxPop++;
if(pqueue->rxPop == &pqueue->rxBuf)
{
pqueue->rxPop = pqueue->rxBuf;
}
}
return n;
}
INT16U UartWrite(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
INT16U n = 0;
UartQueue_t *pqueue;
INT8U*thr;
INT32U *ier;
//tsk_lock();
switch(port)
{
case PORT_UART0:
{
pqueue = &UartQueue0;
thr = (INT8U*)&U0THR;
ier = (INT32U*)&U0IER;
}
break;
case PORT_UART1:
{
pqueue = &UartQueue1;
thr = (INT8U*)&U1THR;
ier = (INT32U*)&U1IER;
}
break;
}
*ier &= ~0x02;
if(OS_R_TMO != os_sem_wait(pqueue->txSem.sem,0))
{
*pqueue->txPush = *buf;
buf++;
pqueue->txPush++;
if(pqueue->txPush == &pqueue->txBuf)
{
pqueue->txPush = pqueue->txBuf;
}
n++;
if(pqueue->txTick == 0)
{
pqueue->txTick = 1;
*thr = *pqueue->txPop;
pqueue->txPop++;
if(pqueue->txPop == &pqueue->txBuf)
{
pqueue->txPop = pqueue->txBuf;
}
os_sem_send(pqueue->txSem.sem);
}
}
*ier |= 0x02;
for(;n<size;n++)
{
if(OS_R_TMO == os_sem_wait(pqueue->txSem.sem,timeout))
{
break;
}
*pqueue->txPush = *buf;
buf++;
pqueue->txPush++;
if(pqueue->txPush == &pqueue->txBuf)
{
pqueue->txPush = pqueue->txBuf;
}
}
return n;
}
/*
UART0 ISR
*/
__inline void Uart0RxIsr(void)
{
INT8U c,cnt;
cnt = UartQueue0.rxSem.cnt;
while(U0LSR & 0x01)//data in fifo
{
c = U0RBR;
if(cnt < UART_RX_SIZE)
{
isr_sem_send(UartQueue0.rxSem.sem);
cnt++;
*UartQueue0.rxPush = c;
UartQueue0.rxPush++;
if(UartQueue0.rxPush == &UartQueue0.rxBuf)
{
UartQueue0.rxPush = UartQueue0.rxBuf;
}
}
}
}
__inline void Uart0TxIsr(void)
{
INT16U n,cnt;
cnt = UART_TX_SIZE - UartQueue0.txSem.cnt;
if(cnt)
{
for(n=0;n<16;n++)
{
if(0==cnt)
{
break;
}
isr_sem_send(UartQueue0.txSem.sem);
cnt--;
U0THR = *UartQueue0.txPop;
UartQueue0.txPop++;
if(UartQueue0.txPop == &UartQueue0.txBuf)
{
UartQueue0.txPop = UartQueue0.txBuf;
}
}
UartQueue0.txTick = n;
}
else
{
UartQueue0.txTick = 0;
}
}
void UART0_IRQ(void) __irq
{
INT32U INT_ID;
INT_ID = U0IIR & 0x0E;
switch(INT_ID)
{
case 0x04:
case 0x0C:
Uart0RxIsr();
break;
case 0x02:
Uart0TxIsr();
break;
default:
break;
}
VICVectAddr = 0; /* Acknowledge Interrupt */
}
/*
UART1 ISR
*/
__inline void Uart1RxIsr(void)
{
INT8U c,cnt;
cnt = UartQueue1.rxSem.cnt;
while(U1LSR & 0x01)//data in fifo
{
c = U1RBR;
if(cnt < UART_RX_SIZE)
{
isr_sem_send(UartQueue1.rxSem.sem);
cnt++;
*UartQueue1.rxPush = c;
UartQueue1.rxPush++;
if(UartQueue1.rxPush == &UartQueue1.rxBuf)
{
UartQueue1.rxPush = UartQueue1.rxBuf;
}
}
}
}
__inline void Uart1TxIsr(void)
{
INT16U n,cnt;
cnt = UART_TX_SIZE - UartQueue1.txSem.cnt;
if(cnt)
{
for(n=0;n<16;n++)
{
if(0==cnt)
{
break;
}
isr_sem_send(UartQueue0.txSem.sem);
cnt--;
U0THR = *UartQueue1.txPop;
UartQueue1.txPop++;
if(UartQueue1.txPop == &UartQueue1.txBuf)
{
UartQueue1.txPop = UartQueue1.txBuf;
}
}
UartQueue1.txTick = n;
}
else
{
UartQueue1.txTick = 0;
}
}
void UART1_IRQ(void) __irq
{
INT32U INT_ID;
INT_ID = U1IIR & 0x0E;
if ((0x04 == INT_ID) || (0x0C == INT_ID))
{
/* Receive interrupt */
Uart1RxIsr();
}
else if (0x02 == INT_ID)
{
/* Transmit interrupt */
Uart1TxIsr();
}
VICVectAddr = 0; /* Acknowledge Interrupt */
}
/*UART INIT */
void UartIntConfig(INT8U port,INT8U slot,INT32U baud)
{
if(port == PORT_UART0)
{
PINSEL0 &= 0xFFFFFFF0;
PINSEL0 |= 0x00000005;
PCONP = PCONP|0x08;
U0LCR = 0x83;
U0DLM = (FPCLK / 16) / baud / 256;
U0DLL = (FPCLK / 16) / baud % 256;
U0LCR = 0x03;
U0FCR = 0x87;
U0IER = 0x03;
*(INT32U*)((INT32U)(&VICVectAddr0) + slot*4) = (U32)UART0_IRQ;
*(INT32U*)((INT32U)(&VICVectCntl0) + slot*4) = (0x20 | VIC_UART0);
VICIntEnable = (INT32U)(1 << VIC_UART0);
UartQueueInit(&UartQueue0);
}
else if(port == PORT_UART1)
{
PINSEL0 &= 0xFFFFFFF0;
PINSEL0 |= 0x00000005;
PCONP = PCONP|0x08;
U1LCR = 0x83;
U1DLM = (FPCLK / 16) / baud / 256;
U1DLL = (FPCLK / 16) / baud % 256;
U1LCR = 0x03;
U1FCR = 0x87;
U1IER = 0x03;
*(INT32U*)((INT32U)(&VICVectAddr0) + slot*4) = (U32)UART1_IRQ;
*(INT32U*)((INT32U)(&VICVectCntl0) + slot*4) = (0x20 | VIC_UART1);
VICIntEnable = (INT32U)(1 << VIC_UART1);
UartQueueInit(&UartQueue1);
}
}
页:
[1]