diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 8b7af0b..cdd3729 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -40,6 +40,7 @@ target_sources(dispensy PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/buttons.c ${CMAKE_CURRENT_LIST_DIR}/src/lcd.c ${CMAKE_CURRENT_LIST_DIR}/src/ring.c + ${CMAKE_CURRENT_LIST_DIR}/src/hw_id.c ${CMAKE_CURRENT_LIST_DIR}/pico-ssd1306/ssd1306.c ) diff --git a/firmware/include/hw_id.h b/firmware/include/hw_id.h new file mode 100644 index 0000000..f2eef0f --- /dev/null +++ b/firmware/include/hw_id.h @@ -0,0 +1,34 @@ +/* + * hw_id.h + * + * Copyright (c) 2022 - 2024 Thomas Buck (thomas@xythobuz.de) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * See . + */ + +#ifndef __HW_ID_H__ +#define __HW_ID_H__ + +#include "pico/stdlib.h" + +enum hw_type { + HW_TYPE_MAINBOARD = 0, +}; + +void hw_id_init(void); +void hw_id_read(void); + +enum hw_type hw_type(void); +uint hw_id(void); + +#endif // __HW_ID_H__ diff --git a/firmware/include/lcd.h b/firmware/include/lcd.h index 34bf9a1..e0c8aec 100644 --- a/firmware/include/lcd.h +++ b/firmware/include/lcd.h @@ -26,6 +26,8 @@ #define FONT_WIDTH 5 void lcd_init(void); + void lcd_splash_version(void); +void lcd_bye(void); #endif // __LCD_H__ diff --git a/firmware/src/console.c b/firmware/src/console.c index f9123e6..1c8b40d 100644 --- a/firmware/src/console.c +++ b/firmware/src/console.c @@ -25,8 +25,7 @@ #include "log.h" #include "util.h" #include "usb_cdc.h" -#include "lcd.h" -#include "main.h" +#include "hw_id.h" #include "console.h" #define CNSL_BUFF_SIZE 64 @@ -81,12 +80,20 @@ static void cnsl_interpret(const char *line) { println(""); println(" reset - reset back into this firmware"); println(" \\x18 - reset to bootloader"); + println(" type - print hardware type"); + println(" id - print hardware ID"); println(""); println("Press Enter with no input to repeat last command."); println("Use repeat to continuously execute last command."); println("Stop this by calling repeat again."); } else if (strcmp(line, "reset") == 0) { reset_to_main(); + } else if (strcmp(line, "type") == 0) { + hw_id_read(); + debug("HW Type: %d", hw_type()); + } else if (strcmp(line, "id") == 0) { + hw_id_read(); + debug("HW ID: %d", hw_id()); } else { println("unknown command \"%s\"", line); } diff --git a/firmware/src/hw_id.c b/firmware/src/hw_id.c new file mode 100644 index 0000000..d30a263 --- /dev/null +++ b/firmware/src/hw_id.c @@ -0,0 +1,82 @@ +/* + * hw_id.c + * + * Copyright (c) 2022 - 2024 Thomas Buck (thomas@xythobuz.de) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * See . + */ + +#include "hardware/watchdog.h" +#include "config.h" +#include "log.h" +#include "hw_id.h" + +#define SR_WIDTH 8 + +#define SR_GPIO_LOAD 20 +#define SR_GPIO_CLK 21 +#define SR_GPIO_DATA 22 + +static bool states[SR_WIDTH] = {0}; + +void hw_id_init(void) { + gpio_init(SR_GPIO_LOAD); + gpio_set_dir(SR_GPIO_LOAD, GPIO_OUT); + gpio_put(SR_GPIO_LOAD, true); + + gpio_init(SR_GPIO_CLK); + gpio_set_dir(SR_GPIO_CLK, GPIO_OUT); + gpio_put(SR_GPIO_CLK, true); + + gpio_init(SR_GPIO_DATA); + gpio_set_dir(SR_GPIO_DATA, GPIO_IN); +} + +void hw_id_read(void) { + gpio_put(SR_GPIO_LOAD, false); + watchdog_update(); + sleep_us(5); + gpio_put(SR_GPIO_LOAD, true); + watchdog_update(); + sleep_us(5); + + for (uint i = 0; i < SR_WIDTH; i++) { + gpio_put(SR_GPIO_CLK, false); + watchdog_update(); + sleep_us(5); + + states[i] = gpio_get(SR_GPIO_DATA); + + gpio_put(SR_GPIO_CLK, true); + watchdog_update(); + sleep_us(5); + + //debug("bit %d is %s", i, states[i] ? "true" : "false"); + } +} + +enum hw_type hw_type(void) { + uint val = 0; + for (uint i = 4; i < 8; i++) { + val |= states[i] ? (1 << (i - 4)) : 0; + } + return val; +} + +uint hw_id(void) { + uint val = 0; + for (uint i = 0; i < 4; i++) { + val |= (!states[i]) ? (1 << (4 - i - 1)) : 0; + } + return val; +} diff --git a/firmware/src/lcd.c b/firmware/src/lcd.c index 95bbbf6..32af78a 100644 --- a/firmware/src/lcd.c +++ b/firmware/src/lcd.c @@ -16,6 +16,7 @@ * See . */ +#include #include #include "hardware/i2c.h" @@ -23,6 +24,7 @@ #include "git.h" #include "config.h" +#include "hw_id.h" #include "log.h" #include "lcd.h" @@ -69,20 +71,31 @@ void lcd_splash_version(void) { if (git_IsPopulated()) { const char *hash = git_CommitSHA1(); - char short_hash[6 + 7 + 1] = {0}; + char short_hash[6 + 7 + 6 + 1] = {0}; memcpy(short_hash, "Hash: ", 6); memcpy(short_hash + 6, hash, 7); - ssd1306_draw_string(&lcd, 0, FONT_HEIGHT * 2 + 1 + (FONT_HEIGHT + 1) * 2, 1, - short_hash); - if (git_AnyUncommittedChanges()) { - ssd1306_draw_string(&lcd, 0, FONT_HEIGHT * 2 + 1 + (FONT_HEIGHT + 1) * 3, 1, - "Repo has changes!"); + memcpy(short_hash + 6 + 7, " dirty", 6); } + ssd1306_draw_string(&lcd, 0, FONT_HEIGHT * 2 + 1 + (FONT_HEIGHT + 1) * 2, 1, + short_hash); } else { ssd1306_draw_string(&lcd, 0, FONT_HEIGHT * 2 + 1 + (FONT_HEIGHT + 1) * 2, 1, "No Git Repo"); } + char hw_id_str[42] = {0}; + snprintf(hw_id_str, sizeof(hw_id_str) - 1, + "HW type=%X id=%X", hw_type(), hw_id()); + ssd1306_draw_string(&lcd, 0, FONT_HEIGHT * 2 + 1 + (FONT_HEIGHT + 1) * 3, 1, + hw_id_str); + + ssd1306_show(&lcd); +} + +void lcd_bye(void) { + ssd1306_clear(&lcd); + ssd1306_draw_string(&lcd, 6, 5, 3, " Boot-"); + ssd1306_draw_string(&lcd, 8, LCD_HEIGHT / 2 + 5, 3, "loader"); ssd1306_show(&lcd); } diff --git a/firmware/src/main.c b/firmware/src/main.c index 3ab15a2..9d418a7 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -24,6 +24,7 @@ #include "usb.h" #include "buttons.h" #include "lcd.h" +#include "hw_id.h" #include "main.h" void main_loop_hw(void) { @@ -35,7 +36,8 @@ int main(void) { watchdog_enable(WATCHDOG_PERIOD_MS, 1); // detect hardware type - // TODO + hw_id_init(); + hw_id_read(); // required for debug console cnsl_init(); @@ -46,7 +48,10 @@ int main(void) { debug("reset by watchdog"); } - buttons_init(); + debug("HW Type: %d", hw_type()); + debug("HW ID: %d", hw_id()); + + //buttons_init(); lcd_init(); lcd_splash_version(); @@ -54,7 +59,7 @@ int main(void) { while (1) { main_loop_hw(); - buttons_run(); + //buttons_run(); cnsl_run(); } diff --git a/firmware/src/util.c b/firmware/src/util.c index 4d7a52e..999583d 100644 --- a/firmware/src/util.c +++ b/firmware/src/util.c @@ -21,6 +21,7 @@ #include "hardware/watchdog.h" #include "config.h" +#include "lcd.h" #include "log.h" #include "util.h" @@ -33,11 +34,8 @@ bool str_startswith(const char *str, const char *start) { } void reset_to_bootloader(void) { -#ifdef PICO_DEFAULT_LED_PIN - reset_usb_boot(1 << PICO_DEFAULT_LED_PIN, 0); -#else // ! PICO_DEFAULT_LED_PIN + lcd_bye(); reset_usb_boot(0, 0); -#endif // PICO_DEFAULT_LED_PIN } void reset_to_main(void) {