diff --git a/lib/caw.c b/lib/caw.c index 480bf147..1595ec1f 100644 --- a/lib/caw.c +++ b/lib/caw.c @@ -59,16 +59,20 @@ static C_cmd_t _find_cmd( char* str, uint32_t len ) while( len-- ){ // FIXME should decrement first? if( *pStr++ == '^' ){ if( *pStr++ == '^' ){ - if( *pStr == 'b' ){ return C_boot; } - else if( *pStr == 's' ){ return C_startupload; } - else if( *pStr == 'e' ){ return C_endupload; } - else if( *pStr == 'w' ){ return C_flashupload; } - else if( *pStr == 'c' ){ return C_flashclear; } - else if( *pStr == 'r' ){ return C_restart; } - else if( *pStr == 'p' ){ return C_print; } - else if( *pStr == 'v' ){ return C_version; } - else if( *pStr == 'i' ){ return C_identity; } - else if( *pStr == 'k' ){ return C_killlua; } + switch( *pStr ){ + case 'b': return C_boot; + case 's': return C_startupload; + case 'e': return C_endupload; + case 'w': return C_flashupload; + case 'c': return C_flashclear; + case 'r': return C_restart; + case 'p': return C_print; + case 'v': return C_version; + case 'i': return C_identity; + case 'k': return C_killlua; + case 'f': // fall through -> + case 'F': return C_loadFirst; + } } } } @@ -109,19 +113,8 @@ C_cmd_t Caw_try_receive( void ) // we're assuming that a new CDC_Itf_Receive interrupt won't occur before below if( USB_rx_dequeue( &buf, &len ) ){ - switch( _find_cmd( (char*)buf, len ) ){ // check for a system command - case C_boot: retcmd = C_boot; goto exit; - case C_startupload: retcmd = C_startupload; goto exit; - case C_endupload: retcmd = C_endupload; goto exit; - case C_flashupload: retcmd = C_flashupload; goto exit; - case C_flashclear: retcmd = C_flashclear; goto exit; - case C_restart: retcmd = C_restart; goto exit; - case C_print: retcmd = C_print; goto exit; - case C_version: retcmd = C_version; goto exit; - case C_identity: retcmd = C_identity; goto exit; - case C_killlua: retcmd = C_killlua; goto exit; - default: break; - } + retcmd = _find_cmd( (char*)buf, len ); // check for a system command + if( retcmd != C_none ){ goto exit; } // sys command received, so skip ahead if( *buf == '\e' ){ // escape key pReader = 0; // clear buffer retcmd = C_none; // no action diff --git a/lib/caw.h b/lib/caw.h index 373ecee2..17e709ba 100644 --- a/lib/caw.h +++ b/lib/caw.h @@ -14,6 +14,7 @@ typedef enum{ C_none , C_version , C_identity , C_killlua + , C_loadFirst } C_cmd_t; uint8_t Caw_Init( void ); diff --git a/lib/flash.c b/lib/flash.c index 4128c8c4..3231284a 100644 --- a/lib/flash.c +++ b/lib/flash.c @@ -3,6 +3,7 @@ #include "../ll/debug_usart.h" #define USER_MAGIC 0xA // bit pattern +#define USER_CLEAR 0xC // bit pattern // private declarations static void clear_flash( uint32_t sector, uint32_t location ); @@ -10,15 +11,51 @@ static uint32_t version12b( void ); // USER LUA SCRIPT // -uint8_t Flash_is_user_script( void ) +USERSCRIPT_t Flash_which_user_script( void ) { - return (USER_MAGIC == (0xF & (*(__IO uint32_t*)USER_SCRIPT_LOCATION))); + uint32_t script = (0xF & (*(__IO uint32_t*)USER_SCRIPT_LOCATION)); + switch( script ){ + case USER_MAGIC: return USERSCRIPT_User; + case USER_CLEAR: return USERSCRIPT_Clear; + default: return USERSCRIPT_Default; + } +} +//uint8_t Flash_is_user_script( void ) +//{ +// return (USER_MAGIC == (0xF & (*(__IO uint32_t*)USER_SCRIPT_LOCATION))); +//} + +void Flash_default_user_script( void ) +{ + printf("loading First script\n"); + clear_flash( USER_SCRIPT_SECTOR, USER_SCRIPT_LOCATION ); } void Flash_clear_user_script( void ) { printf("clear user script\n"); - clear_flash( USER_SCRIPT_SECTOR, USER_SCRIPT_LOCATION ); +// clear the flash + HAL_FLASH_Unlock(); + FLASH_EraseInitTypeDef erase_setup = + { .TypeErase = FLASH_TYPEERASE_SECTORS + , .Sector = USER_SCRIPT_SECTOR + , .NbSectors = 1 + , .VoltageRange = FLASH_VOLTAGE_RANGE_3 + }; + uint32_t error_status; + HAL_FLASHEx_Erase( &erase_setup, &error_status ); + +// set status word + uint32_t sd_addr = USER_SCRIPT_LOCATION; + uint32_t status_word = USER_CLEAR // b0:3 user script present + | (version12b() << 4) // b4:15 version control + | 0 // b16:32 length in bytes + ; + HAL_FLASH_Program( FLASH_TYPEPROGRAM_WORD + , sd_addr + , status_word + ); + HAL_FLASH_Lock(); } uint8_t Flash_write_user_script( char* script, uint32_t length ) @@ -73,7 +110,7 @@ char* Flash_read_user_scriptaddr( void ) uint8_t Flash_read_user_script( char* buffer ) { - if( !Flash_is_user_script() ){ return 1; } // no script + if( Flash_which_user_script() != USERSCRIPT_User ){ return 1; } // no script // FIXME: need to add 1 to length for null char? uint16_t word_length = ((*(__IO uint32_t*)USER_SCRIPT_LOCATION) >> 16) >> 2; diff --git a/lib/flash.h b/lib/flash.h index 0a81cfc2..b89b6f9d 100644 --- a/lib/flash.h +++ b/lib/flash.h @@ -24,8 +24,14 @@ typedef struct FLASH_Store { void* address; } FLASH_Store_t; -uint8_t Flash_is_user_script( void ); +typedef enum { USERSCRIPT_Default + , USERSCRIPT_User + , USERSCRIPT_Clear +} USERSCRIPT_t; + +USERSCRIPT_t Flash_which_user_script( void ); void Flash_clear_user_script( void ); +void Flash_default_user_script( void ); uint8_t Flash_write_user_script( char* script, uint32_t length ); uint16_t Flash_read_user_scriptlen( void ); char* Flash_read_user_scriptaddr( void ); diff --git a/lib/lualink.c b/lib/lualink.c index fb5afde1..78224d99 100644 --- a/lib/lualink.c +++ b/lib/lualink.c @@ -52,7 +52,7 @@ const struct lua_lib_locator Lua_libs[] = }; // Basic crow script -#include "lua/default.lua.h" +#include "lua/First.lua.h" // Private prototypes static void Lua_linkctolua( lua_State* L ); @@ -86,8 +86,8 @@ void Lua_Reset( void ) void Lua_load_default_script( void ) { - Lua_eval(L, lua_default - , strlen(lua_default) + Lua_eval(L, lua_First + , strlen(lua_First) , _printf ); } diff --git a/lib/repl.c b/lib/repl.c index dd338461..0c1411eb 100644 --- a/lib/repl.c +++ b/lib/repl.c @@ -5,7 +5,7 @@ #include #include // HAL_Delay() -#include "lib/flash.h" // Flash_write_(), Flash_is_userscript(), Flash_read() +#include "lib/flash.h" // Flash_write_(), Flash_which_userscript(), Flash_read() #include "lib/caw.h" // Caw_send_raw(), Caw_send_luachunk(), Caw_send_luaerror() // types @@ -29,19 +29,26 @@ void REPL_init( lua_State* lua ) { Lua = lua; - if( Flash_is_user_script() ){ - printf("loaded! %i\n", Flash_read_user_scriptlen() ); - REPL_new_script_buffer( Flash_read_user_scriptlen() ); - if( Flash_read_user_script( new_script ) - || Lua_eval( Lua, new_script - , Flash_read_user_scriptlen() // must call to flash lib! - , Caw_send_luaerror - ) ){ - printf("failed to load user script\n"); - Lua_load_default_script(); // fall back to default - } - free(new_script); - } else { Lua_load_default_script(); } // no user script + switch( Flash_which_user_script() ){ + case USERSCRIPT_Default: + Lua_load_default_script(); + break; + case USERSCRIPT_User: + REPL_new_script_buffer( Flash_read_user_scriptlen() ); + if( Flash_read_user_script( new_script ) + || Lua_eval( Lua, new_script + , Flash_read_user_scriptlen() // must call to flash lib! + , Caw_send_luaerror + ) ){ + printf("failed to load user script\n"); + Caw_send_luachunk("failed to load user script"); + } + free(new_script); + break; + case USERSCRIPT_Clear: + // Do nothing! + break; + } } void REPL_begin_upload( void ) @@ -100,19 +107,26 @@ void REPL_eval( char* buf, uint32_t len, ErrorHandler_t errfn ) void REPL_print_script( void ) { - if( Flash_is_user_script() ){ - uint16_t length = Flash_read_user_scriptlen(); - char* addr = Flash_read_user_scriptaddr(); - const int chunk = 0x200; - while( length > chunk ){ - Caw_send_raw( (uint8_t*)addr, chunk ); - length -= chunk; - addr += chunk; - HAL_Delay(3); // wait for usb tx - } - Caw_send_raw( (uint8_t*)addr, length ); - } else { - Caw_send_luachunk("no user script."); + uint16_t length; // satisfy switch + switch( Flash_which_user_script() ){ + case USERSCRIPT_Default: + Caw_send_luachunk("running 'First' script."); + break; + case USERSCRIPT_User: + length = Flash_read_user_scriptlen(); + char* addr = Flash_read_user_scriptaddr(); + const int chunk = 0x200; + while( length > chunk ){ + Caw_send_raw( (uint8_t*)addr, chunk ); + length -= chunk; + addr += chunk; + HAL_Delay(3); // wait for usb tx + } + Caw_send_raw( (uint8_t*)addr, length ); + break; + case USERSCRIPT_Clear: + Caw_send_luachunk("no user script."); + break; } } diff --git a/lua/default.lua b/lua/First.lua similarity index 100% rename from lua/default.lua rename to lua/First.lua diff --git a/main.c b/main.c index fa06e105..3efa016c 100755 --- a/main.c +++ b/main.c @@ -50,12 +50,21 @@ int main(void) case C_startupload: REPL_begin_upload(); break; case C_endupload: REPL_upload(0); break; case C_flashupload: REPL_upload(1); break; - case C_flashclear: Flash_clear_user_script(); break; case C_restart: bootloader_restart(); break; case C_print: REPL_print_script(); break; case C_version: system_print_version(); break; case C_identity: system_print_identity(); break; case C_killlua: Lua_Reset(); break; + case C_flashclear: + Lua_Reset(); + Flash_clear_user_script(); + break; + case C_loadFirst: + Lua_Reset(); + Flash_default_user_script(); + Lua_load_default_script(); // load default.lua + Lua_crowbegin(); // run init() + break; default: break; // 'C_none' does nothing } Random_Update();