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:
parent
f4fe81da96
commit
2fdefde840
|
|
@ -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 ()
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
check( ((libusb_log >= LIBUSB_LOG_LEVEL_NONE) && (libusb_log <=LIBUSB_LOG_LEVEL_DEBUG)),
|
||||||
"Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value);
|
"Invalid LIBUSB_LOG_LEVEL: %d, must be from 0 to 4", libusb_log );
|
||||||
libusb_log = atoi(L_value);
|
|
||||||
check( ((libusb_log >= LIBUSB_LOG_LEVEL_NONE) && (libusb_log <=LIBUSB_LOG_LEVEL_DEBUG)),
|
//TODO get usb device settings from usb_device.lua
|
||||||
"Invalid LIBUSB_LOG_LEVEL: %d, must be from 0 to 4", libusb_log );
|
|
||||||
}
|
|
||||||
//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 */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue