void initRunMode() { #if ENABLE_SLOTS setupSlots(); #endif mcu_clearTimer(); //TODO: Figure out that dest = destorig shit dest = destorig; #if !(ENABLE_SLOTS) queryReplyCRC = crc16_ccitt(&queryReply[0],2); queryReply[3] = (unsigned char) queryReplyCRC; queryReply[2] = (unsigned char) mcu_swapBytes(queryReplyCRC); #endif #if SENSOR_DATA_IN_ID // this branch is for sensor data in the id ackReply[2] = SENSOR_DATA_TYPE_ID; state = STATE_READ_SENSOR; timeToSample++; #else ackReplyCRC = crc16_ccitt(&ackReply[0], 14); ackReply[15] = (unsigned char) ackReplyCRC; ackReply[14] = (unsigned char) mcu_swapBytes(ackReplyCRC); #endif #if ENABLE_SESSIONS initialize_sessions(); #endif state = STATE_READY; }
int main(void) { //*******************************Timer setup********************************** WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer P1SEL = 0; P2SEL = 0; P1IE = 0; P1IFG = 0; P2IFG = 0; DRIVE_ALL_PINS // set pin directions correctly and outputs to low. // Check power on bootup, decide to receive or sleep. if(!is_power_good()) sleep(); RECEIVE_CLOCK; #if DEBUG_PINS_ENABLED #if USE_2618 DEBUG_PIN5_LOW; #endif #endif #if ENABLE_SLOTS // setup int epc epc = ackReply[2]<<8; epc |= ackReply[3]; // calculate RN16_1 table for (Q = 0; Q < 16; Q++) { rn16 = epc^Q; lfsr(); if (Q > 8) { RN16[(Q<<1)-9] = __swap_bytes(rn16); RN16[(Q<<1)-8] = rn16; } else { RN16[Q] = rn16; } } #endif TACTL = 0; asm("MOV #0000h, R9"); // dest = destorig; #if READ_SENSOR init_sensor(); #endif #if !(ENABLE_SLOTS) queryReplyCRC = crc16_ccitt(&queryReply[0],2); queryReply[3] = (unsigned char)queryReplyCRC; queryReply[2] = (unsigned char)__swap_bytes(queryReplyCRC); #endif #if SENSOR_DATA_IN_ID // this branch is for sensor data in the id ackReply[2] = SENSOR_DATA_TYPE_ID; state = STATE_READ_SENSOR; timeToSample++; #else ackReplyCRC = crc16_ccitt(&ackReply[0], 14); ackReply[15] = (unsigned char)ackReplyCRC; ackReply[14] = (unsigned char)__swap_bytes(ackReplyCRC); #endif #if ENABLE_SESSIONS initialize_sessions(); #endif state = STATE_READY; setup_to_receive(); while (1) { // TIMEOUT! reset timer if (TAR > 0x256 || delimiterNotFound) // was 0x1000 { if(!is_power_good()) { sleep(); } #if SENSOR_DATA_IN_ID // this branch is for sensor data in the id if ( timeToSample++ == 10 ) { state = STATE_READ_SENSOR; timeToSample = 0; } #elif SENSOR_DATA_IN_READ_COMMAND if ( timeToSample++ == 10 ) { state = STATE_READ_SENSOR; timeToSample = 0; } #else #if !(ENABLE_READS) if(!is_power_good()) sleep(); #endif inInventoryRound = 0; state = STATE_READY; #endif #if ENABLE_SESSIONS handle_session_timeout(); #endif #if ENABLE_SLOTS if (shift < 4) shift += 1; else shift = 0; #endif setup_to_receive(); } switch (state) { case STATE_READY: { inInventoryRound = 0; ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// // @ short distance has slight impact on performance else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command ////////////////////////////////////////////////////////////////////// // got >= 22 bits, and it's not the beginning of a select. just reset. ////////////////////////////////////////////////////////////////////// else if ( bits >= MAX_NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) != 0xA0 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } break; } case STATE_ARBITRATE: { ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // got >= 22 bits, and it's not the beginning of a select. just reset. ////////////////////////////////////////////////////////////////////// //else if ( bits >= NUM_QUERY_BITS ) else if ( bits >= MAX_NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) != 0xA0 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // this state handles query, queryrep, queryadjust, and select commands. ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { handle_queryrep(STATE_REPLY); delimiterNotFound = 1; } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYADJ_BITS && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { handle_queryadjust(STATE_REPLY); setup_to_receive(); } // queryadjust command ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// // @ short distance has slight impact on performance else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command break; } case STATE_REPLY: { // this state handles query, query adjust, ack, and select commands /////////////////////////////////////////////////////////////////////// // process the ACK command /////////////////////////////////////////////////////////////////////// if ( bits == NUM_ACK_BITS && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) { #if ENABLE_READS handle_ack(STATE_ACKNOWLEDGED); setup_to_receive(); #elif SENSOR_DATA_IN_ID handle_ack(STATE_ACKNOWLEDGED); delimiterNotFound = 1; // reset #else // this branch for hardcoded query/acks handle_ack(STATE_ACKNOWLEDGED); //delimiterNotFound = 1; // reset setup_to_receive(); #endif } ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { // i'm supposed to stay in state_reply when I get this, but if I'm // running close to 1.8v then I really need to reset and get in the // sleep, which puts me back into state_arbitrate. this is complete // a violation of the protocol, but it sure does make everything // work better. - polly 8/9/2008 handle_query(STATE_REPLY); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { do_nothing(); state = STATE_ARBITRATE; setup_to_receive(); } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYADJ_BITS && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { handle_queryadjust(STATE_REPLY); delimiterNotFound = 1; } // queryadjust command ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command else if ( bits >= MAX_NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) != 0xA0 ) && ( ( cmd[0] & 0xF0 ) != 0x80 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } break; } case STATE_ACKNOWLEDGED: { // responds to query, ack, request_rn cmds // takes action on queryrep, queryadjust, and select cmds ///////////////////////////////////////////////////////////////////// // process the REQUEST_RN command ////////////////////////////////////////////////////////////////////// if ( bits >= NUM_REQRN_BITS && ( cmd[0] == 0xC1 ) ) { #if 1 handle_request_rn(STATE_OPEN); setup_to_receive(); #else handle_request_rn(STATE_READY); delimiterNotFound = 1; #endif } #if 1 ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); delimiterNotFound = 1; } /////////////////////////////////////////////////////////////////////// // process the ACK command /////////////////////////////////////////////////////////////////////// // this code doesn't seem to get exercised in the real world. if i ever // ran into a reader that generated an ack in an acknowledged state, // this code might need some work. //else if ( bits == 20 && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) else if ( bits == NUM_ACK_BITS && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) { handle_ack(STATE_ACKNOWLEDGED); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { // in the acknowledged state, rfid chips don't respond to queryrep // commands do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYADJ_BITS && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // queryadjust command ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command ////////////////////////////////////////////////////////////////////// // process the NAK command ////////////////////////////////////////////////////////////////////// else if ( bits >= 10 && ( cmd[0] == 0xC0 ) ) { do_nothing(); state = STATE_ARBITRATE; delimiterNotFound = 1; } ////////////////////////////////////////////////////////////////////// // process the READ command ////////////////////////////////////////////////////////////////////// // warning: won't work for read addrs > 127d if ( bits == NUM_READ_BITS && ( cmd[0] == 0xC2 ) ) { handle_read(STATE_ARBITRATE); state = STATE_ARBITRATE; delimiterNotFound = 1 ; } // FIXME: need write, kill, lock, blockwrite, blockerase ////////////////////////////////////////////////////////////////////// // process the ACCESS command ////////////////////////////////////////////////////////////////////// if ( bits >= 56 && ( cmd[0] == 0xC6 ) ) { do_nothing(); state = STATE_ARBITRATE; delimiterNotFound = 1 ; } #endif else if ( bits >= MAX_NUM_READ_BITS ) { state = STATE_ARBITRATE; delimiterNotFound = 1 ; } #if 0 // kills performance ... else if ( bits >= 44 ) { do_nothing(); state = STATE_ARBITRATE; delimiterNotFound = 1; } #endif break; } case STATE_OPEN: { // responds to query, ack, req_rn, read, write, kill, access, // blockwrite, and blockerase cmds // processes queryrep, queryadjust, select cmds ////////////////////////////////////////////////////////////////////// // process the READ command ////////////////////////////////////////////////////////////////////// // warning: won't work for read addrs > 127d if ( bits == NUM_READ_BITS && ( cmd[0] == 0xC2 ) ) { handle_read(STATE_OPEN); // note: setup_to_receive() et al handled in handle_read } ////////////////////////////////////////////////////////////////////// // process the REQUEST_RN command ////////////////////////////////////////////////////////////////////// else if ( bits >= NUM_REQRN_BITS && ( cmd[0] == 0xC1 ) ) { handle_request_rn(STATE_OPEN); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); delimiterNotFound = 1; } ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { do_nothing(); state = STATE_READY; setup_to_receive(); } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == 9 && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // queryadjust command /////////////////////////////////////////////////////////////////////// // process the ACK command /////////////////////////////////////////////////////////////////////// else if ( bits == NUM_ACK_BITS && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) { handle_ack(STATE_OPEN); delimiterNotFound = 1; } ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command ////////////////////////////////////////////////////////////////////// // process the NAK command ////////////////////////////////////////////////////////////////////// else if ( bits >= 10 && ( cmd[0] == 0xC0 ) ) { handle_nak(STATE_ARBITRATE); delimiterNotFound = 1; } break; } case STATE_READ_SENSOR: { #if SENSOR_DATA_IN_READ_COMMAND read_sensor(&readReply[0]); // crc is computed in the read state RECEIVE_CLOCK; state = STATE_READY; delimiterNotFound = 1; // reset #elif SENSOR_DATA_IN_ID read_sensor(&ackReply[3]); RECEIVE_CLOCK; ackReplyCRC = crc16_ccitt(&ackReply[0], 14); ackReply[15] = (unsigned char)ackReplyCRC; ackReply[14] = (unsigned char)__swap_bytes(ackReplyCRC); state = STATE_READY; delimiterNotFound = 1; // reset #endif break; } // end case } // end switch } // while loop }