Skip to content

Commit

Permalink
Tristate Flash. 'First', userscript or clear (#208)
Browse files Browse the repository at this point in the history
* restructure ^^ captures and add C_loadFirst for running the First script

* rename default.lua to First.lua

* add 3rd state to the flash nibble for ^^c. non-breaking!
  • Loading branch information
trentgill committed Oct 7, 2019
1 parent b90f744 commit 3512b27
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 59 deletions.
39 changes: 16 additions & 23 deletions lib/caw.c
Expand Up @@ -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;
}
}
}
}
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions lib/caw.h
Expand Up @@ -14,6 +14,7 @@ typedef enum{ C_none
, C_version
, C_identity
, C_killlua
, C_loadFirst
} C_cmd_t;

uint8_t Caw_Init( void );
Expand Down
45 changes: 41 additions & 4 deletions lib/flash.c
Expand Up @@ -3,22 +3,59 @@
#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 );
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 )
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 7 additions & 1 deletion lib/flash.h
Expand Up @@ -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 );
Expand Down
6 changes: 3 additions & 3 deletions lib/lualink.c
Expand Up @@ -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 );
Expand Down Expand Up @@ -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
);
}
Expand Down
68 changes: 41 additions & 27 deletions lib/repl.c
Expand Up @@ -5,7 +5,7 @@
#include <stdbool.h>

#include <stm32f7xx_hal.h> // 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
Expand All @@ -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 )
Expand Down Expand Up @@ -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;
}
}

Expand Down
File renamed without changes.
11 changes: 10 additions & 1 deletion main.c
Expand Up @@ -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();
Expand Down

0 comments on commit 3512b27

Please sign in to comment.