From 6ac1482862c75ef45145fb87588237ce3633a3b9 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Thu, 23 Jan 2014 02:01:12 -0800 Subject: [PATCH] Added more CLI commands. - reset -> Simulates power cycle (Not yet compatible with AVR) - reload -> Sets the device into firmware reload mode - led -> Toggles the error LED - version -> Displays detailed version information (additions to CMake files was necessary, might have broken Windows builds...) --- Debug/cli/cli.c | 60 +++++++++++++++++++++++++++++++++--- Debug/cli/cli.h | 24 +++++++++------ Lib/_buildvars.h | 26 +++++++++++++--- Lib/mk20dx128.h | 3 ++ Output/pjrcUSB/arm/usb_dev.c | 5 ++- Output/pjrcUSB/arm/usb_dev.h | 2 ++ Output/pjrcUSB/output_com.c | 12 +++++++- Output/pjrcUSB/output_com.h | 4 ++- setup.cmake | 42 +++++++++++++++++++++++++ 9 files changed, 156 insertions(+), 22 deletions(-) diff --git a/Debug/cli/cli.c b/Debug/cli/cli.c index 8bc3ab0..80a8af9 100644 --- a/Debug/cli/cli.c +++ b/Debug/cli/cli.c @@ -25,7 +25,9 @@ //#include // Project Includes +#include #include "cli.h" +#include #include @@ -34,8 +36,12 @@ // Basic command dictionary CLIDictItem basicCLIDict[] = { - { "help", "You're looking at it :P", cliFunc_help }, - { "version", "Version information about this firmware.", cliFunc_version }, + { "cliDebug", "Enables/Disables hex output of the most recent cli input.", cliFunc_cliDebug }, + { "help", "You're looking at it :P", cliFunc_help }, + { "led", "Enables/Disables indicator LED. Try a couple times just in case the LED is in an odd state.\r\n\t\t\033[33mWarning\033[0m: May adversely affect some modules...", cliFunc_led }, + { "reload", "Signals microcontroller to reflash/reload.", cliFunc_reload }, + { "reset", "Sends a software reset, should be similar to powering on the device.", cliFunc_reset }, + { "version", "Version information about this firmware.", cliFunc_version }, { 0, 0, 0 } // Null entry for dictionary end }; @@ -59,6 +65,10 @@ inline void init_cli() // Register first dictionary CLIDictionariesUsed = 0; registerDictionary_cli( basicCLIDict ); + + // Initialize main LED + init_errorLED(); + CLILEDState = 0; } void process_cli() @@ -251,6 +261,10 @@ inline void registerDictionary_cli( CLIDictItem *cmdDict ) // ----- CLI Command Functions ----- +void cliFunc_cliDebug( char* args ) +{ +} + void cliFunc_help( char* args ) { // Scan array of dictionaries and print every description @@ -264,15 +278,51 @@ void cliFunc_help( char* args ) // Parse each cmd/description until a null command entry is found for ( uint8_t cmd = 0; CLIDict[dict][cmd].name != 0; cmd++ ) { - dPrintStrs( " \033[35m", CLIDict[dict][cmd].name, NL, "\033[0m ", CLIDict[dict][cmd].description, NL ); + dPrintStrs(" \033[35m", CLIDict[dict][cmd].name, "\033[0m"); + + // Determine number of spaces to tab by the length of the command and TabAlign + uint8_t padLength = CLIEntryTabAlign - lenStr( CLIDict[dict][cmd].name ); + while ( padLength-- > 0 ) + print(" "); + + dPrintStrNL( CLIDict[dict][cmd].description ); } } } +void cliFunc_led( char* args ) +{ + CLILEDState ^= 1 << 1; // Toggle between 0 and 1 + errorLED( CLILEDState ); // Enable/Disable error LED +} + +void cliFunc_reload( char* args ) +{ + // Request to output module to be set into firmware reload mode + output_firmwareReload(); +} + +void cliFunc_reset( char* args ) +{ + // Trigger an overall software reset + SOFTWARE_RESET(); +} + void cliFunc_version( char* args ) { print( NL ); - print("Version!"); - dPrint( args ); + print( " \033[1mRevision:\033[0m " CLI_Revision NL ); + print( " \033[1mBranch:\033[0m " CLI_Branch NL ); + print( " \033[1mTree Status:\033[0m " CLI_ModifiedStatus NL ); + print( " \033[1mRepo Origin:\033[0m " CLI_RepoOrigin NL ); + print( " \033[1mCommit Date:\033[0m " CLI_CommitDate NL ); + print( " \033[1mCommit Author:\033[0m " CLI_CommitAuthor NL ); + print( " \033[1mBuild Date:\033[0m " CLI_BuildDate NL ); + print( " \033[1mBuild OS:\033[0m " CLI_BuildOS NL ); + print( " \033[1mArchitecture:\033[0m " CLI_Arch NL ); + print( " \033[1mChip:\033[0m " CLI_Chip NL ); + print( " \033[1mCPU:\033[0m " CLI_CPU NL ); + print( " \033[1mDevice:\033[0m " CLI_Device NL ); + print( " \033[1mModules:\033[0m " CLI_Modules NL ); } diff --git a/Debug/cli/cli.h b/Debug/cli/cli.h index 399f26f..3b3ab34 100644 --- a/Debug/cli/cli.h +++ b/Debug/cli/cli.h @@ -25,20 +25,17 @@ // ----- Includes ----- // Compiler Includes -#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) - -#elif defined(_mk20dx128_) - -#include "arm/usb_serial.h" - -#endif +#include +// Project Includes +#include // ----- Defines ----- #define CLILineBufferMaxSize 100 #define CLIMaxDictionaries 5 +#define CLIEntryTabAlign 12 // ----- Structs ----- @@ -61,6 +58,8 @@ uint8_t CLILineBufferCurrent; CLIDictItem *CLIDict[CLIMaxDictionaries]; uint8_t CLIDictionariesUsed; +uint8_t CLILEDState; + @@ -74,8 +73,15 @@ void argumentIsolation_cli( char* string, char** first, char** second ); void commandLookup_cli(); // CLI Command Functions -void cliFunc_help ( char* args ); -void cliFunc_version( char* args ); +void cliFunc_arch ( char* args ); +void cliFunc_chip ( char* args ); +void cliFunc_cliDebug( char* args ); +void cliFunc_device ( char* args ); +void cliFunc_help ( char* args ); +void cliFunc_led ( char* args ); +void cliFunc_reload ( char* args ); +void cliFunc_reset ( char* args ); +void cliFunc_version ( char* args ); #endif diff --git a/Lib/_buildvars.h b/Lib/_buildvars.h index 7a8c864..29abafe 100644 --- a/Lib/_buildvars.h +++ b/Lib/_buildvars.h @@ -1,15 +1,15 @@ -/* Copyright (C) 2013 by Jacob Alexander - * +/* Copyright (C) 2013-2014 by Jacob Alexander + * * 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 @@ -30,10 +30,26 @@ // You can change these to give your code its own name. #define STR_MANUFACTURER L"@MANUFACTURER@" -#define STR_PRODUCT L"Keyboard - @ScanModule@ @MacroModule@ @USBModule@ @DebugModule@" +#define STR_PRODUCT L"ForceGauge - @OutputModule@ @DebugModule@" #define STR_SERIAL L"@GitLastCommitDate@" +// Strings used in the CLI module +#define CLI_Revision "@Git_Commit_Revision@" +#define CLI_Branch "@Git_Branch_INFO@" +#define CLI_ModifiedStatus "@Git_Modified_Status@" +#define CLI_RepoOrigin "@Git_Origin_URL@" +#define CLI_CommitDate "@Git_Date_INFO@" +#define CLI_CommitAuthor @Git_Commit_Author@ +#define CLI_Modules "@OutputModule@ @DebugModule@" +#define CLI_BuildDate "@Build_Date@" +#define CLI_BuildOS "@CMAKE_SYSTEM@" +#define CLI_Arch "@COMPILER_FAMILY@" +#define CLI_Chip "@MCU@" +#define CLI_CPU "@CPU@" +#define CLI_Device "ForceGauge" + + // Mac OS-X and Linux automatically load the correct drivers. On // Windows, even though the driver is supplied by Microsoft, an // INF file is needed to load the driver. These numbers need to diff --git a/Lib/mk20dx128.h b/Lib/mk20dx128.h index 49711d0..a1bb7b2 100644 --- a/Lib/mk20dx128.h +++ b/Lib/mk20dx128.h @@ -1424,6 +1424,9 @@ extern "C" { #define ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count #define ARM_DWT_CYCCNT *(volatile uint32_t *)0xE0001004 // Cycle count register +// Software Reset +#define SOFTWARE_RESET() SCB_AIRCR = 0x5FA0004 + extern void nmi_isr(void); extern void hard_fault_isr(void); diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 72dad59..6e99eaf 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -596,7 +596,10 @@ void usb_tx(uint32_t endpoint, usb_packet_t *packet) - +void usb_device_reload() +{ + asm volatile("bkpt"); +} void _reboot_Teensyduino_(void) diff --git a/Output/pjrcUSB/arm/usb_dev.h b/Output/pjrcUSB/arm/usb_dev.h index 2ac3baa..34a7629 100644 --- a/Output/pjrcUSB/arm/usb_dev.h +++ b/Output/pjrcUSB/arm/usb_dev.h @@ -19,6 +19,8 @@ uint32_t usb_tx_packet_count(uint32_t endpoint); void usb_tx(uint32_t endpoint, usb_packet_t *packet); void usb_tx_isr(uint32_t endpoint, usb_packet_t *packet); +void usb_device_reload(); + extern volatile uint8_t usb_configuration; #ifdef CDC_DATA_INTERFACE diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index 06ca58c..d39f9bf 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -73,7 +73,7 @@ volatile uint8_t USBKeys_LEDs = 0; // ----- Functions ----- // USB Module Setup -inline void output_setup(void) +inline void output_setup() { // Initialize the USB, and then wait for the host to set configuration. // If the Teensy is powered without a PC connected to the USB port, @@ -105,3 +105,13 @@ inline void usb_send(void) scan_finishedWithUSBBuffer( USBKeys_Sent <= USBKeys_MaxSize ? USBKeys_Sent : USBKeys_MaxSize ); } + +// Sets the device into firmware reload mode +inline void output_firmwareReload() +{ +#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) +#elif defined(_mk20dx128_) + usb_device_reload(); +#endif +} + diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index bc31b2d..5d20108 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -58,7 +58,9 @@ extern uint8_t USBKeys_Idle_Count; // ----- Functions ----- -void output_setup(void); +void output_setup(); + +void output_firmwareReload(); #endif diff --git a/setup.cmake b/setup.cmake index 8041b08..1028e94 100644 --- a/setup.cmake +++ b/setup.cmake @@ -165,8 +165,10 @@ execute_process( COMMAND git status -s -uno --porcelain OUTPUT_STRIP_TRAILING_WHITESPACE ) string( LENGTH "${Git_Modified_INFO}" Git_Modified_LENGTH ) +set( Git_Modified_Status "Clean" ) if ( ${Git_Modified_LENGTH} GREATER 2 ) string( SUBSTRING "${Git_Modified_INFO}" 1 2 Git_Modified_Flag_INFO ) + set( Git_Modified_Status "Dirty" ) endif () #| Branch @@ -186,6 +188,46 @@ execute_process( COMMAND git show -s --format=%ci OUTPUT_STRIP_TRAILING_WHITESPACE ) +#| Commit Author and Email +execute_process( COMMAND git show -s --format="%cn <%ce>" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE Git_Commit_Author + RESULT_VARIABLE Git_RETURN + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +#| Commit Revision +execute_process( COMMAND git show -s --format=%H + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE Git_Commit_Revision + RESULT_VARIABLE Git_RETURN + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +#| Origin URL +execute_process( COMMAND git config --get remote.origin.url + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE Git_Origin_URL + RESULT_VARIABLE Git_RETURN + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +#| Date Macro +macro ( dateNow RESULT ) + if ( WIN32 ) + execute_process( COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE ) + elseif ( UNIX ) + execute_process( COMMAND "date" "+%Y-%m-%d %T %z" OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE ) + else () + message( send_error "date not implemented" ) + set( ${RESULT} 000000 ) + endif () +endmacro (dateNow) +dateNow( Build_Date ) + #| Only use Git variables if we were successful in calling the commands if ( ${Git_RETURN} EQUAL 0 )