123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- /*********************************************************************
- *
- * BMS Slave Main File
- *
- *********************************************************************
- * FileName: BMS_Slave.c
- * Processor: PIC18F45K80
- * Compiler: Microchip C18 v3.41
- * Company: KIT - CN - IPE
- *
- * Author Date Comment
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Reiling V. 04.04.2012 Release
- *********************************************************************/
- /*********************************************************************
- *
- * Include Files
- *
- ********************************************************************/
- #include "BMS_Slave.h"
- /*********************************************************************
- *
- * Pragmas
- *
- *********************************************************************/
- #pragma config XINST = OFF
- #pragma config FOSC = HS1
- #pragma config WDTEN = OFF // SWDTDIS
- #pragma config WDTPS = 256 // WD TimeOut 1024ms
- #pragma config SOSCSEL = DIG // Port C, Pin 0 & 1 => Digital
- #pragma config PLLCFG = ON
- /*********************************************************************
- *
- * Globals
- *
- *********************************************************************/
- uint32_t CAN_BAL = 0;
- uint16_t gEvent = 0;
- uint8_t gCounter = 0;
- uint8_t MuxCounter = 0; // MuxCounter for Temp.
- uint8_t SlaveMode = INITIALISATION_MODE; // UI Initialisierung
- uint8_t Alive_Master = 0; // Alivecounter Master
- uint8_t Alive_Slave = 0; // Alivecounter Slave
- uint8_t Check_Alive_Master = 0; // Check Alivecounter Master
- uint8_t Count_Error_Master = 0; // Counter-Error Master
- uint8_t SPI_SyncFlag = SPI_SYNC_OFF;
- uint8_t STATE_STATUS = RUN_SLAVE;
- volatile uint16_t timeout_cnt=0;
- SERIAL_NR_t gSerial;
- extern ERROR_flags gERROR;
- /*********************************************************************
- *
- * 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 % 3)) // jeder 3. Interrupt ist 30ms Event
- gEvent |= EV__TimeSlot30ms;
-
- if(!(gTimeSlotCount % 10)) // jeder 10. Interrupt ist 100ms Event
- {
- gEvent |= EV__TimeSlot100ms;
- LATE ^= 2; // toggle LED_1
- if(SlaveMode == RUN_MODE) {
- timeout_cnt++;
- }
- }
- if(gTimeSlotCount == 5) // 1. Temperature Event
- gEvent |= EV__TimeSlotT;
- if(gTimeSlotCount == 8) // 2. Temperature Event
- gEvent |= EV__TimeSlotT;
- if(gTimeSlotCount == 11) // 3. Temperature Event
- gEvent |= EV__TimeSlotT;
- if(gTimeSlotCount == 14) // 4. Temperature Event
- gEvent |= EV__TimeSlotT;
- if(gTimeSlotCount == 17) // 5. Temperature Event
- gEvent |= EV__TimeSlotT;
- if(gTimeSlotCount == 20) // 6. Temperature Event
- gEvent |= EV__TimeSlotT;
- if(!(gTimeSlotCount % 100)) // jeder 100. Interrupt ist 1000ms Event
- {
- gEvent |= EV__TimeSlot1000ms;
- gTimeSlotCount = 0;
- }
-
- gTimeSlotCount++; // naechster Slot
- }
- if(PIR5bits.RXBnIF && PIE5bits.RXBnIE) // bei Auslösen des CAN-Empfangen-Interrupts
- {
- SPI_SyncFlag = SPI_SYNC_ON;
- PIR5bits.RXBnIF = 0;
- CAN_Write_Voltage(); // Tx CAN Spannungswerte
- CAN_Write_Temperature(); // Tx CAN Temperaturwerte
- CAN_Write_Status(); // Tx CAN Statuswerte
- CAN_Read_Balancing(); // CAN RX Auswertung
- timeout_cnt=0;
- gCounter++;
- MuxCounter++;
- if(gCounter >= MAX_ALIVE) // After 7 alive Counter is set to 0
- {
- gCounter = 0;
- }
- if(MuxCounter >= MAX_MUX) // After 5 Mux Counter is set to 0
- {
- MuxCounter = 0;
- }
- }
- }
- #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
- LTC_Init( );
- SlaveMode = SlaveStatus;
- }
- // ***** MAIN SLAVE ***************************************************************
- void main(void)
- {
- uint16_t PEC = 0;
- uint8_t EEPROM_DATA = 0;
- int32_t adc_value = 0;
- // ***** SLAVE STATUS *************************************************************
- switch( SlaveMode )
- {
- // ***** OFF or POWERUP ********************************************************
- case STANDBY_MODE :
- CAN_Read_Master(); // Read Master Frame
- if(SlaveMode == RUN_MODE)
- {
- 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;
- // ***** SLAVE INITIALISATION ********************************************************
- case INITIALISATION_MODE :
- EEPROM_DATA = EEread(EE_START_a); // Read data from EEPROM
- SlaveMode = CALIBRATION_MODE;
- if( !(EEPROM_DATA == EE_LOAD) )
- {
- SlaveMode = RESET_MODE;
- }
- ini(SlaveMode); // Ini des BMS Slaves
-
- // Readout AN0 and AN1
- adc_value = ADC_supply_voltage();
- if( (adc_value > SUPPLY_MAX) | (adc_value < SUPPLY_MIN) )
- {
- gERROR.LIMITVOLTAGE = 1;
- }
- break;
- // ***** SLAVE CALIBRATION ********************************************************
- case CALIBRATION_MODE :
-
- PEC = LTC_SelfTest(); // Selbsttest der LTCs
- SlaveMode = STANDBY_MODE; // Standby Mode
- break;
- // ***** RUN MODE **************************************************************
- case RUN_MODE :
- if( gEvent & EV__TimeSlot30ms ) // wenn 30ms Slot
- {
- gEvent &= (~EV__TimeSlot30ms); // reset 30ms Flag
- if(gEvent & EV__LTC_V_Start)
- Set_LTC_TimeOut();
- else
- {
- gEvent |= EV__LTC_V_Start; // set Spg Messung Start
- }
- }
- if( gEvent & EV__TimeSlot100ms ) // wenn 100ms Slot
- {
- gEvent &= (~EV__TimeSlot100ms); // reset 100ms Flag
- }
- if( gEvent & EV__TimeSlotT ) // wenn T Slot
- {
- gEvent &= (~EV__TimeSlotT); // reset T Slot
- if(gEvent & EV__LTC_T_Start)
- Set_LTC_TimeOut();
- else
- gEvent |= EV__LTC_T_Start; // set Temperatur Messung Start
- }
- if( gEvent & EV__TimeSlot1000ms ) // wenn 1000ms Slot
- {
- gEvent &= (~EV__TimeSlot1000ms); // reset 1000ms Flag
- if(Count_Error_Master >= 4)
- {
- SlaveMode = ERROR_MODE; // Slave Error Case
- }
- gERROR.LIMITVOLTAGE = 0; // Clear Errorflag
-
- // Readout AN0 and AN1
- adc_value = ADC_supply_voltage();
- if( (adc_value > SUPPLY_MAX) | (adc_value < SUPPLY_MIN) )
- {
- gERROR.LIMITVOLTAGE = 1;
- }
- Count_Error_Master = 0; // clear Error Master
- }
- if( !(gEvent & ( EV__LTC_V_Wait + EV__LTC_T_Wait ))) // wenn keine Messung laeuft
- {
- if(timeout_cnt > 10) // Shutdown LTC if there is no longer response from Master
- {
- CAN_BAL = 0x00; //Set Balancing off
- LTC_Terminate(); //Shutdown LTC
- }
- if(SPI_SyncFlag == SPI_SYNC_ON)
- {
- SPI_SyncFlag = SPI_SYNC_OFF;
- LTC_SetCFG(CDC_1, CAN_BAL, ~CAN_BAL); // Set Balancing Outs
- }
- }
- LTC_Do(&gEvent); // Ablaufsteuerung Messung ausführen
- break;
- // ***** ERROR MODE ************************************************************
- case ERROR_MODE :
-
- LATE = LATE & 0xFC; // LED0, LED1 = off
- STATE_STATUS = RUN_SLAVE;
- SlaveMode = RUN_MODE;
- break;
- // ***** RESET SLAVE **************************************************************
- case RESET_MODE :
-
- if(STATE_STATUS == RUN_SLAVE)
- {
- LATE |= 3; // LED0, LED1 = on
- 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
- }
|