LPC2142做的一个基于RTX操作系统的UART程序,数据量大了会错
#define INT_LOCK(p) do{p = VICIntEnable;VICIntEnClr = (U32)0xFFFFFFFF;}while(0)#define INT_UNLOCK(p) do{VICIntEnable = p;}while(0)
typedef struct{
OS_SEM rxSem;
INT16U rxFill;
INT8U*rxPush;
INT8U*rxPop;
INT8UrxBuf;
INT8U rxTick;
OS_SEM txSem;
INT16U txFree;
INT8U*txPush;
INT8U*txPop;
INT8UtxBuf;
INT8UtxTick;
}UartQueue_t;
UartQueue_t UartQueue0;
UartQueue_t UartQueue1;
static void UartQueueInit(UartQueue_t* queue)
{
os_sem_init (queue->rxSem, 0);
queue->rxFill = 0;
queue->rxPush = queue->rxBuf;
queue->rxPop= queue->rxBuf;
queue->rxTick = 0;
os_sem_init (queue->txSem, UART_TX_SIZE);
queue->txFree = UART_TX_SIZE;
queue->txPush = queue->txBuf;
queue->txPop= queue->txBuf;
queue->txTick = UART_TX_EMPTY;
}
static BOOL UartRxPush(INT8U c,UartQueue_t* queue) //in isr
{
if(queue->rxFill < UART_RX_SIZE)
{
*queue->rxPush = c;
queue->rxPush++;
if(queue->rxPush == (queue->rxBuf + UART_RX_SIZE))
{
queue->rxPush = queue->rxBuf;
}
queue->rxFill++;
isr_sem_send(queue->rxSem);
return TRUE;
}
return FALSE;
}
static BOOL UartTxPop(INT8U *c,UartQueue_t* queue) //in isr
{
if(queue->txFree < UART_TX_SIZE)
{
isr_sem_send(queue->txSem);
queue->txFree++;
queue->txPop++;
if(queue->txPop == (queue->txBuf + UART_TX_SIZE))
{
queue->txPop = queue->txBuf;
}
if(queue->txFree < UART_TX_SIZE)
{
*c = *queue->txPop;
return TRUE;
}
}
return FALSE;
}
//run in task
static BOOL UartRxPop(INT8U *c,UartQueue_t* queue,INT16U timeout)
{
if(OS_R_TMO != os_sem_wait(queue->rxSem,timeout))
{
INT32U p;
INT_LOCK(p);
if(queue->rxFill)
{
*c = *queue->rxPop;
queue->rxPop++;
if(queue->rxPop == (queue->rxBuf + UART_RX_SIZE))
{
queue->rxPop = queue->rxBuf;
}
queue->rxFill --;
}
INT_UNLOCK(p);
return TRUE;
}
return FALSE;
}
//run in task
static BOOL UartTxPush(INT8U c,UartQueue_t* queue,INT16U timeout)
{
if(OS_R_TMO != os_sem_wait(queue->txSem,timeout))
{
INT32U p;
INT_LOCK(p);
if(queue->txFree)
{
*queue->txPush = c;
queue->txPush++;
if(queue->txPush == (queue->txBuf + UART_TX_SIZE))
{
queue->txPush = queue->txBuf;
}
queue->txFree--;
}
INT_UNLOCK(p);
return TRUE;
}
return FALSE;
}
/*
static INT16U UartRxFill(UartQueue_t* queue)
{
return queue->rxFill;
}
//
static INT16U UartTxFree(UartQueue_t* queue)
{
return queue->txFree;
}
*/
/*
INT16U UartRead(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
*/
INT16U UartRead(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
INT16U n;
UartQueue_t *pqueue;
tsk_lock();
switch(port)
{
case PORT_UART0:
pqueue = &UartQueue0;
break;
case PORT_UART1:
pqueue = &UartQueue1;
break;
}
UartQueue0.rxTick = 0;
for(n=0;n<size;n++)
{
if(FALSE == UartRxPop(buf,pqueue,timeout))
{
break;
}
buf++;
}
tsk_unlock();
return n;
}
INT16U UartWrite(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
INT16U n = 0;
UartQueue_t *pqueue;
INT8Uch,*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;
ch = *buf;
for(n=0;n<size;n++)
{
if(FALSE == UartTxPush(*buf,pqueue,0))
{
break;
}
buf++;
}
if(UART_TX_EMPTY == pqueue->txTick)
{
*thr = ch;
pqueue->txTick = UART_TX_FULL;
}
*ier |= 0x02;
for(;n<size;n++)
{
if(FALSE == UartTxPush(*buf,pqueue,timeout))
{
break;
}
buf++;
}
tsk_unlock();
return n;
}
/*---- UART 0 INTERRUPT ----*/
void UART0_IRQ(void) __irq
{
INT32U INT_ID;
INT8U i;
INT_ID = U0IIR & 0x0E;
if ((0x04 == INT_ID) || (0x0C == INT_ID))
{
/* Receive interrupt */
for(i=0;i<16;i++)
{
if ((U0LSR & 0x01)==0)
{
break;
}
UartRxPush(U0RBR,&UartQueue0);
}
UartQueue0.rxTick = i;
}
else if (0x02 == INT_ID)
{
INT8U c;
/* Transmit interrupt */
for(i=0;i<16;i++)
{
if(FALSE == UartTxPop(&c,&UartQueue0))
{
UartQueue0.txTick = UART_TX_EMPTY;
break;
}
U0THR = c;
}
}
VICVectAddr = 0; /* Acknowledge Interrupt */
}
/*---- UART 1 INTERRUPT ----*/
void UART1_IRQ(void) __irq
{
INT32U INT_ID;
INT8U i;
INT_ID = U1IIR & 0x0E;
if ((0x04 == INT_ID) || (0x0C == INT_ID))
{
/* Receive interrupt */
for(i=0;i<16;i++)
{
if ((U1LSR & 0x01)==0)
{
break;
}
UartRxPush(U1RBR,&UartQueue1);
}
UartQueue1.rxTick = i;
}
else if (0x02 == INT_ID)
{
INT8U c;
/* Transmit interrupt */
for(i=0;i<16;i++)
{
if(FALSE == UartTxPop(&c,&UartQueue1))
{
UartQueue1.txTick = UART_TX_EMPTY;
break;
}
U1THR = c;
}
}
VICVectAddr = 0; /* Acknowledge Interrupt */
}
/*UART INIT */
void UartIntiFonfig(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]