Have basic lua scripting working.

scripts/usb_device.lua is planned to use for usb device info prior to
connecting.  Currently just used to determine log level.

scripts/inlretro.lua is the main script called by the C main function.
Prior to passing control over to lua in inlretro.lua, commandline args
must be passed in somehow.  And the USB device must be connected to, and
usb transfer object passed to dictionary's local transfer pointer.

Not sure dictionary having a local static pointer to usb transfer struct
is a great idea, but simplest solution I could think of to keep from
complicating lua by passing the pointer/object back and forth between lua
and C.  This method mostly abstracts the usb transfer object from lua
which makes sense to me anyway.

Need to come up with a way for shared_dict_*.h defines to be made
available to lua scripts.  Seems a lua table would be the best solution,
but don't want to keep manual copies for all the defines.  These C defines
are necessary as it's the only clean way to define the dictionaries for
the firmware.  Thinking the best solution will be a lua script that
parses all shared_dict*.h files and creates tables at run time.  Planning
to hardcode some tables for now, then implement a .h file parser in lua.
This commit is contained in:
Paul Molloy pinkASUS 2017-07-09 17:29:35 -05:00
parent f4fe81da96
commit 2fdefde840
33 changed files with 154 additions and 91 deletions

12
host/scripts/inlretro.lua Normal file
View File

@ -0,0 +1,12 @@
-- main script that runs application logic and flow
-- initial function called from C main
function main ()
print("print from main.\n")
print("dict_call ", dict_call( 1, 2, 3, 4), "\n")
end
-- call functions desired to run when script is called
main ()

View File

@ -0,0 +1,2 @@
-- info used to open usb device
libusb_log = 0 -- 0: default no msg printing, 1: errors, 2: warnings, 3: info, 4: debug

View File

