summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coroutine.c21
-rw-r--r--coroutine.h2
-rw-r--r--main.c60
-rw-r--r--usb_common.c23
-rw-r--r--usb_common.h6
-rw-r--r--usb_keyboard.c37
-rw-r--r--usb_keyboard.h10
7 files changed, 83 insertions, 76 deletions
diff --git a/coroutine.c b/coroutine.c
index 6219883..34d84c8 100644
--- a/coroutine.c
+++ b/coroutine.c
@@ -52,15 +52,24 @@ static void call_with_stack(void *stack, cr_fn_t fn, void *args) {
/* %1 */"r"(stack),
/* %2 */"r"(fn),
/* %3 */"r"(args)
- :
+ : "rdi"
);
#elif __arm__
#define STACK_GROWS_DOWNWARD 1
- asm volatile ("mov r0, coroutine_table[_cur_cid].arg"
- "mov _saved_stack sp"
- "mov sp, coroutine_table[_cur_cid].stack"
- "bl coroutine_table[_cur_cid].fn"
- "mov _saved_stack sp");
+ asm volatile ("mov r0, sp\n\t" /* [saved_sp = sp */
+ "str r0, %0\n\t" /* ] */
+ "mov sp, %1\n\t" /* [sp = stack] */
+ "mov r0, %1\n\t" /* [fn(arg0) */
+ "blx %2\n\t" /* ] */
+ "ldr r0, %0\n\t" /* [sp = staved_sp */
+ "mov sp, r0" /* ] */
+ :
+ : /* %0 */"m"(saved_sp),
+ /* %1 */"r"(stack),
+ /* %2 */"r"(fn),
+ /* %3 */"r"(args)
+ : "r0"
+ );
#else
#error unsupported architecture
#endif
diff --git a/coroutine.h b/coroutine.h
index fbaf000..13f9797 100644
--- a/coroutine.h
+++ b/coroutine.h
@@ -54,7 +54,7 @@ cid_t cr_getcid(void);
#define cr_chan_have_req(ch) ((ch)->requester != 0)
#define cr_chan_recv_req(ch, _req_p) do { \
(ch)->responder = cr_getcid(); \
- if ((ch)->requester == 0) { \
+ if ((ch)->requester == 0) \
cr_pause_and_yield(); \
*(_req_p) = (ch)->req; \
} while (0)
diff --git a/main.c b/main.c
index fef917f..098c3fd 100644
--- a/main.c
+++ b/main.c
@@ -4,66 +4,46 @@
* SPDX-Licence-Identifier: AGPL-3.0-or-later
*/
+/* newlib */
+#include <string.h> /* for strlen() */
+
/* pico-sdk */
-#include <stdio.h>
#include "pico/stdlib.h"
-/* TinyUSB */
-#include "bsp/board_api.h"
-#include "tusb.h"
-
/* local */
#include "coroutine.h"
+#include "usb_common.h"
#include "usb_keyboard.h"
-typedef struct {
- usb_keyboard_chan_t *chan;
- size_t i;
-} hello_world_stack_t;
-
-void hello_world_cr(void *_stack) {
+COROUTINE hello_world_cr(void *_chan) {
const char *msg = "Hello world!\n";
- hello_world_stack_t *stack = _stack;
-
+ usb_keyboard_chan_t *chan = _chan;
cr_begin();
- for (;;) {
- cr_chan_req(stack->chan, NULL, msg[stack->i]);
- stack->i = (stack->i + 1) % strlen(msg);
+
+ for (size_t i = 0;; i = (i+1) % strlen(msg)) {
+ cr_chan_req(chan, NULL, msg[i]);
}
+
cr_end();
}
int main() {
- /* pico-sdk initialization */
+ /* initialization */
stdio_uart_init();
- gpio_init(PICO_DEFAULT_LED_PIN);
- gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
+ //gpio_init(PICO_DEFAULT_LED_PIN);
+ //gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
+ usb_common_earlyinit();
usb_keyboard_init();
-
- /* TinyUSB initialization */
- board_init();
- tud_init(BOARD_TUD_RHPORT);
- if (board_init_after_tusb)
- board_init_after_tusb();
-
- /* coroutine initialization */
+ usb_common_lateinit();
coroutine_init();
+ /* set up coroutines */
+ coroutine_add(usb_common_cr, NULL);
usb_keyboard_chan_t keyboard_chan;
-
- usb_keyboard_init();
- usb_keyboard_stack_t usb_keyboard_stack = {0};
- usb_keyboard_stack.chan = &keyboard_chan;
- coroutine_add(usb_keyboard_cr, &usb_keyboard_stack);
-
- hello_world_stack_t hello_world_stack = {0};
- hello_world_stack.chan = &keyboard_chan;
- coroutine_add(hello_world_cr, &hello_world_stack);
+ coroutine_add(usb_keyboard_cr, &keyboard_chan);
+ coroutine_add(hello_world_cr, &keyboard_chan);
/* Event loop. */
- for (;;) {
- tud_task();
- coroutine_task();
- }
+ coroutine_main();
}
diff --git a/usb_common.c b/usb_common.c
index 65882b2..f10ace8 100644
--- a/usb_common.c
+++ b/usb_common.c
@@ -8,7 +8,7 @@
#include <string.h> /* memcpy(newlib) */
#include <assert.h> /* for assert(newlib) */
#include <stdlib.h> /* for malloc(pico_malloc), realloc(pico_malloc), reallocarray(pico_malloc) */
-#include "bsp/board_api.h" /* for board_usb_get_serial(TinyUSB) */
+#include "bsp/board_api.h" /* for board_init(), board_init_after_usb(), board_usb_get_serial(TinyUSB) */
#include "tusb.h" /* for various tusb_*_t types */
#include "tusb_helpers.h" /* for LANGID_*, TU_UTF16() */
@@ -71,7 +71,7 @@ uint16_t const *tud_descriptor_string_cb(uint8_t strid, uint16_t langid) {
uint8_t cfgnum_std = 0;
-void usb_common_init(void) {
+void usb_common_earlyinit(void) {
if (cfgnum_std)
return;
cfgnum_std = usb_add_config(
@@ -80,6 +80,25 @@ void usb_common_init(void) {
100); /* bMaxPower (in mA) ; Maximum power consumption of the device when in this configuration */
}
+void usb_common_lateinit(void) {
+ board_init();
+ tud_init(BOARD_TUD_RHPORT);
+ if (board_init_after_tusb)
+ board_init_after_tusb();
+}
+
+COROUTINE usb_common_cr(void *_arg) {
+ (void) _arg;
+ cr_begin();
+
+ for (;;) {
+ tud_task();
+ cr_yield();
+ }
+
+ cr_end();
+}
+
/* Main utilities *************************************************************/
static uint8_t configc = 0;
diff --git a/usb_common.h b/usb_common.h
index a6006fa..3b45246 100644
--- a/usb_common.h
+++ b/usb_common.h
@@ -7,6 +7,8 @@
#ifndef _USB_COMMON_H_
#define _USB_COMMON_H_
+#include "coroutine.h"
+
/* Strings ********************************************************************/
enum {
@@ -25,7 +27,9 @@ enum {
/* Globals ********************************************************************/
extern uint8_t cfgnum_std;
-void usb_common_init(void);
+void usb_common_earlyinit(void);
+void usb_common_lateinit(void);
+COROUTINE usb_common_cr(void *arg);
/* Main utilities *************************************************************/
diff --git a/usb_keyboard.c b/usb_keyboard.c
index 8212c60..e6638ec 100644
--- a/usb_keyboard.c
+++ b/usb_keyboard.c
@@ -21,7 +21,7 @@ static uint8_t kbd_ifc = 0;
void usb_keyboard_init() {
if (kbd_ifc)
return;
- usb_common_init();
+ usb_common_earlyinit();
kbd_ifc = usb_add_interface(cfgnum_std, TUD_HID_DESC_LEN, (uint8_t[]){
/* USB-HID input-only descriptor for inclusion in the config descriptor; consisting of 3 parts:
@@ -42,38 +42,41 @@ void usb_keyboard_init() {
static uint8_t ascii2keycode[128][2] = { HID_ASCII_TO_KEYCODE };
-void usb_keyboard_cr(void *_stack) {
- usb_keyboard_stack_t *stack = _stack;
-
+COROUTINE usb_keyboard_cr(void *_chan) {
+ usb_keyboard_chan_t *chan = _chan;
cr_begin();
+ uint8_t report_id = 0;
+ uint8_t modifier = 0;
+ uint8_t keycodes[6] = {0};
for (;;) {
while (!tud_hid_n_ready(kbd_ifc))
cr_yield();
- if (cr_chan_have_req(stack->chan)) {
- cr_chan_recv_req(stack->chan, &stack->rune);
+ if (cr_chan_have_req(chan)) {
+ uint32_t rune;
+ cr_chan_recv_req(chan, &rune);
- stack->modifier = ascii2keycode[stack->rune][0] ? KEYBOARD_MODIFIER_LEFTSHIFT : 0;
- stack->keycodes[0] = ascii2keycode[stack->rune][1];
- tud_hid_n_keyboard_report(kbd_ifc, stack->report_id, stack->modifier, stack->keycodes);
+ modifier = ascii2keycode[rune][0] ? KEYBOARD_MODIFIER_LEFTSHIFT : 0;
+ keycodes[0] = ascii2keycode[rune][1];
+ tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes);
while (!tud_hid_n_ready(kbd_ifc))
cr_yield();
- stack->modifier = 0;
- stack->keycodes[0] = 0;
- tud_hid_n_keyboard_report(kbd_ifc, stack->report_id, stack->modifier, stack->keycodes);
+ modifier = 0;
+ keycodes[0] = 0;
+ tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes);
- cr_chan_send_resp(stack->chan, 1);
+ cr_chan_send_resp(chan, 1);
} else {
- stack->modifier = 0;
- stack->keycodes[0] = 0;
- tud_hid_n_keyboard_report(kbd_ifc, stack->report_id, stack->modifier, stack->keycodes);
+ modifier = 0;
+ keycodes[0] = 0;
+ tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes);
}
}
- cr_end()
+ cr_end();
}
/**
diff --git a/usb_keyboard.h b/usb_keyboard.h
index e989700..40b0bb2 100644
--- a/usb_keyboard.h
+++ b/usb_keyboard.h
@@ -11,15 +11,7 @@
typedef cr_chan_t(uint32_t, int) usb_keyboard_chan_t;
-typedef struct {
- usb_keyboard_chan_t *chan;
- uint32_t rune;
- uint8_t report_id;
- uint8_t modifier;
- uint8_t keycodes[0];
-} usb_keyboard_stack_t;
-
void usb_keyboard_init(void);
-void usb_keyboard_cr(void *stack);
+COROUTINE usb_keyboard_cr(void *arg);
#endif /* _USB_KEYBOARD_H_ */