aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/README4
-rw-r--r--lib/pjrc_usb_serial/usb_serial.c12
-rw-r--r--lib/pjrc_usb_serial/usb_serial.patch39
-rw-r--r--src/avr/serial.c3
-rw-r--r--src/avr/usbserial.c4
-rw-r--r--src/command.c2
-rw-r--r--src/pru/main.c6
-rw-r--r--src/sam3x8e/serial.c3
-rw-r--r--src/sched.c10
-rw-r--r--src/sched.h1
10 files changed, 74 insertions, 10 deletions
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<<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);