void DoA36772(void) { ETMCanSlaveDoCan(); ClrWdt(); unsigned int crc_int; unsigned int crc_16_msb; if (_T3IF) { // Run once every 100us _T3IF = 0; if (global_data_A36772.waiting_to_transmit) { global_data_A36772.delay_time++; } } if (global_data_A36772.trigger_received){ unsigned char output_data[4]; global_data_A36772.trigger_received = 0; global_data_A36772.waiting_to_transmit = 1; global_data_A36772.message1_energy ^= 0x01; output_data[1] = global_data_A36772.message1_energy; global_data_A36772.message0_dose = Dose_Array[global_data_A36772.dose_switch_value]; output_data[0] = global_data_A36772.message0_dose; output_data[2] = 0; output_data[3] = 0; // if (global_data_A36772.message1_energy) { // crc_int = CRC_High_Energy[global_data_A36772.dose_switch_value]; // } else { // crc_int = CRC_Low_Energy[global_data_A36772.dose_switch_value]; // } crc_int = ETMCRC16(output_data, 4); crc_16_msb = crc_int >> 8; global_data_A36772.message5_crc_high = (unsigned char)crc_16_msb & 0xff; global_data_A36772.message4_crc_low = (unsigned char)crc_int & 0xff; }
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 DoStateMachine(void) { switch (global_data_A36444.control_state) { case STATE_STARTUP: InitializeA36444(); DisableHVLambda(); _CONTROL_NOT_CONFIGURED = 1; _CONTROL_NOT_READY = 1; _STATUS_STATE_FAULT = 0; global_data_A36444.control_state = STATE_WAITING_FOR_CONFIG; break; case STATE_WAITING_FOR_CONFIG: DisableHVLambda(); _CONTROL_NOT_READY = 1; _STATUS_STATE_FAULT = 0; while (global_data_A36444.control_state == STATE_WAITING_FOR_CONFIG) { DoA36444(); ETMCanSlaveDoCan(); if (_CONTROL_NOT_CONFIGURED == 0) { global_data_A36444.control_state = STATE_WAITING_FOR_POWER; } } break; case STATE_WAITING_FOR_POWER: DisableHVLambda(); _CONTROL_NOT_READY = 1; _STATUS_STATE_FAULT = 0; while (global_data_A36444.control_state == STATE_WAITING_FOR_POWER) { DoA36444(); ETMCanSlaveDoCan(); if (PIN_LAMBDA_NOT_POWERED != ILL_LAMBDA_NOT_POWERED) { global_data_A36444.control_state = STATE_POWER_UP; } } break; case STATE_POWER_UP: EnableHVLambda(); _CONTROL_NOT_READY = 1; _STATUS_STATE_FAULT = 0; global_data_A36444.power_up_delay_counter = 0; while (global_data_A36444.control_state == STATE_POWER_UP) { DoA36444(); ETMCanSlaveDoCan(); if (global_data_A36444.power_up_delay_counter >= POWER_UP_DELAY) { global_data_A36444.control_state = STATE_POWER_TEST; } if (global_data_A36444.power_up_delay_counter >= POWER_UP_DELAY) { if (_STATUS_LAMBDA_AT_EOC) { global_data_A36444.control_state = STATE_OPERATE; } else { global_data_A36444.control_state = STATE_FAULT_WAIT; _FAULT_POWER_UP_TIMEOUT = 1; } } } break; case STATE_POWER_TEST: global_data_A36444.control_state = STATE_OPERATE; break; case STATE_OPERATE: _FAULT_REGISTER = 0; _CONTROL_NOT_READY = 0; _STATUS_STATE_FAULT = 0; while (global_data_A36444.control_state == STATE_OPERATE) { DoA36444(); ETMCanSlaveDoCan(); if (global_data_A36444.fault_active) { global_data_A36444.control_state = STATE_FAULT_WAIT; } if (global_data_A36444.run_post_pulse_process) { // Run this once after each pulse // Send the pulse data up to the ECB for logging if (_SYNC_CONTROL_HIGH_SPEED_LOGGING) { ETMCanSlaveLogCustomPacketC(); } // 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); global_data_A36444.no_pulse_counter = 0; global_data_A36444.run_post_pulse_process = 0; } } break; case STATE_FAULT_WAIT: DisableHVLambda(); _CONTROL_NOT_READY = 1; _STATUS_STATE_FAULT = 1; global_data_A36444.fault_wait_time = 0; while (global_data_A36444.control_state == STATE_FAULT_WAIT) { DoA36444(); ETMCanSlaveDoCan(); if (global_data_A36444.fault_wait_time >= TIME_WAIT_FOR_LAMBDA_TO_SET_FAULT_OUTPUTS) { global_data_A36444.control_state = STATE_FAULT; } } break; case STATE_FAULT: DisableHVLambda(); _CONTROL_NOT_READY = 1; _STATUS_STATE_FAULT = 1; while (global_data_A36444.control_state == STATE_FAULT) { DoA36444(); ETMCanSlaveDoCan(); if (PIN_LAMBDA_NOT_POWERED == ILL_LAMBDA_NOT_POWERED) { global_data_A36444.control_state = STATE_WAITING_FOR_CONFIG; } } break; default: global_data_A36444.control_state = STATE_FAULT; break; } }
void DoA36582(void) { ETMCanSlaveDoCan(); if (ETMCanSlaveGetSyncMsgSystemHVDisable()) { _INT1IE = 0; } else { _INT1IE = 1; } if (ETMCanSlaveGetSyncMsgClearDebug()) { arc_this_hv_on = 0; global_data_A36582.pulse_this_hv_on = 0; pulse_out_of_range_count = 0; } if (ETMCanSlaveGetComFaultStatus()) { _FAULT_CAN_COMMUNICATION_LATCHED = 1; } if (_T3IF) { _T3IF = 0; if (global_data_A36582.external_eeprom_error) { _WARNING_EEPROM_ERROR = 1; } else { _WARNING_EEPROM_ERROR = 0; } // 10ms has passed if (global_data_A36582.control_state == STATE_FLASH_LED) { global_data_A36582.led_flash_counter++; } // Run at 1 second interval global_data_A36582.millisecond_counter += 10; if (global_data_A36582.millisecond_counter >= 1000) { global_data_A36582.millisecond_counter = 0; SavePulseCountersToEEProm(); } // ----------------- UPDATE LOGGING DATA ------------------------ // ETMCanSlaveSetDebugRegister(0, global_data_A36582.fast_arc_counter); ETMCanSlaveSetDebugRegister(1, global_data_A36582.slow_arc_counter); ETMCanSlaveSetDebugRegister(2, global_data_A36582.consecutive_arc_counter); ETMCanSlaveSetDebugRegister(3, global_data_A36582.poor_pulse_counter); //ETMCanSlaveSetDebugRegister(4, global_data_A36582.filt_int_adc_low); //ETMCanSlaveSetDebugRegister(5, global_data_A36582.filt_ext_adc_low); //ETMCanSlaveSetDebugRegister(6, global_data_A36582.filt_int_adc_high); //ETMCanSlaveSetDebugRegister(7, global_data_A36582.filt_ext_adc_high); ETMCanSlaveSetDebugRegister(8, global_data_A36582.imag_external_adc.reading_scaled_and_calibrated); ETMCanSlaveSetDebugRegister(9, global_data_A36582.imag_internal_adc.reading_scaled_and_calibrated); ETMCanSlaveSetDebugRegister(10, global_data_A36582.pulse_with_no_trigger_counter); ETMCanSlaveSetDebugRegister(11, global_data_A36582.minimum_pulse_period_fault_count); ETMCanSlaveSetDebugRegister(12, global_data_A36582.false_trigger_counter); ETMCanSlaveSetDebugRegister(13, over_current_arc_count); ETMCanSlaveSetDebugRegister(14, under_current_arc_count); *(unsigned long long*)&slave_board_data.log_data[8] = global_data_A36582.pulse_total; *(unsigned long*)&slave_board_data.log_data[4] = global_data_A36582.pulse_this_hv_on; *(unsigned long*)&slave_board_data.log_data[6] = global_data_A36582.arc_total; // Update tthe false trigger counter global_data_A36582.false_trigger_decrement_counter++; if (global_data_A36582.false_trigger_decrement_counter >= FALSE_TRIGGER_DECREMENT_10_MS_UNITS) { global_data_A36582.false_trigger_decrement_counter = 0; if (global_data_A36582.false_trigger_counter) { global_data_A36582.false_trigger_counter--; } } if (global_data_A36582.false_trigger_counter >= FALSE_TRIGGERS_FAULT_LEVEL) { _FAULT_FALSE_TRIGGER = 1; } } // DPARKER - THIS DID NOT WORK - IT RESET THE LATCHES WHEN THEY SHOULD NOT BE AND CAUSED FALSE ARCS TO BE DETECTED // However we may need some way to reset the pulse latches if they are set for a long time // If this happens, INT3 will not trigger and we will loose the ability to detect pulses without a trigger // Perhaps another counter that if there has been no trigger for the previous second, then if the latches are set they are cleared. // Alternatively we could check the state of the latches inside the interrupt. That way the checks can't be broken by this call /* // Reset the pulse latches if they are set and it has been more than 2ms since the last pulse if ((TMR2 > TIMER_4_TIME_2_MILLISECONDS) && (PIN_PULSE_OVER_CURRENT_LATCH_4 == ILL_LATCH_SET)) { ResetPulseLatches(); // DPARKER. why doesn't this clear the fault latches before a fault latch check. You would think that the TMR2 check would prevent this. // Perhaps adding a long delay and then reckecking TMR2 before the ResetPulseLatches would fix the problem? } */ }