Esempio n. 1
0
inline void crc16_ccitt_readReply(unsigned int numDataBytes)
{

  // shift everything over by 1 to accomodate leading "0" bit.
  // first, grab address of beginning of array
  readReply[numDataBytes + 2] = 0; // clear out this spot for the loner bit of
                                   // handle
  readReply[numDataBytes + 4] = 0; // clear out this spot for the loner bit of
                                   // crc
  bits = (unsigned short) &readReply[0];
  // shift all bytes and later use only data + handle
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  asm("RRC.b @R5+");
  // store loner bit in array[numDataBytes+2] position
  asm("RRC.b @R5+");
  // make first bit 0
  readReply[0] &= 0x7f;

  // compute crc on data + handle bytes
  readReplyCRC = crc16_ccitt(&readReply[0], numDataBytes + 2);
  readReply[numDataBytes + 4] = readReply[numDataBytes + 2];
  // XOR the MSB of CRC with loner bit.
  readReply[numDataBytes + 4] ^= __swap_bytes(readReplyCRC); // XOR happens with
                                                             // MSB of lower
                                                             // nibble
  // Just take the resulting bit, not the whole byte
  readReply[numDataBytes + 4] &= 0x80;

  unsigned short mask = __swap_bytes(readReply[numDataBytes + 4]);
  mask >>= 3;
  mask |= (mask >> 7);
  mask ^= 0x1020;
  mask >>= 1;  // this is because the loner bit pushes the CRC to the left by 1
  // but we don't shift the crc because it should get pushed out by 1 anyway
  readReplyCRC ^= mask;

  readReply[numDataBytes + 3] = (unsigned char) readReplyCRC;
  readReply[numDataBytes + 2] |= (unsigned char) (__swap_bytes(readReplyCRC) &
          0x7F);
}
Esempio n. 2
0
int cfg_blob_copy( blob_t *from, void *to ) {
	size_t len = from->options & BLOB_LENGTH_MASK;
	
	if( to != NULL ) {
		if( is_host_endian( from ) ||
			( ( from->options & BLOB_LENGTH_MASK ) == 1 )
		)
			__copy( from, to );
		else {
			__copy( from, to );
			if( from->options & BLOB_ARRAY )
				switch( len ) {
					case 2:
						for( char *limit = to + 2 * from->array.length, *cyc = to;
							cyc < limit;
							cyc += 2
						)
							bswap_16( *( ( uint16_t* ) cyc ) );
						break;
					case 4:
						for( char *limit = to + 4 * from->array.length, *cyc = to;
							cyc < limit;
							cyc += 4
						)
							bswap_32( *( ( uint32_t* ) cyc ) );
						break;
					default:
						for( char *limit = to + len * from->array.length, *cyc = to;
							cyc < limit;
							cyc += len
						)
							__swap_bytes( cyc, len );
				}
			else
				switch( len ) {
					case 2:
						bswap_16( *( ( uint16_t* ) to ) );
						break;
					case 4:
						bswap_32( *( ( uint32_t* ) to ) );
						break;
					default:
						__swap_bytes( to, len );
				};
		}
	}

	if( from->options & BLOB_ARRAY )
		return ( len * from->array.length )
	else
		return len;
}
Esempio n. 3
0
/**
 * For talking to the MCP4822 DAC
 */
