MySmartUSB-MK3-Interface

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

cmd.c (9009B)


      1 /*
      2  * MySmartUSB MK3 Interface
      3  * 
      4  * @copyright: 	Copyright (c) 2012, Dominik Schmidt
      5  * @author:		Dominik Schmidt <das1993@hotmail.com>
      6  * @version:	0.0.0 
      7  * @license: 	CC-BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/)
      8  * 
      9 */
     10 #include <cmd.h>
     11 #include <log.h>
     12 #include <com.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 #include <stdio.h>
     16 #include <unistd.h>
     17 #include <option.h>
     18 #include <termios.h>
     19 #include <dev.h>
     20 GENERATE_CALLBACK(cmd_board_reset){
     21 	if(sendMagicPacket(fd,'r')<0){
     22 		do_log("cmd_board_reset","Couldn't send reset packet", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
     23 		return -1;
     24 	}
     25 	if(readMagicPacket(fd)!='r'){
     26 		return -2;
     27 	}
     28 	return 0;
     29 }
     30 GENERATE_CALLBACK(cmd_reset){
     31 	if(sendString(fd,"@main reset")<0){
     32 		do_log("cmd_reset","Couldn't send reset string", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
     33 		return -1;
     34 	}
     35 	do_log("cmd_reset","Starting 3 Second Timeout", LOG_LEVEL_INFO, LOG_TYPE_NORMAL);
     36 	usleep(3000000);
     37 	char *ret=readString(fd, 0);
     38 	if(!checkIfOk(ret)){
     39 		do_log("cmd_reset","Couldn't reset device", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
     40 		free(ret);
     41 		return -2;
     42 	}
     43 	free(ret);
     44 	return 0;
     45 }
     46 GENERATE_CALLBACK(cmd_status){
     47 	if(sendMagicPacket(fd,'i')<0){
     48 		do_log("cmd_board_reset","Couldn't send status request packet", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
     49 		return -1;
     50 	}
     51 	char c=readMagicPacket(fd);
     52 	char str[]={c,'\0'};
     53 	do_log("cmd_status", str, LOG_LEVEL_INFO, LOG_TYPE_RESULT);
     54 	return 0;
     55 }
     56 GENERATE_CALLBACK(cmd_reset_line){
     57 	//do_log("cmd_reset_line","Due to segfault, command not implemented yet", LOG_LEVEL_WARNING, LOG_TYPE_NORMAL);
     58 	if(*cmd->data[0]!='1'&&*cmd->data[0]!='0'){
     59 		do_log("cmd_reset_line","Value must be either 1 or 0",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
     60 		return -1;
     61 	}
     62 	char str[]="@lines rst  ";
     63 	str[strlen(str)]=*cmd->data[0]-'0';
     64 	
     65 	if(sendString(fd,str)<0){
     66 		do_log("cmd_reset_line","Couldn't send power string", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
     67 		return -2;
     68 	}
     69 	
     70 	char *r=readString(fd,0);
     71 	if(!checkIfOk(r)){
     72 		do_log("cmd_reset_line","Couldn't set reset line", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
     73 		free(r);
     74 		return -3;
     75 	}
     76 	free(r);
     77 	return 0;
     78 }
     79 GENERATE_CALLBACK(cmd_board_power){
     80 	char c;
     81 	if(*cmd->data[0]=='1'){
     82 		c='+';
     83 	}
     84 	else if(*cmd->data[0]=='0'){
     85 		c='-';
     86 	}
     87 	else{
     88 		do_log("cmd_board_power","Value must be either 1 or 0",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
     89 		return -1;
     90 	}
     91 	if(sendMagicPacket(fd,c)<0){
     92 		do_log("cmd_board_reset","Couldn't send power string", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
     93 		return -2;
     94 	}
     95 	char r=readMagicPacket(fd);
     96 	if(r!=c){
     97 		return -3;
     98 	}
     99 	return 0;
    100 }
    101 
    102 GENERATE_CALLBACK(cmd_set_emul_mode){
    103 	char mode;
    104 	speed_t newBaud=0;
    105 	if(strcmp(cmd->data[0],"STK500")==0||*cmd->data[0]=='s'){
    106 		mode='s';
    107 		newBaud=B115200;
    108 	}
    109 	else if(strcmp(cmd->data[0],"AVR910")==0||*cmd->data[0]=='a'){
    110 		mode='a';
    111 		newBaud=B19200;
    112 	}
    113 	else if(strcmp(cmd->data[0],"Quiet")==0||*cmd->data[0]=='q'){
    114 		mode='q';
    115 		newBaud=B500000;
    116 	}
    117 	else if(strcmp(cmd->data[0],"UART")==0||*cmd->data[0]=='d'){
    118 		mode='d';
    119 		newBaud=B500000;
    120 	}
    121 	else if(strcmp(cmd->data[0],"MyMode")==0||*cmd->data[0]=='m'){
    122 		mode='m';
    123 		newBaud=B500000;
    124 	}
    125 	else if(strcmp(cmd->data[0],"ProgMode")==0||*cmd->data[0]=='p'){
    126 		mode='p';
    127 	}
    128 	else{
    129 		configuration.print_usage=1;
    130 		char str[50];
    131 		sprintf(str,"Mode %s unknown",cmd->data[0]);
    132 		do_log("cmd_set_emul_mode",str,LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    133 		return -1;
    134 	}
    135 	char str[50];
    136 	sprintf(str,"Setting mode to %c",mode);
    137 	do_log("cmd_set_emul_mode",str,LOG_LEVEL_DEBUG,LOG_TYPE_NORMAL);
    138 	if(sendMagicPacket(fd,mode)<0){
    139 		do_log("cmd_set_emul_mode","Couldn't send magic packet",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    140 		return -2;
    141 	}
    142 	if(newBaud!=0){
    143 		usleep(BAUD_RATE_SWITCH_WAIT);
    144 		setBaudRateExt(fd,newBaud,BAUD_INPUT|BAUD_OUTPUT, TCSADRAIN);
    145 	}
    146 	if(readMagicPacket(fd)!=mode){
    147 		do_log("cmd_set_emul_mode","Couldn't set Mode",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    148 		return -4;
    149 	}
    150 	return 0;
    151 }
    152 
    153 GENERATE_CALLBACK(cmd_set_prog_mode){
    154 	char mode;
    155 	if(strcmp(cmd->data[0],"ISP")==0||*cmd->data[0]=='i'){
    156 		mode='i';
    157 	}
    158 	else if(strcmp(cmd->data[0],"HVP")==0||*cmd->data[0]=='p'){
    159 		mode='p';
    160 	}
    161 	else if(strcmp(cmd->data[0],"HVS")==0||*cmd->data[0]=='s'){
    162 		mode='s';
    163 	}
    164 	else if(strcmp(cmd->data[0],"TPI")==0||*cmd->data[0]=='t'){
    165 		mode='t';
    166 	}
    167 	else if(strcmp(cmd->data[0],"TPIHV")==0||*cmd->data[0]=='T'){
    168 		mode='T';
    169 	}
    170 	else{
    171 		configuration.print_usage=1;
    172 		char str[50];
    173 		sprintf(str,"Mode %s unknown",cmd->data[0]);
    174 		do_log("cmd_set_prog_mode",str,LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    175 		return -1;
    176 	}
    177 	char str[50];
    178 	sprintf(str,"Setting mode to %c",mode);
    179 	do_log("cmd_set_prog_mode",str,LOG_LEVEL_DEBUG,LOG_TYPE_NORMAL);
    180 	char send[]="@prog progMode  ";
    181 	send[strlen(send)]=mode;
    182 	if(sendString(fd,send)<0){
    183 		do_log("cmd_set_prog_mode","Couldn't send magic packet",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    184 		return -2;
    185 	}
    186 	char *res=readString(fd,0);
    187 	if(!checkIfOk(res)){
    188 		do_log("cmd_set_prog_mode","Setting Programming mode failed",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    189 		free(res);
    190 		return -3;
    191 	}
    192 	free(res);
    193 	return 0;
    194 }
    195 
    196 GENERATE_CALLBACK(cmd_set_rescue_clock){
    197 	char c;
    198 	if(*cmd->data[0]=='1'){
    199 		c='C';
    200 	}
    201 	else if(*cmd->data[0]=='0'){
    202 		c='c';
    203 	}
    204 	else{
    205 		do_log("cmd_set_rescue_clock","Value must be either 1 or 0",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    206 		return -1;
    207 	}
    208 	if(sendMagicPacket(fd,c)<0){
    209 		do_log("cmd_set_rescue_clock","Couldn't send rescue Clock", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
    210 		return -2;
    211 	}
    212 	char r=readMagicPacket(fd);
    213 	if(r!=c){
    214 		do_log("cmd_set_rescue_clock","Couldn't change rescue clock mode", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
    215 		return -3;
    216 	}
    217 	return 0;
    218 }
    219 int parseSpeedResponse(const char *response){
    220 	int speed=0;
    221 	while(1){
    222 		if(*response>='0'&&*response<='9'){
    223 			speed=10*speed;
    224 			speed+=*response-'0';
    225 		}
    226 		else if(strcmp(response," ok")==0){
    227 			return speed;
    228 		}
    229 		else if(strcmp(response," error")==0){
    230 			return -speed;
    231 		}
    232 		else{
    233 			return 0;
    234 		}
    235 		response++;
    236 	}
    237 	return 0;
    238 }
    239 int scan_speed(struct command_exec *cmd,int fd, char *location, char *prefix, struct parseSpeedValues *resp){
    240 	char str[50];
    241 	sprintf(str, "@prog %sSpeed scan", prefix);
    242 	array_initiate((void **) &resp->ok.values, &resp->ok.arr, sizeof(int));
    243 	array_initiate((void **) &resp->error.values, &resp->error.arr, sizeof(int));
    244 	if(sendString(fd,str)<0){
    245 		do_log(location, "Couldn't send String",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    246 		return -1;
    247 	}
    248 	short int okcnt=0;
    249 	short int failcnt=0;
    250 	char *recv;
    251 	int speed;
    252 	do_log(location, "Querying Speeds, might take a while", LOG_LEVEL_INFO, LOG_TYPE_NORMAL);
    253 	while(1){
    254 		recv=readString(fd,0);
    255 		speed=parseSpeedResponse(recv+1);
    256 		free(recv);
    257 		if(speed>0){
    258 			array_grow((void **)&resp->ok.values, &resp->ok.arr, sizeof(unsigned int));
    259 			resp->ok.values[okcnt++]=speed;
    260 		}
    261 		else if(speed<0){
    262 			array_grow((void **)&resp->error.values, &resp->error.arr, sizeof(unsigned int));
    263 			resp->error.values[failcnt++]=-speed;
    264 		}
    265 		if(speed==0){
    266 			break;
    267 		}
    268 	}
    269 	return 0;
    270 }
    271 int auto_set_speed(struct command_exec *cmd,int fd, char *location, char *prefix){
    272 	struct parseSpeedValues resp;
    273 	if(scan_speed(cmd,fd,location,prefix,&resp)<0){
    274 		do_log(location, "Error while querying speeds!", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
    275 		return -1;
    276 	}
    277 	if(resp.ok.values[0]==0){
    278 		do_log(location, "No matching speed found!", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
    279 		return -2;
    280 	}
    281 	char str[50];
    282 	itoa(str,resp.ok.values[0],10);
    283 	cmd->data[0]=str;
    284 	array_destroy((void *)&resp.ok.values, &resp.ok.arr);
    285 	array_destroy((void *)&resp.error.values, &resp.error.arr);
    286 	
    287 	if(set_speed(cmd, fd, location, prefix)<0){
    288 		do_log(location, "Couldn't set Speed", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
    289 		return -3;
    290 	}
    291 	return 0;
    292 }
    293 int set_speed(struct command_exec *cmd,int fd, char *location, char *prefix){
    294 	int speed=atoi(cmd->data[0]);
    295 	if(speed<=0){
    296 		do_log(location,"Invalid speed", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
    297 		return -1;
    298 	}
    299 	char str[50];
    300 	sprintf(str,"@prog %sSpeed %u",prefix, speed);
    301 	
    302 	if(sendString(fd,str)<0){
    303 		do_log(location, "Couldn't send String",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    304 		return -2;
    305 	}
    306 	char *recv=readString(fd,0);
    307 	if(recv==NULL){
    308 		do_log(location, "Couldn't receive Answer",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    309 		return -3;
    310 	}
    311 	if(checkIfOk(recv)){
    312 		char *newIsp=&recv[4];
    313 		sprintf(str,"New %sSpeed: %s",prefix, newIsp);
    314 		do_log(location, str, LOG_LEVEL_INFO,LOG_TYPE_SUCCESS);
    315 	}
    316 	else{
    317 		do_log(location, "Couldn't set ISPSpeed",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
    318 		return -4;
    319 	}
    320 	free(recv);
    321 	return 0;
    322 }
    323 GENERATE_CALLBACK(cmd_set_isp_speed){
    324 	int(*func)(struct command_exec *,int, char *, char *);
    325 	if(*cmd->data[0]=='A'||strcmp(cmd->data[0], "Auto")==0){
    326 		func=&auto_set_speed;
    327 	}
    328 	else{
    329 		func=&set_speed;
    330 	}
    331 	return func(cmd, fd, "cmd_set_isp_speed", "isp");
    332 }
    333 GENERATE_CALLBACK(cmd_set_par_speed){
    334 	int(*func)(struct command_exec *,int, char *, char *);
    335 	if(*cmd->data[0]=='A'||strcmp(cmd->data[0], "Auto")==0){
    336 		func=&auto_set_speed;
    337 	}
    338 	else{
    339 		func=&set_speed;
    340 	}
    341 	return func(cmd, fd, "cmd_set_par_speed", "par");
    342 }