166 lines
3.3 KiB
C
166 lines
3.3 KiB
C
#include <string.h>
|
|
#include "LPC2300.h"
|
|
#include "interrupt.h"
|
|
#include "comm.h"
|
|
|
|
|
|
#define BUFFER_SIZE 128
|
|
|
|
#define PCLK 18000000
|
|
#define BPS 230400
|
|
#define DIVADDVAL 5
|
|
#define MULVAL 8
|
|
#define DLVAL ((int)((double)PCLK / BPS / 16 / (1 + (double)DIVADDVAL / MULVAL)))
|
|
|
|
|
|
static volatile struct
|
|
{
|
|
int rptr;
|
|
int wptr;
|
|
int count;
|
|
BYTE buff[BUFFER_SIZE];
|
|
} TxFifo0, RxFifo0;
|
|
static volatile int TxRun0;
|
|
|
|
|
|
|
|
|
|
void Isr_UART0 (void)
|
|
{
|
|
int d, idx, cnt, iir;
|
|
|
|
|
|
for (;;) {
|
|
iir = U0IIR; /* Get Interrupt ID*/
|
|
if (iir & 1) break; /* Exit if there is no interrupt */
|
|
switch (iir & 6) {
|
|
case 4: /* Receive FIFO is half filled or timeout occured */
|
|
idx = RxFifo0.wptr;
|
|
cnt = RxFifo0.count;
|
|
while (U0LSR & 0x01) { /* Receive all data in the FIFO */
|
|
d = U0RBR;
|
|
if (cnt < BUFFER_SIZE) { /* Store data if buffer is not full */
|
|
RxFifo0.buff[idx] = d;
|
|
cnt++;
|
|
idx = (idx + 1) % BUFFER_SIZE;
|
|
}
|
|
}
|
|
RxFifo0.wptr = idx;
|
|
RxFifo0.count = cnt;
|
|
break;
|
|
|
|
case 2: /* Transmisson FIFO empty */
|
|
cnt = TxFifo0.count;
|
|
if (cnt) {
|
|
idx = TxFifo0.rptr;
|
|
for (d = 12; d && cnt; d--, cnt--) { /* Store data into FIFO (max 12 chrs) */
|
|
U0THR = TxFifo0.buff[idx];
|
|
idx = (idx + 1) % BUFFER_SIZE;
|
|
}
|
|
TxFifo0.rptr = idx;
|
|
TxFifo0.count = cnt;
|
|
} else {
|
|
TxRun0 = 0; /* When no data in the buffer, clear running flag */
|
|
}
|
|
break;
|
|
|
|
default: /* Data error or break detected */
|
|
d = U0LSR;
|
|
d = U0RBR;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
int uart0_test (void)
|
|
{
|
|
return RxFifo0.count;
|
|
}
|
|
|
|
|
|
|
|
|
|
BYTE uart0_get (void)
|
|
{
|
|
BYTE d;
|
|
int idx;
|
|
|
|
/* Wait while Rx buffer is empty */
|
|
while (!RxFifo0.count);
|
|
|
|
U0IER = 0; /* Disable interrupts */
|
|
idx = RxFifo0.rptr;
|
|
d = RxFifo0.buff[idx]; /* Get a byte from Rx buffer */
|
|
RxFifo0.rptr = (idx + 1) % BUFFER_SIZE;
|
|
RxFifo0.count--;
|
|
U0IER = 0x07; /* Enable interrupt */
|
|
|
|
return d;
|
|
}
|
|
|
|
|
|
|
|
|
|
void uart0_put (BYTE d)
|
|
{
|
|
#if 0
|
|
while (!(U0LSR & 0x20));
|
|
U0THR = d;
|
|
#else
|
|
int idx, cnt;
|
|
|
|
/* Wait for buffer ready */
|
|
while (TxFifo0.count >= BUFFER_SIZE);
|
|
|
|
U0IER = 0x05; /* Disable Tx Interrupt */
|
|
if (!TxRun0) { /* When not in runnig, trigger transmission */
|
|
U0THR = d;
|
|
TxRun0 = 1;
|
|
} else { /* When transmission is runnig, store the data into the Tx buffer */
|
|
cnt = TxFifo0.count;
|
|
idx = TxFifo0.wptr;
|
|
TxFifo0.buff[idx] = d;
|
|
TxFifo0.wptr = (idx + 1) % BUFFER_SIZE;
|
|
TxFifo0.count = ++cnt;
|
|
}
|
|
U0IER = 0x07; /* Enable Tx Interrupt */
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
void uart0_init (void)
|
|
{
|
|
U0IER = 0x00;
|
|
RegisterVector(UART0_INT, Isr_UART0, PRI_LOWEST, CLASS_IRQ);
|
|
|
|
/* Attach UART0 unit to I/O pad */
|
|
PINSEL0 = (PINSEL0 & 0xFFFFFF0F) | 0x50;
|
|
|
|
/* Initialize UART0 */
|
|
U0LCR = 0x83; /* Select divisor latch */
|
|
U0DLM = DLVAL / 256; /* Initialize BRG */
|
|
U0DLL = DLVAL % 256;
|
|
U0FDR = (MULVAL << 4) | DIVADDVAL;
|
|
U0LCR = 0x03; /* Set serial format N81 and deselect divisor latch */
|
|
U0FCR = 0x87; /* Enable FIFO */
|
|
U0TER = 0x80; /* Enable Tansmission */
|
|
|
|
/* Clear Tx/Rx FIFOs */
|
|
TxFifo0.rptr = 0;
|
|
TxFifo0.wptr = 0;
|
|
TxFifo0.count = 0;
|
|
RxFifo0.rptr = 0;
|
|
RxFifo0.wptr = 0;
|
|
RxFifo0.count = 0;
|
|
|
|
/* Enable Tx/Rx/Error interrupts */
|
|
U0IER = 0x07;
|
|
}
|
|
|
|
|