BMS_UI_Main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*********************************************************************
  2. *
  3. * BMS UI Main File
  4. *
  5. *********************************************************************
  6. * FileName: BMS_UI_Main.c
  7. * Processor: PIC18F25K80
  8. * Compiler: Microchip C18 v3.41
  9. * Company: KIT - CN - IPE
  10. *
  11. * Author Date Comment
  12. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  13. * Ott W. 08.02.2016 Release
  14. *********************************************************************/
  15. /*********************************************************************
  16. *
  17. * Include Files
  18. *
  19. ********************************************************************/
  20. #include "BMS_UI_Main.h"
  21. /*********************************************************************
  22. *
  23. * Pragmas
  24. *
  25. *********************************************************************/
  26. #pragma config XINST = OFF
  27. #pragma config FOSC = HS1
  28. #pragma config WDTEN = OFF
  29. #pragma config WDTPS = 256 // WD TimeOut 1024ms
  30. #pragma config SOSCSEL = DIG // Port C, Pin 0 & 1 => Digital
  31. #pragma config PLLCFG = ON
  32. /*********************************************************************
  33. *
  34. * Globals
  35. *
  36. *********************************************************************/
  37. uint16_t gEvent = 0;
  38. uint16_t gVoltage = 0;
  39. int16_t gCurrent = 0;
  40. int16_t gOffsetCurrent = 0;
  41. uint16_t gOffsetVoltage = 0;
  42. uint8_t gCounter = 0;
  43. uint8_t Write_Flag = 0;
  44. uint8_t Send_Master = 0;
  45. uint8_t Check_Can_Flag = 0;
  46. uint8_t STATE_STATUS = RUN_UI;
  47. uint8_t UI_ERROR = NO_ERROR;
  48. uint8_t gERROR_Counter = 0;
  49. uint8_t t_POWER_PIN = 0;
  50. SERIAL_NR_t gSerial;
  51. uint8_t UIMode = INITIALISATION_MODE; // UI Initialisierung
  52. #pragma udata udata1
  53. uint8_t Alive_Slave[160]; // Alivecounter Slave
  54. #pragma udata udata2
  55. uint8_t Count_Error_Slave[160]; // Counter-Error Slave
  56. #pragma udata udata3
  57. uint8_t Check_Alive_Slave[160]; // Check Alivecounter Slave
  58. #pragma udata udata4
  59. IRC_MSG_BUF gIRC_MSG_BUF;
  60. #pragma udata // return to default section
  61. uint8_t Alive_Master[16]; // Alivecounter Master
  62. uint8_t Check_Alive_Master[16]; // Check Alivecounter Master
  63. uint8_t Count_Error_Master[16]; // Counter-Error Master
  64. uint8_t EEPROM_DATA;
  65. CAN_CONFIG gCAN_CONFIG = {
  66. SlaveNo_VAL,
  67. BRP_VAL,
  68. PROPSEG_VAL,
  69. PHSEG1_VAL,
  70. PHSEG2_VAL,
  71. SJW_VAL,
  72. PHSEG2_MODE_VAL,
  73. BUS_SAMPLE_MODE_VAL,
  74. WAKEUP_MODE_VAL,
  75. FILTER_MODE_VAL};
  76. volatile uint16_t timeout_cnt=0;
  77. /*********************************************************************
  78. *
  79. * Interrupt Vector Tabelle
  80. *
  81. *********************************************************************/
  82. #pragma code low_vetor=0x18
  83. void interrupt_at_low_vector(void)
  84. {
  85. _asm GOTO my_isr _endasm
  86. }
  87. #pragma code // Return to default code section
  88. /*********************************************************************
  89. *
  90. * Interrupt High-priority service
  91. *
  92. *********************************************************************/
  93. #pragma interrupt my_isr
  94. void my_isr(void)
  95. {
  96. static int32_t gTimeSlotCount = 0;
  97. /***** Timer 1 Code *****/
  98. if ((PIE1bits.TMR1IE) && (PIR1bits.TMR1IF))
  99. {
  100. TMR1H = 178; // reload Timer
  101. TMR1L = 0; // 10 ms bei 16 Mhz OSC
  102. PIR1bits.TMR1IF = 0; // clear event flag
  103. if (!(gTimeSlotCount % 5)) // jeder MS_Count Interrupt ist 50ms Event
  104. {
  105. gEvent |= EV__TimeSlot;
  106. //timeout_cnt++;
  107. }
  108. if(!(gTimeSlotCount % 100)) // jeder 100. Interrupt ist 1000ms Event
  109. {
  110. gEvent |= EV__TimeSlot1000ms;
  111. }
  112. gTimeSlotCount++; // naechster Slot
  113. }
  114. if(PIR5bits.RXBnIF && PIE5bits.RXBnIE) // bei Auslösen des CAN-Empfangen-Interrupts
  115. {
  116. timeout_cnt=0;
  117. CAN_Read_Master_Slave(); // Read Canbus
  118. if(Write_Flag == 1)
  119. {
  120. CAN_Write_UI(); // Tx CAN UI-Werte
  121. Write_Flag = 0;
  122. Send_Master = 0; // Clear Flag Can Master receive
  123. gCurrent = 0; // Clear gCurrent
  124. }
  125. }
  126. }
  127. #pragma interrupt my_isr
  128. /*********************************************************************
  129. *
  130. * Intialisierung des BMS Slave
  131. *
  132. *********************************************************************/
  133. void ini(uint8_t SlaveStatus) {
  134. uint8_t RCONcopy = RCON;
  135. RCONcopy &= 0x3B; // IPEN, SBOREN und /PD wegfiltern
  136. switch (RCONcopy) {
  137. case 0x33: // Watch Dog Timer Reset
  138. ClrWdt(); // WDT Reset
  139. break;
  140. case 0x38: // Power On Reset
  141. break;
  142. case 0x3A: // Brown Out Reset
  143. break;
  144. case 0x2B: // Reset by Software
  145. break;
  146. case 0x1B: // Configuration Mismatch Reset
  147. break;
  148. default: // Stack Over/Under Flow Reset or Combinations
  149. break;
  150. }
  151. RCON |= 0x3F; // Reset Flags clear
  152. OSCCONbits.IRCF0 = 0; // 2MHz Prescaler für SPI
  153. OSCCONbits.IRCF1 = 1;
  154. OSCCONbits.IRCF2 = 1;
  155. OSCTUNEbits.PLLEN = 0; // PLL on
  156. // 12 Bit ADC Settings
  157. ADCON0 = 0x00; // Clear ADCON0 register
  158. ADCON1 = 0x10; // External Vref+ = 4,1V, Vreg- = 0V
  159. ADCON2 = 0x92; // right justifield, 4Tad, Fosc/32
  160. ANCON0 = 0x03; // AN0, AN1 as analog inputs
  161. ANCON1 = 0x00;
  162. ADCON0bits.ADON = 0x01; //Enable A/D module
  163. TRISAbits.TRISA0 = 1; // PortA.0 = Analog In (High Voltage)
  164. TRISAbits.TRISA1 = 1; // PortA.1 = Analog In (LEM Current)
  165. LATAbits.LATA5 = 1; // AD_CS Off (UH SPI CS OFF)
  166. TRISAbits.TRISA5 = 0; // Output AD_CS (UH SPI CS)
  167. TRISB = 0xFB; // Port B Input (PB.2 = CAN_1_TX Output)
  168. LATCbits.LATC0 = 1; // AD_CS_2 Off (IH SPI CS OFF)
  169. TRISCbits.TRISC0 = 0; // Output AD_CS_2 (IH SPI CS)
  170. LATCbits.LATC1 = 0; // CS_HV_plus Off
  171. TRISCbits.TRISC1 = 0; // Output CS_HV_plus
  172. LATCbits.LATC2 = 0; // CS_HV_minus Off
  173. TRISCbits.TRISC2 = 0; // Output CS_HV_minus
  174. TRISCbits.TRISC3 = 0; // Output AD_CLK (SPI CLK)
  175. TRISCbits.TRISC5 = 0; // Output AD_DOUT (SPI SDO)
  176. LATCbits.LATC6 = 0; // POWER OFF diactivated
  177. TRISCbits.TRISC6 = 0; // Output POWER OFF
  178. // Init SPI
  179. SSPCON1bits.SSPM = 0x02; // SSPM<3:0> = 0010 => SPI Master mode, clock = FOSC/64
  180. SSPCON1bits.CKP = 0; // Idle state for clock is a high level
  181. SSPCON1bits.SSPEN = 1; // enables SPI and configures SDA, SDI, and SCL pins as SPI pins
  182. SSPSTATbits.CKE = 0; // SDI by SCL Low/High
  183. PIR1bits.SSPIF = 0; // clear SPI IF
  184. //Init Timer
  185. T1CONbits.T1CKPS0 = 1; // Timer 1 prescalar = 0b00
  186. T1CONbits.T1CKPS1 = 1; // = (Fosc/4) / 8 = 2MHz
  187. IPR1bits.TMR1IP = 0; // 1 = make this a low priority interrupt
  188. PIE1bits.TMR1IE = 1; // enable Timer interrupt
  189. PIR1bits.TMR1IF = 0; // clear any pending events
  190. T1CONbits.RD16 = 1; // 16 Bit read-write mode
  191. T1CONbits.TMR1ON = 1; // Timer A run
  192. gCAN_CONFIG.SlaveNo = gSerial.EE_BYTE.SLAVE_ID;
  193. CAN_Init(&gCAN_CONFIG);
  194. INTCONbits.GIE = 1;
  195. INTCONbits.PEIE = 1;
  196. UIMode = SlaveStatus;
  197. }
  198. // ***** MAIN UI ***************************************************************
  199. void main(void)
  200. {
  201. uint8_t i;
  202. uint8_t k;
  203. uint32_t check_id;
  204. uint8_t check_data[8];
  205. int32_t adc_value = 0;
  206. // ***** UI STATUS *************************************************************
  207. switch( UIMode )
  208. {
  209. // ***** OFF or POWERUP ********************************************************
  210. case STANDBY_MODE :
  211. CAN_Read_Master();
  212. if(UIMode == RUN_MODE)
  213. {
  214. // If current offset exceeds the limit --> Error currenrsense dysfunction
  215. if( (gOffsetCurrent > ERROR_OFFSET_p) | (gOffsetCurrent < ERROR_OFFSET_n) )
  216. {
  217. UI_ERROR |= OFFSET_ERROR;
  218. UIMode = ERROR_MODE;
  219. }
  220. // Readout AN0 and AN1
  221. for(i = 0; i < 2; i++)
  222. {
  223. adc_value = ADC_supply_voltage( i );
  224. if( (adc_value > SUPPLY_MAX) | (adc_value < SUPPLY_MIN) )
  225. {
  226. UI_ERROR |= SUPPLY_ERROR;
  227. UIMode = ERROR_MODE;
  228. }
  229. }
  230. // If no Error, turn Relais on
  231. if(UI_ERROR == NO_ERROR)
  232. {
  233. LATCbits.LATC1 = 1; // Relais HV_plus on
  234. LATCbits.LATC2 = 1; // Relais HV_minus on
  235. }
  236. IPR5bits.RXBnIP = 0; // 0 = make this a low priority interrupt
  237. PIE5bits.RXBnIE = 1; // enable CAN-Receive interrupt
  238. PIR5bits.RXBnIF = 0; // clear any pending events
  239. BIE0 = 0x0F;
  240. }
  241. break;
  242. // ***** UI INITIALISATION ********************************************************
  243. case INITIALISATION_MODE :
  244. EEPROM_DATA = EEread(EE_START_a); // Read data from EEPROM
  245. UIMode = CALIBRATION_MODE;
  246. if( !(EEPROM_DATA == EE_LOAD) )
  247. {
  248. //UIMode = RESET_MODE;
  249. }
  250. ini(UIMode); // Ini des BMS UI
  251. // Clear alive-and errorcounter for Master
  252. for(i=0; i < 16; i++)
  253. {
  254. Alive_Master[i] = 0;
  255. Check_Alive_Master[i] = 0;
  256. Count_Error_Master[i] = 0;
  257. }
  258. // Clear alive-and errorcounter for Slaves
  259. for(i=0; i < 160; i++)
  260. {
  261. Alive_Slave[i] = 0;
  262. Check_Alive_Slave[i] = 0;
  263. Count_Error_Slave[i] = 0;
  264. }
  265. break;
  266. // ***** UI CALIBRATION ********************************************************
  267. case CALIBRATION_MODE :
  268. Measure(); // Offset measure
  269. gOffsetCurrent = gCurrent; // Offset corr Current
  270. gCurrent = 0;
  271. gOffsetVoltage = gVoltage; // Offset corr Voltage
  272. UIMode = STANDBY_MODE; // Standby Mode
  273. break;
  274. // ***** RUN MODE **************************************************************
  275. case RUN_MODE :
  276. if (gEvent & EV__TimeSlot) // wenn Time Slot Event
  277. {
  278. gEvent &= (~EV__TimeSlot); // reset Time Slot Event
  279. timeout_cnt++;
  280. Measure(); // Messung ausführen
  281. if( (gCurrent > MAX_CURRENT) | (gCurrent < MIN_CURRENT) )
  282. {
  283. UIMode = ERROR_MODE;
  284. }
  285. }
  286. // No response from Master
  287. if(timeout_cnt > (3000+t_POWER_PIN)) //after 300 sec POWER OFF activated
  288. {
  289. t_POWER_PIN++;
  290. LATCbits.LATC6 ^= 1;
  291. }
  292. else if(timeout_cnt > 10) // after 1 sec Relais switch off
  293. {
  294. UIMode = ERROR_MODE;
  295. }
  296. if(gEvent & EV__TimeSlot1000ms) // wenn Time Slot Event
  297. {
  298. gEvent &= (~EV__TimeSlot1000ms); // reset Time Slot Event
  299. gERROR_Counter = 0; // Clear Errorflag
  300. CAN_Alive();
  301. // Readout AN0 and AN1
  302. for(i = 0; i < 2; i++)
  303. {
  304. adc_value = ADC_supply_voltage( i );
  305. if( (adc_value > SUPPLY_MAX) | (adc_value < SUPPLY_MIN) )
  306. {
  307. UI_ERROR = SUPPLY_ERROR;
  308. UIMode = ERROR_MODE;
  309. }
  310. }
  311. Send_Master = 1; // Set Flag Can Master receive
  312. }
  313. if(Check_Can_Flag == 1)
  314. {
  315. Check_Can_Flag = 0;
  316. for(k = 0; k < 9; k++)
  317. {
  318. check_id = gIRC_MSG_BUF.CAN_ID[k];
  319. for(i = 0; i < 8; i++)
  320. {
  321. check_data[i] = gIRC_MSG_BUF.CAN_DATA[k][i];
  322. }
  323. if( (check_id & 0xF00) == 0x100 )
  324. {
  325. CAN_Master_check(check_id, &check_data[0]);
  326. }
  327. else
  328. {
  329. CAN_Slave_check(check_id, &check_data[0]);
  330. }
  331. }
  332. }
  333. break;
  334. // ***** ERROR MODE ************************************************************
  335. case ERROR_MODE :
  336. LATCbits.LATC2 = 0; // Relais HV_minus off
  337. LATCbits.LATC1 = 0; // Relais HV_plus off
  338. UI_ERROR |= RELAIS_OFF;
  339. UIMode = RUN_MODE;
  340. break;
  341. // ***** RESET UI **************************************************************
  342. case RESET_MODE :
  343. if(STATE_STATUS == RUN_UI)
  344. {
  345. INTCONbits.GIE = 0; // disable Interrupt
  346. INTCONbits.PEIE = 0;
  347. PIE5bits.RXBnIE = 0; // disable CAN-Receive interrupt
  348. STATE_STATUS = UNLOCK_SYSTEM_CAN;
  349. // Unlock System Frame for autom. ID allocation
  350. ECANSetRXM0Value(0xDFF, ECAN_MSG_STD); // activate 0x300 Frame
  351. ECANSetRXF0Value(0x100, ECAN_MSG_STD); // Change start adress for new Canid
  352. }
  353. CAN_Read_System(); // CAN RX System
  354. break;
  355. // ***** PV__STAND_BY **********************************************************
  356. default :
  357. break;
  358. }
  359. ClrWdt(); // WDT Reset
  360. }