void DAC_updateVoltage(uint16_t channel, uint16_t value) {

	// Validate channel selection
	if(channel <= 1) {

		// Cap value to 12 bits only
		if(value > 0x0FFF) {
			value = 0x0FFF;
		}

		char txBuf[2];

		uint16_t cmd = 0x3000 | (value & 0x0FFF);
		if(channel) cmd |= 0x8000;

		txBuf[1] = cmd & 0x00FF;
		txBuf[0] = __swap_bytes(cmd) & 0x00FF;

		CLR_BITS(SPI_PORT(OUT),SSEL | nLDAC); // CS~ falling edge, hold nLDAC low
		SPI_send(txBuf, 2);
		SET_BITS(SPI_PORT(OUT),SSEL); // CS~ Rising edge. Because nLDAC is low, DAC output changes on rising CS~ edge.


	}
}
Esempio n. 4
0
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 /// @author NIVIS LLC, Ion Ticus
 /// @brief  Check if message destination is in current subnet 
 /// @return 1 if message remains in subnet, 0 if not 
 /// @remarks
 ///      Access level: Interrupt level\n
 ///      Context: BBR only
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 uint8 NLME_IsInSameSubnet( uint16 p_unDestAddr )
 {
       p_unDestAddr = __swap_bytes(p_unDestAddr);
       
       for ( uint8  ucIdx = 0; ucIdx < g_stNlme.m_ucToEthRoutesNo; ucIdx ++ )
       {
           if( g_stNlme.m_aToEthRoutes[ucIdx] == p_unDestAddr )
               return !g_stNlme.m_ucDefaultIsDLL;
       }
       return g_stNlme.m_ucDefaultIsDLL;
 }
Esempio n. 5
0
void handle_read(volatile short nextState)
{

#if SENSOR_DATA_IN_READ_COMMAND

  //P1OUT &= ~RX_EN_PIN;   // turn off comparator
  TACCTL1 &= ~CCIE;
  TAR = 0;

  readReply[DATA_LENGTH_IN_BYTES] = queryReply[0]; // remember to restore
                                                   // correct RN before doing
                                                   // crc()
  readReply[DATA_LENGTH_IN_BYTES+1] = queryReply[1]; // because crc() will shift
                                                     // bits to add
  crc16_ccitt_readReply(DATA_LENGTH_IN_BYTES);    // leading "0" bit.

  // DATA_LENGTH_IN_BYTES*8 bits for data + 16 bits for the handle + 16 bits for
  // the CRC + leading 0 + add one to number of bits for xmit code
  sendToReader(&readReply[0], ((DATA_LENGTH_IN_BYTES*8)+16+16+1+1));
  state = nextState;
  delimiterNotFound = 1;

#elif SIMPLE_READ_COMMAND

  //P1OUT &= ~RX_EN_PIN;   // turn off comparator
  TACCTL1 &= ~CCIE;
  TAR = 0;

#define USE_COUNTER 1
#if USE_COUNTER
  readReply[0] = __swap_bytes(read_counter);
  readReply[1] = read_counter;
#else
  readReply[0] = 0x03;
  readReply[1] = 0x04;
#endif
  readReply[2] = queryReply[0]; // remember to restore correct RN before doing
                                // crc()
  readReply[3] = queryReply[1];        // because crc() will shift bits to add
  crc16_ccitt_readReply(2);    // leading "0" bit.

  // after that sends tagResponse
  // 16 bits for data + 16 bits for the handle + 16 bits for the CRC + leading 0
  // + add one to number of bits for seong's xmit code
  sendToReader(&readReply[0], 50);
  state = nextState;
  delimiterNotFound = 1; // reset
#endif
}
Esempio n. 6
0
/**
 * Use the hardware CRC-CCITT module of the MSP430 to generate a CRC as
 *  per ISO/IEC 13239 CRC16 specification used in ISO 15693. Generating
 *  polynomial is 0x8408, preset value is 0xFFFF.
 *
 *  CRC is appended to end of transmitCommand array.
 *
 * @author Aaron Parks
 */
