BMS_Can_ID_init.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * BMS_Can_ID_init.c
  3. *
  4. * Created on: Nov 30, 2016
  5. * Author: le8041
  6. */
  7. #include "BMS_Master.h"
  8. /*
  9. * reads startup config from FRAM and copies it into RAM
  10. */
  11. uint32_t BMS_Can_ID_init_init_startupConfig (MASTER_CAN0_STRUCT_t* s) {
  12. uint8_t i;
  13. uint16_t FRAM_Slave_Can_Id_valid;
  14. s->startupConfig.state.Bit.SOC_Initialized=FALSE;
  15. read_fram_word(&FRAM_Slave_Can_Id_valid,3,BMS_SLAVE_CAN_ID_VALID); // read VALID Flag from FRAM
  16. s->startupConfig.state.Bit.Slave_Can_Id_valid=FRAM_Slave_Can_Id_valid; // store VALID Flag to DRAM
  17. s->startupConfig.fsmState=BMS_CAN_ID_SEARCH_INIT;
  18. for(i=0;i<CAN0_MAX_NR_OF_SLAVES;i++) {
  19. s->startupConfig.SlaveConfig[i].CanId=0;
  20. s->startupConfig.SlaveConfig[i].SerialNr[0]='N';
  21. }
  22. return TRUE;
  23. }
  24. uint32_t BMS_Can_ID_init_recofigure_CAN_IDs(MASTER_CAN0_STRUCT_t* s) {
  25. uint8_t SlaveNummer;
  26. uint8_t MasterAlive=0;
  27. uint8_t SetMode = 16; // This is stand By mode
  28. uint32_t Balancer = 0; // no balancing during startup
  29. uint64_t StartTime =0;
  30. uint16_t IDSEARCH = 1;
  31. // uint16_t LFT;
  32. uint8_t k=0;
  33. uint8_t RxSlave=0;
  34. //Give CAN IDs to Slaves
  35. //Step 0 Bring all Slaves to Reset Mode
  36. for(SlaveNummer=0;SlaveNummer<CAN0_MAX_NR_OF_SLAVES -1;SlaveNummer++)
  37. {
  38. // schreibe Telegram im Reset Mode an alle möglichen Slaves CAn ID 0x100 - 0x1F0
  39. CAN_Tx_MasterX_BMS(s, SlaveNummer, MasterAlive, SetMode, Balancer ); //SetMode(X) = 0b00001 (=StandBy), Balancer = 0 (=OFF)
  40. StartTime = Global_1msCounter;
  41. while( (Global_1msCounter-StartTime) < 200 )
  42. {}; //wait 200ms
  43. }
  44. //Step A
  45. //Transmit cstring "IDSEARCH" to Slave over CAN IDE 0x300
  46. CAN_Tx_System300( IDSEARCH ); //start
  47. StartTime = Global_1msCounter;
  48. while( (Global_1msCounter-StartTime) < 20 )
  49. {} //wait 20ms
  50. SlaveNummer=0;
  51. //Step B
  52. // Transmitt Zero String over CAN ID 10A
  53. // Slave Answers with Serial Number
  54. do {
  55. RxSlave = 0;
  56. // schicke Master Telegram an CAN ID 0
  57. CAN_Tx_MasterXA();
  58. StartTime = Global_1msCounter;
  59. while( ((Global_1msCounter-StartTime)<5000 ) && (SlaveNummer < 16) ) //0.23ms * 2^16
  60. {
  61. //warte auf Antwort von Slave
  62. if( CAN0_check_serial_nr_rec_Can_init(s ,SlaveNummer)) //CAN_Rx_SlaveXA_Master
  63. {
  64. // Slave hat mit serien nummer geantwortet
  65. // here convert Short form of Slave ID to Long Form
  66. // to be done
  67. // LFT = (uint16_t)gSerNrShort[gAnzSlave][0] + ( (uint16_t)gSerNrShort[gAnzSlave][1] << 8);
  68. // gSerNrLong[gAnzSlave][ 0] = (uint8_t)((LFT % 10) + 0x30); LFT = LFT / 10;
  69. // gSerNrLong[gAnzSlave][ 1] = (uint8_t)((LFT % 10) + 0x30); LFT = LFT / 10;
  70. // gSerNrLong[gAnzSlave][ 2] = (uint8_t)((LFT % 10) + 0x30); LFT = LFT / 10;
  71. // gSerNrLong[gAnzSlave][ 3] = (uint8_t)((LFT % 10) + 0x30);
  72. // gSerNrLong[gAnzSlave][ 4] = gSerNrShort[gAnzSlave][2];
  73. // gSerNrLong[gAnzSlave][ 5] = (gSerNrShort[gAnzSlave][3] % 10) + 0x30;
  74. // gSerNrLong[gAnzSlave][ 6] = (gSerNrShort[gAnzSlave][3] / 10) + 0x30;
  75. // gSerNrLong[gAnzSlave][ 7] = gSerNrShort[gAnzSlave][4]; // das hier enthält die CAN ID
  76. // gSerNrLong[gAnzSlave][ 8] = (gSerNrShort[gAnzSlave][5] % 10) + 0x30;
  77. // gSerNrLong[gAnzSlave][ 9] = (gSerNrShort[gAnzSlave][5] / 10) + 0x30;
  78. // gSerNrLong[gAnzSlave][10] = 0x30;
  79. // gSerNrLong[gAnzSlave][11] = gSerNrShort[gAnzSlave][6];
  80. // !! here copy to FRAM !!
  81. SlaveNummer++;
  82. RxSlave++;
  83. }
  84. }
  85. for(k=SlaveNummer-RxSlave; k<SlaveNummer; k++)
  86. {
  87. StartTime = Global_1msCounter;
  88. s->startupConfig.SlaveConfig[k].SerialNr[7]=(k<<4); // damit aus CAN IC 3 can ID 0x30 wird
  89. CAN_Tx_System30A( &(s->startupConfig.SlaveConfig[k].SerialNr[0]) );// übertrage Seriennummer + CAN ID an Slave
  90. while( (Global_1msCounter-StartTime) < 20 )
  91. {} //wait 20ms
  92. }
  93. } while( RxSlave );
  94. // Set Slave Config Accordingly
  95. for(k=0;k<SlaveNummer;k++) {
  96. s->Slave[k].SlaveConnectionState=CONNECTED;
  97. }
  98. // calculate max Battery voltage
  99. s->startupConfig.maxBatteryVoltage = (float)(SlaveNummer * MAX_SLAVE_CELLS * BMS_SLAVE_MAX_CELL_VOLTAGE / 1000.0) ;
  100. // calculate min Battery voltage
  101. s->startupConfig.minBatteryVoltage = (float)(SlaveNummer * MAX_SLAVE_CELLS * BMS_SLAVE_MIN_CELL_VOLTAGE /1000.0);
  102. }
  103. uint32_t BMS_Can_ID_init_fsm (MASTER_CAN0_STRUCT_t* s) {
  104. uint16_t Adr_FRAM = BMS_SERNR;
  105. uint16_t FRAM_NrOfSlaves;
  106. uint8_t FRAM_BMS_SERNR;
  107. uint8_t *ptrFRAM;
  108. uint8_t SlaveNr;
  109. uint8_t CompStatus;
  110. uint8_t i;
  111. switch (s->startupConfig.fsmState) {
  112. case BMS_CAN_ID_SEARCH_INIT:
  113. if(s->startupConfig.state.Bit.Slave_Can_Id_valid == TRUE) {
  114. // CAN Ids valid
  115. s->startupConfig.fsmState=BMS_CAN_ID_SEARCH_CHECK_COMMUNICATION;
  116. return BMS_CAN_ID_INIT_RETURN_RUNNING;
  117. }
  118. else {
  119. s->startupConfig.fsmState=BMS_CAN_ID_SEARCH_RECONFIGURE_CAN0_IDS;
  120. return BMS_CAN_ID_INIT_RETURN_RUNNING;
  121. }
  122. break;
  123. case BMS_CAN_ID_SEARCH_CHECK_COMMUNICATION:
  124. // not implemented yet
  125. BMS_Can_ID_init_recofigure_CAN_IDs(s); // Complete ID scan first
  126. s->NrOfSlaves= get_nr_of_connected_slaves(s); // get NrOfSlaves from actual scan
  127. read_fram_word(&FRAM_NrOfSlaves,3,BMS_SLAVE_ANZ); // read NrOfSlaves from FRAM (past scan)
  128. if(FRAM_NrOfSlaves != s->NrOfSlaves) // if actual and past scan not match
  129. return BMS_CAN_ID_INIT_RETURN_ERROR; // show error
  130. for(SlaveNr=0; SlaveNr<FRAM_NrOfSlaves; SlaveNr++){ // for all Slave present
  131. ptrFRAM = (uint8_t *)BMS_SERNR; // Pointer to Start of SERNR Data
  132. while( ptrFRAM < (uint8_t *)((BMS_SERNR + (8 * BMS_SERNR)))){ // loop
  133. CompStatus = TRUE;
  134. for(i=0; i<8; i++){
  135. read_fram_byte(&FRAM_BMS_SERNR,3,(const volatile unsigned short)ptrFRAM);
  136. if(s->startupConfig.SlaveConfig[SlaveNr].SerialNr[i] != FRAM_BMS_SERNR)
  137. CompStatus=FALSE;
  138. ptrFRAM++;
  139. }
  140. if( CompStatus == TRUE){
  141. ptrFRAM = (uint8_t *) (BMS_SERNR + (8 * BMS_SERNR));
  142. }
  143. }
  144. if(CompStatus == FALSE)
  145. return BMS_CAN_ID_INIT_RETURN_ERROR;
  146. }
  147. s->startupConfig.state.Bit.Slave_Can_Id_valid = TRUE;
  148. write_fram_word(s->startupConfig.state.Bit.Slave_Can_Id_valid,3,BMS_SLAVE_CAN_ID_VALID);
  149. write_fram_word(s->NrOfSlaves,3,BMS_SLAVE_ANZ);
  150. for(SlaveNr=0; SlaveNr<s->NrOfSlaves; SlaveNr++){
  151. for(i=0; i<8; i++){
  152. write_fram_byte(s->startupConfig.SlaveConfig[SlaveNr].SerialNr[i],3,Adr_FRAM);
  153. Adr_FRAM++;
  154. }
  155. }
  156. return BMS_CAN_ID_INIT_RETURN_COMPLETE;
  157. break;
  158. case BMS_CAN_ID_SEARCH_RECONFIGURE_CAN0_IDS:
  159. // start CAN ID reconfiguration
  160. BMS_Can_ID_init_recofigure_CAN_IDs(s);
  161. s->NrOfSlaves= get_nr_of_connected_slaves(s);
  162. s->startupConfig.state.Bit.Slave_Can_Id_valid = TRUE;
  163. write_fram_word(s->startupConfig.state.Bit.Slave_Can_Id_valid,3,BMS_SLAVE_CAN_ID_VALID);
  164. write_fram_word(s->NrOfSlaves,3,BMS_SLAVE_ANZ);
  165. for(SlaveNr=0; SlaveNr<s->NrOfSlaves; SlaveNr++){
  166. for(i=0; i<8; i++){
  167. write_fram_byte(s->startupConfig.SlaveConfig[SlaveNr].SerialNr[i],3,Adr_FRAM);
  168. Adr_FRAM++;
  169. }
  170. }
  171. return BMS_CAN_ID_INIT_RETURN_COMPLETE;
  172. break;
  173. default:
  174. return BMS_CAN_ID_INIT_RETURN_ERROR;
  175. break;
  176. }
  177. }