int get_command(pState state){ //magic len command subcommand data checkval //message is len + 8 (2 magic, 2 len, 4 checkval) //magic = 0xa55a, short len, short command, var subcommand, var data, int checkval // unsigned char *buf = malloc(MAX_MESSAGE_LEN+8); unsigned char buf[MAX_MESSAGE_LEN+8]; unsigned int checkval = 0; unsigned int calc_checkval = 0; unsigned short magic = 0; unsigned short len = 0; unsigned short command = 0xaa; unsigned short subcommand = 0xffff; unsigned short sensorID = 0xffff; unsigned int sensor_address = 0xffff; unsigned int coefficient = 0xffff; unsigned short temp = 0xffff; unsigned short numSteps = 0xffff; unsigned short *tempP = NULL; unsigned short seconds = 0; pStep steps = NULL; int ret = -1; unsigned int fw = 0; bzero(buf,MAX_MESSAGE_LEN+8); //get magic get_bytes(buf ,2); magic = get_short(buf); if (magic != MAGIC){ prime_buf(buf); send(buf,12); //free(buf); return 1; } //get len get_bytes(buf+2,2); len = get_short(buf+2); //check len if (len > MAX_MESSAGE_LEN){ prime_buf(buf); send(buf,12); //free(buf); return 1; } //get the rest of message except checkval get_bytes(buf+4, len); //get checkval checkval = get_int(buf+len); //compare to calculated from message calc_checkval = check_val( buf, len); if ( checkval != calc_checkval ){ //bad check_val prime_buf(buf); send(buf,12); //free(buf); return 1; } //get command command = get_short(buf+4); switch (command) { case 1:{ //set power state subcommand = get_short(buf+6); prime_buf(buf); if (subcommand == 0x0000){ power_off(state); } if (subcommand == 0x0001){ power_on(state); } if (subcommand > 0x0001){ //bad subcommand } send(buf, 12); break; } case 2:{//set temp temp = get_short(buf+6); prime_buf(buf); if (set_temp(state,temp) == 2){ buf[6] = 1; } send(buf, 12); break; } case 3:{ //add sensor sensorID = get_short(buf+6); sensor_address = get_int(buf+8); coefficient = get_int(buf+12); unsigned int sensorTemp = get_int(buf+16); //check count < 10 buf[6] = 0x08, sensor_ID is unique/not in use buf[6] = 0x07, ret = add_sensor(state, sensorID, sensor_address, coefficient, sensorTemp); prime_buf(buf); if (ret == 2){buf[6]=0x07;} if (ret == 3){buf[6]=0x08;} send(buf, 12); break; } case 4:{ //remove sensor sensorID = get_short(buf+6); ret = remove_sensor(state,sensorID); prime_buf(buf); if (ret == 1){buf[6]=0x06;} send(buf, 12); break; } case 5:{ //set smoke sensor subcommand = get_short(buf+6); prime_buf(buf); if (subcommand == 0x0000){ smoke_off(state); } if (subcommand == 0x0001){ smoke_on(state); } if (subcommand > 0x0001){ //bad subcommand //no response } send(buf, 12); break; } case 6:{ //set program numSteps = get_short(buf+6); steps = (pStep)(buf+8) ; ret = add_steps(state,numSteps,steps); prime_buf(buf); if (ret == 3){buf[6]=3;} if (ret == 2){buf[6]=2;} if (ret == 1){buf[6]=1;} send(buf, 12); break; } case 7:{//get program prime_buf(buf); unsigned int lenz = 0; unsigned int program[30]; bzero(program,120); buf[4]=1; buf[6]=7; get_program(state, &lenz, program); lenz = lenz*3*sizeof(int); cgc_memcpy(buf+8,&lenz,sizeof(int)); cgc_memcpy(buf+12,program,lenz); send(buf,lenz + 12); break; } case 8:{//get status prime_buf(buf); buf[4]=1; buf[6]=8; unsigned int status[6]; int len = 24; ret = get_status(state,status); cgc_memcpy(buf+8,&len,sizeof(int)); cgc_memcpy(buf+12,status,24); send(buf,36); break; } case 9:{//simulate seconds seconds = get_short(buf+6); prime_buf(buf); unsigned int bufsize = 12; unsigned int histSize = 0; ret = simulate_seconds(state, seconds); unsigned int currentTime = state->currentTime; unsigned int setTemp = state->setTemp; if (ret == 0 ){ buf[6] = 9; cgc_memcpy(buf+8, ¤tTime ,sizeof(int)); send(buf,12); } if(ret == 2){ buf[4] = 1; buf[6] = 0xc; histSize = state->historyPosition*sizeof(int); unsigned int *pHistoryList = state->history; unsigned int historyListSize = state->historyPosition; unsigned int ambientTemp = state->ambientTemp; new_state(state); if (historyListSize > 0){ cgc_memcpy(buf+8, &historyListSize, sizeof(historyListSize)); cgc_memcpy(buf+12, pHistoryList, histSize); bufsize = histSize + 12; } cgc_memcpy(buf+bufsize, &ambientTemp, sizeof(unsigned int)); bufsize+=4; cgc_memcpy(buf+bufsize, &setTemp, sizeof(unsigned int)); bufsize+=4; send(buf, bufsize); //new_state(state); } break; } case 0xa:{ //validate firmware unsigned int fw = validate_fw(state); prime_buf(buf); buf[4]=1; buf[6]=0xa; buf[8]=4; cgc_memcpy(buf+12, &fw,sizeof(int) ); send(buf, 16); break; } case 0xb:{//cgc_read sensor list prime_buf(buf); int len = 0; buf[4]=1; buf[6]=0xb; len = state->sensorCount * (sizeof(int)*4); //buff is filled with sensor bytes unsigned int sensorList[40*sizeof(int)]; get_sensors(state,sensorList); cgc_memcpy(buf+8,&len,sizeof(int)); cgc_memcpy(buf+12,sensorList,len); send(buf, len+12); break; } case 0xc:{//set ambient temp int ambientTemp = get_signed_int(buf+6); prime_buf(buf); if (set_ambient_temp(state,ambientTemp) == 2){ buf[6] = 1; } send(buf, 12); break; } case 0xff:{ //free(buf); exit_normal(); break; } default:{ //bad command prime_buf(buf); buf[6]=5; send(buf,12); break; } } // free(buf); return 0; }
int main() { unsigned long T = 0L; int Ival; U8 rb; CFG_GCR |= 1; // disable SWIM // Configure clocking CLK_CKDIVR = 0; // F_HSI = 16MHz, f_CPU = 16MHz // Configure timer 1 - systick // prescaler = f_{in}/f_{tim1} - 1 // set Timer1 to 1MHz: 1/1 - 1 = 15 TIM1_PSCRH = 0; TIM1_PSCRL = 15; // LSB should be written last as it updates prescaler // auto-reload each 1ms: TIM_ARR = 1000 = 0x03E8 TIM1_ARRH = 0x03; TIM1_ARRL = 0xE8; // interrupts: update TIM1_IER = TIM_IER_UIE; // auto-reload + interrupt on overflow + enable TIM1_CR1 = TIM_CR1_APRE | TIM_CR1_URS | TIM_CR1_CEN; // Configure pins // PC2 - PP output (on-board LED) PORT(LED_PORT, DDR) |= LED_PIN; PORT(LED_PORT, CR1) |= LED_PIN; // PD5 - UART2_TX PORT(UART_PORT, DDR) |= UART_TX_PIN; PORT(UART_PORT, CR1) |= UART_TX_PIN; // Configure UART // 8 bit, no parity, 1 stop (UART_CR1/3 = 0 - reset value) // 57600 on 16MHz: BRR1=0x11, BRR2=0x06 UART2_BRR1 = 0x11; UART2_BRR2 = 0x06; UART2_CR2 = UART_CR2_TEN | UART_CR2_REN | UART_CR2_RIEN; // Allow RX/TX, generate ints on rx // enable all interrupts enableInterrupts(); set_stepper_speed(1000); setup_stepper_pins(); // Loop do{ if((Global_time - T > paused_val) || (T > Global_time)){ T = Global_time; PORT(LED_PORT, ODR) ^= LED_PIN; // blink on-board LED } if(UART_read_byte(&rb)){ // buffer isn't empty switch(rb){ case 'h': // help case 'H': uart_write("\nPROTO:\n+/-\tLED period\nS/s\tset/get Mspeed\n" "m\tget steps\nx\tstop\np\tpause/resume\nM\tmove motor\na\tadd Nstps\n" "u\tunipolar motor\nb\tbipolar motor\n"); break; case '+': paused_val += 100; if(paused_val > 10000) paused_val = 500; // but not more than 10s break; case '-': paused_val -= 100; if(paused_val < 100) // but not less than 0.1s paused_val = 500; break; case 'S': // set stepper speed if(readInt(&Ival) && Ival > MIN_STEP_LENGTH) set_stepper_speed(Ival); else error_msg("bad speed"); break; case 's': // get stepper speed printUint((U8*)&Stepper_speed, 2); break; case 'm': // how much steps there is to the end of moving printUint((U8*)&Nsteps, 4); break; case 'M': // move motor if(Nsteps){ error_msg("moving!"); break; } if(readInt(&Ival) && Ival) move_motor(Ival); else{ error_msg("bad Nsteps"); } break; case 'x': // stop stop_motor(); break; case 'p': // pause/resume pause_resume(); break; case 'a': // add N steps if(readInt(&Ival) && Ival){ add_steps(Ival); }else{ error_msg("bad value"); } break; case 'u': // unipolar usteps = ustepsUNI; break; case 'b': // bipolar usteps = ustepsBIP; break; } } }while(1); }