unsigned int hw_crc_ccitt(unsigned char* transmitCommand, unsigned int number_of_bytes) {
	// Preset CRC result as per ISO/IEC 13239
	CRCINIRES = 0xFFFF;

	// Iterate over transmitCommand array
	unsigned int crc_i;
	for(crc_i=0; crc_i <number_of_bytes; crc_i++)
	{
		// Load next byte into LSB of data input register
		// TODO: Can this be done faster word-wise?
		CRCDI_L = transmitCommand[crc_i];
	}

	CRCINIRES = ~CRCINIRES; // Invert bits of result

	// Store result from bit-order-reversed version of CRCRES
	transmitCommand[number_of_bytes] = CRCRESR & 0x00FF;
	transmitCommand[number_of_bytes + 1] = __swap_bytes(CRCRESR) & 0x00FF;

	return 1;
}
Esempio n. 7
0
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
}
//-----------------------------------------------------------------------------------------
//	BQ27421_GetAverageCurrent
//-----------------------------------------------------------------------------------------
//	Diese Funktion liest den aktuellen (über 1 Sekunde) gemittelten Strom in mA
//-----------------------------------------------------------------------------------------
int BQ27421_GetAverageCurrent(void)
{
   int iRetValue = 0;
   BQ27421_READ_REG(BQ272421_I2C_ADR, 0x10, &iRetValue, 2);
   return __swap_bytes(iRetValue);
}
//-----------------------------------------------------------------------------------------
//	BQ27421_GetAkkuSpannung
//-----------------------------------------------------------------------------------------
//	Diese Funktion liest die Akku-Spannung aus und gibt diese in mV zurück
//-----------------------------------------------------------------------------------------
int BQ27421_GetAkkuSpannung(void)
{
   WORD wRetValue;
   BQ27421_READ_REG(BQ272421_I2C_ADR, 0x04, &wRetValue, 2);
	return __swap_bytes(wRetValue);
}
Esempio n. 10
0
void handle_query(volatile short nextState)
{
  TAR = 0;
#if (!ENABLE_SLOTS)  && (!ENABLE_SESSIONS)
    while ( TAR < 90 ); // if bit test is 22
  //P1OUT &= ~RX_EN_PIN;   // turn off comparator
  TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
  TAR = 0;
#elif (!ENABLE_SLOTS) && ENABLE_SESSIONS
  while ( TAR < 160 ); // if bit test is 22
  //P1OUT &= ~RX_EN_PIN;   // turn off comparator
  TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
  TAR = 0;
#else
  //P1OUT &= ~RX_EN_PIN;   // turn off comparator
  TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
  TAR = 0;
#endif

  // set up for TRcal
  if ( cmd[0] & BIT3)
  {
    divideRatio = 21;//64/3;
  } else
  {
    divideRatio = 8;
  }
  // set up for subcarrier symbol
  subcarrierNum = cmd[0] & (BIT2 | BIT1);
  if (subcarrierNum == 0)
  {
    subcarrierNum = 1;
  } else if ( subcarrierNum == 2 )
  {
    subcarrierNum = 2;
  } else if (subcarrierNum == 4)
  {
    subcarrierNum = 4;
  } else
  {
    subcarrierNum = 8;
  }

  // set up for TRext
  if (cmd[0] & BIT0)
  {
    TRext = 1;
  } else
  {
    TRext = 0;
  }

#if ENABLE_SESSIONS

#if 1
// command-specific bit masks
#define QUERY_SEL_MASK		0xC0
#define QUERY_SESSION_MASK	0x30
#define QUERY_TARGET_MASK	0x08

// command-specific bit flags
#define QUERY_SEL_SL 		0xC0
#define QUERY_SEL_NOTSL 	0x80

  unsigned short sel = cmd[1] & QUERY_SEL_MASK;
  unsigned short session = (cmd[1] & QUERY_SESSION_MASK) >> 4;
  unsigned short target = cmd[1] & QUERY_TARGET_MASK;
  unsigned short match = 0;

#define TARGETISEQUAL(t,s) \
  ((t == 0x00 && s == SESSION_STATE_A) || (t == 0x08  && s == SESSION_STATE_B))

  // if we are already in an inventory round and the session matches the
  // previous session, invert the session inventory flag
  if ( state == STATE_ACKNOWLEDGED || state == STATE_OPEN ||
          state == STATE_SECURED )
  {
	if ( session == previous_session )
        {
		// invert session's inventory flag
		if ( session_table[session] == SESSION_STATE_A )
            session_table[session] = SESSION_STATE_B;
        else
            session_table[session] = SESSION_STATE_A;
	}
  }

  // now figure out if the SL and session flags match. Let's look at the SL flag
  // first.
  if ( sel < QUERY_SEL_NOTSL || sel == QUERY_SEL_SL && SL == SL_ASSERTED ||
          sel == QUERY_SEL_NOTSL && SL == SL_NOT_ASSERTED )
  {
	// SL flag matches -- now how about the session flag?
	if ( TARGETISEQUAL(target,session_table[session]) )
        {
		// session match too
		match = 1;
	}
  }

  if ( ! match )
  {
    // no matching SL/session flags. don't respond and transistion to READY
    // state.
	TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
	TAR = 0;
	state = STATE_READY;
	return;
  }

  // OK, got matching SL and session inventory flags, so we're in this inventory
  // round. save the session to the previous_session variable in case this is a
  // new session.
  previous_session = session;

#else
  while ( TAR < 140 );
  TAR = 0;
#endif

#else

  // we don't care about SL or session inventory flags at all. just proceed
  // as if we have matched on them.

#endif

#if ENABLE_SLOTS

  // next step is to built a slot counter

  // parse for Q number and choose a Q value randomly
  Q = (cmd[1] & 0x07)<<1;
  if ((cmd[2] & 0x80) == 0x80)
    Q += 0x01;

  // pick Q randomly
  slot_counter = Q >> shift;

  // HACK ALERT: the Impinj reader seems to output at least two Queries before
  // it sends along an Ack. If I followed the spec, I might well reply to the
  // first Query but not the second, owing to a nonzero slot counter. In this
  // case the reader would just send along QueryReps until the slot counter got
  // to zero, and I'd emit another response. Problem is, we're a
  // power-constrained device and we don't necessarily have the ability to
  // respond to a list of QueryReps. Therefore, I will check to see if I'm in an
  // inventory round -- that is, I've already seen a query -- and if I am,
  // pretend my slot counter is zero and respond right away.

  // slot counter built and it's 0. we can send a reply!
  if ( inInventoryRound == 1 || slot_counter == 0)
  {

    // compute a RN16
    loadRN16();

    // compute the CRC
    queryReplyCRC = crc16_ccitt(&queryReply[0],2);
    queryReply[3] = (unsigned char)queryReplyCRC;
    queryReply[2] = (unsigned char)__swap_bytes(queryReplyCRC);

    TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
    while ( TAR < 140 );
    TAR = 0;

    // send out the packet, and transition to STATE_REPLY
    sendToReader(&queryReply[0], 17);
    state = nextState;

    // mix up the RN16 table a bit for next time
    mixupRN16();
  }

  // slot counter isn't 0, so we don't send a reply. We wait for a
  // followup QueryRep or QueryAdjust command. In the meantime,
  // we transition to STATE_ARBITRATE.
  else
  {
    TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
    TAR = 0;
    state = STATE_ARBITRATE;
  }

  inInventoryRound = 1;

#else

  // we don't care about slots, so just send the packet and go to STATE_REPLY.
  sendToReader(&queryReply[0], 17);
  state = nextState;

#endif

}
Esempio n. 11
0
void handle_queryadjust(volatile short nextState)
{

  TAR = 0;
#if !(ENABLE_SLOTS) && !(ENABLE_SESSIONS)
  while ( TAR < 300 );
  //P1OUT &= ~RX_EN_PIN;   // turn off comparator
  TACCTL1 &= ~CCIE;
  TAR = 0;
#endif

#if ENABLE_SESSIONS

// command-specific bit masks
#define QUERYADJ_SESSION_MASK	0x0C

  unsigned short session = (cmd[0] & QUERYADJ_SESSION_MASK) >> 1;

  if ( session != previous_session )
  {
	// drop the packet, but stay in the same state
	TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
	TAR = 0;
	return;
  }

  // if we got this packet in ACKNOWLEDGED, OPEN, or SECURED states, invert the
  // session flag and transition to STATE_READY to take myself out of this
  // inventory round.
  if ( state == STATE_ACKNOWLEDGED || state == STATE_OPEN ||
          state == STATE_SECURED )
  {
	// invert session's inventory flag
	if ( session_table[session] == SESSION_STATE_A )
        session_table[session] = SESSION_STATE_B;
    else
        session_table[session] = SESSION_STATE_A;
	state = STATE_READY;
	TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
	TAR = 0;
	return;
  }

#endif

#if ENABLE_SLOTS

#define QUERYADJ_UPDNB0_MASK	0x01
#define QUERYADJ_UPDNB1_MASK	0xC0

  unsigned char updn = (cmd[0] & QUERYADJ_UPDNB0_MASK) << 2;
  unsigned char tmp = (cmd[1] & QUERYADJ_UPDNB1_MASK) >> 6;
  updn |= tmp;

  if ( Q == 0xf && updn == 0x3 ) updn = 0x0;
  if ( Q == 0x0 && updn == 0x1 ) updn = 0x0;

  if ( updn == 0x6 ) Q += 1;
  else if ( updn == 0x3 ) Q -= 1;
  else if ( updn != 0x0 )
  {
    // impinj likes to send me plenty of updn values of 0x01, which isn't
    // valid. Spec says to ignore the command in these cases.
    return;
  }

  // pick Q randomly
  slot_counter = Q >> shift;

  // slot counter built and it's 0. we can send a reply!
  if (slot_counter == 0)
  {
	// compute a RN16
	loadRN16();

	// compute a CRC
	queryReplyCRC = crc16_ccitt(&queryReply[0],2);
	queryReply[3] = (unsigned char)queryReplyCRC;
	queryReply[2] = (unsigned char)__swap_bytes(queryReplyCRC);

	TACCTL1 &= ~CCIE;     // Disable capturing and comparing interrupt
	TAR = 0;

	// send out the packet, and transition to STATE_REPLY
	sendToReader(&queryReply[0], 17);
	state = nextState;

	// mix up the RN16 table a bit for next time
   	 mixupRN16();
  }
  else
  {
	// slot counter isn't 0, so we don't send a reply. We wait for a
	// followup QueryRep or QueryAdjust command. In the meantime,
	// we transition to STATE_ARBITRATE.
	state = STATE_ARBITRATE;
  }

#else

  // we don't care about slots, so just send the packet and go to STATE_REPLY.
  sendToReader(&queryReply[0], 17);
  state = nextState;
#endif
}
Esempio n. 12
0
unsigned int hw_crc_validate(unsigned char* receiveCommand, unsigned int number_of_bytes) {

	// Preset CRC result as per ISO/IEC 13239
	CRCINIRES = 0xFFFF;
	//
	if(number_of_bytes < 2)
		return 0;

	// Iterate over transmitCommand array
	//In essence we calculate the CRC and then will check it with the one appended to the receiveCommand
	unsigned int crc_i;
	for(crc_i = 0; crc_i < number_of_bytes - 2; crc_i++)
	{
		// Load next byte into LSB of data input register
		// TODO: Can this be done faster word-wise?
		CRCDI_L = receiveCommand[crc_i];
	}

	CRCINIRES = ~CRCINIRES; // Invert bits of result

	// Checks result from bit-order-reversed version of CRCRES to the received CRC (Last 2 bytes of receiveCommand)
	if((receiveCommand[number_of_bytes - 2] == (CRCRESR & 0x00FF)) && (receiveCommand[number_of_bytes - 1] == (__swap_bytes(CRCRESR) & 0x00FF)))
	{
		return (number_of_bytes - 2);
	}else
		//toggle_led_2();
		return 0;

}