diff options
-rw-r--r-- | lib/README | 4 | ||||
-rw-r--r-- | lib/pjrc_usb_serial/usb_serial.c | 12 | ||||
-rw-r--r-- | lib/pjrc_usb_serial/usb_serial.patch | 39 | ||||
-rw-r--r-- | src/avr/serial.c | 3 | ||||
-rw-r--r-- | src/avr/usbserial.c | 4 | ||||
-rw-r--r-- | src/command.c | 2 | ||||
-rw-r--r-- | src/pru/main.c | 6 | ||||
-rw-r--r-- | src/sam3x8e/serial.c | 3 | ||||
-rw-r--r-- | src/sched.c | 10 | ||||
-rw-r--r-- | src/sched.h | 1 |
10 files changed, 74 insertions, 10 deletions
@@ -3,7 +3,9 @@ This directory contains external library code. The pjrc_usb_serial directory contains code from: http://www.pjrc.com/teensy/usb_serial.html version 1.7 (extracted on 20160605). It has been modified to compile -on recent versions of gcc. See usb_serial.patch for the modifications. +on recent versions of gcc, to support asynchronous notification of +incoming data, and to not use SOF interrupts. See usb_serial.patch for +the modifications. The cmsis-sam3x8e directory contains code from the Arduino project: https://www.arduino.cc/ diff --git a/lib/pjrc_usb_serial/usb_serial.c b/lib/pjrc_usb_serial/usb_serial.c index ac5bc8a2..0c2488d5 100644 --- a/lib/pjrc_usb_serial/usb_serial.c +++ b/lib/pjrc_usb_serial/usb_serial.c @@ -325,7 +325,7 @@ void usb_init(void) UDCON = 0; // enable attach resistor usb_configuration = 0; cdc_line_rtsdtr = 0; - UDIEN = (1<<EORSTE)|(1<<SOFE); + UDIEN = (1<<EORSTE); sei(); } @@ -359,6 +359,7 @@ int16_t usb_serial_getchar(void) UEINTX = 0x6B; goto retry; } + UEIENX = (1<<RXOUTE); SREG = intr_state; return -1; } @@ -775,7 +776,14 @@ static inline void usb_ack_out(void) // ISR(USB_COM_vect) { - uint8_t intbits; + uint8_t intbits = UEINT; + if (intbits & (1<<CDC_RX_ENDPOINT)) { + UENUM = CDC_RX_ENDPOINT; + UEIENX = 0; + extern void sched_wake_tasks(void); + sched_wake_tasks(); + return; + } const uint8_t *list; const uint8_t *cfg; uint8_t i, n, len, en; diff --git a/lib/pjrc_usb_serial/usb_serial.patch b/lib/pjrc_usb_serial/usb_serial.patch index 5aaa08e8..73fef81a 100644 --- a/lib/pjrc_usb_serial/usb_serial.patch +++ b/lib/pjrc_usb_serial/usb_serial.patch @@ -1,5 +1,5 @@ ---- usb_serial.c 2011-04-19 05:54:12.000000000 -0400 -+++ usb_serial.c 2016-06-04 23:48:52.590001697 -0400 +--- ../../../lib/pjrc/usb_serial/usb_serial.c 2011-04-19 05:54:12.000000000 -0400 ++++ usb_serial.c 2017-08-07 11:32:47.106357362 -0400 @@ -30,6 +30,7 @@ // Version 1.6: fix zero length packet bug // Version 1.7: fix usb_serial_set_control @@ -62,7 +62,24 @@ uint16_t wValue; uint16_t wIndex; const uint8_t *addr; -@@ -646,7 +647,9 @@ +@@ -324,7 +325,7 @@ + UDCON = 0; // enable attach resistor + usb_configuration = 0; + cdc_line_rtsdtr = 0; +- UDIEN = (1<<EORSTE)|(1<<SOFE); ++ UDIEN = (1<<EORSTE); + sei(); + } + +@@ -358,6 +359,7 @@ + UEINTX = 0x6B; + goto retry; + } ++ UEIENX = (1<<RXOUTE); + SREG = intr_state; + return -1; + } +@@ -646,7 +648,9 @@ // communication uint32_t usb_serial_get_baud(void) { @@ -73,3 +90,19 @@ } uint8_t usb_serial_get_stopbits(void) { +@@ -772,7 +776,14 @@ + // + ISR(USB_COM_vect) + { +- uint8_t intbits; ++ uint8_t intbits = UEINT; ++ if (intbits & (1<<CDC_RX_ENDPOINT)) { ++ UENUM = CDC_RX_ENDPOINT; ++ UEIENX = 0; ++ extern void sched_wake_tasks(void); ++ sched_wake_tasks(); ++ return; ++ } + const uint8_t *list; + const uint8_t *cfg; + uint8_t i, n, len, en; diff --git a/src/avr/serial.c b/src/avr/serial.c index 10b95992..8b9dd14a 100644 --- a/src/avr/serial.c +++ b/src/avr/serial.c @@ -65,6 +65,8 @@ DECL_INIT(serial_init); ISR(USART0_RX_vect) { uint8_t data = UDR0; + if (data == MESSAGE_SYNC) + sched_wake_tasks(); if (receive_pos >= sizeof(receive_buf)) // Serial overflow - ignore it as crc error will force retransmit return; @@ -104,6 +106,7 @@ console_pop_input(uint8_t len) memmove(&receive_buf[copied], &receive_buf[copied + len] , needcopy - copied); copied = needcopy; + sched_wake_tasks(); } irqstatus_t flag = irq_save(); if (rpos != readb(&receive_pos)) { diff --git a/src/avr/usbserial.c b/src/avr/usbserial.c index 1b42d6d3..cc7bb12c 100644 --- a/src/avr/usbserial.c +++ b/src/avr/usbserial.c @@ -42,8 +42,10 @@ static void console_pop_input(uint8_t len) { uint8_t needcopy = receive_pos - len; - if (needcopy) + if (needcopy) { memmove(receive_buf, &receive_buf[len], needcopy); + sched_wake_tasks(); + } receive_pos = needcopy; } diff --git a/src/command.c b/src/command.c index 53263a8f..87284ee8 100644 --- a/src/command.c +++ b/src/command.c @@ -11,7 +11,7 @@ #include "board/misc.h" // crc16_ccitt #include "board/pgm.h" // READP #include "command.h" // output_P -#include "sched.h" // DECL_TASK +#include "sched.h" // sched_is_shutdown static uint8_t next_sequence = MESSAGE_DEST; diff --git a/src/pru/main.c b/src/pru/main.c index 3c2a2725..04d440df 100644 --- a/src/pru/main.c +++ b/src/pru/main.c @@ -85,7 +85,10 @@ timer_kick(void) static void _irq_poll(void) { - if (CT_INTC.SECR0 & (1 << IEP_EVENT)) { + uint32_t secr0 = CT_INTC.SECR0; + if (secr0 & (1 << KICK_PRU1_EVENT)) + sched_wake_tasks(); + if (secr0 & (1 << IEP_EVENT)) { CT_IEP.TMR_CMP_STS = 0xff; uint32_t next = timer_dispatch_many(); timer_set(next); @@ -121,7 +124,6 @@ console_task(void) const struct command_parser *cp = SHARED_MEM->next_command; if (!cp) return; - barrier(); if (sched_is_shutdown() && !(cp->flags & HF_IN_SHUTDOWN)) { sched_report_shutdown(); diff --git a/src/sam3x8e/serial.c b/src/sam3x8e/serial.c index 713c6337..7741d6f8 100644 --- a/src/sam3x8e/serial.c +++ b/src/sam3x8e/serial.c @@ -56,6 +56,8 @@ UART_Handler(void) uint32_t status = UART->UART_SR; if (status & UART_SR_RXRDY) { uint8_t data = UART->UART_RHR; + if (data == MESSAGE_SYNC) + sched_wake_tasks(); if (receive_pos >= sizeof(receive_buf)) // Serial overflow - ignore it as crc error will force retransmit return; @@ -94,6 +96,7 @@ console_pop_input(uint32_t len) memmove(&receive_buf[copied], &receive_buf[copied + len] , needcopy - copied); copied = needcopy; + sched_wake_tasks(); } irqstatus_t flag = irq_save(); if (rpos != readl(&receive_pos)) { diff --git a/src/sched.c b/src/sched.c index 0aadcc75..a2f5fea8 100644 --- a/src/sched.c +++ b/src/sched.c @@ -28,6 +28,9 @@ static struct timer sentinel_timer, deleted_timer; static uint_fast8_t periodic_event(struct timer *t) { + // Make sure the stats task runs periodically + sched_wake_tasks(); + // Reschedule timer periodic_timer.waketime += timer_from_us(100000); sentinel_timer.waketime = periodic_timer.waketime + 0x80000000; return SF_RESCHEDULE; @@ -177,10 +180,17 @@ sched_timer_reset(void) * Task waking ****************************************************************/ +// Note that at least one task is ready to run +void +sched_wake_tasks(void) +{ +} + // Note that a task is ready to run void sched_wake_task(struct task_wake *w) { + sched_wake_tasks(); writeb(&w->wake, 1); } diff --git a/src/sched.h b/src/sched.h index bb6bb975..ba883778 100644 --- a/src/sched.h +++ b/src/sched.h @@ -29,6 +29,7 @@ struct task_wake { void sched_add_timer(struct timer*); void sched_del_timer(struct timer *del); unsigned int sched_timer_dispatch(void); +void sched_wake_tasks(void); void sched_wake_task(struct task_wake *w); uint8_t sched_check_wake(struct task_wake *w); uint8_t sched_is_shutdown(void); |