From 57de3e77f535ac253fe17a34d8ae55a60db25f9f Mon Sep 17 00:00:00 2001 From: joeycastillo Date: Sat, 19 Oct 2024 10:12:45 -0400 Subject: [PATCH] split IrDA demo from light sensor demo --- movement_faces.h | 1 + watch-faces.mk | 1 + watch-faces/demo/irda_demo_face.c | 108 +++++++++++++++++++++++++++ watch-faces/demo/irda_demo_face.h | 56 ++++++++++++++ watch-faces/demo/light_sensor_face.c | 60 ++++----------- 5 files changed, 180 insertions(+), 46 deletions(-) create mode 100644 watch-faces/demo/irda_demo_face.c create mode 100644 watch-faces/demo/irda_demo_face.h diff --git a/movement_faces.h b/movement_faces.h index eb8ff1d3..2b72745f 100644 --- a/movement_faces.h +++ b/movement_faces.h @@ -43,4 +43,5 @@ #include "preferences_face.h" #include "light_sensor_face.h" #include "accelerometer_sleep_state_face.h" +#include "irda_demo_face.h" // New includes go above this line. diff --git a/watch-faces.mk b/watch-faces.mk index 55836d41..3c7f1b4f 100644 --- a/watch-faces.mk +++ b/watch-faces.mk @@ -18,4 +18,5 @@ SRCS += \ ./watch-faces/settings/preferences_face.c \ ./watch-faces/demo/light_sensor_face.c \ ./watch-faces/demo/accelerometer_sleep_state_face.c \ + ./watch-faces/demo/irda_demo_face.c \ # New watch faces go above this line. diff --git a/watch-faces/demo/irda_demo_face.c b/watch-faces/demo/irda_demo_face.c new file mode 100644 index 00000000..52a7c4d3 --- /dev/null +++ b/watch-faces/demo/irda_demo_face.c @@ -0,0 +1,108 @@ +/* + * MIT License + * + * Copyright (c) 2024 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include "irda_demo_face.h" +#include "tc.h" +#include "eic.h" +#include "usb.h" +#include "uart.h" + +#ifdef HAS_IR_SENSOR + +void irda_demo_face_setup(uint8_t watch_face_index, void ** context_ptr) { + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(irda_demo_state_t)); + memset(*context_ptr, 0, sizeof(irda_demo_state_t)); + // Do any one-time tasks in here; the inside of this conditional happens only at boot. + } +} + +void irda_demo_face_activate(void *context) { + irda_demo_state_t *state = (irda_demo_state_t *)context; + (void) state; + // Rev 05 had the polarity reversed, so we had to bodge a different circuit and bypass the enable pin. + // HAL_GPIO_IR_ENABLE_out(); + // HAL_GPIO_IR_ENABLE_clr(); + HAL_GPIO_IRSENSE_in(); + HAL_GPIO_IRSENSE_pmuxen(HAL_GPIO_PMUX_SERCOM_ALT); + uart_init_instance(0, UART_TXPO_NONE, UART_RXPO_0, 300); + uart_set_irda_mode_instance(0, true); + uart_enable_instance(0); +} + +bool irda_demo_face_loop(movement_event_t event, void *context) { + irda_demo_state_t *state = (irda_demo_state_t *)context; + (void) state; + + switch (event.event_type) { + case EVENT_NONE: + case EVENT_ACTIVATE: + case EVENT_TICK: + { + uint8_t data[32]; + size_t bytes_read = uart_read_instance(0, data, 32); + if (bytes_read) { + char buf[14]; + snprintf(buf, 11, "IR%2d%s", bytes_read, data); + watch_display_text(WATCH_POSITION_FULL, buf); + data[31] = 0; + printf("%s\n", data); + printf("%s\n", buf); + } else { + watch_display_text(WATCH_POSITION_FULL, " no dat"); + } + } + break; + case EVENT_LIGHT_BUTTON_UP: + break; + case EVENT_ALARM_BUTTON_UP: + break; + case EVENT_TIMEOUT: + // movement_move_to_face(0); + break; + case EVENT_LOW_ENERGY_UPDATE: + watch_display_text(WATCH_POSITION_TOP_RIGHT, " <"); + break; + default: + return movement_default_loop_handler(event); + } + + return false; +} + +void irda_demo_face_resign(void *context) { + (void) context; + uart_disable_instance(0); + HAL_GPIO_IRSENSE_pmuxdis(); + HAL_GPIO_IRSENSE_off(); +} + +void irq_handler_sercom0(void); +void irq_handler_sercom0(void) { + uart_irq_handler(0); +} +#endif // HAS_IR_SENSOR diff --git a/watch-faces/demo/irda_demo_face.h b/watch-faces/demo/irda_demo_face.h new file mode 100644 index 00000000..5c345b80 --- /dev/null +++ b/watch-faces/demo/irda_demo_face.h @@ -0,0 +1,56 @@ +/* + * MIT License + * + * Copyright (c) 2024 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include "movement.h" + +#ifdef HAS_IR_SENSOR + +/* + * LIGHT SENSOR PLAYGROUND + * + * Temporary watch face for playing with the light sensor. + * + */ + +typedef struct { + // Anything you need to keep track of, put it here! + uint8_t unused; +} irda_demo_state_t; + +void irda_demo_face_setup(uint8_t watch_face_index, void ** context_ptr); +void irda_demo_face_activate(void *context); +bool irda_demo_face_loop(movement_event_t event, void *context); +void irda_demo_face_resign(void *context); + +#define irda_demo_face ((const watch_face_t){ \ + irda_demo_face_setup, \ + irda_demo_face_activate, \ + irda_demo_face_loop, \ + irda_demo_face_resign, \ + NULL, \ +}) + +#endif // HAS_IR_SENSOR diff --git a/watch-faces/demo/light_sensor_face.c b/watch-faces/demo/light_sensor_face.c index 50209a98..2a25108e 100644 --- a/watch-faces/demo/light_sensor_face.c +++ b/watch-faces/demo/light_sensor_face.c @@ -28,7 +28,7 @@ #include "tc.h" #include "eic.h" #include "usb.h" -#include "uart.h" +#include "adc.h" #ifdef HAS_IR_SENSOR @@ -44,13 +44,11 @@ void light_sensor_face_setup(uint8_t watch_face_index, void ** context_ptr) { void light_sensor_face_activate(void *context) { light_sensor_state_t *state = (light_sensor_state_t *)context; (void) state; - HAL_GPIO_IR_ENABLE_out(); - HAL_GPIO_IR_ENABLE_clr(); HAL_GPIO_IRSENSE_in(); - HAL_GPIO_IRSENSE_pmuxen(HAL_GPIO_PMUX_SERCOM_ALT); - uart_init_instance(0, UART_TXPO_NONE, UART_RXPO_0, 300); - uart_set_irda_mode_instance(0, true); - uart_enable_instance(0); + HAL_GPIO_IRSENSE_pmuxen(HAL_GPIO_PMUX_ADC); + adc_init(); + adc_enable(); + movement_request_tick_frequency(8); } bool light_sensor_face_loop(movement_event_t event, void *context) { @@ -60,53 +58,25 @@ bool light_sensor_face_loop(movement_event_t event, void *context) { switch (event.event_type) { case EVENT_NONE: case EVENT_ACTIVATE: - watch_display_text_with_fallback(WATCH_POSITION_TOP, "IrDA", "IR"); - // fall through case EVENT_TICK: { - uint8_t data[32]; - size_t bytes_read = uart_read_instance(0, data, 32); - if (bytes_read) { - char buf[7]; - snprintf(buf, 7, "%3db r", bytes_read); - watch_display_text(WATCH_POSITION_BOTTOM, buf); - data[31] = 0; - printf("%s: ", buf); - // dump as hex - for(size_t i = 0; i < bytes_read; i++) { - printf("%02X ", data[i]); - } - printf("\n"); - } else { - watch_display_text(WATCH_POSITION_BOTTOM, "no dat"); - } + char buf[14]; + uint16_t light_level = adc_get_analog_value(HAL_GPIO_IRSENSE_pin()); + snprintf(buf, 14, "LL %-6d", light_level); + watch_display_text(WATCH_POSITION_FULL, buf); + printf("%s\n", buf); } break; case EVENT_LIGHT_BUTTON_UP: - // You can use the Light button for your own purposes. Note that by default, Movement will also - // illuminate the LED in response to EVENT_LIGHT_BUTTON_DOWN; to suppress that behavior, add an - // empty case for EVENT_LIGHT_BUTTON_DOWN. break; case EVENT_ALARM_BUTTON_UP: - // Just in case you have need for another button. break; case EVENT_TIMEOUT: - // Your watch face will receive this event after a period of inactivity. If it makes sense to resign, - // you may uncomment this line to move back to the first watch face in the list: - // movement_move_to_face(0); break; case EVENT_LOW_ENERGY_UPDATE: - // If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute. - // Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds. - // You should also consider starting the tick animation, to show the wearer that this is sleep mode: - // watch_start_sleep_animation(500); + watch_display_text(WATCH_POSITION_TOP_RIGHT, " <"); break; default: - // Movement's default loop handler will step in for any cases you don't handle above: - // * EVENT_LIGHT_BUTTON_DOWN lights the LED - // * EVENT_MODE_BUTTON_UP moves to the next watch face in the list - // * EVENT_MODE_LONG_PRESS returns to the first watch face (or skips to the secondary watch face, if configured) - // You can override any of these behaviors by adding a case for these events to this switch statement. return movement_default_loop_handler(event); } @@ -116,11 +86,9 @@ bool light_sensor_face_loop(movement_event_t event, void *context) { void light_sensor_face_resign(void *context) { (void) context; - // handle any cleanup before your watch face goes off-screen. + adc_disable(); + HAL_GPIO_IRSENSE_pmuxdis(); + HAL_GPIO_IRSENSE_off(); } -void irq_handler_sercom0(void); -void irq_handler_sercom0(void) { - uart_irq_handler(0); -} #endif // HAS_IR_SENSOR