From 4f29cf24f3db0456b12c89589f3ce0338a6c60cd Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 17 Feb 2022 14:44:40 -0500 Subject: movement: move thermistor to 'sensor' watch faces --- make.mk | 1 + movement/make/Makefile | 7 +- .../watch_faces/sensor/thermistor_logging_face.c | 141 +++++++++++++++++++++ .../watch_faces/sensor/thermistor_logging_face.h | 59 +++++++++ .../watch_faces/sensor/thermistor_readout_face.c | 98 ++++++++++++++ .../watch_faces/sensor/thermistor_readout_face.h | 43 +++++++ .../watch_faces/thermistor/thermistor_driver.c | 58 --------- .../watch_faces/thermistor/thermistor_driver.h | 43 ------- .../thermistor/thermistor_logging_face.c | 141 --------------------- .../thermistor/thermistor_logging_face.h | 59 --------- .../thermistor/thermistor_readout_face.c | 98 -------------- .../thermistor/thermistor_readout_face.h | 43 ------- watch-library/shared/driver/thermistor_driver.c | 58 +++++++++ watch-library/shared/driver/thermistor_driver.h | 43 +++++++ 14 files changed, 446 insertions(+), 446 deletions(-) create mode 100644 movement/watch_faces/sensor/thermistor_logging_face.c create mode 100644 movement/watch_faces/sensor/thermistor_logging_face.h create mode 100644 movement/watch_faces/sensor/thermistor_readout_face.c create mode 100644 movement/watch_faces/sensor/thermistor_readout_face.h delete mode 100644 movement/watch_faces/thermistor/thermistor_driver.c delete mode 100644 movement/watch_faces/thermistor/thermistor_driver.h delete mode 100644 movement/watch_faces/thermistor/thermistor_logging_face.c delete mode 100644 movement/watch_faces/thermistor/thermistor_logging_face.h delete mode 100644 movement/watch_faces/thermistor/thermistor_readout_face.c delete mode 100644 movement/watch_faces/thermistor/thermistor_readout_face.h create mode 100644 watch-library/shared/driver/thermistor_driver.c create mode 100644 watch-library/shared/driver/thermistor_driver.h diff --git a/make.mk b/make.mk index aeada13f..fb54664c 100644 --- a/make.mk +++ b/make.mk @@ -117,6 +117,7 @@ SRCS += \ $(TOP)/watch-library/hardware/hpl/sercom/hpl_sercom.c \ $(TOP)/watch-library/hardware/hpl/slcd/hpl_slcd.c \ $(TOP)/watch-library/hardware/hpl/systick/hpl_systick.c \ + $(TOP)/watch-library/shared/driver/thermistor_driver.c \ $(TOP)/watch-library/shared/driver/lis2dh.c \ $(TOP)/watch-library/shared/driver/lis2dw.c \ $(TOP)/watch-library/shared/driver/spiflash.c \ diff --git a/movement/make/Makefile b/movement/make/Makefile index cc543a93..9231d5ce 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -14,7 +14,7 @@ INCLUDES += \ -I../watch_faces/clock/ \ -I../watch_faces/settings/ \ -I../watch_faces/complication/ \ - -I../watch_faces/thermistor/ \ + -I../watch_faces/sensor/ \ -I../watch_faces/demo/ \ -I../lib/TOTP-MCU/ \ -I../lib/sunriset/ \ @@ -35,9 +35,8 @@ SRCS += \ ../watch_faces/clock/beats_face.c \ ../watch_faces/settings/preferences_face.c \ ../watch_faces/settings/set_time_face.c \ - ../watch_faces/thermistor/thermistor_driver.c \ - ../watch_faces/thermistor/thermistor_readout_face.c \ - ../watch_faces/thermistor/thermistor_logging_face.c \ + ../watch_faces/sensor/thermistor_readout_face.c \ + ../watch_faces/sensor/thermistor_logging_face.c \ ../watch_faces/demo/character_set_face.c \ ../watch_faces/demo/voltage_face.c \ ../watch_faces/demo/lis2dh_logging_face.c \ diff --git a/movement/watch_faces/sensor/thermistor_logging_face.c b/movement/watch_faces/sensor/thermistor_logging_face.c new file mode 100644 index 00000000..40c40027 --- /dev/null +++ b/movement/watch_faces/sensor/thermistor_logging_face.c @@ -0,0 +1,141 @@ +/* + * MIT License + * + * Copyright (c) 2022 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 "thermistor_logging_face.h" +#include "thermistor_driver.h" +#include "watch.h" + +static void _thermistor_logging_face_log_data(thermistor_logger_state_t *logger_state) { + thermistor_driver_enable(); + watch_date_time date_time = watch_rtc_get_date_time(); + size_t pos = logger_state->data_points % THERMISTOR_LOGGING_NUM_DATA_POINTS; + + logger_state->data[pos].timestamp.reg = date_time.reg; + logger_state->data[pos].temperature_c = thermistor_driver_get_temperature(); + logger_state->data_points++; + + thermistor_driver_disable(); +} + +static void _thermistor_logging_face_update_display(thermistor_logger_state_t *logger_state, bool in_fahrenheit, bool clock_mode_24h) { + int8_t pos = (logger_state->data_points - 1 - logger_state->display_index) % THERMISTOR_LOGGING_NUM_DATA_POINTS; + char buf[14]; + + watch_clear_indicator(WATCH_INDICATOR_24H); + watch_clear_indicator(WATCH_INDICATOR_PM); + watch_clear_colon(); + + if (pos < 0) { + sprintf(buf, "TL%2dno dat", logger_state->display_index); + } else if (logger_state->ts_ticks) { + watch_date_time date_time = logger_state->data[pos].timestamp; + watch_set_colon(); + if (clock_mode_24h) { + watch_set_indicator(WATCH_INDICATOR_24H); + } else { + if (date_time.unit.hour > 11) watch_set_indicator(WATCH_INDICATOR_PM); + date_time.unit.hour %= 12; + if (date_time.unit.hour == 0) date_time.unit.hour = 12; + } + sprintf(buf, "AT%2d%2d%02d%02d", date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second); + } else { + if (in_fahrenheit) { + sprintf(buf, "TL%2d%4.1f#F", logger_state->display_index, logger_state->data[pos].temperature_c * 1.8 + 32.0); + } else { + sprintf(buf, "TL%2d%4.1f#C", logger_state->display_index, logger_state->data[pos].temperature_c); + } + } + + watch_display_string(buf, 0); +} + +void thermistor_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(thermistor_logger_state_t)); + memset(*context_ptr, 0, sizeof(thermistor_logger_state_t)); + } +} + +void thermistor_logging_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + thermistor_logger_state_t *logger_state = (thermistor_logger_state_t *)context; + logger_state->display_index = 0; + logger_state->ts_ticks = 0; +} + +bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + thermistor_logger_state_t *logger_state = (thermistor_logger_state_t *)context; + switch (event.event_type) { + case EVENT_TIMEOUT: + movement_move_to_face(0); + break; + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_LIGHT_LONG_PRESS: + // light button shows the timestamp, but if you need the light, long press it. + movement_illuminate_led(); + break; + case EVENT_LIGHT_BUTTON_DOWN: + logger_state->ts_ticks = 2; + _thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h); + break; + case EVENT_ALARM_BUTTON_DOWN: + logger_state->display_index = (logger_state->display_index + 1) % THERMISTOR_LOGGING_NUM_DATA_POINTS; + logger_state->ts_ticks = 0; + // fall through + case EVENT_ACTIVATE: + _thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h); + break; + case EVENT_TICK: + if (logger_state->ts_ticks && --logger_state->ts_ticks == 0) { + _thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h); + } + break; + case EVENT_BACKGROUND_TASK: + _thermistor_logging_face_log_data(logger_state); + break; + default: + break; + } + + return true; +} + +void thermistor_logging_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} + +bool thermistor_logging_face_wants_background_task(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; + // this will get called at the top of each minute, so all we check is if we're at the top of the hour as well. + // if we are, we ask for a background task. + return watch_rtc_get_date_time().unit.minute == 0; +} diff --git a/movement/watch_faces/sensor/thermistor_logging_face.h b/movement/watch_faces/sensor/thermistor_logging_face.h new file mode 100644 index 00000000..4ba593ec --- /dev/null +++ b/movement/watch_faces/sensor/thermistor_logging_face.h @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2022 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. + */ + +#ifndef THERMISTOR_LOGGING_FACE_H_ +#define THERMISTOR_LOGGING_FACE_H_ + +#include "movement.h" +#include "watch.h" + +#define THERMISTOR_LOGGING_NUM_DATA_POINTS (36) + +typedef struct { + watch_date_time timestamp; + float temperature_c; +} thermistor_logger_data_point_t; + +typedef struct { + uint8_t display_index; // the index we are displaying on screen + uint8_t ts_ticks; // when the user taps the LIGHT button, we show the timestamp for a few ticks. + int32_t data_points; // the absolute number of data points logged + thermistor_logger_data_point_t data[THERMISTOR_LOGGING_NUM_DATA_POINTS]; +} thermistor_logger_state_t; + +void thermistor_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void thermistor_logging_face_activate(movement_settings_t *settings, void *context); +bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void thermistor_logging_face_resign(movement_settings_t *settings, void *context); +bool thermistor_logging_face_wants_background_task(movement_settings_t *settings, void *context); + +#define thermistor_logging_face ((const watch_face_t){ \ + thermistor_logging_face_setup, \ + thermistor_logging_face_activate, \ + thermistor_logging_face_loop, \ + thermistor_logging_face_resign, \ + thermistor_logging_face_wants_background_task, \ +}) + +#endif // THERMISTOR_LOGGING_FACE_H_ diff --git a/movement/watch_faces/sensor/thermistor_readout_face.c b/movement/watch_faces/sensor/thermistor_readout_face.c new file mode 100644 index 00000000..b97c8432 --- /dev/null +++ b/movement/watch_faces/sensor/thermistor_readout_face.c @@ -0,0 +1,98 @@ +/* + * MIT License + * + * Copyright (c) 2022 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 "thermistor_readout_face.h" +#include "thermistor_driver.h" +#include "watch.h" + +static void _thermistor_readout_face_update_display(bool in_fahrenheit) { + thermistor_driver_enable(); + float temperature_c = thermistor_driver_get_temperature(); + char buf[14]; + if (in_fahrenheit) { + sprintf(buf, "%4.1f#F", temperature_c * 1.8 + 32.0); + } else { + sprintf(buf, "%4.1f#C", temperature_c); + } + watch_display_string(buf, 4); + thermistor_driver_disable(); +} + +void thermistor_readout_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + (void) context_ptr; +} + +void thermistor_readout_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; + watch_display_string("TE", 0); +} + +bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + (void) context; + watch_date_time date_time = watch_rtc_get_date_time(); + switch (event.event_type) { + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_LIGHT_BUTTON_DOWN: + movement_illuminate_led(); + break; + case EVENT_ALARM_BUTTON_UP: + settings->bit.use_imperial_units = !settings->bit.use_imperial_units; + _thermistor_readout_face_update_display(settings->bit.use_imperial_units); + break; + case EVENT_ACTIVATE: + // force a measurement to be taken immediately. + date_time.unit.second = 0; + // fall through + case EVENT_TICK: + if (date_time.unit.second % 5 == 4) { + // Not 100% on this, but I like the idea of using the signal indicator to indicate that we're sensing data. + // In this case we turn the indicator on a second before the reading is taken, and clear it when we're done. + // In reality the measurement takes a fraction of a second, but this is just to show something is happening. + watch_set_indicator(WATCH_INDICATOR_SIGNAL); + } else if (date_time.unit.second % 5 == 0) { + _thermistor_readout_face_update_display(settings->bit.use_imperial_units); + watch_clear_indicator(WATCH_INDICATOR_SIGNAL); + } + break; + case EVENT_LOW_ENERGY_UPDATE: + watch_display_string("TE SLEEP ", 0); + break; + default: + break; + } + + return true; +} + +void thermistor_readout_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} diff --git a/movement/watch_faces/sensor/thermistor_readout_face.h b/movement/watch_faces/sensor/thermistor_readout_face.h new file mode 100644 index 00000000..7361164e --- /dev/null +++ b/movement/watch_faces/sensor/thermistor_readout_face.h @@ -0,0 +1,43 @@ +/* + * MIT License + * + * Copyright (c) 2022 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. + */ + +#ifndef THERMISTOR_READOUT_FACE_H_ +#define THERMISTOR_READOUT_FACE_H_ + +#include "movement.h" + +void thermistor_readout_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void thermistor_readout_face_activate(movement_settings_t *settings, void *context); +bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void thermistor_readout_face_resign(movement_settings_t *settings, void *context); + +#define thermistor_readout_face ((const watch_face_t){ \ + thermistor_readout_face_setup, \ + thermistor_readout_face_activate, \ + thermistor_readout_face_loop, \ + thermistor_readout_face_resign, \ + NULL, \ +}) + +#endif // THERMISTOR_READOUT_FACE_H_ diff --git a/movement/watch_faces/thermistor/thermistor_driver.c b/movement/watch_faces/thermistor/thermistor_driver.c deleted file mode 100644 index 73bdef41..00000000 --- a/movement/watch_faces/thermistor/thermistor_driver.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 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 "thermistor_driver.h" -#include "watch.h" -#include "watch_utility.h" - -void thermistor_driver_enable(void) { - // Enable the ADC peripheral, which we'll use to read the thermistor value. - watch_enable_adc(); - // Enable analog circuitry on the sense pin, which is tied to the thermistor resistor divider. - watch_enable_analog_input(THERMISTOR_SENSE_PIN); - // Enable digital output on the enable pin, which is the power to the thermistor circuit. - watch_enable_digital_output(THERMISTOR_ENABLE_PIN); - // and make sure it's off. - watch_set_pin_level(THERMISTOR_ENABLE_PIN, !THERMISTOR_ENABLE_VALUE); -} - -void thermistor_driver_disable(void) { - // Disable the ADC peripheral. - watch_disable_adc(); - // Disable analog circuitry on the sense pin to save power. - watch_disable_analog_input(THERMISTOR_SENSE_PIN); - // Disable the enable pin's output circuitry. - watch_disable_digital_output(THERMISTOR_ENABLE_PIN); -} - -float thermistor_driver_get_temperature(void) { - // set the enable pin to the level that powers the thermistor circuit. - watch_set_pin_level(THERMISTOR_ENABLE_PIN, THERMISTOR_ENABLE_VALUE); - // get the sense pin level - uint16_t value = watch_get_analog_pin_level(THERMISTOR_SENSE_PIN); - // and then set the enable pin to the opposite value to power down the thermistor circuit. - watch_set_pin_level(THERMISTOR_ENABLE_PIN, !THERMISTOR_ENABLE_VALUE); - - return watch_utility_thermistor_temperature(value, THERMISTOR_HIGH_SIDE, THERMISTOR_B_COEFFICIENT, THERMISTOR_NOMINAL_TEMPERATURE, THERMISTOR_NOMINAL_RESISTANCE, THERMISTOR_SERIES_RESISTANCE); -} diff --git a/movement/watch_faces/thermistor/thermistor_driver.h b/movement/watch_faces/thermistor/thermistor_driver.h deleted file mode 100644 index 66bec6e9..00000000 --- a/movement/watch_faces/thermistor/thermistor_driver.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 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. - */ - -#ifndef THERMISTOR_DRIVER_H_ -#define THERMISTOR_DRIVER_H_ - -// TODO: Do these belong in movement_config.h? In settings we can set on the watch? In an EEPROM configuration area? -// Think on this. [joey 11/22] -#define THERMISTOR_SENSE_PIN (A2) -#define THERMISTOR_ENABLE_PIN (A0) -#define THERMISTOR_ENABLE_VALUE (false) -#define THERMISTOR_HIGH_SIDE (true) -#define THERMISTOR_B_COEFFICIENT (3380.0) -#define THERMISTOR_NOMINAL_TEMPERATURE (25.0) -#define THERMISTOR_NOMINAL_RESISTANCE (10000.0) -#define THERMISTOR_SERIES_RESISTANCE (10000.0) - -void thermistor_driver_enable(void); -void thermistor_driver_disable(void); -float thermistor_driver_get_temperature(void); - -#endif // THERMISTOR_DRIVER_H_ diff --git a/movement/watch_faces/thermistor/thermistor_logging_face.c b/movement/watch_faces/thermistor/thermistor_logging_face.c deleted file mode 100644 index 40c40027..00000000 --- a/movement/watch_faces/thermistor/thermistor_logging_face.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 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 "thermistor_logging_face.h" -#include "thermistor_driver.h" -#include "watch.h" - -static void _thermistor_logging_face_log_data(thermistor_logger_state_t *logger_state) { - thermistor_driver_enable(); - watch_date_time date_time = watch_rtc_get_date_time(); - size_t pos = logger_state->data_points % THERMISTOR_LOGGING_NUM_DATA_POINTS; - - logger_state->data[pos].timestamp.reg = date_time.reg; - logger_state->data[pos].temperature_c = thermistor_driver_get_temperature(); - logger_state->data_points++; - - thermistor_driver_disable(); -} - -static void _thermistor_logging_face_update_display(thermistor_logger_state_t *logger_state, bool in_fahrenheit, bool clock_mode_24h) { - int8_t pos = (logger_state->data_points - 1 - logger_state->display_index) % THERMISTOR_LOGGING_NUM_DATA_POINTS; - char buf[14]; - - watch_clear_indicator(WATCH_INDICATOR_24H); - watch_clear_indicator(WATCH_INDICATOR_PM); - watch_clear_colon(); - - if (pos < 0) { - sprintf(buf, "TL%2dno dat", logger_state->display_index); - } else if (logger_state->ts_ticks) { - watch_date_time date_time = logger_state->data[pos].timestamp; - watch_set_colon(); - if (clock_mode_24h) { - watch_set_indicator(WATCH_INDICATOR_24H); - } else { - if (date_time.unit.hour > 11) watch_set_indicator(WATCH_INDICATOR_PM); - date_time.unit.hour %= 12; - if (date_time.unit.hour == 0) date_time.unit.hour = 12; - } - sprintf(buf, "AT%2d%2d%02d%02d", date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second); - } else { - if (in_fahrenheit) { - sprintf(buf, "TL%2d%4.1f#F", logger_state->display_index, logger_state->data[pos].temperature_c * 1.8 + 32.0); - } else { - sprintf(buf, "TL%2d%4.1f#C", logger_state->display_index, logger_state->data[pos].temperature_c); - } - } - - watch_display_string(buf, 0); -} - -void thermistor_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { - (void) settings; - (void) watch_face_index; - if (*context_ptr == NULL) { - *context_ptr = malloc(sizeof(thermistor_logger_state_t)); - memset(*context_ptr, 0, sizeof(thermistor_logger_state_t)); - } -} - -void thermistor_logging_face_activate(movement_settings_t *settings, void *context) { - (void) settings; - thermistor_logger_state_t *logger_state = (thermistor_logger_state_t *)context; - logger_state->display_index = 0; - logger_state->ts_ticks = 0; -} - -bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { - thermistor_logger_state_t *logger_state = (thermistor_logger_state_t *)context; - switch (event.event_type) { - case EVENT_TIMEOUT: - movement_move_to_face(0); - break; - case EVENT_MODE_BUTTON_UP: - movement_move_to_next_face(); - break; - case EVENT_LIGHT_LONG_PRESS: - // light button shows the timestamp, but if you need the light, long press it. - movement_illuminate_led(); - break; - case EVENT_LIGHT_BUTTON_DOWN: - logger_state->ts_ticks = 2; - _thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h); - break; - case EVENT_ALARM_BUTTON_DOWN: - logger_state->display_index = (logger_state->display_index + 1) % THERMISTOR_LOGGING_NUM_DATA_POINTS; - logger_state->ts_ticks = 0; - // fall through - case EVENT_ACTIVATE: - _thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h); - break; - case EVENT_TICK: - if (logger_state->ts_ticks && --logger_state->ts_ticks == 0) { - _thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h); - } - break; - case EVENT_BACKGROUND_TASK: - _thermistor_logging_face_log_data(logger_state); - break; - default: - break; - } - - return true; -} - -void thermistor_logging_face_resign(movement_settings_t *settings, void *context) { - (void) settings; - (void) context; -} - -bool thermistor_logging_face_wants_background_task(movement_settings_t *settings, void *context) { - (void) settings; - (void) context; - // this will get called at the top of each minute, so all we check is if we're at the top of the hour as well. - // if we are, we ask for a background task. - return watch_rtc_get_date_time().unit.minute == 0; -} diff --git a/movement/watch_faces/thermistor/thermistor_logging_face.h b/movement/watch_faces/thermistor/thermistor_logging_face.h deleted file mode 100644 index 4ba593ec..00000000 --- a/movement/watch_faces/thermistor/thermistor_logging_face.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 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. - */ - -#ifndef THERMISTOR_LOGGING_FACE_H_ -#define THERMISTOR_LOGGING_FACE_H_ - -#include "movement.h" -#include "watch.h" - -#define THERMISTOR_LOGGING_NUM_DATA_POINTS (36) - -typedef struct { - watch_date_time timestamp; - float temperature_c; -} thermistor_logger_data_point_t; - -typedef struct { - uint8_t display_index; // the index we are displaying on screen - uint8_t ts_ticks; // when the user taps the LIGHT button, we show the timestamp for a few ticks. - int32_t data_points; // the absolute number of data points logged - thermistor_logger_data_point_t data[THERMISTOR_LOGGING_NUM_DATA_POINTS]; -} thermistor_logger_state_t; - -void thermistor_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); -void thermistor_logging_face_activate(movement_settings_t *settings, void *context); -bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context); -void thermistor_logging_face_resign(movement_settings_t *settings, void *context); -bool thermistor_logging_face_wants_background_task(movement_settings_t *settings, void *context); - -#define thermistor_logging_face ((const watch_face_t){ \ - thermistor_logging_face_setup, \ - thermistor_logging_face_activate, \ - thermistor_logging_face_loop, \ - thermistor_logging_face_resign, \ - thermistor_logging_face_wants_background_task, \ -}) - -#endif // THERMISTOR_LOGGING_FACE_H_ diff --git a/movement/watch_faces/thermistor/thermistor_readout_face.c b/movement/watch_faces/thermistor/thermistor_readout_face.c deleted file mode 100644 index b97c8432..00000000 --- a/movement/watch_faces/thermistor/thermistor_readout_face.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 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 "thermistor_readout_face.h" -#include "thermistor_driver.h" -#include "watch.h" - -static void _thermistor_readout_face_update_display(bool in_fahrenheit) { - thermistor_driver_enable(); - float temperature_c = thermistor_driver_get_temperature(); - char buf[14]; - if (in_fahrenheit) { - sprintf(buf, "%4.1f#F", temperature_c * 1.8 + 32.0); - } else { - sprintf(buf, "%4.1f#C", temperature_c); - } - watch_display_string(buf, 4); - thermistor_driver_disable(); -} - -void thermistor_readout_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { - (void) settings; - (void) watch_face_index; - (void) context_ptr; -} - -void thermistor_readout_face_activate(movement_settings_t *settings, void *context) { - (void) settings; - (void) context; - watch_display_string("TE", 0); -} - -bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { - (void) context; - watch_date_time date_time = watch_rtc_get_date_time(); - switch (event.event_type) { - case EVENT_MODE_BUTTON_UP: - movement_move_to_next_face(); - break; - case EVENT_LIGHT_BUTTON_DOWN: - movement_illuminate_led(); - break; - case EVENT_ALARM_BUTTON_UP: - settings->bit.use_imperial_units = !settings->bit.use_imperial_units; - _thermistor_readout_face_update_display(settings->bit.use_imperial_units); - break; - case EVENT_ACTIVATE: - // force a measurement to be taken immediately. - date_time.unit.second = 0; - // fall through - case EVENT_TICK: - if (date_time.unit.second % 5 == 4) { - // Not 100% on this, but I like the idea of using the signal indicator to indicate that we're sensing data. - // In this case we turn the indicator on a second before the reading is taken, and clear it when we're done. - // In reality the measurement takes a fraction of a second, but this is just to show something is happening. - watch_set_indicator(WATCH_INDICATOR_SIGNAL); - } else if (date_time.unit.second % 5 == 0) { - _thermistor_readout_face_update_display(settings->bit.use_imperial_units); - watch_clear_indicator(WATCH_INDICATOR_SIGNAL); - } - break; - case EVENT_LOW_ENERGY_UPDATE: - watch_display_string("TE SLEEP ", 0); - break; - default: - break; - } - - return true; -} - -void thermistor_readout_face_resign(movement_settings_t *settings, void *context) { - (void) settings; - (void) context; -} diff --git a/movement/watch_faces/thermistor/thermistor_readout_face.h b/movement/watch_faces/thermistor/thermistor_readout_face.h deleted file mode 100644 index 7361164e..00000000 --- a/movement/watch_faces/thermistor/thermistor_readout_face.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 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. - */ - -#ifndef THERMISTOR_READOUT_FACE_H_ -#define THERMISTOR_READOUT_FACE_H_ - -#include "movement.h" - -void thermistor_readout_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); -void thermistor_readout_face_activate(movement_settings_t *settings, void *context); -bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *settings, void *context); -void thermistor_readout_face_resign(movement_settings_t *settings, void *context); - -#define thermistor_readout_face ((const watch_face_t){ \ - thermistor_readout_face_setup, \ - thermistor_readout_face_activate, \ - thermistor_readout_face_loop, \ - thermistor_readout_face_resign, \ - NULL, \ -}) - -#endif // THERMISTOR_READOUT_FACE_H_ diff --git a/watch-library/shared/driver/thermistor_driver.c b/watch-library/shared/driver/thermistor_driver.c new file mode 100644 index 00000000..73bdef41 --- /dev/null +++ b/watch-library/shared/driver/thermistor_driver.c @@ -0,0 +1,58 @@ +/* + * MIT License + * + * Copyright (c) 2022 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 "thermistor_driver.h" +#include "watch.h" +#include "watch_utility.h" + +void thermistor_driver_enable(void) { + // Enable the ADC peripheral, which we'll use to read the thermistor value. + watch_enable_adc(); + // Enable analog circuitry on the sense pin, which is tied to the thermistor resistor divider. + watch_enable_analog_input(THERMISTOR_SENSE_PIN); + // Enable digital output on the enable pin, which is the power to the thermistor circuit. + watch_enable_digital_output(THERMISTOR_ENABLE_PIN); + // and make sure it's off. + watch_set_pin_level(THERMISTOR_ENABLE_PIN, !THERMISTOR_ENABLE_VALUE); +} + +void thermistor_driver_disable(void) { + // Disable the ADC peripheral. + watch_disable_adc(); + // Disable analog circuitry on the sense pin to save power. + watch_disable_analog_input(THERMISTOR_SENSE_PIN); + // Disable the enable pin's output circuitry. + watch_disable_digital_output(THERMISTOR_ENABLE_PIN); +} + +float thermistor_driver_get_temperature(void) { + // set the enable pin to the level that powers the thermistor circuit. + watch_set_pin_level(THERMISTOR_ENABLE_PIN, THERMISTOR_ENABLE_VALUE); + // get the sense pin level + uint16_t value = watch_get_analog_pin_level(THERMISTOR_SENSE_PIN); + // and then set the enable pin to the opposite value to power down the thermistor circuit. + watch_set_pin_level(THERMISTOR_ENABLE_PIN, !THERMISTOR_ENABLE_VALUE); + + return watch_utility_thermistor_temperature(value, THERMISTOR_HIGH_SIDE, THERMISTOR_B_COEFFICIENT, THERMISTOR_NOMINAL_TEMPERATURE, THERMISTOR_NOMINAL_RESISTANCE, THERMISTOR_SERIES_RESISTANCE); +} diff --git a/watch-library/shared/driver/thermistor_driver.h b/watch-library/shared/driver/thermistor_driver.h new file mode 100644 index 00000000..66bec6e9 --- /dev/null +++ b/watch-library/shared/driver/thermistor_driver.h @@ -0,0 +1,43 @@ +/* + * MIT License + * + * Copyright (c) 2022 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. + */ + +#ifndef THERMISTOR_DRIVER_H_ +#define THERMISTOR_DRIVER_H_ + +// TODO: Do these belong in movement_config.h? In settings we can set on the watch? In an EEPROM configuration area? +// Think on this. [joey 11/22] +#define THERMISTOR_SENSE_PIN (A2) +#define THERMISTOR_ENABLE_PIN (A0) +#define THERMISTOR_ENABLE_VALUE (false) +#define THERMISTOR_HIGH_SIDE (true) +#define THERMISTOR_B_COEFFICIENT (3380.0) +#define THERMISTOR_NOMINAL_TEMPERATURE (25.0) +#define THERMISTOR_NOMINAL_RESISTANCE (10000.0) +#define THERMISTOR_SERIES_RESISTANCE (10000.0) + +void thermistor_driver_enable(void); +void thermistor_driver_disable(void); +float thermistor_driver_get_temperature(void); + +#endif // THERMISTOR_DRIVER_H_ -- cgit v1.2.3