#include #include #include #include #include #include #include "shell_commands.h" #include "leds.h" #include "remote.h" #include "stm32l_rtc.h" #include "stm32l_eeprom.h" static void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]) { size_t n, size; n = chHeapStatus(NULL, &size); chprintf(chp, "core free memory : %u bytes\r\n", chCoreStatus()); chprintf(chp, "heap fragments : %u\r\n", n); chprintf(chp, "heap free total : %u bytes\r\n", size); } extern unsigned long __main_thread_stack_base__, __main_thread_stack_end__; // From linker script static void thread_free_stack(Thread *thread, int *free_stack_now, int *free_stack_min) { uint32_t current_sp = (uint32_t)thread->p_ctx.r13; uint32_t stack_bottom; if (current_sp >= (uint32_t)&__main_thread_stack_base__ && current_sp <= (uint32_t)&__main_thread_stack_end__) stack_bottom = (uint32_t)&__main_thread_stack_base__; else stack_bottom = (uint32_t)(thread + 1); *free_stack_now = current_sp - stack_bottom; uint32_t *stackentry = (uint32_t*)stack_bottom; uint32_t empty_val = *stackentry; while (*stackentry == empty_val) stackentry++; *free_stack_min = (uint32_t)stackentry - stack_bottom; } static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { static const char *states[] = {THD_STATE_NAMES}; Thread *tp; chprintf(chp, " addr stack prio state time free stack now/min\r\n"); tp = chRegFirstThread(); do { int stacknow, stackmin; thread_free_stack(tp, &stacknow, &stackmin); chprintf(chp, "%8s %.8lx %.8lx %4lu %9s %8lu %lu/%lu\r\n", tp->p_name, (uint32_t)tp, (uint32_t)tp->p_ctx.r13, (uint32_t)tp->p_prio, states[tp->p_state], (uint32_t)tp->p_time, stacknow, stackmin); tp = chRegNextThread(tp); } while (tp != NULL); } static void cmd_reboot(BaseSequentialStream *chp, int argc, char *argv[]) { SCB->AIRCR = 0x05FA0000 | SCB_AIRCR_SYSRESETREQ; } static void cmd_leds(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 3) { int r = atoi(argv[0]); int g = atoi(argv[1]); int b = atoi(argv[2]); set_leds(r, g, b); } else { int r,g,b; get_leds(&r, &g, &b); chprintf(chp, "red: %d green: %d blue: %d (MAX: %d)\n", r, g, b, LED_MAX); chprintf(chp, "Use leds to set.\n"); } } static void cmd_fade(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 4) { int r = atoi(argv[0]); int g = atoi(argv[1]); int b = atoi(argv[2]); int time = atoi(argv[3]); fade_leds(r, g, b, time); } else { chprintf(chp, "Use fade \n"); } } static void cmd_remote(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 0) { chprintf(chp, "Code = %08x, button = %d\n", g_remote_code, g_remote_button); chprintf(chp, "Use remote [time]\n"); return; } int btn = atoi(argv[0]); int time = 100; if (argc == 2) time = atoi(argv[1]); g_remote_button = btn; chThdSleepMilliseconds(time); g_remote_button = RM_IDLE; } static void cmd_rtc(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 2) { time_t time = {}; time.day_of_week = atoi(argv[0]); time.hour = atoi(argv[1] + 0); time.minute = atoi(argv[1] + 3); time.second = atoi(argv[1] + 6); set_rtc(&time); } else { chprintf(chp, "Use rtc DOW HH:MM:SS to set time, 1 = Monday.\n"); } { time_t time; if (!get_rtc(&time)) { chprintf(chp, "RTC is not set.\n"); } else { static const char* days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; chprintf(chp, "%s %02d:%02d:%02d\n", days[time.day_of_week - 1], time.hour, time.minute, time.second); } } } static void cmd_set(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 2) { write_eeprom(atoi(argv[0]), atoi(argv[1])); } else { chprintf(chp, "To set, use set \n"); } chprintf(chp, "1 WDAY_WAKEUP %04d\n", read_eeprom(IDX_WDAY_WAKEUP)); chprintf(chp, "2 WEND_WAKEUP %04d\n", read_eeprom(IDX_WEND_WAKEUP)); chprintf(chp, "3 WAKEUP_LEN %04d\n", read_eeprom(IDX_WAKEUP_LEN)); } const ShellCommand shell_commands[] = { {"mem", cmd_mem}, {"threads", cmd_threads}, {"reboot", cmd_reboot}, {"leds", cmd_leds}, {"fade", cmd_fade}, {"remote", cmd_remote}, {"rtc", cmd_rtc}, {"set", cmd_set}, {NULL, NULL} };