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.15: (45) AD1.5 Ineg (EINT)
|
||||||
* 0.16: (46) SSP SSEL/MCLK MAT0.2
|
* 0.16: (46) SSP SSEL/MCLK MAT0.2
|
||||||
* 0.17: (47) SSP SCK
|
* 0.17: (47) SSP SCK
|
||||||
* 0.18: (53) SSP MISO
|
* 0.18: (53) SSP MISO (CAP1.3)
|
||||||
* 0.19: (54) SSP MOSI
|
* 0.19: (54) SSP MOSI
|
||||||
* 0.20: (55) SSL SSEL ADC
|
* 0.20: (55) SSL SSEL ADC
|
||||||
* 0.21: (1) AD1.6 Vpos (PWM)
|
* 0.21: (1) AD1.6 Vpos (PWM)
|
||||||
|
|
@ -33,9 +33,9 @@
|
||||||
* 0.25: (9) AOUT (AD0.4)
|
* 0.25: (9) AOUT (AD0.4)
|
||||||
* 0.26:
|
* 0.26:
|
||||||
* 0.27:
|
* 0.27:
|
||||||
* 0.28: (13) AD0.1 (MAT)
|
* 0.28: (13) AD0.1 (MAT0.2, CAP0.2)
|
||||||
* 0.29: (14) AD0.2 (MAT)
|
* 0.29: (14) AD0.2 (MAT0.3, CAP0.3)
|
||||||
* 0.30: (15) AD0.3 (MAT, EINT)
|
* 0.30: (15) AD0.3 (CAP0.0, EINT3)
|
||||||
* 0.31: (17) USB UP_LED
|
* 0.31: (17) USB UP_LED
|
||||||
*
|
*
|
||||||
* 1.16: (16) GPIO OUT (internal pull-up)
|
* 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 {
|
enum {
|
||||||
UART1_RX_FLAG_READLINE = 1,
|
UART1_RX_FLAG_READLINE = 1,
|
||||||
UART1_RX_FLAG_ALL_OR_NOTHING = 2,
|
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);
|
unsigned int uart1_receive(char *s, unsigned int n, unsigned int flags);
|
||||||
int uart1_send(const char *s, unsigned int n);
|
int uart1_send(const char *s, unsigned int n);
|
||||||
|
|
||||||
|
|
|
||||||
161
uart1.c
161
uart1.c
|
|
@ -5,17 +5,20 @@
|
||||||
#include <lpc2148/vic.h>
|
#include <lpc2148/vic.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mainloop.h"
|
#include "mainloop.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
static char uart1_buffer[128];
|
static char uart1_buffer[128];
|
||||||
#define buffer_size (sizeof(uart1_buffer))
|
#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
|
// all access must be with irqs disabled, no volatile
|
||||||
|
|
||||||
unsigned int tx_read;
|
static unsigned int tx_read;
|
||||||
unsigned int tx_write;
|
static unsigned int tx_write;
|
||||||
unsigned int rx_read;
|
static unsigned int rx_read;
|
||||||
unsigned int rx_write;
|
static unsigned int rx_write;
|
||||||
|
|
||||||
// uart1_buffer invariants:
|
// uart1_buffer invariants:
|
||||||
// buffer_size = 2^n
|
// buffer_size = 2^n
|
||||||
|
|
@ -28,20 +31,21 @@ unsigned int rx_write;
|
||||||
inline static
|
inline static
|
||||||
void free_rx_space()
|
void free_rx_space()
|
||||||
{
|
{
|
||||||
|
if (rx_read + buffer_size == tx_write)
|
||||||
|
return;
|
||||||
if (rx_read == rx_write) {
|
if (rx_read == rx_write) {
|
||||||
rx_read = rx_write = tx_read - buffer_size;
|
rx_read = rx_write = tx_write - buffer_size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (tx_read == tx_write) {
|
if (tx_read == tx_write) {
|
||||||
tx_read = tx_write = rx_read + buffer_size;
|
tx_read = tx_write = rx_read + buffer_size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rx_read == tx_write)
|
|
||||||
return;
|
|
||||||
unsigned int nrx_write = tx_write - buffer_size;
|
unsigned int nrx_write = tx_write - buffer_size;
|
||||||
rx_read = nrx_write;
|
unsigned int nrx_read = nrx_write;
|
||||||
while (rx_read != rx_write)
|
while (rx_read != rx_write)
|
||||||
buffer(nrx_write++) = buffer(rx_read++);
|
buffer(nrx_write++) = buffer(rx_read++);
|
||||||
|
rx_read = nrx_read;
|
||||||
rx_write = nrx_write;
|
rx_write = nrx_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,6 +113,29 @@ int uart1_status()
|
||||||
unsigned int uart1_interrupt_count;
|
unsigned int uart1_interrupt_count;
|
||||||
unsigned int uart1_overflow;
|
unsigned int uart1_overflow;
|
||||||
unsigned int uart1_frame_errors;
|
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
|
inline static
|
||||||
unsigned int drain_rx_fifo(unsigned int lsr)
|
unsigned int drain_rx_fifo(unsigned int lsr)
|
||||||
|
|
@ -127,10 +154,16 @@ unsigned int drain_rx_fifo(unsigned int lsr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer(rx_write++) = U1RBR;
|
char d = U1RBR;
|
||||||
|
buffer(rx_write++) = d;
|
||||||
iir = U1IIR;
|
iir = U1IIR;
|
||||||
lsr = U1LSR;
|
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))
|
if (!(lsr & UART_LSR_RDR))
|
||||||
U1IER |= UART_IER_RBR;
|
U1IER |= UART_IER_RBR;
|
||||||
return lsr;
|
return lsr;
|
||||||
|
|
@ -164,7 +197,8 @@ void uart1_init()
|
||||||
U1LCR = 0;
|
U1LCR = 0;
|
||||||
U1IER = 0;
|
U1IER = 0;
|
||||||
barrier();
|
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;
|
U1FCR = UART_FCR_Enable | UART_FCR_RxReset | UART_FCR_TxReset | UART_FCR_RxTrigger_14;
|
||||||
U1LCR = UART_LCR_DLAB;
|
U1LCR = UART_LCR_DLAB;
|
||||||
|
|
@ -176,7 +210,8 @@ void uart1_init()
|
||||||
U1LCR = UART_LCR_8bits | UART_LCR_ParityNone;
|
U1LCR = UART_LCR_8bits | UART_LCR_ParityNone;
|
||||||
|
|
||||||
baudrate1 = baud_rates[baud1_select].baud;
|
baudrate1 = baud_rates[baud1_select].baud;
|
||||||
|
|
||||||
|
U1IER |= UART_IER_RBR;
|
||||||
VICVectAddrs[IrqVec_UART1] = uart1_isr;
|
VICVectAddrs[IrqVec_UART1] = uart1_isr;
|
||||||
VICVectCntl[IrqVec_UART1] = VICVectCntl_UART1;
|
VICVectCntl[IrqVec_UART1] = VICVectCntl_UART1;
|
||||||
VICIntEnable = VIC_UART1;
|
VICIntEnable = VIC_UART1;
|
||||||
|
|
@ -185,11 +220,19 @@ void uart1_init()
|
||||||
int uart1_send(const char *s, unsigned int n)
|
int uart1_send(const char *s, unsigned int n)
|
||||||
{
|
{
|
||||||
unsigned int iflag = disable_irq(IRQ_DISABLE);
|
unsigned int iflag = disable_irq(IRQ_DISABLE);
|
||||||
if (free_tx_space(n) < n)
|
if (free_tx_space(n) < n) {
|
||||||
return 0;
|
n = 0;
|
||||||
unsigned int tx_write = tx_write;
|
goto full;
|
||||||
memcpy(&buffer(tx_write), s , n);
|
}
|
||||||
|
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;
|
tx_write += n;
|
||||||
|
full:
|
||||||
uart1_poll(U1LSR);
|
uart1_poll(U1LSR);
|
||||||
enable_irq(iflag);
|
enable_irq(iflag);
|
||||||
return n;
|
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);
|
unsigned int iflag = disable_irq(IRQ_DISABLE);
|
||||||
drain_rx_fifo(U1LSR);
|
drain_rx_fifo(U1LSR);
|
||||||
|
unsigned int b = rx_write - rx_read;
|
||||||
|
enable_irq(iflag);
|
||||||
|
|
||||||
unsigned int r = 0;
|
unsigned int r = 0;
|
||||||
if (rx_write - rx_read < n && flags & UART1_RX_FLAG_ALL_OR_NOTHING)
|
|
||||||
goto empty;
|
|
||||||
if (!n)
|
if (!n)
|
||||||
goto flush;
|
goto flush;
|
||||||
|
|
||||||
|
if (b > n)
|
||||||
|
b = n;
|
||||||
if (flags & UART1_RX_FLAG_READLINE) {
|
if (flags & UART1_RX_FLAG_READLINE) {
|
||||||
|
if (b >= n)
|
||||||
|
b = n - 1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = rx_read; i < rx_write; i++)
|
for (i = 0; i < b; i++)
|
||||||
if (buffer(i) == '\n')
|
if ((buffer(rx_read+i) & uart1_match.mask) == uart1_match.val)
|
||||||
break;
|
break;
|
||||||
i -= rx_read;
|
if (i == b && i < uart1_match.max && n > uart1_match.max)
|
||||||
i++;
|
b = 0;
|
||||||
if (i >= n)
|
else
|
||||||
i = n - 1;
|
b = i;
|
||||||
n = i;
|
if (s)
|
||||||
s[n] = '\0';
|
s[b] = '\0';
|
||||||
}
|
}
|
||||||
unsigned int b = rx_write - rx_read;
|
else if (b < n && flags & UART1_RX_FLAG_ALL_OR_NOTHING)
|
||||||
if (n)
|
goto empty;
|
||||||
memcpy(s, &buffer(rx_read), n);
|
|
||||||
rx_read += n;
|
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:
|
flush:
|
||||||
if (flags & UART1_RX_FLAG_FLUSH)
|
if (flags & UART1_RX_FLAG_FLUSH) {
|
||||||
rx_read = rx_write;
|
rx_read = rx_write;
|
||||||
|
uart1_match.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
empty:
|
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);
|
enable_irq(iflag);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue