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"); } } } }
// 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; }
// 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; }
/******************************************************************** * 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; }