Compare commits
2 commits
6d5e8152aa
...
33e969b5a2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33e969b5a2 | ||
|
|
d11527f131 |
3 changed files with 138 additions and 37 deletions
8
gpio.h
8
gpio.h
|
|
@ -23,7 +23,7 @@
|
|||
* 0.15: (45) AD1.5 Ineg (EINT)
|
||||
* 0.16: (46) SSP SSEL/MCLK MAT0.2
|
||||
* 0.17: (47) SSP SCK
|
||||
* 0.18: (53) SSP MISO
|
||||
* 0.18: (53) SSP MISO (CAP1.3)
|
||||
* 0.19: (54) SSP MOSI
|
||||
* 0.20: (55) SSL SSEL ADC
|
||||
* 0.21: (1) AD1.6 Vpos (PWM)
|
||||
|
|
@ -33,9 +33,9 @@
|
|||
* 0.25: (9) AOUT (AD0.4)
|
||||
* 0.26:
|
||||
* 0.27:
|
||||
* 0.28: (13) AD0.1 (MAT)
|
||||
* 0.29: (14) AD0.2 (MAT)
|
||||
* 0.30: (15) AD0.3 (MAT, EINT)
|
||||
* 0.28: (13) AD0.1 (MAT0.2, CAP0.2)
|
||||
* 0.29: (14) AD0.2 (MAT0.3, CAP0.3)
|
||||
* 0.30: (15) AD0.3 (CAP0.0, EINT3)
|
||||
* 0.31: (17) USB UP_LED
|
||||
*
|
||||
* 1.16: (16) GPIO OUT (internal pull-up)
|
||||
|
|
|
|||
6
uart.h
6
uart.h
|
|
@ -48,10 +48,12 @@ inline static void streol(char *s, int n)
|
|||
}
|
||||
|
||||
enum {
|
||||
UART1_RX_FLAG_READLINE = 1,
|
||||
UART1_RX_FLAG_READLINE = 1,
|
||||
UART1_RX_FLAG_ALL_OR_NOTHING = 2,
|
||||
UART1_RX_FLAG_FLUSH = 4,
|
||||
UART1_RX_FLAG_FLUSH = 4,
|
||||
UART1_RX_FLAG_SEND = 8
|
||||
};
|
||||
|
||||
unsigned int uart1_receive(char *s, unsigned int n, unsigned int flags);
|
||||
int uart1_send(const char *s, unsigned int n);
|
||||
|
||||
|
|
|
|||
161
uart1.c
161
uart1.c
|
|
@ -5,17 +5,20 @@
|
|||
#include <lpc2148/vic.h>
|
||||
#include <string.h>
|
||||
#include "mainloop.h"
|
||||
#include "message.h"
|
||||
#include "parser.h"
|
||||
|
||||
static char uart1_buffer[128];
|
||||
#define buffer_size (sizeof(uart1_buffer))
|
||||
#define buffer(p) uart1_buffer[(p) & (buffer_size - 1)]
|
||||
#define buffer_mask (buffer_size-1)
|
||||
#define buffer(p) uart1_buffer[(p) & buffer_mask]
|
||||
|
||||
// all access must be with irqs disabled, no volatile
|
||||
|
||||
unsigned int tx_read;
|
||||
unsigned int tx_write;
|
||||
unsigned int rx_read;
|
||||
unsigned int rx_write;
|
||||
static unsigned int tx_read;
|
||||
static unsigned int tx_write;
|
||||
static unsigned int rx_read;
|
||||
static unsigned int rx_write;
|
||||
|
||||
// uart1_buffer invariants:
|
||||
// buffer_size = 2^n
|
||||
|
|
@ -28,20 +31,21 @@ unsigned int rx_write;
|
|||
inline static
|
||||
void free_rx_space()
|
||||
{
|
||||
if (rx_read + buffer_size == tx_write)
|
||||
return;
|
||||
if (rx_read == rx_write) {
|
||||
rx_read = rx_write = tx_read - buffer_size;
|
||||
rx_read = rx_write = tx_write - buffer_size;
|
||||
return;
|
||||
}
|
||||
if (tx_read == tx_write) {
|
||||
tx_read = tx_write = rx_read + buffer_size;
|
||||
return;
|
||||
}
|
||||
if (rx_read == tx_write)
|
||||
return;
|
||||
unsigned int nrx_write = tx_write - buffer_size;
|
||||
rx_read = nrx_write;
|
||||
unsigned int nrx_read = nrx_write;
|
||||
while (rx_read != rx_write)
|
||||
buffer(nrx_write++) = buffer(rx_read++);
|
||||
rx_read = nrx_read;
|
||||
rx_write = nrx_write;
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +113,29 @@ int uart1_status()
|
|||
unsigned int uart1_interrupt_count;
|
||||
unsigned int uart1_overflow;
|
||||
unsigned int uart1_frame_errors;
|
||||
unsigned int uart1_mode;
|
||||
|
||||
struct uart1_match {
|
||||
unsigned char size; // available message length
|
||||
unsigned char val; // eol char
|
||||
unsigned char max; // max line length to wait for
|
||||
unsigned char mask; // mask char for eol
|
||||
} uart1_match = {
|
||||
.size = 0,
|
||||
.max = 96,
|
||||
.mask = 0xff,
|
||||
.val = '\n',
|
||||
};
|
||||
|
||||
const struct keywords uart1_variable_names[] = {
|
||||
VARIABLE("uart_mode", &uart1_mode),
|
||||
VARIABLE("uart_match", &uart1_match),
|
||||
VARIABLE("uart_irqs", &uart1_interrupt_count),
|
||||
VARIABLE("uart_overflow", &uart1_overflow),
|
||||
VARIABLE("uart_errors", &uart1_frame_errors),
|
||||
VARIABLE("uart_buffer", &uart1_buffer),
|
||||
KW_END
|
||||
};
|
||||
|
||||
inline static
|
||||
unsigned int drain_rx_fifo(unsigned int lsr)
|
||||
|
|
@ -127,10 +154,16 @@ unsigned int drain_rx_fifo(unsigned int lsr)
|
|||
break;
|
||||
}
|
||||
}
|
||||
buffer(rx_write++) = U1RBR;
|
||||
char d = U1RBR;
|
||||
buffer(rx_write++) = d;
|
||||
iir = U1IIR;
|
||||
lsr = U1LSR;
|
||||
unsigned int n = rx_write - rx_read;
|
||||
if ((d & uart1_match.mask) == uart1_match.val
|
||||
|| n >= uart1_match.max)
|
||||
uart1_match.size = n;
|
||||
}
|
||||
|
||||
if (!(lsr & UART_LSR_RDR))
|
||||
U1IER |= UART_IER_RBR;
|
||||
return lsr;
|
||||
|
|
@ -164,7 +197,8 @@ void uart1_init()
|
|||
U1LCR = 0;
|
||||
U1IER = 0;
|
||||
barrier();
|
||||
tx_read = tx_write = rx_read = rx_write = 0;
|
||||
rx_read = rx_write = 0;
|
||||
tx_read = tx_write = buffer_size;
|
||||
|
||||
U1FCR = UART_FCR_Enable | UART_FCR_RxReset | UART_FCR_TxReset | UART_FCR_RxTrigger_14;
|
||||
U1LCR = UART_LCR_DLAB;
|
||||
|
|
@ -176,7 +210,8 @@ void uart1_init()
|
|||
U1LCR = UART_LCR_8bits | UART_LCR_ParityNone;
|
||||
|
||||
baudrate1 = baud_rates[baud1_select].baud;
|
||||
|
||||
|
||||
U1IER |= UART_IER_RBR;
|
||||
VICVectAddrs[IrqVec_UART1] = uart1_isr;
|
||||
VICVectCntl[IrqVec_UART1] = VICVectCntl_UART1;
|
||||
VICIntEnable = VIC_UART1;
|
||||
|
|
@ -185,11 +220,19 @@ void uart1_init()
|
|||
int uart1_send(const char *s, unsigned int n)
|
||||
{
|
||||
unsigned int iflag = disable_irq(IRQ_DISABLE);
|
||||
if (free_tx_space(n) < n)
|
||||
return 0;
|
||||
unsigned int tx_write = tx_write;
|
||||
memcpy(&buffer(tx_write), s , n);
|
||||
if (free_tx_space(n) < n) {
|
||||
n = 0;
|
||||
goto full;
|
||||
}
|
||||
unsigned int nn = buffer_size - (tx_write & buffer_mask);
|
||||
if (nn >= n)
|
||||
memcpy(&buffer(tx_write), s, n);
|
||||
else {
|
||||
memcpy(&buffer(tx_write), s, nn);
|
||||
memcpy(&buffer(0), s+nn, n - nn);
|
||||
}
|
||||
tx_write += n;
|
||||
full:
|
||||
uart1_poll(U1LSR);
|
||||
enable_irq(iflag);
|
||||
return n;
|
||||
|
|
@ -199,31 +242,87 @@ unsigned int uart1_receive(char *s, unsigned int n, unsigned int flags)
|
|||
{
|
||||
unsigned int iflag = disable_irq(IRQ_DISABLE);
|
||||
drain_rx_fifo(U1LSR);
|
||||
unsigned int b = rx_write - rx_read;
|
||||
enable_irq(iflag);
|
||||
|
||||
unsigned int r = 0;
|
||||
if (rx_write - rx_read < n && flags & UART1_RX_FLAG_ALL_OR_NOTHING)
|
||||
goto empty;
|
||||
if (!n)
|
||||
goto flush;
|
||||
|
||||
if (b > n)
|
||||
b = n;
|
||||
if (flags & UART1_RX_FLAG_READLINE) {
|
||||
if (b >= n)
|
||||
b = n - 1;
|
||||
unsigned int i;
|
||||
for (i = rx_read; i < rx_write; i++)
|
||||
if (buffer(i) == '\n')
|
||||
for (i = 0; i < b; i++)
|
||||
if ((buffer(rx_read+i) & uart1_match.mask) == uart1_match.val)
|
||||
break;
|
||||
i -= rx_read;
|
||||
i++;
|
||||
if (i >= n)
|
||||
i = n - 1;
|
||||
n = i;
|
||||
s[n] = '\0';
|
||||
if (i == b && i < uart1_match.max && n > uart1_match.max)
|
||||
b = 0;
|
||||
else
|
||||
b = i;
|
||||
if (s)
|
||||
s[b] = '\0';
|
||||
}
|
||||
unsigned int b = rx_write - rx_read;
|
||||
if (n)
|
||||
memcpy(s, &buffer(rx_read), n);
|
||||
rx_read += n;
|
||||
else if (b < n && flags & UART1_RX_FLAG_ALL_OR_NOTHING)
|
||||
goto empty;
|
||||
|
||||
if (!b)
|
||||
goto empty;
|
||||
|
||||
unsigned int bb = buffer_size - (rx_read & buffer_mask);
|
||||
if (s)
|
||||
if (bb >= b)
|
||||
memcpy(s, &buffer(rx_read), b);
|
||||
else {
|
||||
memcpy(s, &buffer(rx_read), bb);
|
||||
memcpy(s + bb, &buffer(0), b - bb);
|
||||
}
|
||||
|
||||
if (flags & UART1_RX_FLAG_SEND)
|
||||
if (flags & UART1_RX_FLAG_READLINE) {
|
||||
if (s)
|
||||
printf("UT %s←UT\n", s);
|
||||
else if (bb >= b)
|
||||
printf("UT %.*s←UT\n", b, &buffer(rx_read));
|
||||
else
|
||||
printf("UT %.*s%.*s←UT\n",
|
||||
bb, &buffer(rx_read),
|
||||
b - bb, &buffer(rx_read + bb) );
|
||||
}
|
||||
else {
|
||||
printf("UX");
|
||||
for (unsigned int i=0; i < b; i++)
|
||||
printf(" %02x", buffer(rx_read+i));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
rx_read += b;
|
||||
r = b;
|
||||
|
||||
flush:
|
||||
if (flags & UART1_RX_FLAG_FLUSH)
|
||||
if (flags & UART1_RX_FLAG_FLUSH) {
|
||||
rx_read = rx_write;
|
||||
uart1_match.size = 0;
|
||||
}
|
||||
|
||||
empty:
|
||||
U1IER |= UART_IER_RBR;
|
||||
|
||||
iflag = disable_irq(IRQ_DISABLE);
|
||||
b = rx_write - rx_read;
|
||||
if (b >= uart1_match.max)
|
||||
uart1_match.size = b;
|
||||
else {
|
||||
uart1_match.size = 0;
|
||||
for (unsigned int i=0; i<b; i++)
|
||||
if ((buffer(rx_read+i) & uart1_match.mask) == uart1_match.val) {
|
||||
uart1_match.size = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enable_irq(iflag);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue