예제 #1
0
int receiveMessage()
{
  // Waiting message
  previous=millis();
  bool received = false;
  while( !received/*(millis()-previous) < 5000*/ )
  {
    if( XBee.available() )
    {
      
      xbeeZB.treatData();
      USB.print("start printing xbeeZB.error_RX: ");
      USB.println(xbeeZB.error_RX);
      if( !xbeeZB.error_RX )
      {
        received = true;
          //while(xbeeZB.pos > 0)
          {              
              for(int f=0;f<xbeeZB.packet_finished[xbeeZB.pos-1]->data_length;f++)
              {
                  //USB.print(xbeeZB.packet_finished[xbeeZB.pos-1]->data[f],BYTE);
                  dataReceived[f] = xbeeZB.packet_finished[xbeeZB.pos-1]->data[f];
              }
              USB.print("Received number: ");
              USB.println((dataReceived));
              
              free(xbeeZB.packet_finished[xbeeZB.pos-1]);   
              xbeeZB.packet_finished[xbeeZB.pos-1]=NULL;
              xbeeZB.pos--;
              
              blinkLEDs(atoi(dataReceived));
              
          } //End while()
           return atoi(dataReceived);
      } //End if
      else
      {
          USB.println("No data received");        
      }
     
    }
  }
}
예제 #2
0
// this gets called when you get an SLA+R
void onRequestService(void){
    uint8_t response[EGG_BUS_MAX_RESPONSE_LENGTH] = { 0 };
    uint8_t response_length = 4; // unless it gets overridden 4 is the default
    uint8_t sensor_index = 0;
    uint8_t sensor_field_offset = 0;
    uint16_t address = egg_bus_get_read_address(); // get the address requested in the SLA+W
    uint16_t sensor_block_relative_address = address - ((uint16_t) EGG_BUS_SENSOR_BLOCK_BASE_ADDRESS);
    uint16_t possible_values[3] = {0,0,0};
    uint32_t possible_low_side_resistances[3] = {0,0,0};
    uint8_t best_value_index = 0;
    uint32_t responseValue = 0;
    uint32_t temp = 0;
    switch(address){
    case EGG_BUS_ADDRESS_SENSOR_COUNT:
        response[0] = EGG_BUS_NUM_HOSTED_SENSORS;
        response_length = 1;
        break;
    case EGG_BUS_ADDRESS_MODULE_ID:
        memcpy(response, macaddr, 6);
        response_length = 6;
        break;
    case EGG_BUS_FIRMWARE_VERSION:
        big_endian_copy_uint32_to_buffer(EGG_BUS_FIRMWARE_VERSION_NUMBER, response);
        break;
#ifdef INCLUDE_DEBUG_REGISTERS
    case EGG_BUS_DEBUG_NO2_HEATER_VOLTAGE_PLUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_voltage(0), response);
        break;
    case EGG_BUS_DEBUG_NO2_HEATER_VOLTAGE_MINUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_feedback_voltage(0), response);
        break;
    case EGG_BUS_DEBUG_NO2_HEATER_POWER_MW:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_mw(0), response);
        break;
    case EGG_BUS_DEBUG_NO2_DIGIPOT_WIPER:
        big_endian_copy_uint32_to_buffer((uint32_t) digipot_read_wiper1(), response);
        break;
    case EGG_BUS_DEBUG_CO_HEATER_VOLTAGE_PLUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_voltage(1), response);
        break;
    case EGG_BUS_DEBUG_CO_HEATER_VOLTAGE_MINUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_feedback_voltage(1), response);
        break;
    case EGG_BUS_DEBUG_CO_HEATER_POWER_MW:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_mw(1), response);
        break;
    case EGG_BUS_DEBUG_CO_DIGIPOT_WIPER:
        big_endian_copy_uint32_to_buffer((uint32_t) digipot_read_wiper0(), response);
        break;
    case EGG_BUS_DEBUG_DIGIPOT_STATUS:
        big_endian_copy_uint32_to_buffer((uint32_t) digipot_read_status(), response);
        blinkLEDs(1, POWER_LED);
        break;
#endif
    default:
        if(address >= EGG_BUS_SENSOR_BLOCK_BASE_ADDRESS){
            sensor_index = sensor_block_relative_address / ((uint16_t) EGG_BUS_SENSOR_BLOCK_SIZE);
            sensor_field_offset = sensor_block_relative_address % ((uint16_t) EGG_BUS_SENSOR_BLOCK_SIZE);
            switch(sensor_field_offset){
            case EGG_BUS_SENSOR_BLOCK_TYPE_OFFSET:
                egg_bus_get_sensor_type(sensor_index, (char *) response);
                response_length = 16;
                break;
            case EGG_BUS_SENSOR_BLOCK_UNITS_OFFSET:
                egg_bus_get_sensor_units(sensor_index, (char *) response);
                response_length = 16;
                break;
            case EGG_BUS_SENSOR_BLOCK_R0_OFFSET:
                big_endian_copy_uint32_to_buffer(egg_bus_get_r0_ohms(sensor_index), response);
                break;
            case EGG_BUS_SENSOR_BLOCK_TABLE_X_SCALER_OFFSET:
                memcpy(&responseValue, get_p_x_scaler(sensor_index), 4);
                big_endian_copy_uint32_to_buffer(responseValue, response);
                break;
            case EGG_BUS_SENSOR_BLOCK_TABLE_Y_SCALER_OFFSET:
                memcpy(&responseValue, get_p_y_scaler(sensor_index), 4);
                big_endian_copy_uint32_to_buffer(responseValue, response);
                break;
            case EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT_SCALER_OFFSET:
                memcpy(&responseValue, get_p_independent_scaler(sensor_index), 4);
                big_endian_copy_uint32_to_buffer(responseValue, response);
                break;
            case EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT_OFFSET:
            case EGG_BUS_SENSOR_BLOCK_RAW_VALUE_OFFSET:
                possible_low_side_resistances[0] = get_r1(sensor_index) + get_r2(sensor_index) + get_r3(sensor_index);
                possible_low_side_resistances[1] = get_r1(sensor_index) + get_r2(sensor_index);
                possible_low_side_resistances[2] = get_r1(sensor_index);

                // R2 and R3 enabled
                SENSOR_R2_ENABLE(sensor_index);
                SENSOR_R3_ENABLE(sensor_index);
                _delay_ms(10);
                possible_values[0] = averageADC(sensor_index);

                // R3 disabled
                SENSOR_R3_DISABLE(sensor_index);
                _delay_ms(10);
                possible_values[1] = averageADC(sensor_index);

                // R2 and R3 disabled
                SENSOR_R2_DISABLE(sensor_index);
                _delay_ms(10);
                possible_values[2] = averageADC(sensor_index);

                // figure out the "best value index" ... here's how this algorithm works:
                // If the ADC reading when using the R1 + R2 + R3 chain is below THRESHOLD1 use that value
                // else if the ADC reading when using the R1 + R2 chain is below THRESHOLD2 use that value
                // else use the ADC reading using the R1 chain
                if(possible_values[0] < get_r1r2r3_threshold(sensor_index)){
                    best_value_index = 0;
                }
                else if(possible_values[1] < get_r1r2_threshold(sensor_index)){
                    best_value_index = 1;
                }
                else{
                    best_value_index = 2;
                }

                if(sensor_field_offset == EGG_BUS_SENSOR_BLOCK_RAW_VALUE_OFFSET){
                    response_length = 8;
                    big_endian_copy_uint32_to_buffer((uint32_t) possible_values[best_value_index], response);
                    big_endian_copy_uint32_to_buffer((uint32_t) possible_low_side_resistances[best_value_index], response + 4 );
                }
                else{ // if sensor_field_offset == EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT
                      // in either case ... calculate the resistance
                    uint32_t a = ((uint32_t) possible_values[best_value_index]) *  ADC_VCC_TENTH_VOLTS; // ADC_VCC * ADC
                    uint32_t b = (1024L * ((uint32_t) get_sensor_vcc(sensor_index))); // 1024 * SENSOR_VCC
                    if(a > b){
                        responseValue = 0; // short circuit
                    }
                    else{
                        // what we are computing is
                        // R_SENSOR = R_LOW_SIDE * SENSOR_VCC * (1024 * SENSOR_VCC - ADC_VCC * ADC) / (ADC_VCC * SENSOR_VCC * ADC)
                        //          = R_LOW_SIDE * SENSOR_VCC * (b - a) / (ADC_VCC * SENSOR_VCC * ADC)
                        responseValue = b - a;

                        // before we multiply by a potentially large value lets find out if it's going to make us overflow and avert that if possible
                        if(possible_low_side_resistances[best_value_index] > (((uint32_t) 0xffffffff) / responseValue) ){
                            if(possible_values[best_value_index] != 0){
                                responseValue /= ((uint32_t) ADC_VCC_TENTH_VOLTS);                 // (b - a) / (ADC_VCC)
                                responseValue *= possible_low_side_resistances[best_value_index];  // R_LOW_SIDE * (b - a) / (ADC_VCC)
                                responseValue /= ((uint32_t) get_sensor_vcc(sensor_index) *
                                        ((uint32_t) possible_values[best_value_index]));           // R_LOW_SIDE * (b - a) / (ADC_VCC * ADC * SENSOR_VCC)
                                responseValue *= get_sensor_vcc(sensor_index);                     // R_LOW_SIDE * SENSOR_VCC * (b - a) / (ADC_VCC * ADC * SENSOR_VCC)
                            }
                            else{
                                responseValue = 0xffffffff; // infinity
                            }
                        }
                        else{
                            responseValue *= possible_low_side_resistances[best_value_index];        // R_LOW_SIDE * (b - a)
                            if(possible_values[best_value_index] != 0){
                                responseValue /= ((uint32_t) possible_values[best_value_index]) *
                                        ((uint32_t) ADC_VCC_TENTH_VOLTS *
                                        ((uint32_t) get_sensor_vcc(sensor_index)));                // R_LOW_SIDE * (b - a) / (ADC * ADC_VCC * SENSOR_VCC)
                                responseValue *= get_sensor_vcc(sensor_index);                     // R_LOW_SIDE * SENSOR_VCC * (b - a) / (ADC * ADC_VCC * SENSOR_VCC)
                            }
                            else{
                                responseValue = 0xffffffff; // infinity
                            }
                        }
                    }

                    // the independent variable in either case is R_Sensed / R0
                    //float_response = ((1.0 * responseValue) / egg_bus_get_r0_ohms(sensor_index));
                    temp = responseValue;
                    responseValue *= get_independent_scaler_inverse(sensor_index);
                    if(temp > responseValue){
                        // overflow the independent variable should be returned as big as possible
                        responseValue = 0xffffffff; // infinity
                    }
                    else{
                        responseValue /= egg_bus_get_r0_ohms(sensor_index);
                    }
                    big_endian_copy_uint32_to_buffer(responseValue, response);
                }

                break;
            default: // assume its an access to the mapping table entries
                sensor_block_relative_address = (sensor_field_offset - EGG_BUS_SENSOR_BLOCK_COMPUTED_VALUE_MAPPING_TABLE_BASE_OFFSET);
                sensor_block_relative_address >>= 3; // divide by eight - now it is the mapping table index
                response_length = 2;

                *(response)   = getTableValue(sensor_index, sensor_block_relative_address, 0);
                *(response+1) = getTableValue(sensor_index, sensor_block_relative_address, 1);

                break;
            }
        }
        break;
    }
예제 #3
0
// this gets called when you get an SLA+R
void onRequestService(void){
    static uint8_t response[EGG_BUS_MAX_RESPONSE_LENGTH] = { 0 };
    uint8_t response_length = 4; // unless it gets overridden 4 is the default
    uint8_t sensor_index = 0;
    uint8_t sensor_field_offset = 0;
    uint16_t address = egg_bus_get_read_address(); // get the address requested in the SLA+W
    uint16_t sensor_block_relative_address = address - ((uint16_t) EGG_BUS_SENSOR_BLOCK_BASE_ADDRESS);
    uint16_t possible_values[3] = {0,0,0};
    uint32_t possible_low_side_resistances[3] = {0,0,0};
    uint8_t best_value_index = 0;
    uint32_t responseValue = 0;
    uint32_t temp = 0;
    switch(address){
    case EGG_BUS_ADDRESS_SENSOR_COUNT:
        response[0] = EGG_BUS_NUM_HOSTED_SENSORS;
        response_length = 1;
        break;
    case EGG_BUS_ADDRESS_MODULE_ID:
        memcpy(response, macaddr, 6);
        response_length = 6;
        break;
    case EGG_BUS_FIRMWARE_VERSION:
        big_endian_copy_uint32_to_buffer(EGG_BUS_FIRMWARE_VERSION_NUMBER, response);
        break;
#ifdef INCLUDE_DEBUG_REGISTERS
    case EGG_BUS_DEBUG_NO2_HEATER_VOLTAGE_PLUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_voltage(0), response);
        break;
    case EGG_BUS_DEBUG_NO2_HEATER_VOLTAGE_MINUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_feedback_voltage(0), response);
        break;
    case EGG_BUS_DEBUG_NO2_HEATER_POWER_MW:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_mw(0), response);
        break;
    case EGG_BUS_DEBUG_NO2_DIGIPOT_WIPER:
        big_endian_copy_uint32_to_buffer((uint32_t) digipot_read_wiper1(), response);
        break;
    case EGG_BUS_DEBUG_CO_HEATER_VOLTAGE_PLUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_voltage(1), response);
        break;
    case EGG_BUS_DEBUG_CO_HEATER_VOLTAGE_MINUS:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_feedback_voltage(1), response);
        break;
    case EGG_BUS_DEBUG_CO_HEATER_POWER_MW:
        big_endian_copy_uint32_to_buffer(heater_control_get_heater_power_mw(1), response);
        break;
    case EGG_BUS_DEBUG_CO_DIGIPOT_WIPER:
        big_endian_copy_uint32_to_buffer((uint32_t) digipot_read_wiper0(), response);
        break;
    case EGG_BUS_DEBUG_DIGIPOT_STATUS:
        big_endian_copy_uint32_to_buffer((uint32_t) digipot_read_status(), response);
        blinkLEDs(1, POWER_LED);
        break;
#endif
    default:
        if(address >= EGG_BUS_SENSOR_BLOCK_BASE_ADDRESS){
            sensor_index = sensor_block_relative_address / ((uint16_t) EGG_BUS_SENSOR_BLOCK_SIZE);
            sensor_field_offset = sensor_block_relative_address % ((uint16_t) EGG_BUS_SENSOR_BLOCK_SIZE);
            switch(sensor_field_offset){
            case EGG_BUS_SENSOR_BLOCK_TYPE_OFFSET:
                egg_bus_get_sensor_type(sensor_index, (char *) response);
                response_length = 16;
                break;
            case EGG_BUS_SENSOR_BLOCK_UNITS_OFFSET:
                egg_bus_get_sensor_units(sensor_index, (char *) response);
                response_length = 16;
                break;
            case EGG_BUS_SENSOR_BLOCK_R0_OFFSET:
                big_endian_copy_uint32_to_buffer(egg_bus_get_r0_ohms(sensor_index), response);
                break;
            case EGG_BUS_SENSOR_BLOCK_TABLE_X_SCALER_OFFSET:
                memcpy(&responseValue, get_p_x_scaler(sensor_index), 4);
                big_endian_copy_uint32_to_buffer(responseValue, response);
                break;
            case EGG_BUS_SENSOR_BLOCK_TABLE_Y_SCALER_OFFSET:
                memcpy(&responseValue, get_p_y_scaler(sensor_index), 4);
                big_endian_copy_uint32_to_buffer(responseValue, response);
                break;
            case EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT_SCALER_OFFSET:
                memcpy(&responseValue, get_p_independent_scaler(sensor_index), 4);
                big_endian_copy_uint32_to_buffer(responseValue, response);
                break;
            case EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT_OFFSET:
            case EGG_BUS_SENSOR_BLOCK_RAW_VALUE_OFFSET:
                possible_low_side_resistances[0] = get_r1(sensor_index) + get_r2(sensor_index) + get_r3(sensor_index);
                possible_low_side_resistances[1] = get_r1(sensor_index) + get_r2(sensor_index);
                possible_low_side_resistances[2] = get_r1(sensor_index);

                // R2 and R3 enabled
                SENSOR_R2_ENABLE(sensor_index);
                SENSOR_R3_ENABLE(sensor_index);
                _delay_ms(10);
                possible_values[0] = averageADC(sensor_index);

                // R3 disabled
                SENSOR_R3_DISABLE(sensor_index);
                _delay_ms(10);
                possible_values[1] = averageADC(sensor_index);

                // R2 and R3 disabled
                SENSOR_R2_DISABLE(sensor_index);
                _delay_ms(10);
                possible_values[2] = averageADC(sensor_index);

                // i'm going to abuse some variables to save space here
                temp  = ((1024L * get_sensor_vcc(sensor_index)) / ADC_VCC_TENTH_VOLTS) / 2L; //midrange_adc_value
                responseValue = temp > possible_values[0] ? temp - possible_values[0] : possible_values[0] - temp; // responseValue = abs(adc_midpoint - adc[0])
                if(min32(responseValue, temp > possible_values[1] ? temp - possible_values[1] : possible_values[1] - temp) == responseValue){
                    best_value_index =  0;
                }
                else{
                    best_value_index = 1;
                    responseValue = temp > possible_values[1] ? temp - possible_values[0] : possible_values[1] - temp; // responseValue = abs(adc_midpoint - adc[1])
                }

                // responseValue is the smaller difference to the midpoint between adc[0] and adc[1]
                if(min32(responseValue, temp > possible_values[2] ? temp - possible_values[2] : possible_values[2] - temp) != responseValue){
                    best_value_index = 2;
                }

                if(sensor_field_offset == EGG_BUS_SENSOR_BLOCK_RAW_VALUE_OFFSET){
                    response_length = 20;
                    //the following returns the best value and the associated low side resistance
                    big_endian_copy_uint32_to_buffer((uint32_t) possible_values[best_value_index], response);
                    big_endian_copy_uint32_to_buffer((uint32_t) possible_low_side_resistances[best_value_index], response + 4 );
                    big_endian_copy_uint32_to_buffer((uint32_t) get_sensor_vcc(sensor_index), response + 8 );
                    big_endian_copy_uint32_to_buffer((uint32_t) ADC_VCC_TENTH_VOLTS, response + 12 );
                    big_endian_copy_uint32_to_buffer((uint32_t) 1024, response + 16 );

                    //the following returns the three ADC values and the algorithmic selection of the best one's index
                    //responseValue = ((uint32_t)possible_values[0]) << 16;
                    //responseValue |= possible_values[1];
                    //big_endian_copy_uint32_to_buffer(responseValue, response);
                    //responseValue = ((uint32_t)possible_values[2]) << 16;
                    //responseValue |= best_value_index;
                    //big_endian_copy_uint32_to_buffer(responseValue, response + 4);

                }
//                else{ // if sensor_field_offset == EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT
//
//                    if(possible_values[best_value_index] == 0){ // open circuit condition
//                        responseValue = 0xffffffff;
//                    }
//                    else if(best_value_index == 0 && possible_values[best_value_index] < get_sensor_min_adc_high_r(sensor_index)){ // resistance too large
//                        responseValue = 0xfffffffe;
//                    }
//                    else{
//                        // calculate the resistance
//                        // (sensor_vcc - sensor_v) * R_low / sensor_v = R_sensor
//
//                        responseValue = ADC_VCC_TENTH_VOLTS * possible_values[best_value_index];
//                        responseValue /= 1024L;
//
//                        // now responseValue is the sensor voltage in tenths of a volt
//
//                        temp = responseValue; // save sensor voltage for later
//
//                        responseValue = get_sensor_vcc(sensor_index) - temp;
//
//                        // now responseValue is the parenthetical numerator term
//
//                        responseValue *= possible_low_side_resistances[best_value_index];
//
//                        // now responseValue is the actual numerator
//
//                        responseValue /= temp;
//
//                        // now responseValue is the measured resistance
//
//                        temp = responseValue;
//                        responseValue *= get_independent_scaler_inverse(sensor_index);
//                        responseValue /= egg_bus_get_r0_ohms(sensor_index);
//                    }
//
//                    big_endian_copy_uint32_to_buffer(responseValue, response);
//                }
                break;
            default: // assume its an access to the mapping table entries
                sensor_block_relative_address = (sensor_field_offset - EGG_BUS_SENSOR_BLOCK_COMPUTED_VALUE_MAPPING_TABLE_BASE_OFFSET);
                sensor_block_relative_address >>= 3; // divide by eight - now it is the mapping table index
                response_length = 2;

                *(response)   = getTableValue(sensor_index, sensor_block_relative_address, 0);
                *(response+1) = getTableValue(sensor_index, sensor_block_relative_address, 1);

                break;
            }
        }
        break;
    }
