//the main function waits for all the bytes in the STK500v2 packet, //then sends for processing in the above functions int main(void) { unsigned char ch; unsigned char prev_ch=0; //unsigned char chr_nl=0; //unused unsigned char msgparsestate; unsigned char cksum=0; unsigned char seqnum=0; int msglen=0; int i=0; uart_init(); //wd_init(); LED_INIT; LED_OFF; //sei(); //enable AVR interrupts msgparsestate=MSG_IDLE; // default values: CONFIG_PARAM_SW_MINOR=D_CONFIG_PARAM_SW_MINOR; CONFIG_PARAM_SW_MAJOR=D_CONFIG_PARAM_SW_MAJOR; while(1){ if (msgparsestate==MSG_IDLE){ ch=uart_getchar(1); }else{ ch=uart_getchar(0); //getting extra bytes, use timeout } // parse message according to appl. note AVR068 table 3-1: if (msgparsestate==MSG_IDLE && ch == MESSAGE_START){ msgparsestate=MSG_WAIT_SEQNUM; cksum = ch^0; continue; } if (msgparsestate==MSG_WAIT_SEQNUM){ seqnum=ch; cksum^=ch; msgparsestate=MSG_WAIT_SIZE1; continue; } if (msgparsestate==MSG_WAIT_SIZE1){ cksum^=ch; msglen=ch<<8; msgparsestate=MSG_WAIT_SIZE2; continue; } if (msgparsestate==MSG_WAIT_SIZE2){ cksum^=ch; msglen|=ch; msgparsestate=MSG_WAIT_TOKEN; continue; } if (msgparsestate==MSG_WAIT_TOKEN){ cksum^=ch; if (ch==TOKEN){ msgparsestate=MSG_WAIT_MSG; i=0; }else{ msgparsestate=MSG_IDLE; } continue; } if (msgparsestate==MSG_WAIT_MSG && i<msglen && i<280){ cksum^=ch; msg_buf[i]=ch; i++; wdt_reset(); //wd_kick(); if (i==msglen){ msgparsestate=MSG_WAIT_CKSUM; } continue; } if (msgparsestate==MSG_WAIT_CKSUM){ if (ch==cksum && msglen > 0){ // message correct, process it wdt_reset(); //wd_kick(); programcmd(seqnum); }else{ msg_buf[0] = ANSWER_CKSUM_ERROR; msg_buf[1] = STATUS_CKSUM_ERROR; transmit_answer(seqnum,2); } // no continue here, set state=MSG_IDLE } msgparsestate=MSG_IDLE; msglen=0; seqnum=0; prev_ch=0; i=0; } return(0); }
int main(void) { unsigned char ch; unsigned char prev_ch=0; unsigned char chr_nl=0; unsigned char msgparsestate; unsigned char cksum=0; unsigned char seqnum=0; int msglen=0; int i=0; uart_init(); wd_init(); LED_INIT; LED_OFF; sei(); msgparsestate=MSG_IDLE; // default values: CONFIG_PARAM_SW_MINOR=D_CONFIG_PARAM_SW_MINOR; CONFIG_PARAM_SW_MAJOR=D_CONFIG_PARAM_SW_MAJOR; if (eeprom_read_byte((uint8_t *)EEPROM_MAGIC) == 20){ // ok magic number matches accept values CONFIG_PARAM_SW_MINOR=eeprom_read_byte(EEPROM_MINOR); CONFIG_PARAM_SW_MAJOR=eeprom_read_byte(EEPROM_MAJOR); } while(1){ if (msgparsestate==MSG_IDLE){ ch=uart_getchar(1); }else{ ch=uart_getchar(0); } // parse message according to appl. note AVR068 table 3-1: if (msgparsestate==MSG_IDLE && ch == MESSAGE_START){ msgparsestate=MSG_WAIT_SEQNUM; cksum = ch^0; continue; } // The special avrusb500 terminal mode. // Just connect a serial terminal and press enter twice. // Both Windows and Linux send normally \r (=0xd) as the // only line end character. It is however possible to configure // \r\n as line end in some serial terminals. Therefore we // must handle it. if (msgparsestate==MSG_IDLE && (ch == '\r'||ch == '\n')){ i++; if(chr_nl ==0 && ch=='\n' && prev_ch== '\r'){ // terminal sends \r\n for new line chr_nl=1; } prev_ch=ch; if (chr_nl){ // wait for \r\n \r\n if (i==4){ terminalmode(1); i=0; } }else{ // Linux wait for \n\n if (i==2){ terminalmode(0); i=0; } } continue; } if (msgparsestate==MSG_WAIT_SEQNUM){ seqnum=ch; cksum^=ch; msgparsestate=MSG_WAIT_SIZE1; continue; } if (msgparsestate==MSG_WAIT_SIZE1){ cksum^=ch; msglen=ch<<8; msgparsestate=MSG_WAIT_SIZE2; continue; } if (msgparsestate==MSG_WAIT_SIZE2){ cksum^=ch; msglen|=ch; msgparsestate=MSG_WAIT_TOKEN; continue; } if (msgparsestate==MSG_WAIT_TOKEN){ cksum^=ch; if (ch==TOKEN){ msgparsestate=MSG_WAIT_MSG; i=0; }else{ msgparsestate=MSG_IDLE; } continue; } if (msgparsestate==MSG_WAIT_MSG && i<msglen && i<280){ cksum^=ch; msg_buf[i]=ch; i++; wdt_reset(); //wd_kick(); if (i==msglen){ msgparsestate=MSG_WAIT_CKSUM; } continue; } if (msgparsestate==MSG_WAIT_CKSUM){ if (ch==cksum && msglen > 0){ // message correct, process it wdt_reset(); //wd_kick(); programcmd(seqnum); }else{ msg_buf[0] = ANSWER_CKSUM_ERROR; msg_buf[1] = STATUS_CKSUM_ERROR; transmit_answer(seqnum,2); } // no continue here, set state=MSG_IDLE } msgparsestate=MSG_IDLE; msglen=0; seqnum=0; prev_ch=0; i=0; } return(0); }