MySmartUSB-MK3-Interface

MySmartUSB MK3 Interface
git clone git://xatko.vsos.ethz.ch/MySmartUSB-MK3-Interface.git
Log | Files | Refs

commit 3aafce4657fa6e39b07dd5b6ddebb33cef8888a1
parent 26c7152364122f0fce09897a4cdf0f630506e155
Author: Dominik Schmidt <das1993@hotmail.com>
Date:   Sat, 15 Dec 2012 16:00:57 +0100

ISP and Parallel speed autodetection added

Diffstat:
ctrl.c | 3+++
include/cmd.h | 17++++++++++++++++-
include/common.h | 8+++++---
include/log.h | 4++--
src/cmd.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
src/cmd_dispatch.c | 3++-
src/com.c | 10++--------
src/common.c | 35+++++++++++++++++++++++++++++++----
src/log.c | 21++++++++++++---------
src/option.c | 2+-
10 files changed, 176 insertions(+), 37 deletions(-)

diff --git a/ctrl.c b/ctrl.c @@ -11,6 +11,9 @@ #include <dev.h> #include <com.h> #include <unistd.h> +#include <common.h> +#include <stdio.h> int main(int argc, char **argv){ return engine_autorun(argc,argv); + return 0; } diff --git a/include/cmd.h b/include/cmd.h @@ -9,12 +9,26 @@ */ #pragma once #define GENERATE_CALLBACK(name) int name(struct command_exec *cmd,int fd) - +#include <common.h> struct command_exec{ struct command_def *cmd_def; char **data; }; +struct parseSpeedValues{ + struct { + struct array arr; + unsigned int *values; + } ok; + struct { + struct array arr; + unsigned int *values; + } error; +}; +extern int parseSpeedResponse(const char *response); +extern int scan_speed(struct command_exec *cmd,int fd, char *location, char *prefix, struct parseSpeedValues *resp); +extern int auto_set_speed(struct command_exec *cmd,int fd, char *location, char *prefix); +extern int set_speed(struct command_exec *cmd,int fd, char *location, char *prefix); extern GENERATE_CALLBACK(cmd_board_reset); extern GENERATE_CALLBACK(cmd_reset); @@ -25,3 +39,4 @@ extern GENERATE_CALLBACK(cmd_set_emul_mode); extern GENERATE_CALLBACK(cmd_set_prog_mode); extern GENERATE_CALLBACK(cmd_set_rescue_clock); extern GENERATE_CALLBACK(cmd_set_isp_speed); +extern GENERATE_CALLBACK(cmd_set_par_speed); diff --git a/include/common.h b/include/common.h @@ -15,6 +15,8 @@ struct array{ }; -int array_initiate(void *data, struct array *arr, unsigned short int size); -int array_grow(void **data, struct array *arr, unsigned short int by); -int array_destroy(void *data, struct array *arr); +extern int array_initiate(void **data, struct array *arr, unsigned short int size); +extern int array_grow(void **data, struct array *arr, unsigned short int by); +extern int array_destroy(void **data, struct array *arr); +extern int itoa(char *a, int i, int base); +extern void strrevert(char *str); diff --git a/include/log.h b/include/log.h @@ -10,20 +10,20 @@ #pragma once enum LOG_TYPE{ LOG_TYPE_RESULT, + LOG_TYPE_SUCCESS, LOG_TYPE_NORMAL, LOG_TYPE_SIGNAL }; enum LOG_LEVEL{ LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, - LOG_LEVEL_SUCCESS, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_COUNT }; -extern void log_string(char *str, unsigned short int level); +extern void log_string(char *str, unsigned short int level, char *force_color); extern void do_log(char *src, char *msg, unsigned short int level, unsigned short int type); #define LOG_LEVEL_names_length 8 extern char LOG_LEVEL_names[LOG_LEVEL_COUNT][LOG_LEVEL_names_length]; diff --git a/src/cmd.c b/src/cmd.c @@ -216,33 +216,127 @@ GENERATE_CALLBACK(cmd_set_rescue_clock){ } return 0; } -GENERATE_CALLBACK(cmd_set_isp_speed){ +int parseSpeedResponse(const char *response){ + int speed=0; + while(1){ + if(*response>='0'&&*response<='9'){ + speed=10*speed; + speed+=*response-'0'; + } + else if(strcmp(response," ok")==0){ + return speed; + } + else if(strcmp(response," error")==0){ + return -speed; + } + else{ + return 0; + } + response++; + } + return 0; +} +int scan_speed(struct command_exec *cmd,int fd, char *location, char *prefix, struct parseSpeedValues *resp){ + char str[50]; + sprintf(str, "@prog %sSpeed scan", prefix); + array_initiate((void **) &resp->ok.values, &resp->ok.arr, sizeof(int)); + array_initiate((void **) &resp->error.values, &resp->error.arr, sizeof(int)); + if(sendString(fd,str)<0){ + do_log(location, "Couldn't send String",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL); + return -1; + } + short int okcnt=0; + short int failcnt=0; + char *recv; + int speed; + do_log(location, "Querying Speeds, might take a while", LOG_LEVEL_INFO, LOG_TYPE_NORMAL); + while(1){ + recv=readString(fd,0); + speed=parseSpeedResponse(recv+1); + free(recv); + if(speed>0){ + array_grow((void **)&resp->ok.values, &resp->ok.arr, sizeof(unsigned int)); + resp->ok.values[okcnt++]=speed; + } + else if(speed<0){ + array_grow((void **)&resp->error.values, &resp->error.arr, sizeof(unsigned int)); + resp->error.values[failcnt++]=-speed; + } + if(speed==0){ + break; + } + } + return 0; +} +int auto_set_speed(struct command_exec *cmd,int fd, char *location, char *prefix){ + struct parseSpeedValues resp; + if(scan_speed(cmd,fd,location,prefix,&resp)<0){ + do_log(location, "Error while querying speeds!", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL); + return -1; + } + if(resp.ok.values[0]==0){ + do_log(location, "No matching speed found!", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL); + return -2; + } + char str[50]; + itoa(str,resp.ok.values[0],10); + cmd->data[0]=str; + array_destroy((void *)&resp.ok.values, &resp.ok.arr); + array_destroy((void *)&resp.error.values, &resp.error.arr); + + if(set_speed(cmd, fd, location, prefix)<0){ + do_log(location, "Couldn't set Speed", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL); + return -3; + } + return 0; +} +int set_speed(struct command_exec *cmd,int fd, char *location, char *prefix){ int speed=atoi(cmd->data[0]); if(speed<=0){ - do_log("cmd_set_isp_speed","Invalid speed", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL); + do_log(location,"Invalid speed", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL); return -1; } char str[50]; - sprintf(str,"@prog ispSpeed %u",speed); + sprintf(str,"@prog %sSpeed %u",prefix, speed); if(sendString(fd,str)<0){ - do_log("cmd_set_ispeed", "Couldn't send String",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL); + do_log(location, "Couldn't send String",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL); return -2; } char *recv=readString(fd,0); if(recv==NULL){ - do_log("cmd_set_ispeed", "Couldn't receive Answer",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL); + do_log(location, "Couldn't receive Answer",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL); return -3; } if(checkIfOk(recv)){ char *newIsp=&recv[4]; - sprintf(str,"New ISPSpeed: %s",newIsp); - do_log("cmd_set_ispeed", str, LOG_LEVEL_SUCCESS,LOG_TYPE_NORMAL); + sprintf(str,"New %sSpeed: %s",prefix, newIsp); + do_log(location, str, LOG_LEVEL_INFO,LOG_TYPE_SUCCESS); } else{ - do_log("cmd_set_ispeed", "Couldn't set ISPSpeed",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL); + do_log(location, "Couldn't set ISPSpeed",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL); return -4; } free(recv); return 0; } +GENERATE_CALLBACK(cmd_set_isp_speed){ + int(*func)(struct command_exec *,int, char *, char *); + if(*cmd->data[0]=='A'||strcmp(cmd->data[0], "Auto")==0){ + func=&auto_set_speed; + } + else{ + func=&set_speed; + } + return func(cmd, fd, "cmd_set_isp_speed", "isp"); +} +GENERATE_CALLBACK(cmd_set_par_speed){ + int(*func)(struct command_exec *,int, char *, char *); + if(*cmd->data[0]=='A'||strcmp(cmd->data[0], "Auto")==0){ + func=&auto_set_speed; + } + else{ + func=&set_speed; + } + return func(cmd, fd, "cmd_set_par_speed", "par"); +} diff --git a/src/cmd_dispatch.c b/src/cmd_dispatch.c @@ -27,7 +27,8 @@ struct command_def commands[]={ {.name="Emulation Mode", .opt={.usage="[d/UART,s/STK500,a/AVR910,q/Quiet,m/MyMode,p/ProgMode]", .arg_length=1, .short_option="-eM", .long_option="--emulation-mode"}, .request_mymode=0, .callback=&cmd_set_emul_mode}, {.name="Rescue Clock", .opt={.usage="[1,0]", .arg_length=1, .short_option="-rC", .long_option="--rescue-clock"}, .request_mymode=0, .callback=&cmd_set_rescue_clock}, {.name="Programming Mode", .opt={.usage="[i/ISP, p/HVP, s/HVS, t/TPI, T/TPIHV]", .arg_length=1, .short_option="-pM", .long_option="--programming-mode"}, .request_mymode=1, .callback=&cmd_set_prog_mode}, - {.name="ISP Speed", .opt={.usage="<UINT>", .arg_length=1, .short_option="-iS", .long_option="--isp-speed"}, .request_mymode=1, .callback=&cmd_set_isp_speed}, + {.name="ISP Speed", .opt={.usage="[<UINT>, A/Auto]", .arg_length=1, .short_option="-iS", .long_option="--isp-speed"}, .request_mymode=1, .callback=&cmd_set_isp_speed}, + {.name="Par Speed", .opt={.usage="[<UINT>, A/Auto]", .arg_length=1, .short_option="-pS", .long_option="--par-speed"}, .request_mymode=1, .callback=&cmd_set_par_speed}, {.name=NULL} }; int executeCommand(struct command_exec *cmd, int fd){ diff --git a/src/com.c b/src/com.c @@ -39,14 +39,8 @@ char *readString(int fd, unsigned int length){ break; } if(c==*tp){ - if(*(tp+1)=='\0'){ - str[i]='\0'; - break; - } - else{ - tp++; - continue; - } + str[i]='\0'; + break; } else if(c==0){ continue; diff --git a/src/common.c b/src/common.c @@ -9,10 +9,11 @@ */ #include <common.h> #include <stdlib.h> +#include <string.h> -int array_initiate(void *data, struct array *arr, unsigned short int size){ +int array_initiate(void **data, struct array *arr, unsigned short int size){ arr->alloc=10; - data=malloc(size); + *data=malloc(size); return 0; } int array_grow(void **data, struct array *arr, unsigned short int by){ @@ -23,9 +24,35 @@ int array_grow(void **data, struct array *arr, unsigned short int by){ *data=realloc(*data, arr->alloc); return 0; } -int array_destroy(void *data, struct array *arr){ - free(data); +int array_destroy(void **data, struct array *arr){ + free(*data); arr->count=0; arr->alloc=0; return 0; } +void strrevert(char *str){ + char a; + unsigned int i; + unsigned int length=strlen(str); + for(i=0;i<length/2; i++){ + a=str[i]; + str[i]=str[length-i-1]; + str[length-i-1]=a; + } +} +int itoa(char *a, int i, int base){ + char *aptr=a; + int val=(i<0) ? -i : i; + while(val>0){ + *aptr='0'+val%base; + val=val/base; + aptr++; + } + if(i<0){ + *aptr='-'; + aptr++; + } + *aptr='\0'; + strrevert(a); + return 0; +} diff --git a/src/log.c b/src/log.c @@ -13,18 +13,18 @@ #include <stdlib.h> #include <string.h> #include <option.h> -char LOG_LEVEL_names[LOG_LEVEL_COUNT][8]={"DEBUG","INFO", "SUCCESS","WARNING","ERROR","FATAL"}; -void log_string(char *str, unsigned short int level){ +char LOG_LEVEL_names[LOG_LEVEL_COUNT][8]={"DEBUG","INFO","WARNING","ERROR","FATAL"}; +void log_string(char *str, unsigned short int level, char *force_color){ FILE *stream; - if(level>=LOG_LEVEL_WARNING&&level!=LOG_LEVEL_COUNT&&level!=LOG_LEVEL_SUCCESS){ + if(level>=LOG_LEVEL_WARNING&&level!=LOG_LEVEL_COUNT){ stream=stderr; } else{ stream=stdout; } - char *color=""; + char *color=(force_color==NULL) ? "" : force_color; char *reset_color="\e[0m"; - if(configuration.color){ + if(configuration.color&&force_color==NULL){ switch(level){ case LOG_LEVEL_DEBUG: color="\e[2;37;40m"; @@ -41,9 +41,6 @@ void log_string(char *str, unsigned short int level){ case LOG_LEVEL_FATAL: color="\e[1;33;41m"; break; - case LOG_LEVEL_SUCCESS: - color="\e[1;32m"; - break; } } if(configuration.log_level<=level){ @@ -52,6 +49,12 @@ void log_string(char *str, unsigned short int level){ } void do_log(char *src, char *msg, unsigned short int level, unsigned short int type){ int error=errno; + char success_color[]="\e[1;32m"; + char *force_color=NULL; + if(type==LOG_TYPE_SUCCESS){ + level=LOG_LEVEL_COUNT; + force_color=success_color; + } char *str=malloc(strlen("%s[%s]: %s (%s)")+strlen(src)+strlen(msg)+strlen(LOG_LEVEL_names[level])+strlen(strerror(error))); if(type==LOG_TYPE_SIGNAL){ sprintf(str,"%s[%s]: %s (%s)",LOG_LEVEL_names[level],src,msg,strerror(error)); @@ -63,6 +66,6 @@ void do_log(char *src, char *msg, unsigned short int level, unsigned short int t else{ sprintf(str,"%s[%s]: %s",LOG_LEVEL_names[level],src,msg); } - log_string(str,level); + log_string(str,level, force_color); free(str); } diff --git a/src/option.c b/src/option.c @@ -33,7 +33,7 @@ struct command_exec *optionAddCommand(struct conf *config, struct command_def *c int parseArguments(int argc, char **argv, struct conf *config){ unsigned int i=0; struct command_def *cmd_def; - array_initiate(&config->cmdlist.data,&config->cmdlist.arr, sizeof(struct command_exec)); + array_initiate((void **)&config->cmdlist.data,&config->cmdlist.arr, sizeof(struct command_exec)); for(i=0;i<argc;i++){ cmd_def=getCmdDefByOpt(argv[i]); if(cmd_def!=NULL){