summaryrefslogtreecommitdiffstats
path: root/pressure_control/firmware
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-10-23 21:24:31 +0200
committerMichael Buesch <mb@bu3sch.de>2008-10-23 21:24:31 +0200
commit13ff7496a156bb366b7c861575ba77b1ed337dfb (patch)
tree76cc5ade830a8a3443668b8fe619a6f1403b941a /pressure_control/firmware
parent5d469653af9d29a7747d88225f65284fad71cd6f (diff)
downloadcnc-13ff7496a156bb366b7c861575ba77b1ed337dfb.tar.xz
cnc-13ff7496a156bb366b7c861575ba77b1ed337dfb.zip
pressure_control: Fix uart handling
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Diffstat (limited to 'pressure_control/firmware')
-rw-r--r--pressure_control/firmware/remote.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/pressure_control/firmware/remote.c b/pressure_control/firmware/remote.c
index 6607098..dafca5d 100644
--- a/pressure_control/firmware/remote.c
+++ b/pressure_control/firmware/remote.c
@@ -35,6 +35,7 @@
static struct remote_message rx_msg;
static uint8_t rx_msg_count;
static bool rx_msg_valid;
+static bool rx_softirq;
static inline void usart_tx(uint8_t data)
@@ -63,21 +64,22 @@ static void usart_tx_buf(const void *_buf, uint8_t size)
static inline int8_t usart_rx(uint8_t *data)
{
uint8_t status;
+ int8_t err = 0;
status = UCSRA;
if (!(status & (1 << RXC)))
return -ENODATA;
if (unlikely(status & ((1 << FE) | (1 << PE) | (1 << DOR)))) {
if (status & (1 << FE))
- return -ERXFE;
+ err = -ERXFE;
if (status & (1 << PE))
- return -ERXPE;
+ err = -ERXPE;
if (status & (1 << DOR))
- return -ERXOV;
+ err = -ERXOV;
}
*data = UDR;
- return 0;
+ return err;
}
static void send_message(struct remote_message *msg)
@@ -219,24 +221,18 @@ out:
}
}
-/* RX interrupt */
-ISR(USART_RXC_vect)
+static void usart_handle_rx_irq(void)
{
uint8_t *rxbuf = (uint8_t *)&rx_msg;
int8_t err;
uint8_t data;
- if (rx_msg_valid)
- return;
-
while (1) {
err = usart_rx(&data);
if (err == -ENODATA)
break;
- if (unlikely(err)) {
- //TODO other error
- data = 0;
- }
+ /* Ignore other errors. The CRC check will detect them later. */
+
rxbuf[rx_msg_count++] = data;
if (rx_msg_count == sizeof(struct remote_message)) {
rx_msg_count = 0;
@@ -247,6 +243,17 @@ ISR(USART_RXC_vect)
}
}
+/* RX interrupt */
+ISR(USART_RXC_vect)
+{
+ if (rx_msg_valid) {
+ /* We're busy. Schedule a software IRQ for later. */
+ rx_softirq = 1;
+ return;
+ }
+ usart_handle_rx_irq();
+}
+
void print_pgm(const prog_char *str)
{
struct remote_message msg;
@@ -276,6 +283,12 @@ void remote_work(void)
mb();
rx_msg_valid = 0;
}
+ cli();
+ if (rx_softirq) {
+ rx_softirq = 0;
+ usart_handle_rx_irq();
+ }
+ sei();
}
void remote_pressure_change_notification(uint16_t mbar,
bues.ch cgit interface