From 2fdefde840c7e6b719c033d79fd44372167e4a2a Mon Sep 17 00:00:00 2001 From: Paul Molloy pinkASUS Date: Sun, 9 Jul 2017 17:29:35 -0500 Subject: [PATCH] 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. --- host/scripts/inlretro.lua | 12 ++ host/scripts/usb_device.lua | 2 + host/source/dictionary.c | 35 +++++ host/source/dictionary.h | 9 ++ host/source/inlprog.c | 166 +++++++++++++---------- host/source/{ => old}/buffer.c | 0 host/source/{ => old}/buffer.h | 0 host/source/{ => old}/cartridge.c | 0 host/source/{ => old}/cartridge.h | 0 host/source/{ => old}/dump.c | 0 host/source/{ => old}/dump.h | 0 host/source/{ => old}/erase.c | 0 host/source/{ => old}/erase.h | 0 host/source/{ => old}/file.c | 0 host/source/{ => old}/file.h | 0 host/source/{ => old}/flash.c | 0 host/source/{ => old}/flash.h | 0 host/source/{ => old}/io.c | 0 host/source/{ => old}/io.h | 0 host/source/{ => old}/memory.c | 0 host/source/{ => old}/memory.h | 0 host/source/{ => old}/nes.c | 0 host/source/{ => old}/nes.h | 0 host/source/{ => old}/operation.c | 0 host/source/{ => old}/operation.h | 0 host/source/{ => old}/snes.c | 0 host/source/{ => old}/snes.h | 0 host/source/{ => old}/test.c | 0 host/source/{ => old}/test.h | 0 host/source/{ => old}/write_operations.c | 0 host/source/{ => old}/write_operations.h | 0 host/source/temp | 20 --- host/source/usb_operations.c | 1 + 33 files changed, 154 insertions(+), 91 deletions(-) create mode 100644 host/scripts/inlretro.lua create mode 100644 host/scripts/usb_device.lua rename host/source/{ => old}/buffer.c (100%) rename host/source/{ => old}/buffer.h (100%) rename host/source/{ => old}/cartridge.c (100%) rename host/source/{ => old}/cartridge.h (100%) rename host/source/{ => old}/dump.c (100%) rename host/source/{ => old}/dump.h (100%) rename host/source/{ => old}/erase.c (100%) rename host/source/{ => old}/erase.h (100%) rename host/source/{ => old}/file.c (100%) rename host/source/{ => old}/file.h (100%) rename host/source/{ => old}/flash.c (100%) rename host/source/{ => old}/flash.h (100%) rename host/source/{ => old}/io.c (100%) rename host/source/{ => old}/io.h (100%) rename host/source/{ => old}/memory.c (100%) rename host/source/{ => old}/memory.h (100%) rename host/source/{ => old}/nes.c (100%) rename host/source/{ => old}/nes.h (100%) rename host/source/{ => old}/operation.c (100%) rename host/source/{ => old}/operation.h (100%) rename host/source/{ => old}/snes.c (100%) rename host/source/{ => old}/snes.h (100%) rename host/source/{ => old}/test.c (100%) rename host/source/{ => old}/test.h (100%) rename host/source/{ => old}/write_operations.c (100%) rename host/source/{ => old}/write_operations.h (100%) delete mode 100644 host/source/temp diff --git a/host/scripts/inlretro.lua b/host/scripts/inlretro.lua new file mode 100644 index 0000000..037beca --- /dev/null +++ b/host/scripts/inlretro.lua @@ -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 () + diff --git a/host/scripts/usb_device.lua b/host/scripts/usb_device.lua new file mode 100644 index 0000000..93bef6f --- /dev/null +++ b/host/scripts/usb_device.lua @@ -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 diff --git a/host/source/dictionary.c b/host/source/dictionary.c index fd62939..d9b9bac 100644 --- a/host/source/dictionary.c +++ b/host/source/dictionary.c @@ -1,5 +1,40 @@ #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 * provide USBtransfer pointer with handle set to retro programmer * provide dictionary as defined in shared_dictionaries.h (request) diff --git a/host/source/dictionary.h b/host/source/dictionary.h index 885f70c..b227cdb 100644 --- a/host/source/dictionary.h +++ b/host/source/dictionary.h @@ -19,6 +19,15 @@ #include "shared_errors.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 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); diff --git a/host/source/inlprog.c b/host/source/inlprog.c index c84f263..7e6e454 100644 --- a/host/source/inlprog.c +++ b/host/source/inlprog.c @@ -12,23 +12,24 @@ //"make debug" to get DEBUG msgs on entire program #include "dbg.h" -#include "shared_dictionaries.h" +//#include "shared_dictionaries.h" #include "usb_operations.h" -#include "write_operations.h" -#include "erase.h" -#include "test.h" -#include "cartridge.h" -#include "file.h" -#include "dump.h" -#include "flash.h" -#include "shared_enums.h" +#include "dictionary.h" +//#include "write_operations.h" +//#include "erase.h" +//#include "test.h" +//#include "cartridge.h" +//#include "file.h" +//#include "dump.h" +//#include "flash.h" +//#include "shared_enums.h" //lua libraries #include "lua/lua.h" #include "lua/lauxlib.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_start(argp, fmt); vfprintf(stderr, fmt, argp); @@ -42,41 +43,21 @@ int getglobint (lua_State *L, const char *var) { lua_getglobal(L, var); result = (int)lua_tointegerx(L, -1, &isnum); if (!isnum) - error(L, "'%s' should be a number\n", var); - //printf("'%s' should be a number\n", var); + error_lua(L, "'%s' should be a number\n", var); lua_pop(L, 1); /* remove result from the stack */ return result; } void load (lua_State *L, const char *fname, int *w, int *h) { if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0)) - error(L, "cannot run config. file: %s", lua_tostring(L, -1)); - //printf("cannot run config. file: %s", lua_tostring(L, -1)); + error_lua(L, "cannot run config. file: %s", lua_tostring(L, -1)); *w = getglobint(L, "width"); *h = getglobint(L, "height"); } 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 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 *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 rv = 0; opterr = 0; + //usb variables + USBtransfer *transfer = NULL; + + //lua variables + lua_State *L = NULL; + + //getopt returns args till done then returns -1 //string of possible args : denotes 1 required additional arg //:: 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", -// 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= 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("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 ); + 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= O:%s P:%s S:%s W:%s", O_value, P_value, S_value, W_value); for( index = optind; index < argc; 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"); 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"); } +*/ - //Determine overall operation being performed based on user args - //Also don't want to continue if conflicting args are being used + //Start up Lua + 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 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."); @@ -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."); 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 libusb_context *context = NULL; //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 - //libusb_device_handle *rprog_handle = NULL; transfer->handle = NULL; + //create file object/struct - rom_image *rom = malloc( sizeof(rom_image)); - - check_mem(transfer); - check_mem(rom); - init_rom_elements(rom); +// rom_image *rom = malloc( sizeof(rom_image)); +// +// check_mem(rom); +// init_rom_elements(rom); - //command line arg L_value to set different LIBUSB debugging options - //any value > 0 also prints debug statements in open_usb_device function + //lua script arg to set different LIBUSB debugging options + 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 - if (L_value != NULL) { - check( isdigit(L_value[0]), - "Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value); - 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)), - "Invalid LIBUSB_LOG_LEVEL: %d, must be from 0 to 4", libusb_log ); - } + libusb_log = getglobint(L, "libusb_log"); + + //any value > 0 also prints debug statements in open_usb_device function + 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 ); + + //TODO get usb device settings from usb_device.lua + //open INL retro prog with firmware version 2.0 or greater - if (K_value != NULL) { - //TODO take K_value option to connect to different version kazzo - } + //if (K_value != NULL) { + // //TODO take K_value option to connect to different version kazzo + //} transfer->handle = open_usb_device( context, libusb_log ); 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 cartridge *cart = malloc( sizeof(cartridge)); check_mem(cart); @@ -351,6 +363,7 @@ int main(int argc, char *argv[]) rom->fileptr = NULL; debug("closed"); } +*/ //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 //TODO cut this newbie code out of here +/* int xfr_cnt = 0; uint8_t rbuf[8]; @@ -390,20 +404,31 @@ int main(int argc, char *argv[]) } printf("\n"); } +*/ -close: +//close: + lua_close(L); + close_usb( context, transfer->handle); - if(rom->fileptr != NULL){ - //close file - fclose(rom->fileptr); - } + free(transfer); + +// if(rom->fileptr != NULL){ +// //close file +// fclose(rom->fileptr); +// } return 0; -error: -// printf("main program went to error\n"); +error: //checks goto error when failed + printf("main program went to error\n"); + + if ( transfer != NULL ) + free(transfer); + + if ( L != NULL ) + lua_close(L); // // close_usb( context, transfer->handle); // if(rom->fileptr != NULL){ @@ -412,6 +437,5 @@ error: return 1; - luacut */ } diff --git a/host/source/buffer.c b/host/source/old/buffer.c similarity index 100% rename from host/source/buffer.c rename to host/source/old/buffer.c diff --git a/host/source/buffer.h b/host/source/old/buffer.h similarity index 100% rename from host/source/buffer.h rename to host/source/old/buffer.h diff --git a/host/source/cartridge.c b/host/source/old/cartridge.c similarity index 100% rename from host/source/cartridge.c rename to host/source/old/cartridge.c diff --git a/host/source/cartridge.h b/host/source/old/cartridge.h similarity index 100% rename from host/source/cartridge.h rename to host/source/old/cartridge.h diff --git a/host/source/dump.c b/host/source/old/dump.c similarity index 100% rename from host/source/dump.c rename to host/source/old/dump.c diff --git a/host/source/dump.h b/host/source/old/dump.h similarity index 100% rename from host/source/dump.h rename to host/source/old/dump.h diff --git a/host/source/erase.c b/host/source/old/erase.c similarity index 100% rename from host/source/erase.c rename to host/source/old/erase.c diff --git a/host/source/erase.h b/host/source/old/erase.h similarity index 100% rename from host/source/erase.h rename to host/source/old/erase.h diff --git a/host/source/file.c b/host/source/old/file.c similarity index 100% rename from host/source/file.c rename to host/source/old/file.c diff --git a/host/source/file.h b/host/source/old/file.h similarity index 100% rename from host/source/file.h rename to host/source/old/file.h diff --git a/host/source/flash.c b/host/source/old/flash.c similarity index 100% rename from host/source/flash.c rename to host/source/old/flash.c diff --git a/host/source/flash.h b/host/source/old/flash.h similarity index 100% rename from host/source/flash.h rename to host/source/old/flash.h diff --git a/host/source/io.c b/host/source/old/io.c similarity index 100% rename from host/source/io.c rename to host/source/old/io.c diff --git a/host/source/io.h b/host/source/old/io.h similarity index 100% rename from host/source/io.h rename to host/source/old/io.h diff --git a/host/source/memory.c b/host/source/old/memory.c similarity index 100% rename from host/source/memory.c rename to host/source/old/memory.c diff --git a/host/source/memory.h b/host/source/old/memory.h similarity index 100% rename from host/source/memory.h rename to host/source/old/memory.h diff --git a/host/source/nes.c b/host/source/old/nes.c similarity index 100% rename from host/source/nes.c rename to host/source/old/nes.c diff --git a/host/source/nes.h b/host/source/old/nes.h similarity index 100% rename from host/source/nes.h rename to host/source/old/nes.h diff --git a/host/source/operation.c b/host/source/old/operation.c similarity index 100% rename from host/source/operation.c rename to host/source/old/operation.c diff --git a/host/source/operation.h b/host/source/old/operation.h similarity index 100% rename from host/source/operation.h rename to host/source/old/operation.h diff --git a/host/source/snes.c b/host/source/old/snes.c similarity index 100% rename from host/source/snes.c rename to host/source/old/snes.c diff --git a/host/source/snes.h b/host/source/old/snes.h similarity index 100% rename from host/source/snes.h rename to host/source/old/snes.h diff --git a/host/source/test.c b/host/source/old/test.c similarity index 100% rename from host/source/test.c rename to host/source/old/test.c diff --git a/host/source/test.h b/host/source/old/test.h similarity index 100% rename from host/source/test.h rename to host/source/old/test.h diff --git a/host/source/write_operations.c b/host/source/old/write_operations.c similarity index 100% rename from host/source/write_operations.c rename to host/source/old/write_operations.c diff --git a/host/source/write_operations.h b/host/source/old/write_operations.h similarity index 100% rename from host/source/write_operations.h rename to host/source/old/write_operations.h diff --git a/host/source/temp b/host/source/temp deleted file mode 100644 index 5cd31c1..0000000 --- a/host/source/temp +++ /dev/null @@ -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) - diff --git a/host/source/usb_operations.c b/host/source/usb_operations.c index 6ade27e..9bfa670 100644 --- a/host/source/usb_operations.c +++ b/host/source/usb_operations.c @@ -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"); break; case 4: + default: printf("\tDEBUG: debug, info, warning, & error messages are printed to stdout\n"); break; }