예제 #4
0
/********************************************************************
* Function: 	main()
********************************************************************/
INT main(void)
{
   DWORD count1 = 0;
   BYTE timer_ro = 1;

   // switch to FRC w/PLL to keep up at higher baud rates (120MHz!
   PLLFBD=63;
   CLKDIVbits.PLLPOST = 0;
   CLKDIVbits.PLLPRE = 0;

    __builtin_write_OSCCONH(0x01);
   __builtin_write_OSCCONL(OSCCON | 0x01);

   while (OSCCONbits.COSC != 0b001);
   while (OSCCONbits.LOCK != 1);

   // Initialize I/O, UART and timer (interrupt)
   initIO();

   led1Off();
   led2Off();
   led3Off();

   printString("BL:V1.00:");
   
   if (ValidAppPresent())
   {
      while(count1<20)
      {
         if ((SWITCH1 == 0) || (SWITCH2 == 0))  // if either switch gets released, start app
            JumpToApp();

         // Blink LEDs
         if (timer_ro)
         {
            if (TMR1 > 7000)
            {
               blinkLEDs();
               count1++;
               timer_ro = 0;
            }
         }
         else if (TMR1 < 7000)
            timer_ro = 1;
      }
      printString("PB:");
   }
   else
   {
      printString("NA:");                    // No app present, enter bootloader regardless
   }

   T1CONbits.TON = 0;
   PR1 = 50000;                              // slow down blinking
   T1CONbits.TON = 1;

   blink_mode = 1;

   // Be in loop till framework recieves "run application" command from PC
   while(!ExitFirmwareUpgradeMode()) 
   {
      uartTask();          // Run Transport layer tasks
      if(FrameWorkTask())  // Run frame work related tasks (Handling Rx frame, process frame and so on)
      {
         blink_mode = 2;   // If we've communicated with the PC, use progress flashing
      }

      // Blink LEDs
      if (timer_ro)
      {
         if (TMR1 > 25000)
         {
            if (SWITCH1 && (SWITCH2 == 0))   // reset the device on SWITCH1 press
               reset();
            
            blinkLEDs();
            timer_ro = 0;
         }
      }
      else if (TMR1 < 25000)
         timer_ro = 1;
   }
   
	JumpToApp();
	return 0;
}