123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- /*********************************************************************
- *
- * BMS UI Main File
- *
- *********************************************************************
- * FileName: BMS_UI_Main.c
- * Processor: PIC18F25K80
- * Compiler: Microchip C18 v3.41
- * Company: KIT - CN - IPE
- *
- * Author Date Comment
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Ott W. 08.02.2016 Release
- *********************************************************************/
- /*********************************************************************
- *
- * Include Files
- *
- ********************************************************************/
- #include "BMS_UI_Main.h"
- /*********************************************************************
- *
- * Pragmas
- *
- *********************************************************************/
- #pragma config XINST = OFF
- #pragma config FOSC = HS1
- #pragma config WDTEN = OFF
- #pragma config WDTPS = 256 // WD TimeOut 1024ms
- #pragma config SOSCSEL = DIG // Port C, Pin 0 & 1 => Digital
- #pragma config PLLCFG = ON
- /*********************************************************************
- *
- * Globals
- *
- *********************************************************************/
- uint16_t gEvent = 0;
- uint16_t gVoltage = 0;
- int16_t gCurrent = 0;
- int16_t gOffsetCurrent = 0;
- uint16_t gOffsetVoltage = 0;
- uint8_t gCounter = 0;
- uint8_t Write_Flag = 0;
- uint8_t Send_Master = 0;
- uint8_t Check_Can_Flag = 0;
- uint8_t STATE_STATUS = RUN_UI;
- uint8_t UI_ERROR = NO_ERROR;
- uint8_t gERROR_Counter = 0;
- uint8_t t_POWER_PIN = 0;
- SERIAL_NR_t gSerial;
- uint8_t UIMode = INITIALISATION_MODE; // UI Initialisierung
- #pragma udata udata1
- uint8_t Alive_Slave[160]; // Alivecounter Slave
- #pragma udata udata2
- uint8_t Count_Error_Slave[160]; // Counter-Error Slave
- #pragma udata udata3
- uint8_t Check_Alive_Slave[160]; // Check Alivecounter Slave
- #pragma udata udata4
- IRC_MSG_BUF gIRC_MSG_BUF;
- #pragma udata // return to default section
- uint8_t Alive_Master[16]; // Alivecounter Master
- uint8_t Check_Alive_Master[16]; // Check Alivecounter Master
- uint8_t Count_Error_Master[16]; // Counter-Error Master
- uint8_t EEPROM_DATA;
- CAN_CONFIG gCAN_CONFIG = {
- SlaveNo_VAL,
- BRP_VAL,
- PROPSEG_VAL,
- PHSEG1_VAL,
- PHSEG2_VAL,
- SJW_VAL,
- PHSEG2_MODE_VAL,
- BUS_SAMPLE_MODE_VAL,
- WAKEUP_MODE_VAL,
- FILTER_MODE_VAL};
- volatile uint16_t timeout_cnt=0;
- /*********************************************************************
- *
- * Interrupt Vector Tabelle
- *
- *********************************************************************/
- #pragma code low_vetor=0x18
- void interrupt_at_low_vector(void)
- {
- _asm GOTO my_isr _endasm
- }
- #pragma code // Return to default code section
- /*********************************************************************
- *
- * Interrupt High-priority service
- *
- *********************************************************************/
- #pragma interrupt my_isr
- void my_isr(void)
- {
- static int32_t gTimeSlotCount = 0;
- /***** Timer 1 Code *****/
- if ((PIE1bits.TMR1IE) && (PIR1bits.TMR1IF))
- {
- TMR1H = 178; // reload Timer
- TMR1L = 0; // 10 ms bei 16 Mhz OSC
- PIR1bits.TMR1IF = 0; // clear event flag
- if (!(gTimeSlotCount % 5)) // jeder MS_Count Interrupt ist 50ms Event
- {
- gEvent |= EV__TimeSlot;
- //timeout_cnt++;
- }
- if(!(gTimeSlotCount % 100)) // jeder 100. Interrupt ist 1000ms Event
- {
- gEvent |= EV__TimeSlot1000ms;
- }
- gTimeSlotCount++; // naechster Slot
- }
- if(PIR5bits.RXBnIF && PIE5bits.RXBnIE) // bei Auslösen des CAN-Empfangen-Interrupts
- {
- timeout_cnt=0;
- CAN_Read_Master_Slave(); // Read Canbus
-
- if(Write_Flag == 1)
- {
- CAN_Write_UI(); // Tx CAN UI-Werte
- Write_Flag = 0;
- Send_Master = 0; // Clear Flag Can Master receive
- gCurrent = 0; // Clear gCurrent
- }
- }
- }
- #pragma interrupt my_isr
- /*********************************************************************
- *
- * Intialisierung des BMS Slave
- *
- *********************************************************************/
- void ini(uint8_t SlaveStatus) {
- uint8_t RCONcopy = RCON;
-
- RCONcopy &= 0x3B; // IPEN, SBOREN und /PD wegfiltern
- switch (RCONcopy) {
- case 0x33: // Watch Dog Timer Reset
- ClrWdt(); // WDT Reset
- break;
- case 0x38: // Power On Reset
- break;
- case 0x3A: // Brown Out Reset
- break;
- case 0x2B: // Reset by Software
- break;
- case 0x1B: // Configuration Mismatch Reset
- break;
- default: // Stack Over/Under Flow Reset or Combinations
- break;
- }
- RCON |= 0x3F; // Reset Flags clear
- OSCCONbits.IRCF0 = 0; // 2MHz Prescaler für SPI
- OSCCONbits.IRCF1 = 1;
- OSCCONbits.IRCF2 = 1;
- OSCTUNEbits.PLLEN = 0; // PLL on
- // 12 Bit ADC Settings
- ADCON0 = 0x00; // Clear ADCON0 register
- ADCON1 = 0x10; // External Vref+ = 4,1V, Vreg- = 0V
- ADCON2 = 0x92; // right justifield, 4Tad, Fosc/32
- ANCON0 = 0x03; // AN0, AN1 as analog inputs
- ANCON1 = 0x00;
- ADCON0bits.ADON = 0x01; //Enable A/D module
- TRISAbits.TRISA0 = 1; // PortA.0 = Analog In (High Voltage)
- TRISAbits.TRISA1 = 1; // PortA.1 = Analog In (LEM Current)
- LATAbits.LATA5 = 1; // AD_CS Off (UH SPI CS OFF)
- TRISAbits.TRISA5 = 0; // Output AD_CS (UH SPI CS)
- TRISB = 0xFB; // Port B Input (PB.2 = CAN_1_TX Output)
- LATCbits.LATC0 = 1; // AD_CS_2 Off (IH SPI CS OFF)
- TRISCbits.TRISC0 = 0; // Output AD_CS_2 (IH SPI CS)
- LATCbits.LATC1 = 0; // CS_HV_plus Off
- TRISCbits.TRISC1 = 0; // Output CS_HV_plus
- LATCbits.LATC2 = 0; // CS_HV_minus Off
- TRISCbits.TRISC2 = 0; // Output CS_HV_minus
- TRISCbits.TRISC3 = 0; // Output AD_CLK (SPI CLK)
- TRISCbits.TRISC5 = 0; // Output AD_DOUT (SPI SDO)
- LATCbits.LATC6 = 0; // POWER OFF diactivated
- TRISCbits.TRISC6 = 0; // Output POWER OFF
- // Init SPI
- SSPCON1bits.SSPM = 0x02; // SSPM<3:0> = 0010 => SPI Master mode, clock = FOSC/64
- SSPCON1bits.CKP = 0; // Idle state for clock is a high level
- SSPCON1bits.SSPEN = 1; // enables SPI and configures SDA, SDI, and SCL pins as SPI pins
- SSPSTATbits.CKE = 0; // SDI by SCL Low/High
- PIR1bits.SSPIF = 0; // clear SPI IF
- //Init Timer
- T1CONbits.T1CKPS0 = 1; // Timer 1 prescalar = 0b00
- T1CONbits.T1CKPS1 = 1; // = (Fosc/4) / 8 = 2MHz
- IPR1bits.TMR1IP = 0; // 1 = make this a low priority interrupt
- PIE1bits.TMR1IE = 1; // enable Timer interrupt
- PIR1bits.TMR1IF = 0; // clear any pending events
- T1CONbits.RD16 = 1; // 16 Bit read-write mode
- T1CONbits.TMR1ON = 1; // Timer A run
- gCAN_CONFIG.SlaveNo = gSerial.EE_BYTE.SLAVE_ID;
- CAN_Init(&gCAN_CONFIG);
- INTCONbits.GIE = 1;
- INTCONbits.PEIE = 1;
- UIMode = SlaveStatus;
- }
- // ***** MAIN UI ***************************************************************
- void main(void)
- {
- uint8_t i;
- uint8_t k;
- uint32_t check_id;
- uint8_t check_data[8];
- int32_t adc_value = 0;
-
- // ***** UI STATUS *************************************************************
- switch( UIMode )
- {
- // ***** OFF or POWERUP ********************************************************
- case STANDBY_MODE :
- CAN_Read_Master();
- if(UIMode == RUN_MODE)
- {
- // If current offset exceeds the limit --> Error currenrsense dysfunction
- if( (gOffsetCurrent > ERROR_OFFSET_p) | (gOffsetCurrent < ERROR_OFFSET_n) )
- {
- UI_ERROR |= OFFSET_ERROR;
- UIMode = ERROR_MODE;
- }
- // Readout AN0 and AN1
- for(i = 0; i < 2; i++)
- {
- adc_value = ADC_supply_voltage( i );
- if( (adc_value > SUPPLY_MAX) | (adc_value < SUPPLY_MIN) )
- {
- UI_ERROR |= SUPPLY_ERROR;
- UIMode = ERROR_MODE;
- }
- }
- // If no Error, turn Relais on
- if(UI_ERROR == NO_ERROR)
- {
- LATCbits.LATC1 = 1; // Relais HV_plus on
- LATCbits.LATC2 = 1; // Relais HV_minus on
- }
- IPR5bits.RXBnIP = 0; // 0 = make this a low priority interrupt
- PIE5bits.RXBnIE = 1; // enable CAN-Receive interrupt
- PIR5bits.RXBnIF = 0; // clear any pending events
- BIE0 = 0x0F;
- }
- break;
- // ***** UI INITIALISATION ********************************************************
- case INITIALISATION_MODE :
- EEPROM_DATA = EEread(EE_START_a); // Read data from EEPROM
- UIMode = CALIBRATION_MODE;
- if( !(EEPROM_DATA == EE_LOAD) )
- {
- //UIMode = RESET_MODE;
- }
- ini(UIMode); // Ini des BMS UI
- // Clear alive-and errorcounter for Master
- for(i=0; i < 16; i++)
- {
- Alive_Master[i] = 0;
- Check_Alive_Master[i] = 0;
- Count_Error_Master[i] = 0;
- }
- // Clear alive-and errorcounter for Slaves
- for(i=0; i < 160; i++)
- {
- Alive_Slave[i] = 0;
- Check_Alive_Slave[i] = 0;
- Count_Error_Slave[i] = 0;
- }
-
- break;
- // ***** UI CALIBRATION ********************************************************
- case CALIBRATION_MODE :
- Measure(); // Offset measure
- gOffsetCurrent = gCurrent; // Offset corr Current
- gCurrent = 0;
- gOffsetVoltage = gVoltage; // Offset corr Voltage
- UIMode = STANDBY_MODE; // Standby Mode
- break;
- // ***** RUN MODE **************************************************************
- case RUN_MODE :
-
- if (gEvent & EV__TimeSlot) // wenn Time Slot Event
- {
- gEvent &= (~EV__TimeSlot); // reset Time Slot Event
- timeout_cnt++;
- Measure(); // Messung ausführen
- if( (gCurrent > MAX_CURRENT) | (gCurrent < MIN_CURRENT) )
- {
- UIMode = ERROR_MODE;
- }
- }
- // No response from Master
- if(timeout_cnt > (3000+t_POWER_PIN)) //after 300 sec POWER OFF activated
- {
- t_POWER_PIN++;
- LATCbits.LATC6 ^= 1;
- }
- else if(timeout_cnt > 10) // after 1 sec Relais switch off
- {
- UIMode = ERROR_MODE;
- }
- if(gEvent & EV__TimeSlot1000ms) // wenn Time Slot Event
- {
- gEvent &= (~EV__TimeSlot1000ms); // reset Time Slot Event
- gERROR_Counter = 0; // Clear Errorflag
- CAN_Alive();
- // Readout AN0 and AN1
- for(i = 0; i < 2; i++)
- {
- adc_value = ADC_supply_voltage( i );
- if( (adc_value > SUPPLY_MAX) | (adc_value < SUPPLY_MIN) )
- {
- UI_ERROR = SUPPLY_ERROR;
- UIMode = ERROR_MODE;
- }
- }
- Send_Master = 1; // Set Flag Can Master receive
- }
- if(Check_Can_Flag == 1)
- {
- Check_Can_Flag = 0;
- for(k = 0; k < 9; k++)
- {
- check_id = gIRC_MSG_BUF.CAN_ID[k];
- for(i = 0; i < 8; i++)
- {
- check_data[i] = gIRC_MSG_BUF.CAN_DATA[k][i];
- }
- if( (check_id & 0xF00) == 0x100 )
- {
- CAN_Master_check(check_id, &check_data[0]);
- }
- else
- {
- CAN_Slave_check(check_id, &check_data[0]);
- }
-
- }
- }
- break;
- // ***** ERROR MODE ************************************************************
- case ERROR_MODE :
- LATCbits.LATC2 = 0; // Relais HV_minus off
- LATCbits.LATC1 = 0; // Relais HV_plus off
- UI_ERROR |= RELAIS_OFF;
- UIMode = RUN_MODE;
- break;
- // ***** RESET UI **************************************************************
- case RESET_MODE :
- if(STATE_STATUS == RUN_UI)
- {
- INTCONbits.GIE = 0; // disable Interrupt
- INTCONbits.PEIE = 0;
- PIE5bits.RXBnIE = 0; // disable CAN-Receive interrupt
-
- STATE_STATUS = UNLOCK_SYSTEM_CAN;
- // Unlock System Frame for autom. ID allocation
- ECANSetRXM0Value(0xDFF, ECAN_MSG_STD); // activate 0x300 Frame
- ECANSetRXF0Value(0x100, ECAN_MSG_STD); // Change start adress for new Canid
- }
- CAN_Read_System(); // CAN RX System
- break;
- // ***** PV__STAND_BY **********************************************************
- default :
- break;
- }
-
- ClrWdt(); // WDT Reset
- }
|