diff --git a/Makefile b/Makefile index 0554fefa..f7a90bda 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ endif ifdef NEED_ENCODED_DISKBOOT @echo dance \-\> DISKBOOT.BIN ver $(NEED_ENCODED_DISKBOOT) $(ENCODE_DISKBOOT) $(topdir)bin/main.bin $(topdir)bin/DISKBOOT.BIN $(NEED_ENCODED_DISKBOOT) -# rm $(topdir)bin/main.bin + rm $(topdir)bin/main.bin else mv $(topdir)bin/main.bin $(topdir)bin/DISKBOOT.BIN endif diff --git a/buildconf.inc b/buildconf.inc index da6e397c..88bba60e 100644 --- a/buildconf.inc +++ b/buildconf.inc @@ -17,7 +17,7 @@ OPT_LUA_STRLIB=1 #OPT_LUA_CALL_NATIVE=1 #OPT_MD_DEBUG=1 # needs proper fi2.inc in platform/ !!! see http://chdk.setepontos.com/index.php/topic,2995.0.html -OPT_FI2=1 +#OPT_FI2=1 # if enabled, compiler will produce a lot of warnings, maybe not always correct ones, see http://chdk.setepontos.com/index.php/topic,2509.msg32191.html#msg32191 #OPT_WARNINGS=1 # If enabled (and reference binaries are present in /tools), compiler will generate function signatures diff --git a/core/gui.c b/core/gui.c index 06cdae35..0af3b097 100644 --- a/core/gui.c +++ b/core/gui.c @@ -2589,69 +2589,32 @@ void gui_draw_debug_vals_osd() { // long v=get_file_counter(); // sprintf(osd_buf, "1:%03d-%04d ", (v>>18)&0x3FF, (v>>4)&0x3FFF); // sprintf(osd_buf, "1:%d, %08X ", xxxx, eeee); - -// extern long debug_long; -// sprintf(osd_buf, "8:%08x ", debug_long); -// draw_txt_string(28, 10, osd_buf, conf.osd_color); - -// sprintf(osd_buf, "8:%08x ", *((int *)0xC02200F8)); -// draw_txt_string(28, 10, osd_buf, conf.osd_color); -// -// sprintf(osd_buf, "C:%08x ", *((int *)0xC02200FC)); -// draw_txt_string(28, 11, osd_buf, conf.osd_color); - -// int zp=lens_get_zoom_point(), fl1=get_focal_length(zp); -// sprintf(osd_buf, "zp:%8i ", zp); -// draw_txt_string(28, 10, osd_buf, conf.osd_color); -// -// sprintf(osd_buf, "fl:%8i ", fl1); -// draw_txt_string(28, 11, osd_buf, conf.osd_color); - + /* extern long physw_status[3]; -// sprintf(osd_buf, "0:%8x ", physw_status[0]); -// draw_txt_string(28, 10, osd_buf, conf.osd_color); -// -// sprintf(osd_buf, "1:%8x ", physw_status[1]); -// draw_txt_string(28, 11, osd_buf, conf.osd_color); -// - sprintf(osd_buf, "2:%8x ", physw_status[2]); - draw_txt_string(28, 9, osd_buf, conf.osd_color); - short x; - sprintf(osd_buf, "zs:%8x ", zoom_status); + sprintf(osd_buf, "1:%8x ", physw_status[0]); draw_txt_string(28, 10, osd_buf, conf.osd_color); - get_property_case(PROPCASE_DIGITAL_ZOOM_STATE, &x, sizeof(x)); - sprintf(osd_buf, "dzs:%8x ", x); + + sprintf(osd_buf, "2:%8x ", physw_status[1]); draw_txt_string(28, 11, osd_buf, conf.osd_color); - get_property_case(PROPCASE_DIGITAL_ZOOM_POSITION, &x, sizeof(x)); - sprintf(osd_buf, "dzp:%8x ", x); + + sprintf(osd_buf, "3:%8x ", physw_status[2]); draw_txt_string(28, 12, osd_buf, conf.osd_color); // sprintf(osd_buf, "4:%8x ", vid_get_viewport_fb_d()); - -// sprintf(osd_buf, "j:%8x ", Get_JogDial()); -// draw_txt_string(28, 9, osd_buf, conf.osd_color); - -// extern long movie_status; -// sprintf(osd_buf, "m:%8x ", movie_status); -// draw_txt_string(28, 9, osd_buf, conf.osd_color); - -// extern long playrec_mode; -// sprintf(osd_buf, "m:%8x ", playrec_mode); -// draw_txt_string(28, 9, osd_buf, conf.osd_color); - - //sprintf(osd_buf, "u:%8x ", get_usb_power(1)); - //draw_txt_string(28, 9, osd_buf, conf.osd_color); + */ + sprintf(osd_buf, "u:%8x ", get_usb_power(1)); + draw_txt_string(28, 9, osd_buf, conf.osd_color); sprintf(osd_buf, "1:%8x ", (void*) (*(int*)conf.mem_view_addr_init)); - //draw_txt_string(28, 10, osd_buf, conf.osd_color); + draw_txt_string(28, 10, osd_buf, conf.osd_color); extern volatile long focus_busy; sprintf(osd_buf, "f:%8x ", focus_busy); - //draw_txt_string(28, 11, osd_buf, conf.osd_color); + draw_txt_string(28, 11, osd_buf, conf.osd_color); extern volatile long zoom_busy; sprintf(osd_buf, "z:%8x ", zoom_busy); - //draw_txt_string(28, 12, osd_buf, conf.osd_color); + draw_txt_string(28, 12, osd_buf, conf.osd_color); // some cameras missing zoom_status #if 0 diff --git a/core/gui_draw.c b/core/gui_draw.c index 2582dd6e..94047ba7 100644 --- a/core/gui_draw.c +++ b/core/gui_draw.c @@ -389,9 +389,7 @@ void draw_clear() { //------------------------------------------------------------------- void draw_restore() { -// if (gui_get_mode()!=GUI_MODE_NONE) vid_turn_on_updates(); vid_bitmap_refresh(); -// if (gui_get_mode()!=GUI_MODE_NONE) vid_turn_off_updates(); } //------------------------------------------------------------------- diff --git a/core/luascript.c b/core/luascript.c index a94f7208..cad7135d 100644 --- a/core/luascript.c +++ b/core/luascript.c @@ -536,9 +536,15 @@ static int luaCB_exit_alt( lua_State* L ) return 0; } +// optional parameter is 0 for soft shutdown (default) or 1 for hard/immediate static int luaCB_shut_down( lua_State* L ) { - camera_shutdown_in_a_second(); + if ( luaL_optnumber(L,1,0) == 1 ) + { + shutdown(); + } else { + camera_shutdown_in_a_second(); + } return 0; } @@ -1155,6 +1161,30 @@ static int luaCB_set_record( lua_State* L ) return 0; } +// reboot camera (with FI2 if supplied as arg) +static int luaCB_reboot( lua_State* L ) +{ + const char *fn = luaL_optstring(L,1,NULL); + + reboot(fn); + + return 0; +} + +// switch mode (0 = playback, 1 = record) +// XXX currently only for when USB is connected +static int luaCB_switch_mode( lua_State* L ) +{ + int mode = luaL_checknumber(L,1); + + if ( mode != 0 && mode != 1 ) + { + return 0; + } + + return switch_mode(mode); +} + /* pack the lua args into a buffer to pass to the native code calling functions currently only handles strings/numbers @@ -1434,6 +1464,9 @@ void register_lua_funcs( lua_State* L ) FUNC(set_record); + FUNC(reboot); + FUNC(switch_mode); + #ifdef OPT_LUA_CALL_NATIVE FUNC(call_event_proc); FUNC(call_func_ptr); diff --git a/core/ptp.c b/core/ptp.c index 2f5ea0ab..2d5d9ea3 100644 --- a/core/ptp.c +++ b/core/ptp.c @@ -1,10 +1,16 @@ +#include "camera.h" +#ifdef CAM_CHDK_PTP + #include "platform.h" #include "stdlib.h" #include "ptp.h" #include "script.h" -int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, - int param1, int param2, int param3, int param4, int param5); +#define BUF_SIZE 0x20000 // XXX what's a good camera-independent value? + +static int handle_ptp( + int h, ptp_data *data, int opcode, int sess_id, int trans_id, + int param1, int param2, int param3, int param4, int param5); void init_chdk_ptp() { @@ -21,7 +27,56 @@ void init_chdk_ptp() ExitTask(); } -int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, +static int recv_ptp_data(ptp_data *data, char *buf, int size) + // repeated calls per transaction are ok +{ + while ( size >= BUF_SIZE ) + { + data->recv_data(data->handle,buf,BUF_SIZE,0,0); + // XXX check for success?? + + size -= BUF_SIZE; + buf += BUF_SIZE; + } + if ( size != 0 ) + { + data->recv_data(data->handle,buf,size,0,0); + // XXX check for success?? + } + + return 1; +} + +static int send_ptp_data(ptp_data *data, char *buf, int size) + // repeated calls per transaction are *not* ok +{ + int tmpsize; + + tmpsize = size; + while ( size >= BUF_SIZE ) + { + if ( data->send_data(data->handle,buf,BUF_SIZE,tmpsize,0,0,0) ) + { + return 0; + } + + tmpsize = 0; + size -= BUF_SIZE; + buf += BUF_SIZE; + } + if ( size != 0 ) + { + if ( data->send_data(data->handle,buf,size,tmpsize,0,0,0) ) + { + return 0; + } + } + + return 1; +} + +static int handle_ptp( + int h, ptp_data *data, int opcode, int sess_id, int trans_id, int param1, int param2, int param3, int param4, int param5) { static char *temp_data = NULL; @@ -39,80 +94,36 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, switch ( param1 ) { - case PTP_CHDK_Shutdown: - ptp.code = PTP_RC_GeneralError; // default in case shutdown/reboot fails - switch ( param2 ) - { - case 0: // hard shutdown - shutdown(); - break; - case 1: // soft shutdown - shutdown_soft(); - ptp.code = PTP_RC_OK; // shutdown is not immediate - break; - case 2: // reboot - reboot(NULL); - break; - case 3: // reboot using firmware update - { - FILE *f; - int s = data->get_data_size(data->handle); - char *fn = (char *) malloc(s+1); - - sprintf(fn,"%i",s); - script_console_add_line(fn); - if ( fn == NULL ) - { - ptp.code = PTP_RC_GeneralError; - break; - } - fn[s] = '\0'; - - data->recv_data(data->handle,fn,s,0,0); - - if ( s == 0 ) - { - free(fn); - fn = "A/PS.FI2"; - } - - if ( (f = fopen(fn,"rb")) == NULL ) - { - ptp.code = PTP_RC_GeneralError; - } else { - fclose(f); - reboot(fn); - } - - if ( s != 0 ) - { - free(fn); - } - break; - } - default: - ptp.code = PTP_RC_ParameterNotSupported; - break; - } + case PTP_CHDK_Version: + ptp.num_param = 2; + ptp.param1 = PTP_CHDK_VERSION_MAJOR; + ptp.param2 = PTP_CHDK_VERSION_MINOR; break; case PTP_CHDK_GetMemory: + if ( param2 == 0 || param3 < 1 ) // null pointer or invalid size? { - if ( param2 == 0 || param3 < 1 ) // null pointer or invalid size? - { - ptp.code = PTP_RC_GeneralError; - break; - } - - if ( data->send_data(data->handle,(char *) param2,param3,param3,0,0,0) ) - { - ptp.code = PTP_RC_GeneralError; - } + ptp.code = PTP_RC_GeneralError; break; } + + if ( !send_ptp_data(data,(char *) param2,param3) ) + { + ptp.code = PTP_RC_GeneralError; + } + break; - case PTP_CHDK_SetMemoryLong: - *((volatile long *) param2) = param3; + case PTP_CHDK_SetMemory: + if ( param2 == 0 || param3 < 1 ) // null pointer or invalid size? + { + ptp.code = PTP_RC_GeneralError; + break; + } + + if ( !recv_ptp_data(data,(char *) param2,param3) ) + { + ptp.code = PTP_RC_GeneralError; + } break; case PTP_CHDK_CallFunction: @@ -127,92 +138,19 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, } s = data->get_data_size(data->handle); - data->recv_data(data->handle,(char *) buf,s,0,0); - - ptp.num_param = 1; - ptp.param1 = ((int (*)(int,int,int,int,int,int,int,int,int,int)) buf[0])(buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10]); - - free(buf); - break; - } - - case PTP_CHDK_GetPropCase: - { - int *buf, i; - - if ( param3 < 1 ) // invalid number of properties - { - ptp.code = PTP_RC_GeneralError; - break; - } - - buf = (int *) malloc(param3*sizeof(int)); - if ( buf == NULL ) + if ( !recv_ptp_data(data,(char *) buf,s) ) { ptp.code = PTP_RC_GeneralError; break; } - for (i=0; isend_data(data->handle,(char *) buf,param3*sizeof(int),param3*sizeof(int),0,0,0) ) - { - ptp.code = PTP_RC_GeneralError; - } free(buf); break; } - case PTP_CHDK_GetParamData: - { - extern long* FlashParamsTable[]; - char *buf, *p; - int i, s; - - if ( param3 < 1 ) // invalid number of parameters - { - ptp.code = PTP_RC_GeneralError; - break; - } - - // calculate required size for all properties (and lengths) - s = 0; - for (i=0; i>16); // room for size and actual data - } - - buf = (char *) malloc(s); - if ( buf == NULL ) - { - ptp.code = PTP_RC_GeneralError; - break; - } - - // construct result - p = buf; - for (i=0; i>16; - // write size - memcpy(p,&t,4); - p += 4; - // write value - get_parameter_data(param2+i,p,t); - p += t; - } - - if ( data->send_data(data->handle,buf,s,s,0,0,0) ) - { - ptp.code = PTP_RC_GeneralError; - } - free(buf); - break; - } - case PTP_CHDK_TempData: if ( temp_data != NULL ) { @@ -229,8 +167,10 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, break; } - data->recv_data(data->handle,temp_data,temp_data_size,0,0); - + if ( !recv_ptp_data(data,temp_data,temp_data_size) ) + { + ptp.code = PTP_RC_GeneralError; + } break; case PTP_CHDK_UploadFile: @@ -241,7 +181,7 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, s = data->get_data_size(data->handle); - data->recv_data(data->handle,(char *) &fn_len,4,0,0); + recv_ptp_data(data,(char *) &fn_len,4); s -= 4; fn = (char *) malloc(fn_len+1); @@ -252,7 +192,7 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, } fn[fn_len] = '\0'; - data->recv_data(data->handle,fn,fn_len,0,0); + recv_ptp_data(data,fn,fn_len); s -= fn_len; f = fopen(fn,"wb"); @@ -264,7 +204,6 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, } free(fn); -#define BUF_SIZE 4096 buf = (char *) malloc(BUF_SIZE); if ( buf == NULL ) { @@ -275,11 +214,11 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, { if ( s >= BUF_SIZE ) { - r = data->recv_data(data->handle,buf,BUF_SIZE,0,0); + recv_ptp_data(data,buf,BUF_SIZE); fwrite(buf,1,BUF_SIZE,f); s -= BUF_SIZE; } else { - data->recv_data(data->handle,buf,s,0,0); + recv_ptp_data(data,buf,s); fwrite(buf,1,s,f); s = 0; } @@ -294,7 +233,7 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, case PTP_CHDK_DownloadFile: { FILE *f; - int s,r,fn_len; + int tmp,t,s,r,fn_len; char *buf, *fn; if ( temp_data == NULL ) @@ -330,18 +269,25 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, s = ftell(f); fseek(f,0,SEEK_SET); - buf = (char *) malloc(s); + buf = (char *) malloc(BUF_SIZE); if ( buf == NULL ) { ptp.code = PTP_RC_GeneralError; - fclose(f); break; } - fread(buf,1,s,f); + tmp = s; + t = s; + while ( (r = fread(buf,1,(t 0 ) + { + t -= r; + // cannot use send_ptp_data here + data->send_data(data->handle,buf,r,tmp,0,0,0); + tmp = 0; + } fclose(f); + // XXX check that we actually read/send s bytes! (t == 0) - data->send_data(data->handle,buf,s,s,0,0,0); ptp.num_param = 1; ptp.param1 = s; @@ -351,20 +297,17 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, } break; - case PTP_CHDK_SwitchMode: - if ( param2 != 0 && param2 != 1 ) - { - ptp.code = PTP_RC_ParameterNotSupported; - } else { - switch_mode(param2); - } - break; - - case PTP_CHDK_ExecuteLUA: + case PTP_CHDK_ExecuteScript: { int s; char *buf; + if ( param2 != PTP_CHDK_SL_LUA ) + { + ptp.code = PTP_RC_ParameterNotSupported; + break; + } + s = data->get_data_size(data->handle); buf = (char *) malloc(s); @@ -374,7 +317,7 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, break; } - data->recv_data(data->handle,buf,s,0,0); + recv_ptp_data(data,buf,s); lua_script_exec(buf); @@ -393,3 +336,5 @@ int handle_ptp(int h, ptp_data *data, int opcode, int sess_id, int trans_id, return 1; } + +#endif // CAM_CHDK_PTP diff --git a/core/ptp.h b/core/ptp.h index e0c0779f..19e66fc7 100644 --- a/core/ptp.h +++ b/core/ptp.h @@ -1,6 +1,12 @@ #ifndef __PTP_H #define __PTP_H +// N.B.: not checking to see if CAM_CHDK_PTP is set as ptp.h is currently +// only included by ptp.c (which already checks this before including ptp.h) + +#define PTP_CHDK_VERSION_MAJOR 0 // increase only with backwards incompatible changes (and reset minor) +#define PTP_CHDK_VERSION_MINOR 0 // increase with extensions of functionality + #define PTP_OC_CHDK 0x9999 #define PTP_RC_OK 0x2001 @@ -8,27 +14,26 @@ #define PTP_RC_ParameterNotSupported 0x2006 enum { - PTP_CHDK_Shutdown = 0, // param2 is 0 (hard), 1 (soft), 2 (reboot) or 3 (reboot fw update) - // if param2 == 3, then filename of fw update is send as data (empty for default) + PTP_CHDK_Version = 0, // return param1 is major version number + // return param2 is minor version number PTP_CHDK_GetMemory, // param2 is base address (not NULL; circumvent by taking 0xFFFFFFFF and size+1) // param3 is size (in bytes) // return data is memory block - PTP_CHDK_SetMemoryLong, // param2 is address - // param3 is value + PTP_CHDK_SetMemory, // param2 is address + // param3 is size (in bytes) + // data is new memory block PTP_CHDK_CallFunction, // data is array of function pointer and (long) arguments (max: 10 args) // return param1 is return value - PTP_CHDK_GetPropCase, // param2 is base id - // param3 is number of properties - // return data is array of longs - PTP_CHDK_GetParamData, // param2 is base id - // param3 is number of parameters - // return data is sequence of strings prefixed by their length (as long) PTP_CHDK_TempData, // data is data to be stored for later PTP_CHDK_UploadFile, // data is 4-byte length of filename, followed by filename and contents PTP_CHDK_DownloadFile, // preceded by PTP_CHDK_TempData with filename // return data are file contents - PTP_CHDK_SwitchMode, // param2 is 0 (playback) or 1 (record) - PTP_CHDK_ExecuteLUA, // data is script to be executed + PTP_CHDK_ExecuteScript, // data is script to be executed + // param2 is language of script } ptp_chdk_command; +// Script Languages +#define PTP_CHDK_SL_LUA 0 +#define PTP_CHDK_SL_UBASIC 1 + #endif // __PTP_H diff --git a/include/camera.h b/include/camera.h index 89750a84..7d2bcba2 100644 --- a/include/camera.h +++ b/include/camera.h @@ -52,6 +52,7 @@ #undef CAM_REAR_CURTAIN // Camera do not have front/rear curtain flash sync in menu #undef CAM_BRACKETING // Cameras that have bracketing (focus & ev) in original firmware already, most likely s- & g-series (propcase for digic III not found yet!) #undef CAM_EXT_TV_RANGE // CHDK can make exposure time longer than 64s + #undef CAM_CHDK_PTP // include CHDK PTP support #define CAM_UNCACHED_BIT 0x10000000 // bit indicating the uncached memory @@ -1498,7 +1499,8 @@ #define CAM_HAS_ZOOM_LEVER 1 #define CAM_MULTIPART 1 #define CAM_REMOTE 1 - #define CAM_SYNCH 1 // XXX + #define CAM_SYNCH 1 + #define CAM_CHDK_PTP 1 #undef CAM_UNCACHED_BIT #define CAM_UNCACHED_BIT 0x40000000 // 0xFF874198 (via ExMem.FreeCacheable #define PARAM_CAMERA_NAME 4 // parameter number for GetParameterData diff --git a/include/core.h b/include/core.h index db9d2070..47283997 100644 --- a/include/core.h +++ b/include/core.h @@ -1,6 +1,8 @@ #ifndef CORE_H #define CORE_H +#include "camera.h" + void core_spytask(); void core_hook_task_create(void *tcb); @@ -19,7 +21,9 @@ void core_spytask_can_start(); long core_get_noise_reduction_value(); +#ifdef CAM_CHDK_PTP void init_chdk_ptp(); +#endif #endif diff --git a/include/lolevel.h b/include/lolevel.h index e94621a3..a3afa63c 100644 --- a/include/lolevel.h +++ b/include/lolevel.h @@ -280,10 +280,8 @@ extern unsigned _ExecuteEventProcedure(const char *name,...); // known in CHDK as _RefreshPhysicalScreen //extern void _ScreenUnLock(); +#ifdef CAM_CHDK_PTP extern int _add_ptp_handler(int, void*, int); -extern void _reboot_fw_update(char *); -extern void _set_control_event(int); -extern void _PB2Rec(); -extern void _Rec2PB(); +#endif #endif diff --git a/include/platform.h b/include/platform.h index 492cbf29..d6f25135 100644 --- a/include/platform.h +++ b/include/platform.h @@ -489,6 +489,7 @@ unsigned call_func_ptr(void *func, const unsigned *args, unsigned n_args); #define finished() debug_led(0) +#ifdef CAM_CHDK_PTP typedef struct { int code; @@ -504,7 +505,7 @@ typedef struct { typedef struct { int handle; - int (*send_data)(int handle, char *buf, int size, int size_again, int, int, int); // (0xFF9F525C) + int (*send_data)(int handle, char *buf, int part_size, int total_size, int, int, int); // (0xFF9F525C), total_size should be 0 except for the first call int (*recv_data)(int handle, char *buf, int size, int, int); // (0xFF9F5500) int (*send_resp)(int handle, PTPContainer *resp); // (0xFF9F5688) int (*get_data_size)(int handle); // (0xFF9F5830) @@ -519,9 +520,11 @@ typedef int (*ptp_handler)(int, ptp_data*, int, int, int, int, int, int, int, in int add_ptp_handler(int opcode, ptp_handler handler, int unknown); -void shutdown_soft(); -void reboot(char *fw_update); // fw_update == NULL implies normal reboot -void switch_mode(int mode); // 0 = playback, 1 = record; only call while USB connected +#endif // CAM_CHDK_PTP + +void reboot(const char *fw_update); // fw_update == NULL implies normal reboot +int switch_mode(int mode); // 0 = playback, 1 = record; return indicates success + // N.B.: switch_mode currently only supported when USB is connected void ExitTask(); diff --git a/makefile.inc b/makefile.inc index 0d6c9790..49607138 100644 --- a/makefile.inc +++ b/makefile.inc @@ -1,7 +1,7 @@ VER=CHDK -#PLATFORM=s3is -#PLATFORMSUB=100a +PLATFORM=s3is +PLATFORMSUB=100a #PLATFORM=a620 #PLATFORMSUB=100f @@ -124,8 +124,8 @@ VER=CHDK #PLATFORM=ixus870_sd880 #PLATFORMSUB=100e -PLATFORM=ixus870_sd880 -PLATFORMSUB=101a +#PLATFORM=ixus870_sd880 +#PLATFORMSUB=101a #PLATFORM=ixus870_sd880 #PLATFORMSUB=102b diff --git a/platform/generic/wrappers.c b/platform/generic/wrappers.c index cab7318e..ec18c742 100644 --- a/platform/generic/wrappers.c +++ b/platform/generic/wrappers.c @@ -948,12 +948,23 @@ long __attribute__((weak)) _GetCurrentTargetDistance() } #endif +#ifdef CAM_CHDK_PTP int add_ptp_handler(int opcode, ptp_handler handler, int unknown) { return _add_ptp_handler(opcode,handler,unknown); } +#endif void ExitTask() { _ExitTask(); } + +void __attribute__((weak)) reboot(const char *fw_update) +{ +} + +int __attribute__((weak)) switch_mode(int mode) +{ + return 0; +} diff --git a/platform/ixus870_sd880/lib.c b/platform/ixus870_sd880/lib.c index 3aab8fd1..2d624713 100644 --- a/platform/ixus870_sd880/lib.c +++ b/platform/ixus870_sd880/lib.c @@ -95,16 +95,13 @@ void vid_turn_on_updates() _RefreshPhysicalScreen(1); } -void shutdown_soft() -{ - _PostLogicalEventForNotPowerType(0x1005,0); -} - -void reboot(char *fw_update) +extern void _reboot_fw_update(const char *); +void reboot(const char *fw_update) { if ( fw_update == 0 ) { // sequence taken from reboot_fw_update + // XXX only for 1.01a!!! ((void (*)()) 0xFF94F7B8)(); ((void (*)()) 0xFF842480)(); ((void (*)()) 0xFF841594)(); @@ -115,7 +112,11 @@ void reboot(char *fw_update) } } -void switch_mode(int mode) +extern void _set_control_event(int); +extern void _PB2Rec(); +extern void _Rec2PB(); +int switch_mode(int mode) + // XXX make independent of USB { if ( mode == 0 ) { @@ -125,5 +126,9 @@ void switch_mode(int mode) { _set_control_event(0x902); // 0x10A6 DisconnectUSBCable _PB2Rec(); + } else { + return 0; } + + return 1; } diff --git a/tools/ptpcam/ptp.c b/tools/ptpcam/ptp.c index e3af82e8..4701f8bf 100644 --- a/tools/ptpcam/ptp.c +++ b/tools/ptpcam/ptp.c @@ -1700,78 +1700,37 @@ ptp_get_operation_name(PTPParams* params, uint16_t oc) int ptp_chdk_shutdown_hard(PTPParams* params, PTPDeviceInfo* deviceinfo) { - uint16_t ret; - PTPContainer ptp; - - PTP_CNT_INIT(ptp); - ptp.Code=PTP_OC_CHDK; - ptp.Nparam=2; - ptp.Param1=PTP_CHDK_Shutdown; - ptp.Param2=0; - ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL); - if ( ret != 0x2ff ) - { - ptp_error(params,"unexpected return code 0x%x",ret); - return 0; - } - return 1; + return ptp_chdk_exec_lua("shut_down(1);",params,deviceinfo); } int ptp_chdk_shutdown_soft(PTPParams* params, PTPDeviceInfo* deviceinfo) { - uint16_t ret; - PTPContainer ptp; - - PTP_CNT_INIT(ptp); - ptp.Code=PTP_OC_CHDK; - ptp.Nparam=2; - ptp.Param1=PTP_CHDK_Shutdown; - ptp.Param2=1; - ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL); - if ( ret != 0x2001 ) - { - ptp_error(params,"unexpected return code 0x%x",ret); - return 0; - } - return 1; + return ptp_chdk_exec_lua("shut_down(0);",params,deviceinfo); } int ptp_chdk_reboot(PTPParams* params, PTPDeviceInfo* deviceinfo) { - uint16_t ret; - PTPContainer ptp; - - PTP_CNT_INIT(ptp); - ptp.Code=PTP_OC_CHDK; - ptp.Nparam=2; - ptp.Param1=PTP_CHDK_Shutdown; - ptp.Param2=2; - ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL); - if ( ret != 0x2ff ) - { - ptp_error(params,"unexpected return code 0x%x",ret); - return 0; - } - return 1; + return ptp_chdk_exec_lua("reboot();",params,deviceinfo); } int ptp_chdk_reboot_fw_update(char *path, PTPParams* params, PTPDeviceInfo* deviceinfo) { - uint16_t ret; - PTPContainer ptp; + char *s; + int ret; - PTP_CNT_INIT(ptp); - ptp.Code=PTP_OC_CHDK; - ptp.Nparam=2; - ptp.Param1=PTP_CHDK_Shutdown; - ptp.Param2=3; - ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, strlen(path), &path); - if ( ret != 0x2ff ) + s = malloc(strlen(path)+12); + if ( s == NULL ) { - ptp_error(params,"unexpected return code 0x%x",ret); + ptp_error(params,"could not allocate memory for command",ret); return 0; } - return 1; + + sprintf(s,"reboot(\"%s\");",path); + ret = ptp_chdk_exec_lua(s,params,deviceinfo); + + free(s); + + return ret; } char* ptp_chdk_get_memory(int start, int num, PTPParams* params, PTPDeviceInfo* deviceinfo) @@ -1800,14 +1759,15 @@ int ptp_chdk_set_memory_long(int addr, int val, PTPParams* params, PTPDeviceInfo { uint16_t ret; PTPContainer ptp; + char *buf = (char *) &val; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_CHDK; ptp.Nparam=3; - ptp.Param1=PTP_CHDK_SetMemoryLong; + ptp.Param1=PTP_CHDK_SetMemory; ptp.Param2=addr; - ptp.Param3=val; - ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL); + ptp.Param3=4; + ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, 4, &buf); if ( ret != 0x2001 ) { ptp_error(params,"unexpected return code 0x%x",ret); @@ -1840,46 +1800,14 @@ int ptp_chdk_call(int *args, int size, int *ret, PTPParams* params, PTPDeviceInf int* ptp_chdk_get_propcase(int start, int num, PTPParams* params, PTPDeviceInfo* deviceinfo) { - uint16_t ret; - PTPContainer ptp; - char *buf = NULL; - - PTP_CNT_INIT(ptp); - ptp.Code=PTP_OC_CHDK; - ptp.Nparam=3; - ptp.Param1=PTP_CHDK_GetPropCase; - ptp.Param2=start; - ptp.Param3=num; - ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &buf); - if ( ret != 0x2001 ) - { - ptp_error(params,"unexpected return code 0x%x",ret); - free(buf); - return NULL; - } - return (int *) buf; + ptp_error(params,"not implemented! (use Lua)"); + return NULL; } char* ptp_chdk_get_paramdata(int start, int num, PTPParams* params, PTPDeviceInfo* deviceinfo) { - uint16_t ret; - PTPContainer ptp; - char *buf = NULL; - - PTP_CNT_INIT(ptp); - ptp.Code=PTP_OC_CHDK; - ptp.Nparam=3; - ptp.Param1=PTP_CHDK_GetParamData; - ptp.Param2=start; - ptp.Param3=num; - ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &buf); - if ( ret != 0x2001 ) - { - ptp_error(params,"unexpected return code 0x%x",ret); - free(buf); - return NULL; - } - return buf; + ptp_error(params,"not implemented! (use Lua)"); + return NULL; } int ptp_chdk_upload(char *local_fn, char *remote_fn, PTPParams* params, PTPDeviceInfo* deviceinfo) @@ -1974,24 +1902,39 @@ int ptp_chdk_download(char *remote_fn, char *local_fn, PTPParams* params, PTPDev int ptp_chdk_switch_mode(int mode, PTPParams* params, PTPDeviceInfo* deviceinfo) { - uint16_t ret; + char s[16]; + int ret; + + if ( mode/10 != 0 ) + { + ptp_error(params,"mode not supported by ptpcam"); + return 0; + } + + sprintf(s,"switch_mode(%i);",mode); + return ptp_chdk_exec_lua(s,params,deviceinfo); +} + +int ptp_chdk_exec_lua(char *script, PTPParams* params, PTPDeviceInfo* deviceinfo) +{ + uint16_t r; PTPContainer ptp; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_CHDK; ptp.Nparam=2; - ptp.Param1=PTP_CHDK_SwitchMode; - ptp.Param2=mode; - ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL); - if ( ret != 0x2001 ) + ptp.Param1=PTP_CHDK_ExecuteScript; + ptp.Param2=PTP_CHDK_SL_LUA; + r=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, strlen(script)+1, &script); + if ( r != 0x2001 ) { - ptp_error(params,"unexpected return code 0x%x",ret); + ptp_error(params,"unexpected return code 0x%x",r); return 0; } return 1; } -int ptp_chdk_exec_lua(char *script, PTPParams* params, PTPDeviceInfo* deviceinfo) +int ptp_chdk_get_version(PTPParams* params, PTPDeviceInfo* deviceinfo, int *major, int *minor) { uint16_t r; PTPContainer ptp; @@ -1999,13 +1942,14 @@ int ptp_chdk_exec_lua(char *script, PTPParams* params, PTPDeviceInfo* deviceinfo PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_CHDK; ptp.Nparam=1; - ptp.Param1=PTP_CHDK_ExecuteLUA; - r=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, strlen(script)+1, &script); + ptp.Param1=PTP_CHDK_Version; + r=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL); if ( r != 0x2001 ) { ptp_error(params,"unexpected return code 0x%x",r); return 0; } + *major = ptp.Param1; + *minor = ptp.Param2; return 1; } - diff --git a/tools/ptpcam/ptp.h b/tools/ptpcam/ptp.h index 3db3da7a..d78d0492 100644 --- a/tools/ptpcam/ptp.h +++ b/tools/ptpcam/ptp.h @@ -164,8 +164,6 @@ typedef struct _PTPUSBEventContainer PTPUSBEventContainer; #define PTP_OC_NIKON_SetControlMode 0x90C2 #define PTP_OC_NIKON_CheckEvent 0x90C7 #define PTP_OC_NIKON_KeepAlive 0x90C8 -/* CHDK extension */ -#define PTP_OC_CHDK 0x9999 /* Proprietary vendor extension operations mask */ @@ -876,30 +874,39 @@ uint16_t ptp_prop_getcodebyname (PTPParams* params, char* propname); const char* ptp_prop_getvalbyname (PTPParams* params, char* name, uint16_t dpc); + +/******************/ +/* CHDK extension */ +/******************/ + +#define PTP_CHDK_VERSION_MAJOR 0 // increases only with backwards incompatible changes +#define PTP_CHDK_VERSION_MINOR 0 // increases with extensions of functionality + +#define PTP_OC_CHDK 0x9999 + enum { - PTP_CHDK_Shutdown = 0, // param2 is 0 (hard), 1 (soft), 2 (reboot) or 3 (reboot fw update) - // if param2 == 3, then filename of fw update is send as data (empty for default) + PTP_CHDK_Version = 0, // return param1 is major version number + // return param2 is minor version number PTP_CHDK_GetMemory, // param2 is base address (not NULL; circumvent by taking 0xFFFFFFFF and size+1) // param3 is size (in bytes) // return data is memory block - PTP_CHDK_SetMemoryLong, // param2 is address - // param3 is value + PTP_CHDK_SetMemory, // param2 is address + // param3 is size (in bytes) + // data is new memory block PTP_CHDK_CallFunction, // data is array of function pointer and (long) arguments (max: 10 args) // return param1 is return value - PTP_CHDK_GetPropCase, // param2 is base id - // param3 is number of properties - // return data is array of longs - PTP_CHDK_GetParamData, // param2 is base id - // param3 is number of parameters - // return data is sequence of strings prefixed by their length (as long) PTP_CHDK_TempData, // data is data to be stored for later PTP_CHDK_UploadFile, // data is 4-byte length of filename, followed by filename and contents PTP_CHDK_DownloadFile, // preceded by PTP_CHDK_TempData with filename // return data are file contents - PTP_CHDK_SwitchMode, // param2 is 0 (playback) or 1 (record) - PTP_CHDK_ExecuteLUA, // data is script to be executed + PTP_CHDK_ExecuteScript, // data is script to be executed + // param2 is language of script } ptp_chdk_command; +// Script Languages +#define PTP_CHDK_SL_LUA 0 +#define PTP_CHDK_SL_UBASIC 1 + int ptp_chdk_shutdown_hard(PTPParams* params, PTPDeviceInfo* deviceinfo); int ptp_chdk_shutdown_soft(PTPParams* params, PTPDeviceInfo* deviceinfo); int ptp_chdk_reboot(PTPParams* params, PTPDeviceInfo* deviceinfo); @@ -913,6 +920,7 @@ int ptp_chdk_upload(char *local_fn, char *remote_fn, PTPParams* params, PTPDevic int ptp_chdk_download(char *remote_fn, char *local_fn, PTPParams* params, PTPDeviceInfo* deviceinfo); int ptp_chdk_switch_mode(int mode, PTPParams* params, PTPDeviceInfo* deviceinfo); int ptp_chdk_exec_lua(char *script, PTPParams* params, PTPDeviceInfo* deviceinfo); +int ptp_chdk_get_version(PTPParams* params, PTPDeviceInfo* deviceinfo, int *major, int *minor); #endif /* __PTP_H__ */ diff --git a/tools/ptpcam/ptpcam.c b/tools/ptpcam/ptpcam.c index b529d0cb..9b25d274 100644 --- a/tools/ptpcam/ptpcam.c +++ b/tools/ptpcam/ptpcam.c @@ -2165,6 +2165,17 @@ static int connected = 0; static void open_connection() { connected = (0 == open_camera(camera_bus,camera_dev,camera_force,&ptp_usb,¶ms,&dev)); + if ( connected ) + { + int major,minor; + if ( !ptp_chdk_get_version(¶ms,¶ms.deviceinfo,&major,&minor) ) + { + printf("error: cannot get camera CHDK PTP version; either it has an unsupported version or no CHDK PTP support at all\n"); + } else if ( major != PTP_CHDK_VERSION_MAJOR || minor < PTP_CHDK_VERSION_MINOR ) + { + printf("error: camera has unsupported camera version %i.%i; some functionality may be missing or cause unintented consequences\n",major,minor); + } + } } static void close_connection() @@ -2295,6 +2306,7 @@ int chdk(int busn, int devn, short force) "q quit quit program\n" "h help list commands\n" "r reset reconnect to camera\n" + " version get CHDK PTP version (ptpcam and camera)\n" " shutdown-hard shutdown camera (hard)\n" " shutdown-soft shutdown camera (soft)\n" " reboot reboot camera\n" @@ -2305,12 +2317,12 @@ int chdk(int busn, int devn, short force) "m memory
get num bytes at given address\n" " set
set long value at address\n" "c call
... call function at address with given arguments\n" - " prop get value of property\n" - " prop - get values in property range\n" - " prop get num values of properties starting at id\n" - " param get value of parameter\n" - " param - get values in parameter range\n" - " param get num values of parameters starting at id\n" +// " prop get value of property\n" +// " prop - get values in property range\n" +// " prop get num values of properties starting at id\n" +// " param get value of parameter\n" +// " param - get values in parameter range\n" +// " param get num values of parameters starting at id\n" "u upload upload local file to camera\n" "d download download file from camera\n" " mode set mode (0=playback,1=record)\n" @@ -2321,6 +2333,15 @@ int chdk(int busn, int devn, short force) { reset_connection(); + } else if ( !strcmp("version",buf) ) + { + int major, minor; + printf("ptpcam: %i.%i\n",PTP_CHDK_VERSION_MAJOR,PTP_CHDK_VERSION_MINOR); + if ( ptp_chdk_get_version(¶ms,¶ms.deviceinfo,&major,&minor) ) + { + printf("camera: %i.%i\n",major,minor); + } + } else if ( !strcmp("shutdown-hard",buf) ) { if ( ptp_chdk_shutdown_hard(¶ms,¶ms.deviceinfo) )