bool hex_scan(const String & string, S8 & hex) { S32 tmp; bool ret = hex_scan(string,tmp); hex = tmp; return ret; }
/* *----------------------------------------------------------------------------- * process_arg *----------------------------------------------------------------------------- * Dscr: process argument *----------------------------------------------------------------------------- * Input : option index, equ_ptr - pointer to option value * Output: 0 - continue * <0 - error code to exit * >0 - code to exit * Notes : call exit(1) in case of error in argument *----------------------------------------------------------------------------- */ int process_arg( int opt_index, char* equ_ptr ) { int rc=0; int i,sz; /* * process argument */ switch ( usage_descriptor[opt_index].case_code ) { case HELP_CMD_CASE: usage( 1, OPTIONS_N ); return 1; case VER_CMD_CASE: XPRINT_VERSION; config.todo[config.todo_sz++]='V'; break; case SERNO_CMD_CASE: config.serno = strtoul(equ_ptr, NULL, 0); break; case STOP_CMD_CASE: config.todo[config.todo_sz++]='P'; break; case START_CMD_CASE: config.todo[config.todo_sz++]='S'; break; case CMD_CMD_CASE: hex_scan( equ_ptr, config.cmd, &config.cmd_sz ); equ_ptr+=(config.cmd_sz*3-1); if( *equ_ptr != ',' ) { printf("RESP_SIZE missing\n"); return -1; } sscanf( equ_ptr+1,"%d", &config.resp_sz ); break; case I2C_CMD_CASE: { char hex_buf[MAX_CMD*3]; i = sscanf( equ_ptr, "%x,%x,%x,%d,%768c", &config.sa, &config.ma_sz, &config.ma, &config.sz, hex_buf); if( i == 5 ) { config.todo[config.todo_sz++]='W'; hex_scan( hex_buf, config.buf, &sz ); if( sz != config.sz ) { printf("HEX size=%d mismatch in i2c option\n", sz); return -1; } } else if( i == 4 ) { config.todo[config.todo_sz++]='R'; } else { printf("I2C Command incomplete\n"); return -1; } } break; case SPI_CMD_CASE: { char hex_buf[MAX_CMD*3]; char cmd=0; if( (equ_ptr[0]=='i') || (equ_ptr[0]=='I') ) { equ_ptr++; cmd = 'U'; } i = sscanf( equ_ptr, "%d,%768c", &config.spi_in_sz, hex_buf); if( i == 2 ) { if( !cmd ) cmd = 'T'; if( !strcmp(hex_buf,"...") ) config.spi_out_sz = config.spi_in_sz; else { hex_scan( hex_buf, config.buf, &sz ); if( (sz != config.spi_in_sz) && (cmd=='T') ) { printf("HEX size=%d mismatch in spi option\n", sz); return -1; } config.spi_out_sz = sz; } } else { if( !cmd ) cmd = 't'; config.spi_out_sz=0; } config.todo[config.todo_sz++]=cmd; } break; case SPI_SS_CMD_CASE: i = equ_ptr[0]-'0'; if( i>15 ) { printf("SS number %d does not exist\n",i); return -1; } if( !strcasecmp("h",equ_ptr+2) ) config.ss = SS_CONF(i,SS_H); else if( !strcasecmp("hl",equ_ptr+2) ) config.ss = SS_CONF(i,SS_HL); else if( !strcasecmp("hhl",equ_ptr+2) ) config.ss = SS_CONF(i,SS_HHL); else if( !strcasecmp("hhhl",equ_ptr+2) ) config.ss = SS_CONF(i,SS_HHHL); else if( !strcasecmp("hhhhl",equ_ptr+2) ) config.ss = SS_CONF(i,SS_HHHHL); else if( !strcasecmp("hi",equ_ptr+2) ) config.ss = SS_CONF(i,SS_HI); else if( !strcasecmp("l",equ_ptr+2) ) config.ss = SS_CONF(i,SS_L); else if( !strcasecmp("lh",equ_ptr+2) ) config.ss = SS_CONF(i,SS_LH); else if( !strcasecmp("llh",equ_ptr+2) ) config.ss = SS_CONF(i,SS_LLH); else if( !strcasecmp("lllh",equ_ptr+2) ) config.ss = SS_CONF(i,SS_LLLH); else if( !strcasecmp("llllh",equ_ptr+2) ) config.ss = SS_CONF(i,SS_LLLLH); else if( !strcasecmp("lo",equ_ptr+2) ) config.ss = SS_CONF(i,SS_LO); else if( !strcasecmp("hiz",equ_ptr+2) ) config.ss = SS_CONF(i,SS_HiZ); else if( !strcasecmp("0",equ_ptr+2) ) config.ss = SS_CONF(i,0); else { printf("Unknown SS configuration\n"); return -1; } break; case I2C_CFG_CMD_CASE: switch( equ_ptr[0] ) { case 'f': case 'F': config.i2c_freq = strtoul(equ_ptr+1,0,0); config.todo[config.todo_sz++]='b'; break; case 's': case 'S': config.i2c_sa = strtoul(equ_ptr+1,0,0); config.todo[config.todo_sz++]='d'; break; case 'm': case 'M': config.bb_i2c_mode = strtoul(equ_ptr+1,0,0); config.todo[config.todo_sz++]='C'; break; case 'c': case 'C': config.bb_i2c_stretch = strtoul(equ_ptr+1,0,0); config.todo[config.todo_sz++]='C'; break; default: printf( "Unknown parameter `%c' in i2c config\n", equ_ptr[0] ); return -1; } break; case I2C_CH_CMD_CASE: config.bb_i2c_ch = strtoul(equ_ptr,0,0); break; case SCAN_CMD_CASE: config.todo[config.todo_sz++]='N'; break; case SPI_CFG_CMD_CASE: config.spi_config = 0; while( *equ_ptr ) { switch( *equ_ptr ) { case 'g': case 'G': config.todo[config.todo_sz++]='G'; goto xx1; case 'e': case 'E': config.spi_config|=SPI_ENABLE; break; case 's': case 'S': config.spi_config|=SPI_SLAVE; break; case 'P': case 'p': config.spi_config|=SPI_SMPL_SETUP; break; case 't': case 'T': config.spi_config|=SPI_SETUP_SMPL; break; case 'r': case 'R': config.spi_config|=SPI_CPOL_RISE; break; case 'f': case 'F': config.spi_config|=SPI_CPOL_FALL; break; case 'm': case 'M': config.spi_config|=SPI_MSB_FIRST; break; case 'l': case 'L': config.spi_config|=SPI_LSB_FIRST; break; case '8': config.spi_config|=SPI_CLK_8MHZ; break; case '4': config.spi_config|=SPI_CLK_4MHZ; break; case '2': config.spi_config|=SPI_CLK_2MHZ; break; case '1': config.spi_config|=SPI_CLK_1MHZ; break; case '5': config.spi_config|=SPI_CLK_500KHZ; break; case '6': config.spi_config|=SPI_CLK_250KHZ; break; case '7': config.spi_config|=SPI_CLK_125KHZ; break; } equ_ptr++; } config.todo[config.todo_sz++]='f'; xx1: break; case GPIO_CMD_CASE: switch( equ_ptr[0] ) { case 'B': case 'b': switch( equ_ptr[1] ) { case 'R': case 'r': config.todo[config.todo_sz++]='e'; break; case 'W': case 'w': config.todo[config.todo_sz++]='n'; break; case 'C': case 'c': config.todo[config.todo_sz++]='E'; break; default: printf("Wrong GPIOB function\n"); return -1; } sscanf( equ_ptr+2, ",%x,%x", &config.gpiob_val, &config.gpiob_mask ); break; case 'R': case 'r': config.todo[config.todo_sz++]='I'; break; case 'W': case 'w': config.todo[config.todo_sz++]='O'; break; case 'C': case 'c': config.todo[config.todo_sz++]='D'; break; default: printf("Wrong GPIO function\n"); return -1; } sscanf( equ_ptr+1, ",%x,%x", &config.gpio_val, &config.gpio_mask ); break; case RPT_CMD_CASE: sz = strtoul(equ_ptr,0,0); for( i=0; i<sz; i++ ) { config.todo[config.todo_sz]=config.todo[config.todo_sz-1]; config.todo_sz++; } break; case GETSN_CMD_CASE: config.todo[config.todo_sz++]='s'; break; case GETID_CMD_CASE: config.todo[config.todo_sz++]='i'; break; case BOOT_CMD_CASE: config.todo[config.todo_sz++]='B'; break; case GETVPD_CMD_CASE: config.todo[config.todo_sz++]='v'; break; case FIFO_CMD_CASE: { char *p; sscanf( equ_ptr, "%d", &config.sz ); p = strchr( equ_ptr,',' ); if( p ) { hex_scan( p+1, config.buf, 0 ); config.todo[config.todo_sz++]='A'; } else config.todo[config.todo_sz++]='a'; } break; case FIFO_CFG_CMD_CASE: while( *equ_ptr ) { switch( *equ_ptr ) { case 's': case 'S': config.fifo_cfg |= FIFO_SELECT_SPI; break; case 'u': case 'U': config.fifo_cfg |= FIFO_SELECT_UART; break; case 'c': case 'C': config.fifo_cfg |= FIFO_CLEAR; break; case 'i': case 'I': config.fifo_cfg |= FIFO_SELECT_I2C; break; default: printf("Unknown FIFO Config parameter `%c'\n", *equ_ptr); return -1; } equ_ptr++; } config.todo[config.todo_sz++]='c'; break; case LCDWR_CMD_CASE: { int i=0,j=0; config.lcd_str = equ_ptr; /* Parse LCD String */ while( config.lcd_str[i] ) { if( config.lcd_str[i] == '\\' ) { switch( config.lcd_str[i+1] ) { case 'n': config.lcd_str[j] = '\n'; i++; break; case 'f': config.lcd_str[j] = '\f'; i++; break; case 'r': config.lcd_str[j] = '\r'; i++; break; case 'e': config.lcd_str[j++]=0x1b; config.lcd_str[j++]=config.lcd_str[i+2]; config.lcd_str[j] =config.lcd_str[i+3]; i+=3; break; default: config.lcd_str[j] = '\\'; } } else config.lcd_str[j] = config.lcd_str[i]; j++; i++; } config.lcd_str[j] = 0x00; config.todo[config.todo_sz++]='L'; } break; case RS_CFG_CMD_CASE: { char* p = equ_ptr; config.todo[config.todo_sz++]='r'; if( *p == '0' ) { config.rs_baud = 0; break; } while( *p ) { if( *p == '_' ) break; p++; } if( !*p ) { printf( "Wrong RS Config parameter\n" ); return -1; } *p=0; config.rs_baud = atoi( equ_ptr ); p++; switch( *p ) { case '5': config.rs_config |= RS_CHAR_5; break; case '6': config.rs_config |= RS_CHAR_6; break; case '7': config.rs_config |= RS_CHAR_7; break; case '8': config.rs_config |= RS_CHAR_8; break; case '9': config.rs_config |= RS_CHAR_9; break; default: printf( "Wrong character size in RS Config\n" ); return -1; } p++; switch( *p ) { case 'N': config.rs_config |= RS_PARITY_NONE; break; case 'E': config.rs_config |= RS_PARITY_EVEN; break; case 'O': config.rs_config |= RS_PARITY_ODD; break; default: printf( "Wrong parity code in RS Config\n" ); return -1; } p++; switch( *p ) { case '1': config.rs_config |= RS_STOP_1; break; case '2': config.rs_config |= RS_STOP_2; break; default: printf( "Wrong stop bits in RS Config\n" ); return -1; } config.rs_config |= RS_RX_ENABLE|RS_TX_ENABLE; } break; case RS_TMG_CMD_CASE: if( toupper(equ_ptr[0]) == 'B' ) { config.rs_flags |= RS_RX_BEFORE_TX; equ_ptr+=2; } else if( toupper(equ_ptr[0]) == 'A' ) { config.rs_flags |= RS_RX_AFTER_TX; equ_ptr+=2; } if( sscanf(equ_ptr, "%u,%u,%u", &config.rs_tx_space, &config.rs_rx_msg_to, &config.rs_rx_byte_to) != 3 ) { printf("Bad RS Timing configuration\n" ); return -1; } config.todo[config.todo_sz++]='u'; break; case RS_XFER_CMD_CASE: { char hex_buf[MAX_CMD*3]; i = sscanf( equ_ptr, "%d,%768c", &config.rs_rx_sz, hex_buf); if( i == 2 ) { hex_scan( hex_buf, config.buf, &config.rs_tx_sz ); } } config.todo[config.todo_sz++]='X'; break; case FPWM_CMD_CASE: config.fpwm_flags |= FPWM_ENABLE; if( (equ_ptr[0]=='f') || (equ_ptr[0]=='F') ) { if( sscanf( equ_ptr+1, "%lf", &config.fpwm_freq ) != 1 ) { printf("Specify fast PWM frequency as --fpwm=F<FREQ_HZ>\n"); return -1; } if( config.fpwm_freq == 0 ) config.fpwm_flags &= ~FPWM_ENABLE; config.todo[config.todo_sz++]='M'; } else { int pwm_n = equ_ptr[0]-'0'; equ_ptr++; if( (pwm_n<0) || (pwm_n>2) ) { printf("Fast PWM number must be 0,1,2\n"); return -1; } config.fpwm_flags |= FPWM_EN0>>(pwm_n*2); if( sscanf(equ_ptr, ",%lf", &config.fpwm_duty[pwm_n]) != 1 ) { printf("Fast PWM set format is --fpwm=<N>,<DUTY>\n"); return -1; } config.todo[config.todo_sz++]='m'; } break; case PWM_CMD_CASE: if( (equ_ptr[0]=='c') || (equ_ptr[0]=='C') ) { if( sscanf(equ_ptr+1,"%u,%u",&config.pwm_res,&config.pwm_limit) != 2 ) { printf("Specify PWM configuration as --pwm=C<RES>,<LIMIT>\n"); return -1; } config.todo[config.todo_sz++]='K'; } else { int pwm_n = equ_ptr[0]-'0'; equ_ptr++; if( (pwm_n<0) || (pwm_n>7) ) { printf("PWM number must be 0..7\n"); return -1; } if( sscanf(equ_ptr, ",%u", &config.pwm_duty[pwm_n]) != 1 ) { printf("PWM set format is --pwm=<N>,<DUTY>\n"); return -1; } config.todo[config.todo_sz++]='k'; } break; case ADC_CFG_CMD_CASE: while( *equ_ptr ) { switch(*equ_ptr) { case 'e': case 'E': config.adc_cfg|=ADC_ENABLE; break; case 'v': case 'V': config.adc_cfg|=ADC_REF_VCC; break; case '2': config.adc_cfg|=ADC_REF_2_56; break; default: printf("Unknown option `%c' in ADC config\n", *equ_ptr); return -1; } equ_ptr++; } config.todo[config.todo_sz++]='Z'; break; case ADC_CMD_CASE: config.adc_mux[ config.adc_reads++ ] = strtoul( equ_ptr,0,0 ); if( config.adc_reads == 1 ) config.todo[config.todo_sz++]='z'; break; case MDIO_CMD_CASE: if( *equ_ptr == '1' ) { config.mdio_channel = 1; equ_ptr++; } switch( *equ_ptr ) { case 'a': config.mdios[config.mdio_n].clause45.op = SUB_MDIO45_ADDR; break; case 'w': config.mdios[config.mdio_n].clause45.op = SUB_MDIO45_WRITE; break; case 'r': config.mdios[config.mdio_n].clause45.op = SUB_MDIO45_READ; break; case 'p': config.mdios[config.mdio_n].clause45.op = SUB_MDIO45_PRIA; break; case 'R': config.mdios[config.mdio_n].clause45.op = SUB_MDIO22_READ; break; case 'W': config.mdios[config.mdio_n].clause45.op = SUB_MDIO22_WRITE; break; default: printf("Unknown mdio operation\n"); return -1; } if( sscanf(equ_ptr+1, ",%x,%x,%x", &config.mdios[config.mdio_n].clause45.prtad, &config.mdios[config.mdio_n].clause45.devad, &config.mdios[config.mdio_n].clause45.data) != 3 ) { printf("Wrong mdio option format\n"); return -1; } config.mdio_n++; config.todo[config.todo_sz++]='o'; break; }/*switch*/ return rc; }