summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoey Castillo <jose.castillo@gmail.com>2021-08-28 19:49:49 -0400
committerJoey Castillo <jose.castillo@gmail.com>2021-08-28 19:53:12 -0400
commitef0ed276a54fa304cf865b52d3665fa1f2f83b47 (patch)
treea01808d3ccd4633f61f34f7f6f3563b0ac844b71
parent27e3863a0558a21b4364a39595873e5902d87464 (diff)
downloadSensor-Watch-ef0ed276a54fa304cf865b52d3665fa1f2f83b47.tar.gz
Sensor-Watch-ef0ed276a54fa304cf865b52d3665fa1f2f83b47.tar.bz2
Sensor-Watch-ef0ed276a54fa304cf865b52d3665fa1f2f83b47.zip
handle tinyusb device tasks on a timer, allows delays in app
-rwxr-xr-xwatch-library/main.c12
-rw-r--r--watch-library/watch/watch_private.c34
2 files changed, 38 insertions, 8 deletions
diff --git a/watch-library/main.c b/watch-library/main.c
index 886ab851..3133c2d2 100755
--- a/watch-library/main.c
+++ b/watch-library/main.c
@@ -58,11 +58,8 @@ int main(void) {
// check if we are plugged into USB power.
watch_enable_digital_input(VBUS_DET);
watch_enable_pull_down(VBUS_DET);
- // IF WE ARE:
if (watch_get_pin_level(VBUS_DET)) {
- // Ramp up to 16 MHz (seems necessary for USB to work)...
- hri_oscctrl_write_OSC16MCTRL_reg(OSCCTRL, OSCCTRL_OSC16MCTRL_ONDEMAND | OSCCTRL_OSC16MCTRL_FSEL_16 | OSCCTRL_OSC16MCTRL_ENABLE);
- // ...and enable USB functionality.
+ // if so, enable USB functionality.
_watch_enable_usb();
}
watch_disable_digital_input(VBUS_DET);
@@ -71,11 +68,10 @@ int main(void) {
app_setup();
while (1) {
+ bool usb_enabled = hri_usbdevice_get_CTRLA_ENABLE_bit(USB);
bool can_sleep = app_loop();
- if (hri_usbdevice_get_CTRLA_ENABLE_bit(USB)) {
- // if USB is enabled, do not sleep, and handle any pending TinyUSB tasks.
- tud_task();
- } else if (can_sleep) {
+
+ if (can_sleep && !usb_enabled) {
app_prepare_for_sleep();
sleep(4);
app_wake_from_sleep();
diff --git a/watch-library/watch/watch_private.c b/watch-library/watch/watch_private.c
index 550419a2..ab988d10 100644
--- a/watch-library/watch/watch_private.c
+++ b/watch-library/watch/watch_private.c
@@ -49,6 +49,11 @@ void _watch_enable_usb() {
// disable USB, just in case.
hri_usb_clear_CTRLA_ENABLE_bit(USB);
+ // Ramp up to 16 MHz (seems necessary for USB to work)...
+ hri_oscctrl_write_OSC16MCTRL_reg(OSCCTRL, OSCCTRL_OSC16MCTRL_ONDEMAND | OSCCTRL_OSC16MCTRL_FSEL_16 | OSCCTRL_OSC16MCTRL_ENABLE);
+ // ...and wait for it to be ready.
+ while (!hri_oscctrl_get_STATUS_OSC16MRDY_bit(OSCCTRL));
+
// reset flags and disable DFLL
OSCCTRL->INTFLAG.reg = OSCCTRL_INTFLAG_DFLLRDY;
OSCCTRL->DFLLCTRL.reg = 0;
@@ -86,7 +91,31 @@ void _watch_enable_usb() {
gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM);
gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP);
+ // before we init TinyUSB, we are going to need a periodic callback to handle TinyUSB tasks.
+ // TC2 and TC3 are reserved for devices on the 9-pin connector, so let's use TC0.
+ // clock TC0 with the 16 MHz clock on GCLK0.
+ hri_gclk_write_PCHCTRL_reg(GCLK, TC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN);
+ // and enable the peripheral clock.
+ hri_mclk_set_APBCMASK_TC0_bit(MCLK);
+ // disable and reset TC0.
+ hri_tc_clear_CTRLA_ENABLE_bit(TC0);
+ hri_tc_wait_for_sync(TC0, TC_SYNCBUSY_ENABLE);
+ hri_tc_write_CTRLA_reg(TC0, TC_CTRLA_SWRST);
+ hri_tc_wait_for_sync(TC0, TC_SYNCBUSY_SWRST);
+ // configure the TC to overflow 1,000 times per second
+ hri_tc_write_CTRLA_reg(TC0, TC_CTRLA_PRESCALER_DIV64 | // divide the clock by 64 to count at 250000 KHz
+ TC_CTRLA_MODE_COUNT8 | // count in 8-bit mode
+ TC_CTRLA_RUNSTDBY); // run in standby, just in case we figure that out
+ hri_tccount8_write_PER_reg(TC0, 250); // 250000 KHz / 250 = 1,000 Hz
+ // set an interrupt on overflow; this will call TC0_Handler below.
+ hri_tc_set_INTEN_OVF_bit(TC0);
+ NVIC_ClearPendingIRQ(TC0_IRQn);
+ NVIC_EnableIRQ (TC0_IRQn);
+
+ // now we can init TinyUSB
tusb_init();
+ // and start the timer that handles USB device tasks.
+ hri_tc_set_CTRLA_ENABLE_bit(TC0);
}
// this function ends up getting called by printf to log stuff to the USB console.
@@ -119,6 +148,11 @@ void USB_Handler(void) {
tud_int_handler(0);
}
+void TC0_Handler(void) {
+ tud_task();
+ TC0->COUNT8.INTFLAG.reg |= TC_INTFLAG_OVF;
+}
+
// USB Descriptors and tinyUSB callbacks follow.