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:
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){