@ -1,5 +1,40 @@
#include "dictionary.h" #include "dictionary.h"
static USBtransfer *usb_xfr = NULL;
void init_dictionary( USBtransfer *transfer ) {
usb_xfr = transfer;
return;
}
int lua_dictionary_call (lua_State *L) {
//double d = lua_tonumber(L, 1); /* get argument */
int arg1 = luaL_checknumber(L, 1); /* get argument */
int arg2 = luaL_checknumber(L, 2); /* get argument */
int arg3 = luaL_checknumber(L, 3); /* get argument */
int arg4 = luaL_checknumber(L, 4); /* get argument */
printf("arg1 %d, arg2 %d\n", arg1, arg2);
printf("arg3 %d, arg4 %d\n", arg3, arg4);
check( usb_xfr != NULL, "dictionary usb transfer pointer not initialized.\n")
//dictionary_call_print_option( FALSE, transfer, dictionary, opcode, addr, miscdata, endpoint, buffer, length);
dictionary_call( usb_xfr, DICT_PINPORT, LED_OP, 0, 0, USB_IN,
NULL, 1);
dictionary_call( usb_xfr, DICT_PINPORT, LED_ON, 0, 0, USB_IN,
NULL, 1);
lua_pushnumber(L, (2*arg1)); /* push result */
return 1; /* number of results */
error:
printf("dictionary call went to error\n");
lua_pushstring(L, "ERROR"); /* push result */
return 1;
}
/* Make dictionary calls simpler /* Make dictionary calls simpler
* provide USBtransfer pointer with handle set to retro programmer * provide USBtransfer pointer with handle set to retro programmer
* provide dictionary as defined in shared_dictionaries.h (request) * provide dictionary as defined in shared_dictionaries.h (request)

View File

@ -19,6 +19,15 @@
#include "shared_errors.h" #include "shared_errors.h"
#include "shared_dictionaries.h" #include "shared_dictionaries.h"
#include "lua/lua.h"
#include "lua/lauxlib.h"
#include "lua/lualib.h"
void init_dictionary( USBtransfer *transfer );
int lua_dictionary_call (lua_State *L);
//default call dictionary without print option //default call dictionary without print option
int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr,
uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length); uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length);

View File

@ -12,23 +12,24 @@
//"make debug" to get DEBUG msgs on entire program //"make debug" to get DEBUG msgs on entire program
#include "dbg.h" #include "dbg.h"
#include "shared_dictionaries.h" //#include "shared_dictionaries.h"
#include "usb_operations.h" #include "usb_operations.h"
#include "write_operations.h" #include "dictionary.h"
#include "erase.h" //#include "write_operations.h"
#include "test.h" //#include "erase.h"
#include "cartridge.h" //#include "test.h"
#include "file.h" //#include "cartridge.h"
#include "dump.h" //#include "file.h"
#include "flash.h" //#include "dump.h"
#include "shared_enums.h" //#include "flash.h"
//#include "shared_enums.h"
//lua libraries //lua libraries
#include "lua/lua.h" #include "lua/lua.h"
#include "lua/lauxlib.h" #include "lua/lauxlib.h"
#include "lua/lualib.h" #include "lua/lualib.h"
void error (lua_State *L, const char *fmt, ...) { void error_lua (lua_State *L, const char *fmt, ...) {
va_list argp; va_list argp;
va_start(argp, fmt); va_start(argp, fmt);
vfprintf(stderr, fmt, argp); vfprintf(stderr, fmt, argp);
@ -42,41 +43,21 @@ int getglobint (lua_State *L, const char *var) {
lua_getglobal(L, var); lua_getglobal(L, var);
result = (int)lua_tointegerx(L, -1, &isnum); result = (int)lua_tointegerx(L, -1, &isnum);
if (!isnum) if (!isnum)
error(L, "'%s' should be a number\n", var); error_lua(L, "'%s' should be a number\n", var);
//printf("'%s' should be a number\n", var);
lua_pop(L, 1); /* remove result from the stack */ lua_pop(L, 1); /* remove result from the stack */
return result; return result;
} }
void load (lua_State *L, const char *fname, int *w, int *h) { void load (lua_State *L, const char *fname, int *w, int *h) {
if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0)) if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0))
error(L, "cannot run config. file: %s", lua_tostring(L, -1)); error_lua(L, "cannot run config. file: %s", lua_tostring(L, -1));
//printf("cannot run config. file: %s", lua_tostring(L, -1));
*w = getglobint(L, "width"); *w = getglobint(L, "width");
*h = getglobint(L, "height"); *h = getglobint(L, "height");
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// char buff[256];
// int error;
lua_State *L = luaL_newstate(); /* opens Lua */
luaL_openlibs(L); /* opens the standard libraries */
int high, wide;
load(L, "scripts/test.lua", &high, &wide );
printf("high= %d, wide=%d\n", high, wide);
// while (fgets(buff, sizeof(buff), stdin) != NULL) {
// error = luaL_loadstring(L, buff) || lua_pcall(L, 0, 0, 0);
// if (error) {
// fprintf(stderr, "%s\n", lua_tostring(L, -1));
// lua_pop(L, 1); /* pop error message from the stack */
// }
// }
lua_close(L);
return 0;
/*luacut
//lower case flags suggested for average user //lower case flags suggested for average user
int e_flag = 0; //FORCE ERASE int e_flag = 0; //FORCE ERASE
@ -109,11 +90,18 @@ int main(int argc, char *argv[])
char *S_value = NULL; //program SNES binary file char *S_value = NULL; //program SNES binary file
char *W_value = NULL; //program WRAM/SRAM file char *W_value = NULL; //program WRAM/SRAM file
int operation = 0; //used to denote the overall operation being requested flash/dump/verify etc // int operation = 0; //used to denote the overall operation being requested flash/dump/verify etc
int index = 0; int index = 0;
int rv = 0; int rv = 0;
opterr = 0; opterr = 0;
//usb variables
USBtransfer *transfer = NULL;
//lua variables
lua_State *L = NULL;
//getopt returns args till done then returns -1 //getopt returns args till done then returns -1
//string of possible args : denotes 1 required additional arg //string of possible args : denotes 1 required additional arg
//:: denotes optional additional arg follows //:: denotes optional additional arg follows
@ -180,11 +168,11 @@ int main(int argc, char *argv[])
} }
// debug("flags= o:%d n:%d e:%d f:%d h:%d i:%d t:%d x:%d y:%d T:%d", debug("flags= o:%d n:%d e:%d f:%d h:%d i:%d t:%d x:%d y:%d T:%d",
// o_flag, n_flag, e_flag, f_flag, h_flag, i_flag, t_flag, x_flag, y_flag, T_flag ); o_flag, n_flag, e_flag, f_flag, h_flag, i_flag, t_flag, x_flag, y_flag, T_flag );
// debug("args= b:%s c:%s d:%s m:%s p:%s", b_value, c_value, d_value, m_value, p_value); debug("args= b:%s c:%s d:%s m:%s p:%s", b_value, c_value, d_value, m_value, p_value);
// debug("args= s:%s v:%s C:%s L:%s K:%s", s_value, v_value, C_value, L_value, K_value); debug("args= s:%s v:%s C:%s L:%s K:%s", s_value, v_value, C_value, L_value, K_value);
// debug("args= O:%s P:%s S:%s W:%s", O_value, P_value, S_value, W_value); debug("args= O:%s P:%s S:%s W:%s", O_value, P_value, S_value, W_value);
for( index = optind; index < argc; index++) { for( index = optind; index < argc; index++) {
log_err("Non-option arguement: %s \n", argv[index]); log_err("Non-option arguement: %s \n", argv[index]);
@ -195,14 +183,21 @@ int main(int argc, char *argv[])
printf("You've asked for help but the help message still needs created...\n"); printf("You've asked for help but the help message still needs created...\n");
return 0; return 0;
} }
/*
if ( O_value || v_value || s_value || b_value || y_flag || t_flag || f_flag ) { if ( O_value || v_value || b_value || y_flag || t_flag || f_flag ) {
printf("option not currently supported sorry...\n"); printf("option not currently supported sorry...\n");
} }
*/
//Determine overall operation being performed based on user args //Start up Lua
//Also don't want to continue if conflicting args are being used L = luaL_newstate(); //opens Lua
luaL_openlibs(L); //opens the standard libraries
//register C functions that can be called from Lua
lua_pushcfunction(L, lua_dictionary_call);
lua_setglobal(L, "dict_call");
/*
//flags about input files only used for writes //flags about input files only used for writes
if ( p_value || i_flag || C_value || P_value || S_value || W_value ) { if ( p_value || i_flag || C_value || P_value || S_value || W_value ) {
check( d_value == NULL, "input args conflict can't program and dump in same operation."); check( d_value == NULL, "input args conflict can't program and dump in same operation.");
@ -214,44 +209,61 @@ int main(int argc, char *argv[])
check( e_flag == 0, "input args conflict can't erase and dump in same operation."); check( e_flag == 0, "input args conflict can't erase and dump in same operation.");
operation = READ; operation = READ;
} }
*/
//TODO all commandline args must be collected and passed into lua
//context set to NULL since only acting as single user of libusb //context set to NULL since only acting as single user of libusb
libusb_context *context = NULL; libusb_context *context = NULL;
//create USBtransfer struct to hold all transfer info //create USBtransfer struct to hold all transfer info
USBtransfer *transfer = malloc( sizeof(USBtransfer)); transfer = malloc( sizeof(USBtransfer));
check_mem(transfer);
//create usb device handle pointer to interact with retro-prog //create usb device handle pointer to interact with retro-prog
//libusb_device_handle *rprog_handle = NULL;
transfer->handle = NULL; transfer->handle = NULL;
//create file object/struct //create file object/struct
rom_image *rom = malloc( sizeof(rom_image)); // rom_image *rom = malloc( sizeof(rom_image));
//
check_mem(transfer); // check_mem(rom);
check_mem(rom); // init_rom_elements(rom);
init_rom_elements(rom);
//command line arg L_value to set different LIBUSB debugging options //lua script arg to set different LIBUSB debugging options
//any value > 0 also prints debug statements in open_usb_device function check( !(luaL_loadfile(L, "scripts/usb_device.lua") || lua_pcall(L, 0, 0, 0)),
"cannot run config. file: %s", lua_tostring(L, -1));
int libusb_log = LIBUSB_LOG_LEVEL_NONE; // 0: default no msgs ever printed int libusb_log = LIBUSB_LOG_LEVEL_NONE; // 0: default no msgs ever printed
if (L_value != NULL) { libusb_log = getglobint(L, "libusb_log");
check( isdigit(L_value[0]),
"Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value); //any value > 0 also prints debug statements in open_usb_device function
check( strlen(L_value) == 1,
"Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value);
libusb_log = atoi(L_value);
check( ((libusb_log >= LIBUSB_LOG_LEVEL_NONE) && (libusb_log <=LIBUSB_LOG_LEVEL_DEBUG)), check( ((libusb_log >= LIBUSB_LOG_LEVEL_NONE) && (libusb_log <=LIBUSB_LOG_LEVEL_DEBUG)),
"Invalid LIBUSB_LOG_LEVEL: %d, must be from 0 to 4", libusb_log ); "Invalid LIBUSB_LOG_LEVEL: %d, must be from 0 to 4", libusb_log );
}
//TODO get usb device settings from usb_device.lua
//open INL retro prog with firmware version 2.0 or greater //open INL retro prog with firmware version 2.0 or greater
if (K_value != NULL) { //if (K_value != NULL) {
//TODO take K_value option to connect to different version kazzo // //TODO take K_value option to connect to different version kazzo
} //}
transfer->handle = open_usb_device( context, libusb_log ); transfer->handle = open_usb_device( context, libusb_log );
check( transfer->handle != NULL, "Unable to open INL retro-prog usb device handle."); check( transfer->handle != NULL, "Unable to open INL retro-prog usb device handle.");
//provide dictionary.c with pointer to transfer so it can update it's local pointer
init_dictionary( transfer );
//usb device is open, pass args and control over to lua
if (s_value) {
check( !(luaL_loadfile(L, s_value) || lua_pcall(L, 0, 0, 0)),
"cannot run config. file: %s", lua_tostring(L, -1));
}
//program flow doesn't come back to this point until script call ends/returns
/*
//create board object/struct //create board object/struct
cartridge *cart = malloc( sizeof(cartridge)); cartridge *cart = malloc( sizeof(cartridge));
check_mem(cart); check_mem(cart);
@ -351,6 +363,7 @@ int main(int argc, char *argv[])
rom->fileptr = NULL; rom->fileptr = NULL;
debug("closed"); debug("closed");
} }
*/
//dump or program data based on user args //dump or program data based on user args
@ -361,6 +374,7 @@ int main(int argc, char *argv[])
//handle simple LED ON/OFF within main for now //handle simple LED ON/OFF within main for now
//TODO cut this newbie code out of here //TODO cut this newbie code out of here
/*
int xfr_cnt = 0; int xfr_cnt = 0;
uint8_t rbuf[8]; uint8_t rbuf[8];
@ -390,20 +404,31 @@ int main(int argc, char *argv[])
} }
printf("\n"); printf("\n");
} }
*/
close: //close:
lua_close(L);
close_usb( context, transfer->handle); close_usb( context, transfer->handle);
if(rom->fileptr != NULL){ free(transfer);
//close file
fclose(rom->fileptr); // if(rom->fileptr != NULL){
} // //close file
// fclose(rom->fileptr);
// }
return 0; return 0;
error: error: //checks goto error when failed
// printf("main program went to error\n"); printf("main program went to error\n");
if ( transfer != NULL )
free(transfer);
if ( L != NULL )
lua_close(L);
// //
// close_usb( context, transfer->handle); // close_usb( context, transfer->handle);
// if(rom->fileptr != NULL){ // if(rom->fileptr != NULL){
@ -412,6 +437,5 @@ error:
return 1; return 1;
luacut */
} }

View File

@ -1,20 +0,0 @@
AVR Memory Usage
----------------
Device: atmega164a
Program: 5486 bytes (33.5% Full)
(.text + .data + .bootloader)
Data: 653 bytes (63.8% Full)
(.data + .bss + .noinit)
AVR Memory Usage
----------------
Device: atmega164a
Program: 5498 bytes (33.6% Full)
(.text + .data + .bootloader)
Data: 653 bytes (63.8% Full)
(.data + .bss + .noinit)

View File

@ -50,6 +50,7 @@ libusb_device_handle * open_usb_device( libusb_context *context, int log_level )
printf("\tINFO: informational, warning, & error messages are printed to stdout\n"); printf("\tINFO: informational, warning, & error messages are printed to stdout\n");
break; break;
case 4: case 4:
default:
printf("\tDEBUG: debug, info, warning, & error messages are printed to stdout\n"); printf("\tDEBUG: debug, info, warning, & error messages are printed to stdout\n");
break; break;
} }