short read_sensor(unsigned char volatile *target) { static short cntr = 0; if(!is_power_good()) sleep(); P1OUT &= ~RX_EN_PIN; // turn off comparator // set up watchdog interval timer to sleep during settle time WDTCTL = WDT_MDLY_0_5; IE1 |= WDTIE; // a little time for regulator to stabilize active mode current AND // filter caps to settle. for WDT_MDLY_0_5 * 48, this is 10 ms DEBUG_PIN5_HIGH; for ( int k = 0 ; k < 48 ; k++ ) { _BIS_SR(LPM1_bits+GIE); } DEBUG_PIN5_LOW; IE1 &= ~WDTIE; if ( !is_power_good() ) { DEBUG_PIN5_HIGH; DEBUG_PIN5_LOW; return 0; } //#define DELTA 0x05 #define DELTA 0x0B //#define DELTA 0x14 #define HIBYTE 0x01 //#define HIBYTE 0x02 *(target) = HIBYTE; *(target + 1 ) = 0xF8; *(target + 2) = HIBYTE; *(target + 3 ) = 0xF3; *(target + 4) = HIBYTE; *(target + 5 ) = 0xCA; if ( cntr++ == 2 ) { *(target + 1 ) = 0xF8 - DELTA; *(target + 3 ) = 0xF3 - DELTA; *(target + 5 ) = 0xCA + DELTA; cntr = 0; } return 1; }
void read_sensor(unsigned char volatile *target) { #if MONITOR_DEBUG_ON // for monitor - set READ_SENSOR_STATE debug line - 00101 - 5 P1OUT |= wisp_debug_1; P1OUT &= ~wisp_debug_1; P2OUT &= ~wisp_debug_2; P3OUT = 0x21; #endif // slow down clock BCSCTL1 = XT2OFF + RSEL1; // select internal resistor (still has effect when DCOR=1) DCOCTL = DCO1+DCO0; // set DCO step. if(!is_power_good()) sleep(); // already off. Only needs to be done when READ has set P1OUT &= ~RX_EN_PIN; // turn off comparator // Set up ADC for internal temperature sensor ADC10CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4 ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON; // a little time for regulator to stabilize active mode current AND // filter caps to settle. for (int i = 0; i < 50; i++); // start conversion unsigned int k = 0; ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start while (ADC10CTL1 & ADC10BUSY); // wait while ADC finished work *(target + k + 1 ) = (ADC10MEM & 0xff); // grab msb bits and store it *(target + k) = (ADC10MEM & 0x0300) >> 8; // Power off sensor and adc ADC10CTL0 &= ~ENC; ADC10CTL1 = 0; // turn adc off ADC10CTL0 = 0; // turn adc off // Store sensor read count sensor_counter++; ackReply[10] = (sensor_counter & 0x00ff); // grab msb bits and store it ackReply[9] = (sensor_counter & 0xff00) >> 8; return; }
inline void sleep() { P1OUT &= ~RX_EN_PIN; // enable port interrupt for voltage supervisor P2IES = 0; P2IFG = 0; P2IE |= VOLTAGE_SV_PIN; P1IE = 0; P1IFG = 0; TACTL = 0; _BIC_SR(GIE); // temporarily disable GIE so we can sleep and enable interrupts // at the same time P2IE |= VOLTAGE_SV_PIN; // Enable Port 2 interrupt if (is_power_good()) P2IFG = VOLTAGE_SV_PIN; _BIS_SR(LPM4_bits | GIE); return; }
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 }
short read_sensor(unsigned char volatile *target) { unsigned short enough_power; if(!is_power_good()) sleep(); P1OUT &= ~RX_EN_PIN; // turn off comparator // slow down clock BCSCTL1 = XT2OFF + RSEL3; DCOCTL = DCO2 + DCO1 + DCO0; // Power sensor, enable analog in ADC10AE0 |= (X_INCH + Y_INCH + Z_INCH); SET_ACCEL_ENABLE_DIR; TURN_ON_ACCEL_ENABLE; // set up watchdog interval timer to sleep during settle time WDTCTL = WDT_MDLY_0_5; IE1 |= WDTIE; P1IE = 0; P2IE = 0; // a little time for regulator to stabilize active mode current AND // filter caps to settle. for WDT_MDLY_0_5 * 46, this is slightly less than 10 ms for ( int k = 0 ; k < 46 ; k++ ) { #if CHECK_FOR_GOOD_VOLTAGE //DEBUG_PIN5_HIGH; if ( k == 1 ) { //DEBUG_PIN5_HIGH; enough_power = is_power_good(); //DEBUG_PIN5_LOW; } #endif _BIS_SR(LPM1_bits+GIE); //DEBUG_PIN5_LOW; } IE1 &= ~WDTIE; #if CHECK_FOR_GOOD_VOLTAGE // make sure there's enough voltage to generate good samples. samples // get seriously wacky at ~1.8V, especially the already-noisy Z channel. // see the accel data sheet for details. if ( ! enough_power ) { // low voltage -- don't sample //DEBUG_PIN5_HIGH; CLEAR_ACCEL_ENABLE_DIR; TURN_OFF_ACCEL_ENABLE; ADC10AE0 &= ~(X_INCH + Y_INCH + Z_INCH); ADC10CTL0 &= ~ENC; ADC10CTL1 = 0; // turn adc off ADC10CTL0 = 0; // turn adc off //DEBUG_PIN5_LOW; return 0; } #endif // grab data for (int i = (DATA_LENGTH_IN_WORDS-1); i >= 0; i--) { ADC10CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE; if (i == 2) // sample Z channel first, because it is the most noisy ADC10CTL1 = ADC10DIV_4 + ADC10SSEL_0 + SHS_0 + CONSEQ_0 + Z_INCH; else if (i == 1) ADC10CTL1 = ADC10DIV_4 + ADC10SSEL_0 + SHS_0 + CONSEQ_0 + Y_INCH; else ADC10CTL1 = ADC10DIV_4 + ADC10SSEL_0 + SHS_0 + CONSEQ_0 + X_INCH; ADC10CTL0 |= ENC; ADC10CTL0 |= ADC10SC; LPM4; unsigned int k; if ( i == 0 ) k = 0; else if ( i == 1 ) k = 2; else k = 4; // grab sample and write it to ram *(target + k + 1 ) = (ADC10MEM & 0xff); *(target + k) = (ADC10MEM & 0x0300) >> 8; #if DEBUG_BAD_SAMPLES if ( i == 0 ) x = ADC10MEM; else if ( i == 1 ) y = ADC10MEM; else z = ADC10MEM; #endif k += 2; } #if DEBUG_BAD_SAMPLES //#define THRES 50 // about 5% ... never fires //#define THRES 30 // about 3% ... fires very rarely //#define THRES 20 #define THRES 10 unsigned short fired = 0; diff = ((x - lastx) > 0) ? (x - lastx) : (lastx -x); if ( lastx != 0xffff && diff > THRES ) { fired = 1; } diff = ((y - lasty) > 0) ? (y - lasty) : (lasty -y); if ( lasty != 0xffff && diff > THRES ) { fired = 1; } diff = ((z - lastz) > 0) ? (z- lastz) : (lastz -z); if ( lastz != 0xffff && diff > THRES ) { fired = 1; } lastx = x; lasty = y ; lastz = z; if ( fired ) { DEBUG_PIN5_HIGH; DEBUG_PIN5_LOW; } #endif // Power off sensor and adc CLEAR_ACCEL_ENABLE_DIR; TURN_OFF_ACCEL_ENABLE; ADC10AE0 &= ~(X_INCH + Y_INCH + Z_INCH); ADC10CTL0 &= ~ENC; ADC10CTL1 = 0; // turn adc off ADC10CTL0 = 0; // turn adc off return 1; }
void read_sensor(unsigned char volatile *target) { // turn off comparator P1OUT &= ~RX_EN_PIN; // slow down clock BCSCTL1 = XT2OFF + RSEL1; // select internal resistor (still has effect when // DCOR=1) DCOCTL = DCO1+DCO0; // set DCO step. if(!is_power_good()) sleep(); // Clear out any lingering voltage on the accelerometer outputs P6SEL = 0; P6OUT &= ~(ACCEL_X | ACCEL_Y | ACCEL_Z); P6DIR |= ACCEL_X | ACCEL_Y | ACCEL_Z; P6DIR &= ~(ACCEL_X | ACCEL_Y | ACCEL_Z); P1DIR |= ACCEL_POWER; P1OUT |= ACCEL_POWER; P6SEL |= ACCEL_X | ACCEL_Y | ACCEL_Z; // a little time for regulator to stabilize active mode current AND // filter caps to settle. for(int i = 0; i < 225; i++); RECEIVE_CLOCK; // GRAB DATA ADC12CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC12CTL0 = ADC12ON + SHT0_1; // Turn on and set up ADC12 ADC12CTL1 = SHP; // Use sampling timer ADC12MCTL0 = INCH_ACCEL_X + SREF_0; // Vr+=AVcc=Vreg=1.8V // ADC12CTL1 = + ADC12SSEL_0 + SHS_0 + CONSEQ_0; ADC12CTL0 |= ENC; ADC12CTL0 |= ADC12SC; while (ADC12CTL1 & ADC12BUSY); // wait while ADC finished work ackReply[4] = (ADC12MEM0 & 0xff); ackReply[3] = (ADC12MEM0 & 0x0f00) >> 8; // grab msb bits and store it // GRAB DATA ADC12CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC12CTL0 = ADC12ON + SHT0_1; ADC12CTL1 = SHP; // Use sampling timer ADC12MCTL0 = INCH_ACCEL_Y + SREF_0; ADC12CTL0 |= ENC; ADC12CTL0 |= ADC12SC; while (ADC12CTL1 & ADC12BUSY); // wait while ADC finished work ackReply[6] = (ADC12MEM0 & 0xff); ackReply[5] = (ADC12MEM0 & 0x0f00) >> 8; // grab msb bits and store it // GRAB DATA ADC12CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC12CTL0 = ADC12ON + SHT0_1; ADC12CTL1 = SHP; ADC12MCTL0 = INCH_ACCEL_Z + SREF_0; ADC12CTL0 |= ENC; ADC12CTL0 |= ADC12SC; while (ADC12CTL1 & ADC12BUSY); // wait while ADC finished work ackReply[8] = (ADC12MEM0 & 0xff); ackReply[7] = (ADC12MEM0 & 0x0f00) >> 8; // grab msb bits and store it // Power off sensor and adc P1DIR &= ~ACCEL_POWER; P1OUT &= ~ACCEL_POWER; ADC12CTL0 &= ~ENC; ADC12CTL1 = 0; // turn adc off ADC12CTL0 = 0; // turn adc off // Store sensor read count sensor_counter++; ackReply[10] = (sensor_counter & 0x00ff); ackReply[9] = (sensor_counter & 0xff00) >> 8; // grab msb bits and store it // turn on comparator P1OUT |= RX_EN_PIN; }
void read_sensor(unsigned char volatile *target) { // turn off comparator P1OUT &= ~RX_EN_PIN; // slow down clock BCSCTL1 = XT2OFF + RSEL1; // select internal resistor (still has effect when DCOR=1) DCOCTL = DCO1+DCO0; // set DCO step. if(!is_power_good()) sleep(); // Clear out any lingering voltage on the accelerometer outputs ADC10AE0 = 0; #if(WISP_VERSION == BLUE_WISP || WISP_VERSION == PURPLE_WISP) P2OUT &= ~(ACCEL_X | ACCEL_Y | ACCEL_Z); P2DIR |= ACCEL_X | ACCEL_Y | ACCEL_Z; P2DIR &= ~(ACCEL_X | ACCEL_Y | ACCEL_Z); #elif(WISP_VERSION == RED_WISP) P1OUT &= ~(ACCEL_X | ACCEL_Y | ACCEL_Z); P1DIR |= ACCEL_X | ACCEL_Y | ACCEL_Z; P1DIR &= ~(ACCEL_X | ACCEL_Y | ACCEL_Z); #endif P1DIR |= ACCEL_POWER; P1OUT |= ACCEL_POWER; ADC10AE0 |= ACCEL_X | ACCEL_Y | ACCEL_Z; // a little time for regulator to stabilize active mode current AND // filter caps to settle. for(int i = 0; i < 225; i++); RECEIVE_CLOCK; // GRAB DATA ADC10CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC10CTL0 = SREF_0 + ADC10SHT_1 + ADC10ON; ADC10CTL1 = ADC10DIV_2 + ADC10SSEL_0 + SHS_0 + CONSEQ_0 + INCH_ACCEL_X; ADC10CTL0 |= ENC; ADC10CTL0 |= ADC10SC; while (ADC10CTL1 & ADC10BUSY); // wait while ADC finished work *(target+1) = (ADC10MEM & 0xff); // grab msb bits and store it *(target) = (ADC10MEM & 0x0300) >> 8; // GRAB DATA ADC10CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC10CTL0 = SREF_0 + ADC10SHT_1 + ADC10ON; ADC10CTL1 = ADC10DIV_2 + ADC10SSEL_0 + SHS_0 + CONSEQ_0 + INCH_ACCEL_Y; ADC10CTL0 |= ENC; ADC10CTL0 |= ADC10SC; while (ADC10CTL1 & ADC10BUSY); // wait while ADC finished work *(target+3) = (ADC10MEM & 0xff); // grab msb bits and store it *(target+2) = (ADC10MEM & 0x0300) >> 8; // GRAB DATA ADC10CTL0 &= ~ENC; // make sure this is off otherwise settings are locked. ADC10CTL0 = SREF_0 + ADC10SHT_1 + ADC10ON; ADC10CTL1 = ADC10DIV_2 + ADC10SSEL_0 + SHS_0 + CONSEQ_0 + INCH_ACCEL_Z; ADC10CTL0 |= ENC; ADC10CTL0 |= ADC10SC; while (ADC10CTL1 & ADC10BUSY); // wait while ADC finished work *(target+5) = (ADC10MEM & 0xff); // grab msb bits and store it *(target+4) = (ADC10MEM & 0x0300) >> 8; // Power off sensor and adc P1DIR &= ~ACCEL_POWER; P1OUT &= ~ACCEL_POWER; ADC10CTL0 &= ~ENC; ADC10CTL1 = 0; // turn adc off ADC10CTL0 = 0; // turn adc off // Store sensor read count sensor_counter++; *(target+7) = (sensor_counter & 0x00ff); // grab msb bits and store it *(target+6) = (sensor_counter & 0xff00) >> 8; // turn on comparator P1OUT |= RX_EN_PIN; }