// Goes to the x,y coordinates on the lcd specified by the two data bytes void do_lcd_goto_xy() { unsigned char x = read_next_byte(); if(check_data_byte(x)) return; unsigned char y = read_next_byte(); if(check_data_byte(y)) return; lcd_goto_xy(x,y); }
// Optimization: in der Funktion selbst loopen (spart function calls) void read_data_fn(struct state *s) { debug(__func__, s); byte current_byte = read_next_byte(s); switch (current_byte) { case START_BYTE_CASE: reset_state(s); s->next = length_fn; break; case STOP_BYTE_CASE: s->flush_cb(s); reset_state(s); s->next = start_fn; break; case ESCAPE_BYTE_CASE: s->next = read_data_esc_fn; break; default: if (s->already_read > s->next_packet_size) { printf("We're exceeding the new length\n"); // unescaped START in payload? } s->buffer[s->already_read] = current_byte; s->already_read++; break; } }
// writes the byte after an escape without interpretation void read_data_esc_fn(struct state *s) { debug(__func__, s); s->next = read_data_fn; byte current_byte = read_next_byte(s); s->buffer[s->already_read] = current_byte; s->already_read++; }
// Drives m2 backward. void m2_backward() { char byte = read_next_byte(); if(check_data_byte(byte)) return; set_m2_speed(byte == 127 ? -255 : -byte*2); }
// Drives m1 forward. void m1_forward() { char byte = read_next_byte(); if(check_data_byte(byte)) return; set_m1_speed(byte == 127 ? 255 : byte*2); }
// Displays data to the screen void do_print() { unsigned char string_length = read_next_byte(); if(check_data_byte(string_length)) return; unsigned char i; for(i=0;i<string_length;i++) { unsigned char character; character = read_next_byte(); if(check_data_byte(character)) return; print_character(character); } }
void start_fn(struct state *s) { debug(__func__, s); byte current_byte = read_next_byte(s); switch (current_byte) { case START_BYTE_CASE: s->next = length_fn; break; default: break; } }
// Plays a musical sequence. void do_play() { unsigned char tune_length = read_next_byte(); if(check_data_byte(tune_length)) return; unsigned char i; for(i=0;i<tune_length;i++) { if(i > sizeof(music_buffer)) // avoid overflow return; music_buffer[i] = read_next_byte(); if(check_data_byte(music_buffer[i])) return; } // add the end of string character 0 music_buffer[i] = 0; play(music_buffer); }
void length_fn(struct state *s) { debug(__func__, s); byte current_byte = read_next_byte(s); switch (current_byte) { case START_BYTE_CASE: case STOP_BYTE_CASE: s->next = length_fn; break; case ESCAPE_BYTE_CASE: s->next = length_esc_fn; break; default: s->next_packet_size = current_byte; s->next = read_data_fn; break; } }
// Turns on PID according to the supplied PID constants void set_pid() { unsigned char constants[5]; unsigned char i; for(i=0;i<5;i++) { constants[i] = read_next_byte(); if(check_data_byte(constants[i])) return; } // make the max speed 2x of the first one, so that it can reach 255 max_speed = (constants[0] == 127 ? 255 : constants[0]*2); // set the other parameters directly p_num = constants[1]; p_den = constants[2]; d_num = constants[3]; d_den = constants[4]; // enable pid pid_enabled = 1; }
/* * This implements the state machine defined in the IPMI manual, see * that for details on how this works. Divide that flowchart into * sections delimited by "Wait for IBF" and this will become clear. */ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) { unsigned char status; unsigned char state; status = read_status(kcs); if (kcs_debug & KCS_DEBUG_STATES) printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status); /* All states wait for ibf, so just do it here. */ if (!check_ibf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; /* Just about everything looks at the KCS state, so grab that, too. */ state = GET_STATUS_STATE(status); switch (kcs->state) { case KCS_IDLE: /* If there's and interrupt source, turn it off. */ clear_obf(kcs, status); if (GET_STATUS_ATN(status)) return SI_SM_ATTN; else return SI_SM_IDLE; case KCS_START_OP: if (state != KCS_IDLE_STATE) { start_error_recovery(kcs, "State machine not idle at start"); break; } clear_obf(kcs, status); write_cmd(kcs, KCS_WRITE_START); kcs->state = KCS_WAIT_WRITE_START; break; case KCS_WAIT_WRITE_START: if (state != KCS_WRITE_STATE) { start_error_recovery( kcs, "Not in write state at write start"); break; } read_data(kcs); if (kcs->write_count == 1) { write_cmd(kcs, KCS_WRITE_END); kcs->state = KCS_WAIT_WRITE_END; } else { write_next_byte(kcs); kcs->state = KCS_WAIT_WRITE; } break; case KCS_WAIT_WRITE: if (state != KCS_WRITE_STATE) { start_error_recovery(kcs, "Not in write state for write"); break; } clear_obf(kcs, status); if (kcs->write_count == 1) { write_cmd(kcs, KCS_WRITE_END); kcs->state = KCS_WAIT_WRITE_END; } else { write_next_byte(kcs); } break; case KCS_WAIT_WRITE_END: if (state != KCS_WRITE_STATE) { start_error_recovery(kcs, "Not in write state" " for write end"); break; } clear_obf(kcs, status); write_next_byte(kcs); kcs->state = KCS_WAIT_READ; break; case KCS_WAIT_READ: if ((state != KCS_READ_STATE) && (state != KCS_IDLE_STATE)) { start_error_recovery( kcs, "Not in read or idle in read state"); break; } if (state == KCS_READ_STATE) { if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; read_next_byte(kcs); } else { /* * We don't implement this exactly like the state * machine in the spec. Some broken hardware * does not write the final dummy byte to the * read register. Thus obf will never go high * here. We just go straight to idle, and we * handle clearing out obf in idle state if it * happens to come in. */ clear_obf(kcs, status); kcs->orig_write_count = 0; kcs->state = KCS_IDLE; return SI_SM_TRANSACTION_COMPLETE; } break; case KCS_ERROR0: clear_obf(kcs, status); status = read_status(kcs); if (GET_STATUS_OBF(status)) /* controller isn't responding */ if (time_before(jiffies, kcs->error0_timeout)) return SI_SM_CALL_WITH_TICK_DELAY; write_cmd(kcs, KCS_GET_STATUS_ABORT); kcs->state = KCS_ERROR1; break; case KCS_ERROR1: clear_obf(kcs, status); write_data(kcs, 0); kcs->state = KCS_ERROR2; break; case KCS_ERROR2: if (state != KCS_READ_STATE) { start_error_recovery(kcs, "Not in read state for error2"); break; } if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); write_data(kcs, KCS_READ_BYTE); kcs->state = KCS_ERROR3; break; case KCS_ERROR3: if (state != KCS_IDLE_STATE) { start_error_recovery(kcs, "Not in idle state for error3"); break; } if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); if (kcs->orig_write_count) { restart_kcs_transaction(kcs); } else { kcs->state = KCS_IDLE; return SI_SM_TRANSACTION_COMPLETE; } break; case KCS_HOSED: break; } if (kcs->state == KCS_HOSED) { init_kcs_data(kcs, kcs->io); return SI_SM_HOSED; } return SI_SM_CALL_WITHOUT_DELAY; }
static enum si_sm_result smic_event(struct si_sm_data *smic, long time) { unsigned char status; unsigned char flags; unsigned char data; if (smic->state == SMIC_HOSED) { init_smic_data(smic, smic->io); return SI_SM_HOSED; } if (smic->state != SMIC_IDLE) { if (smic_debug & SMIC_DEBUG_STATES) printk(KERN_DEBUG "smic_event - smic->smic_timeout = %ld," " time = %ld\n", smic->smic_timeout, time); if (time < SMIC_RETRY_TIMEOUT) { smic->smic_timeout -= time; if (smic->smic_timeout < 0) { start_error_recovery(smic, "smic timed out."); return SI_SM_CALL_WITH_DELAY; } } } flags = read_smic_flags(smic); if (flags & SMIC_FLAG_BSY) return SI_SM_CALL_WITH_DELAY; status = read_smic_status(smic); if (smic_debug & SMIC_DEBUG_STATES) printk(KERN_DEBUG "smic_event - state = %d, flags = 0x%02x," " status = 0x%02x\n", smic->state, flags, status); switch (smic->state) { case SMIC_IDLE: if (flags & SMIC_SMS_DATA_AVAIL) return SI_SM_ATTN; return SI_SM_IDLE; case SMIC_START_OP: write_smic_control(smic, SMIC_CC_SMS_GET_STATUS); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_OP_OK; break; case SMIC_OP_OK: if (status != SMIC_SC_SMS_READY) { start_error_recovery(smic, "state = SMIC_OP_OK," " status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } write_smic_control(smic, SMIC_CC_SMS_WR_START); write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_WRITE_START; break; case SMIC_WRITE_START: if (status != SMIC_SC_SMS_WR_START) { start_error_recovery(smic, "state = SMIC_WRITE_START, " "status != SMIC_SC_SMS_WR_START"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_WRITE_NEXT: if (status != SMIC_SC_SMS_WR_NEXT) { start_error_recovery(smic, "state = SMIC_WRITE_NEXT, " "status != SMIC_SC_SMS_WR_NEXT"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_WRITE_END: if (status != SMIC_SC_SMS_WR_END) { start_error_recovery(smic, "state = SMIC_WRITE_END, " "status != SMIC_SC_SMS_WR_END"); return SI_SM_CALL_WITH_DELAY; } data = read_smic_data(smic); if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) printk(KERN_DEBUG "SMIC_WRITE_END: data = %02x\n", data); start_error_recovery(smic, "state = SMIC_WRITE_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else smic->state = SMIC_WRITE2READ; break; case SMIC_WRITE2READ: if (flags & SMIC_RX_DATA_READY) { write_smic_control(smic, SMIC_CC_SMS_RD_START); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_START; } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_READ_START: if (status != SMIC_SC_SMS_RD_START) { start_error_recovery(smic, "state = SMIC_READ_START, " "status != SMIC_SC_SMS_RD_START"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_READ_NEXT: switch (status) { case SMIC_SC_SMS_RD_END: read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_END); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_END; break; case SMIC_SC_SMS_RD_NEXT: if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else return SI_SM_CALL_WITH_DELAY; break; default: start_error_recovery( smic, "state = SMIC_READ_NEXT, " "status != SMIC_SC_SMS_RD_(NEXT|END)"); return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_END: if (status != SMIC_SC_SMS_READY) { start_error_recovery(smic, "state = SMIC_READ_END, " "status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } data = read_smic_data(smic); if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) printk(KERN_DEBUG "SMIC_READ_END: data = %02x\n", data); start_error_recovery(smic, "state = SMIC_READ_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else { smic->state = SMIC_IDLE; return SI_SM_TRANSACTION_COMPLETE; } case SMIC_HOSED: init_smic_data(smic, smic->io); return SI_SM_HOSED; default: if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_DEBUG "smic->state = %d\n", smic->state); start_error_recovery(smic, "state = UNKNOWN"); return SI_SM_CALL_WITH_DELAY; } } smic->smic_timeout = SMIC_RETRY_TIMEOUT; return SI_SM_CALL_WITHOUT_DELAY; }
static enum si_sm_result smic_event (struct si_sm_data *smic, long time) { unsigned char status; unsigned char flags; unsigned char data; if (smic->state == SMIC_HOSED) { init_smic_data(smic, smic->io); return SI_SM_HOSED; } if (smic->state != SMIC_IDLE) { if (smic_debug & SMIC_DEBUG_STATES) { printk(KERN_INFO "smic_event - smic->smic_timeout = %ld," " time = %ld\n", smic->smic_timeout, time); } /* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */ if (time < SMIC_RETRY_TIMEOUT) { smic->smic_timeout -= time; if (smic->smic_timeout < 0) { start_error_recovery(smic, "smic timed out."); return SI_SM_CALL_WITH_DELAY; } } } flags = read_smic_flags(smic); if (flags & SMIC_FLAG_BSY) return SI_SM_CALL_WITH_DELAY; status = read_smic_status (smic); if (smic_debug & SMIC_DEBUG_STATES) printk(KERN_INFO "smic_event - state = %d, flags = 0x%02x," " status = 0x%02x\n", smic->state, flags, status); switch (smic->state) { case SMIC_IDLE: /* in IDLE we check for available messages */ if (flags & (SMIC_SMI | SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL)) { return SI_SM_ATTN; } return SI_SM_IDLE; case SMIC_START_OP: /* sanity check whether smic is really idle */ write_smic_control(smic, SMIC_CC_SMS_GET_STATUS); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_OP_OK; break; case SMIC_OP_OK: if (status != SMIC_SC_SMS_READY) { /* this should not happen */ start_error_recovery(smic, "state = SMIC_OP_OK," " status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } /* OK so far; smic is idle let us start ... */ write_smic_control(smic, SMIC_CC_SMS_WR_START); write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_WRITE_START; break; case SMIC_WRITE_START: if (status != SMIC_SC_SMS_WR_START) { start_error_recovery(smic, "state = SMIC_WRITE_START, " "status != SMIC_SC_SMS_WR_START"); return SI_SM_CALL_WITH_DELAY; } /* we must not issue WR_(NEXT|END) unless TX_DATA_READY is set */ if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { /* last byte */ write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_WRITE_NEXT: if (status != SMIC_SC_SMS_WR_NEXT) { start_error_recovery(smic, "state = SMIC_WRITE_NEXT, " "status != SMIC_SC_SMS_WR_NEXT"); return SI_SM_CALL_WITH_DELAY; } /* this is the same code as in SMIC_WRITE_START */ if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_WRITE_END: if (status != SMIC_SC_SMS_WR_END) { start_error_recovery (smic, "state = SMIC_WRITE_END, " "status != SMIC_SC_SMS_WR_END"); return SI_SM_CALL_WITH_DELAY; } /* data register holds an error code */ data = read_smic_data(smic); if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_INFO "SMIC_WRITE_END: data = %02x\n", data); } start_error_recovery(smic, "state = SMIC_WRITE_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else { smic->state = SMIC_WRITE2READ; } break; case SMIC_WRITE2READ: /* we must wait for RX_DATA_READY to be set before we can continue */ if (flags & SMIC_RX_DATA_READY) { write_smic_control(smic, SMIC_CC_SMS_RD_START); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_START; } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_START: if (status != SMIC_SC_SMS_RD_START) { start_error_recovery(smic, "state = SMIC_READ_START, " "status != SMIC_SC_SMS_RD_START"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_NEXT: switch (status) { /* smic tells us that this is the last byte to be read --> clean up */ case SMIC_SC_SMS_RD_END: read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_END); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_END; break; case SMIC_SC_SMS_RD_NEXT: if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else { return SI_SM_CALL_WITH_DELAY; } break; default: start_error_recovery( smic, "state = SMIC_READ_NEXT, " "status != SMIC_SC_SMS_RD_(NEXT|END)"); return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_END: if (status != SMIC_SC_SMS_READY) { start_error_recovery(smic, "state = SMIC_READ_END, " "status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } data = read_smic_data(smic); /* data register holds an error code */ if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_INFO "SMIC_READ_END: data = %02x\n", data); } start_error_recovery(smic, "state = SMIC_READ_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else { smic->state = SMIC_IDLE; return SI_SM_TRANSACTION_COMPLETE; } case SMIC_HOSED: init_smic_data(smic, smic->io); return SI_SM_HOSED; default: if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_WARNING "smic->state = %d\n", smic->state); start_error_recovery(smic, "state = UNKNOWN"); return SI_SM_CALL_WITH_DELAY; } } smic->smic_timeout = SMIC_RETRY_TIMEOUT; return SI_SM_CALL_WITHOUT_DELAY; }
/*==========la fonction main()=======*/ int main(void) { lcd_init_printf(); pololu_3pi_init(2000); play_mode(PLAY_CHECK); clear(); print("Hello!"); play("L16 ceg>c"); // start receiving data at 9600 baud serial_set_baud_rate(9600); serial_receive_ring(buffer, 100); int i=0; char dirct,chaine[4], comp='C',*recuper = NULL, *ok; long val, veri=0; char command; /* la boucle qui permet de recuperer la trame caractere par caractere */ while(1){ for(i=0;i<4;i++){ command = read_next_byte(); if (command) { chaine[i] = command; } } /*recuperation de la lettre recu dans la trame */ dirct = chaine[0]; /*recuperation du reste de la trame en chaine de caractere */ recuper = strchr(chaine,chaine[1]); /*conversion de cette chaine recuperer en entier (type long)*/ val = strtol(recuper, &ok,10); /* cette condition permet d'eviter l'execution de la meme trame plusieurs fois*/ if(dirct != comp || veri != val) { clear(); printf("%s",chaine); switch(dirct) { case 'A': avancer(val); break; case 'R': reculer(val); break; case 'D': droit(val); break; case 'G': gauche(val); break; case 'M': melodie(); break; default: set_motors(0,0); break; } comp = dirct; veri = val; } } return 0; }
static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) { unsigned char status; unsigned char state; status = read_status(kcs); if (kcs_debug & KCS_DEBUG_STATES) printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status); if (!check_ibf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; state = GET_STATUS_STATE(status); switch (kcs->state) { case KCS_IDLE: clear_obf(kcs, status); if (GET_STATUS_ATN(status)) return SI_SM_ATTN; else return SI_SM_IDLE; case KCS_START_OP: if (state != KCS_IDLE_STATE) { start_error_recovery(kcs, "State machine not idle at start"); break; } clear_obf(kcs, status); write_cmd(kcs, KCS_WRITE_START); kcs->state = KCS_WAIT_WRITE_START; break; case KCS_WAIT_WRITE_START: if (state != KCS_WRITE_STATE) { start_error_recovery( kcs, "Not in write state at write start"); break; } read_data(kcs); if (kcs->write_count == 1) { write_cmd(kcs, KCS_WRITE_END); kcs->state = KCS_WAIT_WRITE_END; } else { write_next_byte(kcs); kcs->state = KCS_WAIT_WRITE; } break; case KCS_WAIT_WRITE: if (state != KCS_WRITE_STATE) { start_error_recovery(kcs, "Not in write state for write"); break; } clear_obf(kcs, status); if (kcs->write_count == 1) { write_cmd(kcs, KCS_WRITE_END); kcs->state = KCS_WAIT_WRITE_END; } else { write_next_byte(kcs); } break; case KCS_WAIT_WRITE_END: if (state != KCS_WRITE_STATE) { start_error_recovery(kcs, "Not in write state" " for write end"); break; } clear_obf(kcs, status); write_next_byte(kcs); kcs->state = KCS_WAIT_READ; break; case KCS_WAIT_READ: if ((state != KCS_READ_STATE) && (state != KCS_IDLE_STATE)) { start_error_recovery( kcs, "Not in read or idle in read state"); break; } if (state == KCS_READ_STATE) { if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; read_next_byte(kcs); } else { clear_obf(kcs, status); kcs->orig_write_count = 0; kcs->state = KCS_IDLE; return SI_SM_TRANSACTION_COMPLETE; } break; case KCS_ERROR0: clear_obf(kcs, status); status = read_status(kcs); if (GET_STATUS_OBF(status)) if (time_before(jiffies, kcs->error0_timeout)) return SI_SM_CALL_WITH_TICK_DELAY; write_cmd(kcs, KCS_GET_STATUS_ABORT); kcs->state = KCS_ERROR1; break; case KCS_ERROR1: clear_obf(kcs, status); write_data(kcs, 0); kcs->state = KCS_ERROR2; break; case KCS_ERROR2: if (state != KCS_READ_STATE) { start_error_recovery(kcs, "Not in read state for error2"); break; } if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); write_data(kcs, KCS_READ_BYTE); kcs->state = KCS_ERROR3; break; case KCS_ERROR3: if (state != KCS_IDLE_STATE) { start_error_recovery(kcs, "Not in idle state for error3"); break; } if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); if (kcs->orig_write_count) { restart_kcs_transaction(kcs); } else { kcs->state = KCS_IDLE; return SI_SM_TRANSACTION_COMPLETE; } break; case KCS_HOSED: break; } if (kcs->state == KCS_HOSED) { init_kcs_data(kcs, kcs->io); return SI_SM_HOSED; } return SI_SM_CALL_WITHOUT_DELAY; }
int main() { pololu_3pi_init(2000); play_mode(PLAY_CHECK); clear(); // start receiving data at 115.2 kbaud serial_set_baud_rate(115200); serial_receive_ring(buffer, 100); while(1) { // wait for a command char command = read_next_byte(); // The list of commands is below: add your own simply by // choosing a command byte and introducing another case // statement. switch(command) { case (char)0x00: // silent error - probable master resetting break; case (char)0x81: send_signature(); break; case (char)0x86: send_raw_sensor_values(); break; case (char)0x87: send_calibrated_sensor_values(1); break; case (char)0xB0: send_trimpot(); break; case (char)0xB1: send_battery_millivolts(); break; case (char)0xB3: do_play(); break; case (char)0xB4: calibrate_line_sensors(IR_EMITTERS_ON); send_calibrated_sensor_values(1); break; case (char)0xB5: line_sensors_reset_calibration(); break; case (char)0xB6: send_line_position(); break; case (char)0xB7: do_clear(); break; case (char)0xB8: do_print(); break; case (char)0xB9: do_lcd_goto_xy(); break; case (char)0xBA: auto_calibrate(); break; case (char)0xBB: set_pid(); break; case (char)0xBC: stop_pid(); break; case (char)0xC1: m1_forward(); break; case (char)0xC2: m1_backward(); break; case (char)0xC5: m2_forward(); break; case (char)0xC6: m2_backward(); break; default: clear(); print("Bad cmd"); lcd_goto_xy(0,1); print_hex_byte(command); play("o7l16crc"); continue; // bad command } } }
void length_esc_fn(struct state *s) { debug(__func__, s); s->next_packet_size = read_next_byte(s); s->next = read_data_fn; }