diff options
-rw-r--r-- | .editorconfig | 13 | ||||
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | LICENSE | 21 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | control/Makefile | 22 | ||||
-rw-r--r-- | control/application.c | 145 | ||||
m--------- | sdk | 0 |
8 files changed, 213 insertions, 0 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..50ef1f9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = tab +trim_trailing_whitespace = true + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f345021 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +obj/ +out/ +.gitmodules +.DS_Store +firmware.bin diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..da22a46 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sdk"] + path = sdk + url = https://github.com/bigclownlabs/bcf-sdk.git @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 BigClown Labs s.r.o. + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c3da7f7 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +<a href="https://www.bigclown.com/"><img src="https://bigclown.sirv.com/logo.png" width="200" alt="BigClown Logo" align="right"></a> + +# Led strip control +This is firmware for controlling led strip using LCD module. diff --git a/control/Makefile b/control/Makefile new file mode 100644 index 0000000..a86d630 --- /dev/null +++ b/control/Makefile @@ -0,0 +1,22 @@ +APP_DIR ?= . +SDK_DIR ?= ../sdk +VERSION ?= vdev + +CFLAGS += -D'VERSION="${VERSION}"' + +Q ?= @ + +-include $(SDK_DIR)/Makefile.mk + +.PHONY: all +all: debug + +.PHONY: sdk +sdk: ../sdk/Makefile.mk + +.PHONY: update +update: sdk + @echo "Updating Git submodule 'sdk'..."; git submodule update --remote --merge sdk + +../sdk/Makefile.mk: + $(Q) git submodule update --init ../sdk diff --git a/control/application.c b/control/application.c new file mode 100644 index 0000000..c14f5b1 --- /dev/null +++ b/control/application.c @@ -0,0 +1,145 @@ +#include <bcl.h> +#include <bc_eeprom.h> +#include <bc_spi.h> +#include <bc_dice.h> + +#define SERVICE_INTERVAL_INTERVAL (60 * 60 * 1000) +#define BATTERY_UPDATE_INTERVAL (60 * 60 * 1000) + +#define TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL (15 * 60 * 1000) +#define TEMPERATURE_TAG_PUB_VALUE_CHANGE 0.2f +#define TEMPERATURE_UPDATE_SERVICE_INTERVAL (5 * 1000) +#define TEMPERATURE_UPDATE_NORMAL_INTERVAL (10 * 1000) + +#define APPLICATION_TASK_ID 0 + +#define COLOR_BLACK true + + +typedef struct { + uint8_t number; + float value; + bc_tick_t next_pub; +} event_param_t; + +bc_led_t led; +bc_led_t led_lcd_red; +bc_led_t led_lcd_blue; + +// Thermometer instance +bc_tmp112_t tmp112; +event_param_t temperature_event_param = { .next_pub = 0, .value = NAN }; +float temperature_on_display = NAN; + +void tmp112_event_handler(bc_tmp112_t *self, bc_tmp112_event_t event, void *event_param) { + float value; + event_param_t *param = (event_param_t *)event_param; + + if (event != BC_TMP112_EVENT_UPDATE) + return; + + if (bc_tmp112_get_temperature_celsius(self, &value)) { + if ((fabsf(value - param->value) >= TEMPERATURE_TAG_PUB_VALUE_CHANGE) || (param->next_pub < bc_scheduler_get_spin_tick())) { + bc_radio_pub_temperature(BC_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_ALTERNATE, &value); + param->value = value; + param->next_pub = bc_scheduler_get_spin_tick() + TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL; + } + } else + param->value = NAN; + + if ((fabsf(param->value - temperature_on_display) >= 0.1) || isnan(temperature_on_display)) + bc_scheduler_plan_now(APPLICATION_TASK_ID); +} + +void on_lcd_button_click(void) { +} + +void lcd_button_left_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param) { + if (event != BC_BUTTON_EVENT_CLICK) + return; + bc_led_pulse(&led_lcd_blue, 30); + on_lcd_button_click(); +} + +void lcd_button_right_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param) { + if (event != BC_BUTTON_EVENT_CLICK) + return; + bc_led_pulse(&led_lcd_red, 30); + on_lcd_button_click(); +} + +void battery_event_handler(bc_module_battery_event_t event, void *event_param) { + if (event != BC_MODULE_BATTERY_EVENT_UPDATE) + return; + float voltage; + if (bc_module_battery_get_voltage(&voltage)) + bc_radio_pub_battery(&voltage); +} + +void switch_to_normal_mode_task(void *param) { + bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_NORMAL_INTERVAL); + bc_scheduler_unregister(bc_scheduler_get_current_task_id()); +} + +void application_init(void) { + // Initialize LED on core module + bc_led_init(&led, BC_GPIO_LED, false, false); + bc_led_set_mode(&led, BC_LED_MODE_OFF); + + // Initialize Radio + bc_radio_init(BC_RADIO_MODE_NODE_SLEEPING); + + // Initialize battery + bc_module_battery_init(); + bc_module_battery_set_event_handler(battery_event_handler, NULL); + bc_module_battery_set_update_interval(BATTERY_UPDATE_INTERVAL); + + // Initialize thermometer sensor on core module + bc_tmp112_init(&tmp112, BC_I2C_I2C0, 0x49); + bc_tmp112_set_event_handler(&tmp112, tmp112_event_handler, &temperature_event_param); + bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_SERVICE_INTERVAL); + + // Initialize LCD + bc_module_lcd_init(); + + // Initialize LCD button left + static bc_button_t lcd_left; + bc_button_init_virtual(&lcd_left, BC_MODULE_LCD_BUTTON_LEFT, bc_module_lcd_get_button_driver(), false); + bc_button_set_event_handler(&lcd_left, lcd_button_left_event_handler, NULL); + + // Initialize LCD button right + static bc_button_t lcd_right; + bc_button_init_virtual(&lcd_right, BC_MODULE_LCD_BUTTON_RIGHT, bc_module_lcd_get_button_driver(), false); + bc_button_set_event_handler(&lcd_right, lcd_button_right_event_handler, NULL); + + // Initialize red and blue LED on LCD module + bc_led_init_virtual(&led_lcd_red, BC_MODULE_LCD_LED_RED, bc_module_lcd_get_led_driver(), true); + bc_led_init_virtual(&led_lcd_blue, BC_MODULE_LCD_LED_BLUE, bc_module_lcd_get_led_driver(), true); + + bc_radio_pairing_request("lcd-thermostat", VERSION); + + bc_scheduler_register(switch_to_normal_mode_task, NULL, SERVICE_INTERVAL_INTERVAL); + + bc_led_pulse(&led, 2000); +} + +void application_task(void) { + static char str_temperature[10]; + if (!bc_module_lcd_is_ready()) + return; + + bc_system_pll_enable(); + bc_module_lcd_clear(); + + bc_module_lcd_set_font(&bc_font_ubuntu_33); + snprintf(str_temperature, sizeof(str_temperature), "%.1f ", temperature_event_param.value); + int x = bc_module_lcd_draw_string(20, 20, str_temperature, COLOR_BLACK); + temperature_on_display = temperature_event_param.value; + + bc_module_lcd_set_font(&bc_font_ubuntu_24); + bc_module_lcd_draw_string(x - 20, 25, "\xb0" "C ", COLOR_BLACK); + + bc_module_lcd_update(); + + bc_system_pll_disable(); +} diff --git a/sdk b/sdk new file mode 160000 +Subproject 6fd4c3dd3fc08274e56606068fb807b33335e16 |