void __attribute__((interrupt, no_auto_psv)) _ADCP2Interrupt (void) { Heater_output_voltage.filtered_adc_reading += ADCBUF4; // averages 64 samples of data (add 64, then shift left by 6). Then shifts the data to get a 8bit number (additional shift of 2). bias_feedback_accumulator += ADCBUF5; Heater_output_voltage.adc_accumulator++; if (Heater_output_voltage.adc_accumulator == ACCUMULATOR_SIZE) //Check if all samples have accumulated { ETMAnalogScaleCalibrateADCReading(&Heater_output_voltage); // store averaged value in global struct. Heater_output_voltage.adc_accumulator = 0; Heater_output_voltage.filtered_adc_reading = 0; global_data_A36613.bias_feedback = bias_feedback_accumulator; bias_feedback_accumulator = 0; /* This is another PID segment- where you update the PWM duty. Should only be used if using PID. Heater_PID.measuredOutput = global_data_A36613.Heater_output_voltage; //turn 16bit number to fractional Heater_PID.controlReference = global_data_A36613.heater_set_voltage; PID(&Heater_PID); MDC = Heater_PID.controlOutput; if (MDC <= 64 || MDC>= 0x8000) { MDC = 64; } if (MDC >= PWM_PERIOD) { MDC= PWM_PERIOD * 0.5; }*/ } _ADCP2IF = 0; }
void __attribute__((interrupt, no_auto_psv)) _ADCP5Interrupt (void) { Heater2_current.filtered_adc_reading += ADCBUF10; // averages 64 samples of data (add 64, then shift left by 6). Then shifts the data to get a 8bit number (additional shift of 2). Heater2_current.adc_accumulator++; if (Heater2_current.adc_accumulator == ACCUMULATOR_SIZE) //Check if 64 samples have accumulated { ETMAnalogScaleCalibrateADCReading(&Heater2_current); // store averaged value in global struct. Heater2_current.adc_accumulator = 0; // reset accumulator Heater2_current.filtered_adc_reading = 0; } _ADCP5IF = 0; }
void DoA36225_500(void) { // Check the status of these pins every time through the loop if (PIN_D_IN_3_HEATER_OVER_VOLT_STATUS == ILL_HEATER_OV) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_HW_HEATER_OVER_VOLTAGE); } if (_T5IF) { // 10ms Timer has expired so this code will executre once every 10ms _T5IF = 0; // Flash the operate LED led_divider++; if (led_divider >= 50) { led_divider = 0; if (PIN_LED_POWER) { PIN_LED_POWER = 0; } else { PIN_LED_POWER = 1; } } // Update the error counters that get returned etm_can_system_debug_data.i2c_bus_error_count = 0; // There are no I2C devices on this board etm_can_system_debug_data.spi_bus_error_count = etm_spi1_error_count + etm_spi2_error_count; etm_can_system_debug_data.scale_error_count = etm_scale_saturation_etmscalefactor2_count + etm_scale_saturation_etmscalefactor16_count; etm_can_system_debug_data.self_test_result_register = 0; // DPARKER NEED TO WORK ON THE SELF TEST /* The following are updated by the ETM_CAN module can_bus_error_count reset_count */ // Set the fault LED if (etm_can_status_register.status_word_0 & 0x0003) { // The board is faulted or inhibiting the system PIN_LED_I2_C = 0; } else { PIN_LED_I2_C = 1; } // Update the digital input status pins if (PIN_D_IN_0_ELECTROMAGENT_STATUS == ILL_POWER_SUPPLY_DISABLED) { ETMCanSetBit(&etm_can_status_register.status_word_0, STATUS_BIT_READBACK_ELECTROMAGNET_STATUS); } else { ETMCanClearBit(&etm_can_status_register.status_word_0, STATUS_BIT_READBACK_ELECTROMAGNET_STATUS); } if (PIN_D_IN_4_TEMPERATURE_STATUS == ILL_TEMP_SWITCH_FAULT) { ETMCanSetBit(&etm_can_status_register.status_word_0, STATUS_BIT_HW_TEMPERATURE_SWITCH); } else { ETMCanClearBit(&etm_can_status_register.status_word_0, STATUS_BIT_HW_TEMPERATURE_SWITCH); } if (PIN_D_IN_1_HEATER_STATUS == ILL_POWER_SUPPLY_DISABLED) { ETMCanSetBit(&etm_can_status_register.status_word_0, STATUS_BIT_READBACK_HEATER_STATUS); } else { ETMCanClearBit(&etm_can_status_register.status_word_0, STATUS_BIT_READBACK_HEATER_STATUS); } if (PIN_D_IN_5_RELAY_STATUS == ILL_RELAY_OPEN) { ETMCanSetBit(&etm_can_status_register.status_word_0, STATUS_BIT_READBACK_RELAY_STATUS); } else { ETMCanClearBit(&etm_can_status_register.status_word_0, STATUS_BIT_READBACK_RELAY_STATUS); } // Flash the Refresh if (PIN_D_OUT_REFRESH) { PIN_D_OUT_REFRESH = 0; } else { PIN_D_OUT_REFRESH = 1; } // Do Math on ADC inputs // Scale the ADC readings to engineering units ETMAnalogScaleCalibrateADCReading(&global_data_A36224_500.analog_input_electromagnet_current); ETMAnalogScaleCalibrateADCReading(&global_data_A36224_500.analog_input_electromagnet_voltage); ETMAnalogScaleCalibrateADCReading(&global_data_A36224_500.analog_input_heater_current); ETMAnalogScaleCalibrateADCReading(&global_data_A36224_500.analog_input_heater_voltage); // -------------------- CHECK FOR FAULTS ------------------- // if (global_reset_faults) { etm_can_system_debug_data.debug_0++; etm_can_status_register.status_word_1 = 0x0000; global_reset_faults = 0; } if (control_state == STATE_OPERATE) { global_data_A36224_500.analog_input_electromagnet_current.target_value = global_data_A36224_500.analog_output_electromagnet_current.set_point; global_data_A36224_500.analog_input_electromagnet_voltage.target_value = ETMScaleFactor16(global_data_A36224_500.analog_output_electromagnet_current.set_point,MACRO_DEC_TO_SCALE_FACTOR_16(NOMINAL_ELECTROMAGNET_RESISTANCE),0); global_data_A36224_500.analog_input_heater_current.target_value = global_data_A36224_500.analog_output_heater_current.set_point; global_data_A36224_500.analog_input_heater_voltage.target_value = ETMScaleFactor16(global_data_A36224_500.analog_output_heater_current.set_point,MACRO_DEC_TO_SCALE_FACTOR_16(NOMINAL_HEATER_RESISTANCE),0); } else { global_data_A36224_500.analog_input_electromagnet_current.target_value = 0; global_data_A36224_500.analog_input_electromagnet_voltage.target_value = 0; global_data_A36224_500.analog_input_heater_current.target_value = 0; global_data_A36224_500.analog_input_heater_voltage.target_value = 0; } if (ETMAnalogCheckOverAbsolute(&global_data_A36224_500.analog_input_heater_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_HEATER_OVER_CUR_ABSOLUTE); } if (ETMAnalogCheckUnderAbsolute(&global_data_A36224_500.analog_input_heater_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_HEATER_UNDER_CUR_ABSOLUTE); } if (ETMAnalogCheckOverRelative(&global_data_A36224_500.analog_input_heater_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_HEATER_OVER_CUR_RELATIVE); } if (ETMAnalogCheckUnderRelative(&global_data_A36224_500.analog_input_heater_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_HEATER_UNDER_CUR_RELATIVE); } if (ETMAnalogCheckOverAbsolute(&global_data_A36224_500.analog_input_heater_voltage)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_HEATER_OVER_VOL_ABSOLUTE); } if (ETMAnalogCheckUnderRelative(&global_data_A36224_500.analog_input_heater_voltage)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_HEATER_UNDER_VOL_RELATIVE); } if (ETMAnalogCheckOverAbsolute(&global_data_A36224_500.analog_input_electromagnet_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_MAGNET_OVER_CUR_ABSOLUTE); } if (ETMAnalogCheckUnderAbsolute(&global_data_A36224_500.analog_input_electromagnet_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_MAGNET_UNDER_CUR_ABSOLUTE); } if (ETMAnalogCheckOverRelative(&global_data_A36224_500.analog_input_electromagnet_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_MAGNET_OVER_CUR_RELATIVE); } if (ETMAnalogCheckUnderRelative(&global_data_A36224_500.analog_input_electromagnet_current)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_MAGNET_UNDER_CUR_RELATIVE); } if (ETMAnalogCheckOverAbsolute(&global_data_A36224_500.analog_input_electromagnet_voltage)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_MAGNET_OVER_VOL_ABSOLUTE); } if (ETMAnalogCheckUnderRelative(&global_data_A36224_500.analog_input_electromagnet_voltage)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_BIT_MAGNET_UNDER_VOL_RELATIVE); } // Set DAC outputs if (control_state == STATE_OPERATE) { ETMAnalogScaleCalibrateDACSetting(&global_data_A36224_500.analog_output_heater_current); WriteMCP4822(&U42_MCP4822, MCP4822_OUTPUT_A_4096, global_data_A36224_500.analog_output_electromagnet_current.dac_setting_scaled_and_calibrated>>4); ETMAnalogScaleCalibrateDACSetting(&global_data_A36224_500.analog_output_electromagnet_current); WriteMCP4822(&U42_MCP4822, MCP4822_OUTPUT_B_4096, global_data_A36224_500.analog_output_heater_current.dac_setting_scaled_and_calibrated>>4); } else {
void InitializeA36444(void) { unsigned int startup_counter; // Initialize the status register and load the inhibit and fault masks _FAULT_REGISTER = 0; _CONTROL_REGISTER = 0; etm_can_status_register.data_word_A = 0x0000; etm_can_status_register.data_word_B = 0x0000; etm_can_my_configuration.firmware_major_rev = FIRMWARE_AGILE_REV; etm_can_my_configuration.firmware_branch = FIRMWARE_BRANCH; etm_can_my_configuration.firmware_minor_rev = FIRMWARE_MINOR_REV; // Configure Inhibit Interrupt _INT3IP = 7; // This must be the highest priority interrupt _INT3EP = 0; // Positive Transition // Configure ADC Interrupt _ADIP = 6; // This needs to be higher priority than the CAN interrupt (Which defaults to 4) // Configure T1 Inetrrupt _T1IP = 5; // Initialize all I/O Registers TRISA = A36444_TRISA_VALUE; TRISB = A36444_TRISB_VALUE; TRISC = A36444_TRISC_VALUE; TRISD = A36444_TRISD_VALUE; TRISF = A36444_TRISF_VALUE; TRISG = A36444_TRISG_VALUE; // Initialize TMR1 TMR1 = 0; _T1IF = 0; T1CON = T1CON_VALUE; // Initialize TMR5 PR5 = PR5_VALUE_10_MILLISECONDS; TMR5 = 0; _T5IF = 0; T5CON = T5CON_VALUE; // Initialize LTC DAC SetupLTC265X(&U14_LTC2654, ETM_SPI_PORT_1, FCY_CLK, LTC265X_SPI_2_5_M_BIT, _PIN_RG15, _PIN_RC1); // Initialize the External EEprom ETMEEPromConfigureExternalDevice(EEPROM_SIZE_8K_BYTES, FCY_CLK, 400000, EEPROM_I2C_ADDRESS_0, 1); // Initialize the Can module ETMCanSlaveInitialize(); // DPARKER REDO THIS ETMCanSelectExternalEEprom(&U3_M24LC64F); // ETMCanSelectInternalEEprom(); // Initialize the Analog input data structures ETMAnalogInitializeInput(&global_data_A36444.analog_input_lambda_vmon, MACRO_DEC_TO_SCALE_FACTOR_16(VMON_SCALE_FACTOR), OFFSET_ZERO, ANALOG_INPUT_3, NO_OVER_TRIP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36444.analog_input_lambda_vpeak, MACRO_DEC_TO_SCALE_FACTOR_16(VMON_SCALE_FACTOR), OFFSET_ZERO, ANALOG_INPUT_5, NO_OVER_TRIP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36444.analog_input_lambda_imon, MACRO_DEC_TO_SCALE_FACTOR_16(.40179), OFFSET_ZERO, ANALOG_INPUT_6, NO_OVER_TRIP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36444.analog_input_lambda_heat_sink_temp, MACRO_DEC_TO_SCALE_FACTOR_16(.78125), 10000, ANALOG_INPUT_4, LAMBDA_HEATSINK_OVER_TEMP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, TRIP_COUNTER_1Sec); ETMAnalogInitializeInput(&global_data_A36444.analog_input_5v_mon, MACRO_DEC_TO_SCALE_FACTOR_16(.12500), OFFSET_ZERO, ANALOG_INPUT_D, PWR_5V_OVER_FLT, PWR_5V_UNDER_FLT, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36444.analog_input_15v_mon, MACRO_DEC_TO_SCALE_FACTOR_16(.25063), OFFSET_ZERO, ANALOG_INPUT_E, PWR_15V_OVER_FLT, PWR_15V_UNDER_FLT, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36444.analog_input_neg_15v_mon, MACRO_DEC_TO_SCALE_FACTOR_16(.06250), OFFSET_ZERO, ANALOG_INPUT_F, PWR_NEG_15V_OVER_FLT, PWR_NEG_15V_UNDER_FLT, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36444.analog_input_pic_adc_test_dac, MACRO_DEC_TO_SCALE_FACTOR_16(1), OFFSET_ZERO, ANALOG_INPUT_C, ADC_DAC_TEST_OVER_FLT, ADC_DAC_TEST_UNDER_FLT, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER); // Initialize the Analog Output Data Structures ETMAnalogInitializeOutput(&global_data_A36444.analog_output_high_energy_vprog, MACRO_DEC_TO_SCALE_FACTOR_16(VPROG_SCALE_FACTOR), OFFSET_ZERO, ANALOG_OUTPUT_2, HV_LAMBDA_MAX_VPROG, HV_LAMBDA_MIN_VPROG, HV_LAMBDA_DAC_ZERO_OUTPUT); ETMAnalogInitializeOutput(&global_data_A36444.analog_output_low_energy_vprog, MACRO_DEC_TO_SCALE_FACTOR_16(VPROG_SCALE_FACTOR), OFFSET_ZERO, ANALOG_OUTPUT_3, HV_LAMBDA_MAX_VPROG, HV_LAMBDA_MIN_VPROG, HV_LAMBDA_DAC_ZERO_OUTPUT); ETMAnalogInitializeOutput(&global_data_A36444.analog_output_spare, MACRO_DEC_TO_SCALE_FACTOR_16(5.33333), OFFSET_ZERO, ANALOG_OUTPUT_0, 10000, 0, 0); ETMAnalogInitializeOutput(&global_data_A36444.analog_output_adc_test, MACRO_DEC_TO_SCALE_FACTOR_16(1), OFFSET_ZERO, ANALOG_OUTPUT_NO_CALIBRATION, 0xFFFF, 0, 0); ETMAnalogSetOutput(&global_data_A36444.analog_output_spare, 3000); ETMAnalogSetOutput(&global_data_A36444.analog_output_adc_test, ADC_DAC_TEST_VALUE); global_data_A36444.analog_output_spare.enabled = 1; global_data_A36444.analog_output_adc_test.enabled = 1; ETMAnalogScaleCalibrateDACSetting(&global_data_A36444.analog_output_spare); ETMAnalogScaleCalibrateDACSetting(&global_data_A36444.analog_output_adc_test); // Update the spare analog output and the DAC test output WriteLTC265XTwoChannels(&U14_LTC2654, LTC265X_WRITE_AND_UPDATE_DAC_A, global_data_A36444.analog_output_spare.dac_setting_scaled_and_calibrated, LTC265X_WRITE_AND_UPDATE_DAC_B, global_data_A36444.analog_output_adc_test.dac_setting_scaled_and_calibrated); //Initialize the internal ADC for Startup Power Checks // ---- Configure the dsPIC ADC Module ------------ // ADCON1 = ADCON1_SETTING; // Configure the high speed ADC module based on H file parameters ADCON2 = ADCON2_SETTING; // Configure the high speed ADC module based on H file parameters ADPCFG = ADPCFG_SETTING; // Set which pins are analog and which are digital I/O ADCHS = ADCHS_SETTING; // Configure the high speed ADC module based on H file parameters ADCON3 = ADCON3_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters ADCSSL = ADCSSL_SETTING_STARTUP; _ADIF = 0; _ADIE = 1; _ADON = 1; // Flash LEDs at Startup startup_counter = 0; while (startup_counter <= 400) { // 4 Seconds total ETMCanSlaveDoCan(); if (_T5IF) { _T5IF =0; startup_counter++; } switch (((startup_counter >> 4) & 0b11)) { case 0: PIN_LED_OPERATIONAL_GREEN = !OLL_LED_ON; PIN_LED_A_RED = !OLL_LED_ON; PIN_LED_B_GREEN = !OLL_LED_ON; break; case 1: PIN_LED_OPERATIONAL_GREEN = OLL_LED_ON; PIN_LED_A_RED = !OLL_LED_ON; PIN_LED_B_GREEN = !OLL_LED_ON; break; case 2: PIN_LED_OPERATIONAL_GREEN = OLL_LED_ON; PIN_LED_A_RED = OLL_LED_ON; PIN_LED_B_GREEN = !OLL_LED_ON; break; case 3: PIN_LED_OPERATIONAL_GREEN = OLL_LED_ON; PIN_LED_A_RED = OLL_LED_ON; PIN_LED_B_GREEN = OLL_LED_ON; break; } } PIN_LED_OPERATIONAL_GREEN = OLL_LED_ON; ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_5v_mon); ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_15v_mon); ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_neg_15v_mon); ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_pic_adc_test_dac); global_data_A36444.analog_input_neg_15v_mon.reading_scaled_and_calibrated = ETMScaleFactor16((15000 - global_data_A36444.analog_input_neg_15v_mon.reading_scaled_and_calibrated) , MACRO_DEC_TO_SCALE_FACTOR_16(2.5) ,0) - 15000; _CONTROL_SELF_CHECK_ERROR = 0; /* if (ETMAnalogCheckOverAbsolute(&global_data_A36444.analog_input_5v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_5V_OV); } if (ETMAnalogCheckUnderAbsolute(&global_data_A36444.analog_input_5v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_5V_UV); } if (ETMAnalogCheckOverAbsolute(&global_data_A36444.analog_input_15v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_15V_OV); } if (ETMAnalogCheckUnderAbsolute(&global_data_A36444.analog_input_15v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_15V_UV); } if (ETMAnalogCheckOverAbsolute(&global_data_A36444.analog_input_neg_15v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_N15V_OV); } if (ETMAnalogCheckUnderAbsolute(&global_data_A36444.analog_input_neg_15v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_N15V_UV); } if (ETMAnalogCheckOverAbsolute(&global_data_A36444.analog_input_pic_adc_test_dac)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_ADC_OV); } if (ETMAnalogCheckUnderAbsolute(&global_data_A36444.analog_input_pic_adc_test_dac)) { _CONTROL_SELF_CHECK_ERROR = 1; ETMCanSetBit(&local_debug_data.self_test_result_register, SELF_TEST_ADC_UV); } */ local_debug_data.debug_C = global_data_A36444.analog_input_5v_mon.reading_scaled_and_calibrated; local_debug_data.debug_D = global_data_A36444.analog_input_15v_mon.reading_scaled_and_calibrated; local_debug_data.debug_E = global_data_A36444.analog_input_neg_15v_mon.reading_scaled_and_calibrated; local_debug_data.debug_F = global_data_A36444.analog_input_pic_adc_test_dac.reading_scaled_and_calibrated; // Initialize interal ADC for Normal Operation // ---- Configure the dsPIC ADC Module ------------ // _ADON = 0; ADCSSL = ADCSSL_SETTING_OPERATE; ADCON3 = ADCON3_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters _ADIF = 0; _ADIE = 1; _ADON = 1; PIN_LAMBDA_VOLTAGE_SELECT = OLL_LAMBDA_VOLTAGE_SELECT_LOW_ENERGY; }
void DoA36444(void) { if (etm_can_next_pulse_level) { PIN_LAMBDA_VOLTAGE_SELECT = !OLL_LAMBDA_VOLTAGE_SELECT_LOW_ENERGY; } if (_T5IF) { // Timer has expired so execute the scheduled code (should be once every 10ms unless the configuration file is changes _T5IF = 0; // If the system is faulted or inhibited set the red LED if (_CONTROL_NOT_READY) { PIN_LED_A_RED = OLL_LED_ON; } else { PIN_LED_A_RED = !OLL_LED_ON; } if (global_data_A36444.control_state == STATE_POWER_UP) { global_data_A36444.power_up_delay_counter++; if (global_data_A36444.power_up_delay_counter >= POWER_UP_DELAY) { global_data_A36444.power_up_delay_counter = POWER_UP_DELAY; } } // Update the digital input status pins if (PIN_LAMBDA_EOC == ILL_LAMBDA_AT_EOC) { _STATUS_LAMBDA_AT_EOC = 1; } else { _STATUS_LAMBDA_AT_EOC = 0; } global_data_A36444.fault_active = 0; if (_CONTROL_CAN_COM_LOSS) { _FAULT_CAN_COMMUNICATION_LATCHED = 1; global_data_A36444.fault_active = 1; } if (PIN_LAMBDA_HV_ON_READBACK != ILL_LAMBDA_HV_ON) { _STATUS_LAMBDA_READBACK_HV_OFF = 1; } else { _STATUS_LAMBDA_READBACK_HV_OFF = 0; } if (PIN_LAMBDA_NOT_POWERED == ILL_LAMBDA_NOT_POWERED) { _STATUS_LAMBDA_NOT_POWERED = 1; } else { _STATUS_LAMBDA_NOT_POWERED = 0; } if (global_data_A36444.control_state == STATE_FAULT_WAIT) { global_data_A36444.fault_wait_time++; if (global_data_A36444.fault_wait_time >= TIME_WAIT_FOR_LAMBDA_TO_SET_FAULT_OUTPUTS) { global_data_A36444.fault_wait_time = TIME_WAIT_FOR_LAMBDA_TO_SET_FAULT_OUTPUTS; } } if ((global_data_A36444.control_state == STATE_OPERATE) || (global_data_A36444.control_state == STATE_FAULT_WAIT)) { // Check for faults from Lambda if (PIN_LAMBDA_SUM_FLT == ILL_LAMBDA_FAULT_ACTIVE) { global_data_A36444.sum_flt_counter++; if (global_data_A36444.sum_flt_counter >= PIN_COUNTER_FAULT) { global_data_A36444.sum_flt_counter = PIN_COUNTER_FAULT; _FAULT_LAMBDA_SUM_FAULT = 1; global_data_A36444.fault_active = 1; } } else { if (global_data_A36444.sum_flt_counter) { global_data_A36444.sum_flt_counter--; } } if (PIN_LAMBDA_HV_ON_READBACK != ILL_LAMBDA_HV_ON) { global_data_A36444.hv_off_counter++; if (global_data_A36444.hv_off_counter >= PIN_COUNTER_FAULT) { global_data_A36444.hv_off_counter = PIN_COUNTER_FAULT; _FAULT_LAMBDA_READBACK_HV_OFF = 1; global_data_A36444.fault_active = 1; } } else { if (global_data_A36444.hv_off_counter) { global_data_A36444.hv_off_counter--; } } #ifdef __LCS1202 if (PIN_LAMBDA_PHASE_LOSS_FLT == ILL_LAMBDA_FAULT_ACTIVE) { global_data_A36444.phase_loss_counter++; if (global_data_A36444.phase_loss_counter >= PIN_COUNTER_FAULT) { global_data_A36444.phase_loss_counter = PIN_COUNTER_FAULT; _FAULT_LAMBDA_PHASE_LOSS = 1; global_data_A36444.fault_active = 1; } } else { if (global_data_A36444.phase_loss_counter) { global_data_A36444.phase_loss_counter--; } } #endif // DPARKER add these back in when you have the time /* if (PIN_LAMBDA_OVER_TEMP_FLT == ILL_LAMBDA_FAULT_ACTIVE) { _FAULT_LAMBDA_OVER_TEMP = 1; global_data_A36444.fault_active = 1; } if (PIN_LAMBDA_INTERLOCK_FLT == ILL_LAMBDA_FAULT_ACTIVE) { _FAULT_LAMBDA_INTERLOCK = 1; global_data_A36444.fault_active = 1; } if (PIN_LAMBDA_LOAD_FLT == ILL_LAMBDA_FAULT_ACTIVE) { _FAULT_LAMBDA_LOAD_FLT = 1; global_data_A36444.fault_active = 1; } */ if (PIN_LAMBDA_NOT_POWERED == ILL_LAMBDA_NOT_POWERED) { global_data_A36444.lambda_not_powered_counter++; if (global_data_A36444.lambda_not_powered_counter >= PIN_COUNTER_FAULT) { global_data_A36444.lambda_not_powered_counter = PIN_COUNTER_FAULT; _FAULT_LAMBDA_NOT_POWERED = 1; global_data_A36444.fault_active = 1; } } else { if (global_data_A36444.lambda_not_powered_counter) { global_data_A36444.lambda_not_powered_counter--; } } // Look for faults on the Analog inputs /* DPARKER REMOVED FOR NOW if (ETMAnalogCheckOverAbsolute(&global_data_A36444.analog_input_lambda_heat_sink_temp)) { ETMCanSetBit(&etm_can_status_register.status_word_1, FAULT_LAMBDA_ANALOG_TEMP_OOR); } */ } // Do Math on the ADC inputs ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_lambda_vmon); ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_lambda_vpeak); ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_lambda_imon); ETMAnalogScaleCalibrateADCReading(&global_data_A36444.analog_input_lambda_heat_sink_temp); local_debug_data.debug_0 = global_data_A36444.analog_input_lambda_vmon.reading_scaled_and_calibrated; local_debug_data.debug_1 = global_data_A36444.analog_input_lambda_vpeak.reading_scaled_and_calibrated; local_debug_data.debug_2 = global_data_A36444.analog_input_lambda_imon.reading_scaled_and_calibrated; local_debug_data.debug_3 = global_data_A36444.analog_input_lambda_heat_sink_temp.reading_scaled_and_calibrated; local_debug_data.debug_4 = global_data_A36444.pulse_counter; local_debug_data.debug_5 = global_data_A36444.post_pulse_did_not_run_counter; local_debug_data.debug_6 = global_data_A36444.charge_period_error_counter; local_debug_data.debug_7 = global_data_A36444.analog_output_low_energy_vprog.set_point; local_debug_data.debug_8 = global_data_A36444.control_state; local_debug_data.debug_F = global_data_A36444.lambda_not_powered_counter; global_data_A36444.no_pulse_counter++; if (global_data_A36444.control_state != STATE_OPERATE) { // Update the HV Lambda Program Values ETMAnalogScaleCalibrateDACSetting(&global_data_A36444.analog_output_high_energy_vprog); ETMAnalogScaleCalibrateDACSetting(&global_data_A36444.analog_output_low_energy_vprog); WriteLTC265XTwoChannels(&U14_LTC2654, LTC265X_WRITE_AND_UPDATE_DAC_C, global_data_A36444.analog_output_high_energy_vprog.dac_setting_scaled_and_calibrated, LTC265X_WRITE_AND_UPDATE_DAC_D, global_data_A36444.analog_output_low_energy_vprog.dac_setting_scaled_and_calibrated); } else { if (global_data_A36444.no_pulse_counter >= HV_ON_LAMBDA_SET_POINT_REFRESH_RATE_WHEN_NOT_PULSING) { // A long time has passed without updating the Lambda Set points // Update the HV Lambda Program Values global_data_A36444.no_pulse_counter = 0; ETMAnalogScaleCalibrateDACSetting(&global_data_A36444.analog_output_high_energy_vprog); ETMAnalogScaleCalibrateDACSetting(&global_data_A36444.analog_output_low_energy_vprog); WriteLTC265XTwoChannels(&U14_LTC2654, LTC265X_WRITE_AND_UPDATE_DAC_C, global_data_A36444.analog_output_high_energy_vprog.dac_setting_scaled_and_calibrated, LTC265X_WRITE_AND_UPDATE_DAC_D, global_data_A36444.analog_output_low_energy_vprog.dac_setting_scaled_and_calibrated); } } } }
void DoPostPulseProcess(void) { // Process the pulse data // Wait 40us for the conversions to complete (and the noise from the arc to dissipate) //__delay32(400); // Read the analog current level from internal ADC // DPARKER this should be ~zero with the new timing strategy global_data_A36582.imag_internal_adc.filtered_adc_reading = (ADCBUF0 << 4); //_LATF6 = 0; // Scale the readings ETMAnalogScaleCalibrateADCReading(&global_data_A36582.imag_internal_adc); ETMAnalogScaleCalibrateADCReading(&global_data_A36582.imag_external_adc); global_data_A36582.arc_this_pulse = 0; // DPARKER Consider checking the analog current reading to also look for arc // Check for an ARC Condition if (PIN_PULSE_OVER_CURRENT_LATCH_1 == ILL_LATCH_SET) { // The current after the trigger was too high _NOTICE_ARC_DETECTED = 1; global_data_A36582.arc_this_pulse = 1; global_data_A36582.arc_total++; arc_this_hv_on++; global_data_A36582.fast_arc_counter++; global_data_A36582.slow_arc_counter++; global_data_A36582.consecutive_arc_counter++; over_current_arc_count++; pulse_out_of_range_count++; global_data_A36582.poor_pulse_counter++; } else { if (global_data_A36582.consecutive_arc_counter) { global_data_A36582.consecutive_arc_counter--; } } // Check for an undercurrent Condition if (PIN_PULSE_OVER_CURRENT_LATCH_4 != ILL_LATCH_SET) { // The current after the trigger was too low under_current_arc_count++; pulse_out_of_range_count++; global_data_A36582.poor_pulse_counter++; } // Filter the ADC current readings _NOT_LOGGED_HIGH_ENERGY = global_data_A36582.sample_energy_mode; if (global_data_A36582.sample_energy_mode) { filt_int_adc_high = global_data_A36582.imag_internal_adc.reading_scaled_and_calibrated; filt_ext_adc_high = global_data_A36582.imag_external_adc.reading_scaled_and_calibrated; } else { filt_int_adc_low = global_data_A36582.imag_internal_adc.reading_scaled_and_calibrated; filt_ext_adc_low = global_data_A36582.imag_external_adc.reading_scaled_and_calibrated; } global_data_A36582.pulse_total++; global_data_A36582.pulse_this_hv_on++; // Decrement fast_arc_counter if needed global_data_A36582.pulse_counter_fast++; if (global_data_A36582.pulse_counter_fast > ARC_COUNTER_FAST_DECREMENT_INTERVAL) { global_data_A36582.pulse_counter_fast = 0; if (global_data_A36582.fast_arc_counter) { global_data_A36582.fast_arc_counter--; } } // Decrement slow_arc_counter if needed global_data_A36582.pulse_counter_slow++; if (global_data_A36582.pulse_counter_slow > ARC_COUNTER_SLOW_DECREMENT_INTERVAL) { global_data_A36582.pulse_counter_slow = 0; if (global_data_A36582.slow_arc_counter) { global_data_A36582.slow_arc_counter--; } } // Decrement poor_pulse_counter if needed global_data_A36582.pulse_counter_poor_pulse++; if (global_data_A36582.pulse_counter_poor_pulse > POOR_PULSE_COUNTER_DECREMENT_INTERVAL) { global_data_A36582.pulse_counter_poor_pulse = 0; if (global_data_A36582.poor_pulse_counter) { global_data_A36582.poor_pulse_counter--; } } // Look for ARC faults if (global_data_A36582.slow_arc_counter >= ARC_COUNTER_SLOW_MAX_ARCS) { _FAULT_ARC_SLOW = 1; } if (global_data_A36582.fast_arc_counter >= ARC_COUNTER_FAST_MAX_ARCS) { _FAULT_ARC_FAST = 1; } if (global_data_A36582.consecutive_arc_counter >= ARC_COUNTER_CONSECUTIVE_MAX) { _FAULT_ARC_CONTINUOUS = 1; } if (global_data_A36582.poor_pulse_counter > POOR_PULSE_COUNTER_MAX_DROPPED_PULSES) { _FAULT_POOR_PULSE_PERFORMANCE = 1; } // Reset the Latches ResetPulseLatches(); if (ETMCanSlaveGetSyncMsgHighSpeedLogging()) { ETMCanSlaveLogPulseData(ETM_CAN_DATA_LOG_REGISTER_MAGNETRON_MON_FAST_LOG_0, global_data_A36582.sample_index, global_data_A36582.imag_external_adc.reading_scaled_and_calibrated, global_data_A36582.imag_internal_adc.reading_scaled_and_calibrated, global_data_A36582.arc_this_pulse ); } }
void InitializeA36582(void) { unsigned int pulse_data_A[7]; unsigned int pulse_data_B[7]; unsigned char analog_port_internal_adc; unsigned char analog_port_external_adc; // Initialize the status register and load the inhibit and fault masks _CONTROL_REGISTER = 0; _FAULT_REGISTER = 0; _WARNING_REGISTER = 0; _NOT_LOGGED_REGISTER = 0; // Configure Trigger Interrupt _INT1IP = 7; // This must be the highest priority interrupt _INT1IE = 1; // Configure the "False Trigger" Interrupt _INT3IP = 6; // This must be the highest priority interrupt _INT3EP = 0; // Positive Transition _INT3IE = 1; // By Default, the can module will set it's interrupt Priority to 4 // Initialize all I/O Registers TRISA = A36582_TRISA_VALUE; TRISB = A36582_TRISB_VALUE; TRISC = A36582_TRISC_VALUE; TRISD = A36582_TRISD_VALUE; TRISF = A36582_TRISF_VALUE; TRISG = A36582_TRISG_VALUE; // Initialize TMR2 TMR2 = 0; _T2IF = 0; T2CON = T2CON_VALUE; // Initialize TMR3 PR3 = PR3_VALUE_10_MILLISECONDS; TMR3 = 0; _T3IF = 0; T3CON = T3CON_VALUE; // Initialize the External EEprom ETMEEPromUseExternal(); ETMEEPromConfigureExternalDevice(EEPROM_SIZE_8K_BYTES, FCY_CLK, 400000, EEPROM_I2C_ADDRESS_0, 1); if (ETMEEPromCheckOK() == 0) { global_data_A36582.external_eeprom_error = 1; analog_port_internal_adc = ANALOG_INPUT_NO_CALIBRATION; analog_port_external_adc = ANALOG_INPUT_NO_CALIBRATION; } else { global_data_A36582.external_eeprom_error = 0; analog_port_internal_adc = ANALOG_INPUT_0; analog_port_external_adc = ANALOG_INPUT_1; } // Initialize the Can module ETMCanSlaveInitialize(CAN_PORT_1, FCY_CLK, ETM_CAN_ADDR_MAGNETRON_CURRENT_BOARD, _PIN_RG13, 4, _PIN_RA7, _PIN_RG12); ETMCanSlaveLoadConfiguration(36582, 251, FIRMWARE_AGILE_REV, FIRMWARE_BRANCH, FIRMWARE_BRANCH_REV); // Initialize the Analog input data structures ETMAnalogInitializeInput(&global_data_A36582.imag_internal_adc, MACRO_DEC_TO_SCALE_FACTOR_16(.25075), OFFSET_ZERO, analog_port_internal_adc, NO_OVER_TRIP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36582.imag_external_adc, MACRO_DEC_TO_SCALE_FACTOR_16(.25075), OFFSET_ZERO, analog_port_external_adc, NO_OVER_TRIP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36582.analog_input_5v_mon, MACRO_DEC_TO_SCALE_FACTOR_16(.12500), OFFSET_ZERO, ANALOG_INPUT_NO_CALIBRATION, PWR_5V_OVER_FLT, PWR_5V_UNDER_FLT, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER, NO_COUNTER); // Configure SPI port, used by External ADC ConfigureSPI(ETM_SPI_PORT_2, ETM_DEFAULT_SPI_CON_VALUE, ETM_DEFAULT_SPI_CON2_VALUE, ETM_DEFAULT_SPI_STAT_VALUE, SPI_CLK_2_MBIT, FCY_CLK); //Initialize the internal ADC for Startup Power Checks // ---- Configure the dsPIC ADC Module ------------ // ADPCFG = ADPCFG_SETTING; // Set which pins are analog and which are digital I/O ADCON1 = ADCON1_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters ADCON2 = ADCON2_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters ADCON3 = ADCON3_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters ADCHS = ADCHS_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters //ADCSSL = ADCSSL_SETTING_STARTUP; _ADIF = 0; _ADON = 1; while (_ADIF == 0); // Wait for 16 ADC conversions to complete; _ADON = 0; global_data_A36582.analog_input_5v_mon.filtered_adc_reading = ADCBUF0 + ADCBUF1 + ADCBUF2 +ADCBUF3 + ADCBUF4 + ADCBUF5 + ADCBUF6 + ADCBUF7; global_data_A36582.analog_input_5v_mon.filtered_adc_reading += ADCBUF8 + ADCBUF9 + ADCBUFA +ADCBUFB + ADCBUFC + ADCBUFD + ADCBUFE + ADCBUFF; ETMAnalogScaleCalibrateADCReading(&global_data_A36582.analog_input_5v_mon); if (ETMAnalogCheckOverAbsolute(&global_data_A36582.analog_input_5v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; // DPARKER use the self test bits } if (ETMAnalogCheckUnderAbsolute(&global_data_A36582.analog_input_5v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; // DPARKER use the self test bits } ADCON1 = ADCON1_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters ADCON2 = ADCON2_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters ADCON3 = ADCON3_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters ADCHS = ADCHS_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters //ADCSSL = ADCSSL_SETTING_STARTUP; _ADIF = 0; _ADON = 1; _SAMP = 1; // Read Data from EEPROM if (global_data_A36582.external_eeprom_error == 0) { // Only read from the EEPROM if we can connect to it succesfully ETMEEPromReadPage(PULSE_COUNT_REGISTER_A, 7, &pulse_data_A[0]); ETMEEPromReadPage(PULSE_COUNT_REGISTER_B, 7, &pulse_data_B[0]); // If the data checks out, update with data if (pulse_data_A[6] == ETMCRCModbus(pulse_data_A, 12)) { global_data_A36582.arc_total = *(unsigned long*)&pulse_data_A[0]; global_data_A36582.pulse_total = *(unsigned long long*)&pulse_data_A[2]; } else if (pulse_data_B[6] == ETMCRCModbus(pulse_data_B, 12)) { global_data_A36582.arc_total = *(unsigned long*)&pulse_data_B[0]; global_data_A36582.pulse_total = *(unsigned long long*)&pulse_data_B[2]; } else { // Both EEPROM Registers were corrupted global_data_A36582.arc_total = 0; //global_data_A36582.arc_total |= 0x00000000; // Set the highest bit high to indicate an EEPROM reading error global_data_A36582.pulse_total = 0; //global_data_A36582.pulse_total |= 0x0000000000000000; // Set the highest bit high to indicate an EEPROM reading error } } else { // There is an EEPROM Error, use values that we can use to interpret global_data_A36582.arc_total = 0; //global_data_A36582.arc_total |= 0x00000000; // Set the highest bit high to indicate an EEPROM reading error global_data_A36582.pulse_total = 0; //global_data_A36582.pulse_total = 0x0000000000000000; // Set the highest bit high to indicate an EEPROM reading error } // Run a dummy conversion _SAMP = 0; }