diff --git a/lib/README b/lib/README index 90c38ede..e6bdb7fd 100644 --- a/lib/README +++ b/lib/README @@ -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<= 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);