1 /*
2  * v3_0p.c
3  *
4  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *    Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  *    Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the
17  *    distribution.
18  *
19  *    Neither the name of Texas Instruments Incorporated nor the names of
20  *    its contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //! \ingroup MODULBIOS
37 //! \file v3_0p.c
38 //! \brief process and route the different message types
39 //! \li forwarding (execute) messages to HAL
40 //! \li upload of HAL macros
41 //! \li loop management
42 
43 #include "fet/v3_0p_hw_fet.h"
44 #include "fet/bios.h"
45 #include "v3_0p.h"
46 #include "stream.h"
47 #include <stdlib.h>
48 #include "Fet_IccMonitor.h"
49 #include "USB_API/USB_Common/types.h"
50 #include "USB_API/USB_CDC_API/UsbCdc.h"
51 #include <string.h>
52 #include "../dcdc/FetDcdc.h"
53 #include "../Uart/FetCom.h"
54 #include "FetUsb.h"
55 #include "usbMain.h"
56 #include "usbConstructs.h"
57 
58  // module handling
59 typedef void *(*DcdcInit)(DCDC_INFOS_t* dcdcInfos_Pointer);
60 DCDC_INFOS_t dcdcInfos_;
61 #pragma required=dcdcInfos_
62 
63 typedef void *(*ComInit)(COM_INFOS_t* comInfos_Pointer);
64 
65 
66 edt_common_methods_t  _edt_Common_Methods;
67 typedef void (*HilInitGetEdtCommenFunc)(edt_common_methods_t* edt_commen); // * hal_size, void * stream_adr)
68 HilInitGetEdtCommenFunc hilEdtCom = NULL;
69 
70 typedef short (*HalFpgaUpdateFunc)(void);// FPGA update function
71 
_dummy_shortOutVoidIn(void)72 short _dummy_shortOutVoidIn(void) {return 0;}
_dummy_voidOutVoidIn(void)73 void _dummy_voidOutVoidIn(void){};
_dummy_comConfig(unsigned long Baudrate,unsigned long MCLK_Frequency,unsigned short toolId)74 short  _dummy_comConfig (unsigned long Baudrate, unsigned long MCLK_Frequency, unsigned short toolId){return 0;};
_dummy_comTransmit(void)75 short _dummy_comTransmit(void){return 0;};
_dummy_comReceive(unsigned char character)76 short _dummy_comReceive (unsigned char character){return 0;};
_dummy_comGetBuffer()77 unsigned char *_dummy_comGetBuffer (){return 0;};
78 
_dummy_dcdcCalibrate(unsigned short resistor[4],unsigned short resCount,unsigned short vcc)79 short _dummy_dcdcCalibrate(unsigned short resistor[4], unsigned short resCount, unsigned short vcc){return 0;}
_dummy_dcdcSetVcc(unsigned short vcc)80 short _dummy_dcdcSetVcc(unsigned short vcc ){return 0;}
_dummy_dcdcRestart(unsigned short fetType_)81 short _dummy_dcdcRestart(unsigned short fetType_){return 0;};
_dummy_dcdc_getCalibrationValues(unsigned short vcc,unsigned short resistor,unsigned short resCount,unsigned long * ticks,unsigned long * time)82 void _dummy_dcdc_getCalibrationValues(unsigned short vcc, unsigned short resistor, unsigned short resCount, unsigned long *ticks, unsigned long *time){return;}
83 
_dummy_comSetHil(edt_common_methods_t * dummy)84 void _dummy_comSetHil(edt_common_methods_t* dummy){};
_dummy_comSetDcdc(DCDC_INFOS_t * dummy)85 void _dummy_comSetDcdc(DCDC_INFOS_t* dummy){};
_dummy_comSetUSB(FET_USB_INFOS_t * dummy)86 void _dummy_comSetUSB(FET_USB_INFOS_t* dummy){};
_dummy_comLoop(void)87 void _dummy_comLoop(void){};
_dummy_comConfig2(unsigned long Baudrate)88 short _dummy_comConfig2(unsigned long Baudrate){return 0;};
89 
_dummy_InitHil(void)90 short _dummy_InitHil( void ){return 0;};
_dummy_SetVcc(unsigned short Vcc)91 short _dummy_SetVcc(unsigned short Vcc){return 0;};
_dummy_SwitchVccFET(unsigned short state)92 void _dummy_SwitchVccFET(unsigned short state) {return;};
_dummy_GetVcc(double * Vcc,double * ExtVcc)93 short _dummy_GetVcc(double* Vcc, double* ExtVcc){return 0;};
_dummy_setFpgaTimeOut(unsigned short state)94 void _dummy_setFpgaTimeOut(unsigned short state) {return;};
_dummy_regulateVcc(void)95 short _dummy_regulateVcc(void) { return 0; }
96 
97 unsigned char rx_queu_counter_public_;
98 
99 COM_INFOS_t comInfos_ =
100 {
101     _dummy_shortOutVoidIn,
102     _dummy_comConfig,
103     _dummy_comTransmit,
104     _dummy_comReceive,
105     _dummy_voidOutVoidIn,
106     _dummy_comSetHil,
107     _dummy_comSetDcdc,
108     _dummy_comSetUSB,
109     _dummy_comLoop,
110     _dummy_comConfig2,
111     _dummy_comTransmit,
112     _dummy_comTransmit,
113     _dummy_voidOutVoidIn
114 };
115 #pragma required=comInfos_
116 
117 FET_USB_INFOS_t fetUsbInfos_ =
118 {
119     USBCDC_bytesInUSBBuffer,
120     USBCDC_receiveData,
121     cdcSendDataInBackground,
122 };
123 #pragma required=fetUsbInfos_
124 
125 //------------------------------------------------------------------------------
126 // Global Variables - Data Memory used by this module
127 //
128 V3opLoopArray v3op_loop_array_[V3OP_LOOP_ARRAY_COUNT] = {
129     { 0xFFFF, (unsigned char*)0xFFFF, 0x00, 0x00, 0x00, 1 },
130     { 0xFFFF, (unsigned char*)0xFFFF, 0x00, 0x00, 0x00, 1 },
131     { 0xFFFF, (unsigned char*)0xFFFF, 0x00, 0x00, 0x00, 1 },
132     { 0xFFFF, (unsigned char*)0xFFFF, 0x00, 0x00, 0x00, 1 }
133 };
134 
135 HAL_INFOS no_hal_infos_ = {NULL, 0, 0, 0, NULL, 0, 0};
136 
137 HAL_INFOS_PTR hal_infos_ = &no_hal_infos_;
138 // ID from and pointer to all HAL functions
139 HAL_REC_ARRAY hal_ptr_ = NULL;
140 // informations about first and last measages
141 unsigned short v30p_stream_flags_ = 0;
142 
143 short HAL_Zero(unsigned char *data);
144 
V3OP_HwReset(void)145 void V3OP_HwReset(void)
146 {
147     STREAM_resetSharedVariables();
148     BIOS_UsbTxClear();
149     BIOS_UsbRxClear();
150     BIOS_InitCom();
151 }
152 
153 #pragma optimize = low
HAL_Zero(unsigned char * data)154 short HAL_Zero(unsigned char *data)
155 {
156     short ret_value = 0;
157     unsigned short i;
158     if(data[MESSAGE_EXECUTE_ZERO_ADDR_POS] == STREAM_CORE_ZERO_VERSION)  // call for SW version
159     {
160         if(STREAM_out_init(data[MESSAGE_MSG_ID_POS], RESPTYP_DATA) >= 0)
161         {
162             unsigned long coreVersion_ToolId = Bios_getCore_version();
163             coreVersion_ToolId =(coreVersion_ToolId<<16) + Bios_getTool_id();
164             if(Bios_getHal_signature() == 0xBEEFBEEF && V3OP_HalCrcOk() &&
165                Bios_getHil_signature() == 0xF00DF00D && V3OP_HilCrcOk())
166             {
167                 STREAM_put_word((*hal_infos_).sw_0);
168                 STREAM_put_word((*hal_infos_).sw_1);
169             }
170             else
171             {
172                 STREAM_put_word(Bios_getTool_id());
173                 STREAM_put_word(Bios_getTool_id());
174             }
175             STREAM_put_word(Bios_getInfo_hw_0());
176             STREAM_put_word(Bios_getInfo_hw_1());
177 
178             STREAM_put_bytes((unsigned char*)&coreVersion_ToolId,sizeof(coreVersion_ToolId));
179             STREAM_put_word((*hal_infos_).hil_version);
180 
181             if(Bios_getDcdc_signature() == 0xABBAABBA && V3OP_DcdcCrcOk())
182             {
183                 STREAM_put_word(dcdcInfos_.getLayerVersion());
184             }
185             else
186             {
187                 STREAM_put_word(-1);
188             }
189             if(Bios_getDcdc_signature() == 0xABBAABBA && V3OP_DcdcCrcOk() && Bios_getTool_id() != eZ_FET_NO_DCDC)
190             {
191                 STREAM_put_word(dcdcInfos_.getSubMcuVersion());
192 
193             }
194             else
195             {
196                 STREAM_put_word(-1);
197             }
198              // return dummy value for Uart version module
199             if(Bios_getCom_signature() == 0xACDCACDC && V3OP_ComChannelCrcOk())
200             {
201                 STREAM_put_word(comInfos_.comGetLayerVersion());
202             }
203             else
204             {
205                 STREAM_put_word(-1);
206             }
207 
208             // return CRC's for core and all firmware modules
209             STREAM_put_word(V3OP_GetHilCrc());
210             STREAM_put_word(V3OP_GetHalCrc());
211             STREAM_put_word(V3OP_GetDcdcCrc());
212             STREAM_put_word(V3OP_GetCoreCrc());
213             STREAM_put_word(V3OP_GetComChannelCrc());
214             STREAM_put_word((*hal_infos_).fpga_version);
215 
216             STREAM_put_word(BIOS_RX_QUEUS);
217             STREAM_put_word(BIOS_RX_SIZE);
218             STREAM_put_long(0);
219 
220             // reset static vars
221             STREAM_resetSharedVariables();
222             ret_value = 1;
223         }
224         else
225         {
226             ret_value = -3;
227         }
228     }
229     else if(data[MESSAGE_EXECUTE_ZERO_ADDR_POS] == STREAM_CORE_ZERO_MACRO_SIZE)
230     {
231         if((*hal_infos_).hal_size)
232         {
233             if(STREAM_out_init(data[MESSAGE_MSG_ID_POS], RESPTYP_DATA) >= 0)
234             {
235                 STREAM_put_word((*hal_infos_).hal_size);
236                 ret_value =  1;
237             }
238             else
239             {
240                 ret_value = -4;
241             }
242         }
243         else
244         {
245             ret_value = -2;
246         }
247     }
248     else if(data[MESSAGE_EXECUTE_ZERO_ADDR_POS] == STREAM_CORE_ZERO_MACRO_ADDR)
249     {
250         if(STREAM_out_init(data[MESSAGE_MSG_ID_POS], RESPTYP_DATA) >= 0)
251         {
252             for(i =0;i<(*hal_infos_).hal_size;i++)
253             {
254                 STREAM_put_word(i);
255                 STREAM_put_word((*hal_ptr_)[i].id);
256             }
257             ret_value = 1;
258         }
259         else
260         {
261             ret_value = -5;
262         }
263     }
264     else if(data[MESSAGE_EXECUTE_ZERO_ADDR_POS] == STREAM_CORE_ZERO_PUC_RESET)
265     {
266         if(STREAM_out_init(data[MESSAGE_MSG_ID_POS], RESPTYP_ACKNOWLEDGE) >= 0)
267         {
268             STREAM_flush();
269             ret_value = -6;
270         }
271         V3OP_HwReset();
272         // there can't send a ret_value
273     }
274     if(ret_value == 1)
275     {
276         ret_value = MESSAGE_NO_RESPONSE;
277         STREAM_flush();
278     }
279     return(ret_value);
280 }
281 
V3OP_PauseLoop(unsigned char msg_id)282 short V3OP_PauseLoop(unsigned char msg_id)
283 {
284     if ( msg_id != 0x40 )
285     {
286         int i = 0;
287         for(i = 0; i < V3OP_LOOP_ARRAY_COUNT; i++)
288         {
289             if(v3op_loop_array_[i].msg_id == msg_id)
290             {
291                 v3op_loop_array_[i].active = 0;
292                 break;
293             }
294         }
295     }
296     return 1;
297 }
298 
V3OP_ResumeLoop(unsigned char msg_id)299 short V3OP_ResumeLoop(unsigned char msg_id)
300 {
301     if ( msg_id != 0x40 )
302     {
303         int i = 0;
304         for(i = 0; i < V3OP_LOOP_ARRAY_COUNT; i++)
305         {
306             if(v3op_loop_array_[i].msg_id == msg_id)
307             {
308                 v3op_loop_array_[i].active = 1;
309                 break;
310             }
311         }
312     }
313     return 1;
314 }
315 
316 //! \brief kill all loop functions, including vcc monitor
V3OP_KillAllLoops(void)317 void V3OP_KillAllLoops(void)
318 {
319     int i = 0;
320     for(i = 0; i < V3OP_LOOP_ARRAY_COUNT; i++)
321     {
322         if(v3op_loop_array_[i].indata != NULL)
323         {
324             free(v3op_loop_array_[i].indata);
325         }
326         v3op_loop_array_[i].indata = NULL;
327         v3op_loop_array_[i].addr = 0xFFFF;
328         v3op_loop_array_[i].active = 1;
329     }
330 }
331 
332 //! \brief kill (stop) functions in loop
333 //! \param[in] addr index of function to kill
334 //! \param[in] id with there the function was install in the loop
335 //! \details if addr and id are zero, all function in loop are killed
336 //! \return  0 -> no function found in loop to kill (only posible if addr and id 0)
337 //! \return >0 -> count of functions in loop who killed
338 //! \return <0 -> no function to kill
V3OP_KillLoop(unsigned char msg_id)339 short V3OP_KillLoop(unsigned char msg_id)
340 {
341     unsigned short i;
342     short ret_value = -1;
343 
344     if(msg_id == 0)
345     {
346         ret_value = 0;
347         for(i = 0; i < V3OP_LOOP_ARRAY_COUNT; i++)
348         {
349             if((v3op_loop_array_[i].addr != 0xFFFF) && ((*hal_ptr_)[v3op_loop_array_[i].addr].id < 0xFF00))
350             {
351                 if(v3op_loop_array_[i].indata != NULL)
352                 {
353                     //free(v3op_loop_array_[i].indata);
354                 }
355                 v3op_loop_array_[i].indata = NULL;
356                 v3op_loop_array_[i].addr = 0xFFFF;
357                 v3op_loop_array_[i].active = 0;
358 
359                 ret_value++;
360             }
361         }
362     }
363     else
364     {
365         for(i = 0; i < V3OP_LOOP_ARRAY_COUNT; i++)
366         {
367             if(v3op_loop_array_[i].msg_id == msg_id) break;
368         }
369         if(i < V3OP_LOOP_ARRAY_COUNT)   // addr found
370         {
371             if(v3op_loop_array_[i].indata != NULL)
372             {
373                 free(v3op_loop_array_[i].indata);
374             }
375             v3op_loop_array_[i].indata = NULL;
376             v3op_loop_array_[i].addr = 0xFFFF;
377             v3op_loop_array_[i].active = 0;
378         }
379         ret_value = 1;
380     }
381     return(ret_value);
382 }
383 
384 //! \brief install a HAL function in loop
385 //! \param[in] *addr id (addr) to receive buffer
386 //! \param[in] flags 0 -> function in loop until kill
387 //! \param[in] flags 1 -> function in loop until function returns with !=0
388 //! \return <0 -> function not install
389 //! \return  1 -> function install in loop
390 
391 unsigned static char tempInData[4][100]= {0x0,0x0};
392 
V3OP_SetLoop(unsigned char * payload_incl_addr,unsigned char flags)393 short V3OP_SetLoop(unsigned char *payload_incl_addr, unsigned char flags)
394 {
395     unsigned short i, j;
396     unsigned char payload_size;
397     short ret_value = -1;
398 
399     // search for same running function
400     for(i = 0; i < V3OP_LOOP_ARRAY_COUNT; i++)
401     {
402         if((v3op_loop_array_[i].addr == *(unsigned short*)&payload_incl_addr[MESSAGE_EXECUTE_CALL_ADDR_POS]) &&
403            (v3op_loop_array_[i].msg_id == payload_incl_addr[MESSAGE_MSG_ID_POS]))
404         {
405             ret_value = -2;
406             break;
407         }
408     }
409     // search free slot
410     for(i = 0; i < V3OP_LOOP_ARRAY_COUNT; i++)
411     {
412         if(v3op_loop_array_[i].addr == 0xFFFF)
413         {
414             break;
415         }
416     }
417     if(i < V3OP_LOOP_ARRAY_COUNT)   // free slot found
418     {
419         if(payload_incl_addr[0] >= MESSAGE_EXECUTE_PAYLOAD_POS)
420         {
421             payload_size = payload_incl_addr[0]+1;
422             v3op_loop_array_[i].indata = tempInData[i];// (unsigned char*)malloc(payload_size);
423             if(v3op_loop_array_[i].indata)
424             {
425                 for(j = 0; j < payload_size; j++)
426                 {
427                     v3op_loop_array_[i].indata[j] = payload_incl_addr[j];
428                 }
429                 v3op_loop_array_[i].flags = flags & V3OP_LOOP_WAIT_FLAG;
430                 v3op_loop_array_[i].msg_id = payload_incl_addr[2] | 0x40;
431                 v3op_loop_array_[i].msg_type = RESPTYP_DATA;
432                 v3op_loop_array_[i].addr = *(unsigned short*)&payload_incl_addr[MESSAGE_EXECUTE_CALL_ADDR_POS];
433                 v3op_loop_array_[i].active = 1;
434                 ret_value = 1;
435             }
436             else
437             {
438                 ret_value = -4;
439             }
440         }
441         else
442         {
443             v3op_loop_array_[i].indata = NULL;
444             v3op_loop_array_[i].flags = flags & V3OP_LOOP_WAIT_FLAG;
445             v3op_loop_array_[i].msg_id = payload_incl_addr[2] | 0x40;
446             v3op_loop_array_[i].msg_type = RESPTYP_DATA;
447             v3op_loop_array_[i].addr = *(unsigned short*)&payload_incl_addr[MESSAGE_EXECUTE_CALL_ADDR_POS];
448             v3op_loop_array_[i].active = 1;
449             ret_value = 1;
450         }
451     }
452   else
453   {
454     ret_value = -3;
455   }
456   return(ret_value);
457 }
458 
459 short V3OP_Calibrate(unsigned char *str);
460 
461 //! \brief process message type
462 //! \param[in] *str pointer on received buffer
463 //! \li str[1] message type
464 //! \li str[2] message id
465 //! \li str[3] function timeout (not used)
466 //! \li str[4...] message type (function) depended payload
467 //! \return 0
V3OP_Rx(unsigned char * str)468 short V3OP_Rx (unsigned char *str)
469 {
470     unsigned char tmp_char;
471     unsigned short call_addr;
472     short ret_value = -1;
473     //short ret_value = 0x8000;
474 	short ret_value_tmp = 0;
475     HalFuncInOut pCallAddr;
476 
477     if((bios_rx_record_.last_cmd_typ != str[MESSAGE_CMDTYP_POS]) || !(bios_rx_record_.last_msg_id & 0x80))
478     {
479       bios_rx_record_.last_cmd_typ = str[MESSAGE_CMDTYP_POS];
480       bios_rx_record_.last_msg_call = str[MESSAGE_EXECUTE_CALL_ADDR_POS];
481       v30p_stream_flags_ |= MESSAGE_NEW_MSG;
482     }
483     else
484     {
485         v30p_stream_flags_ &= ~MESSAGE_NEW_MSG;
486     }
487     if(!(str[MESSAGE_MSG_ID_POS] & 0x80))
488     {
489         v30p_stream_flags_ |= MESSAGE_LAST_MSG;
490     }
491     else
492     {
493         v30p_stream_flags_ &= ~MESSAGE_LAST_MSG;
494     }
495     bios_rx_record_.last_msg_id = str[MESSAGE_MSG_ID_POS];
496 
497     if(!bios_wb_control_)
498     {
499         BIOS_LedOn(BIOS_LED_MODE);
500         bios_wb_control_ = 1;
501     }
502     if(str[MESSAGE_CMDTYP_POS] == CMDTYP_EXECUTE) // bypass CMDTYP_EXECUTE at switch instruction
503     {
504         if(v30p_stream_flags_ & MESSAGE_NEW_MSG)
505         {
506             call_addr = *(unsigned short*)&str[MESSAGE_EXECUTE_CALL_ADDR_POS]; // first short is on a word boundary
507             STREAM_discard_bytes(2);
508         }
509         else
510         {
511             call_addr = bios_rx_record_.last_msg_call;
512         }
513         if(call_addr == 0)
514         {
515             ret_value_tmp = HAL_Zero(str);
516         }
517         if(!ret_value_tmp)
518         {
519             // adjust to payload for HAL (payload without cmd-index)
520             STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
521             #ifdef HAL_HISTORY
522             if(hal_history_count_ >= sizeof(hal_history_)/2)
523             {
524                 hal_history_count_=0;
525             }
526             hal_history_[hal_history_count_++] = call_addr;
527             hal_history_last_ = call_addr;
528             #endif
529             if(call_addr < (*hal_infos_).hal_size)
530             {
531                 pCallAddr = (HalFuncInOut)(*hal_ptr_)[call_addr].function;
532                 if(pCallAddr != NULL)
533                 {
534                     ret_value = pCallAddr(v30p_stream_flags_);
535                     if(!ret_value)
536                     {
537                         STREAM_flush();
538                         ret_value = MESSAGE_NO_RESPONSE;
539                     }
540                 }
541             }
542         }
543         else
544         {
545             ret_value = ret_value_tmp;
546         }
547     }
548     else
549     {
550         switch(str[MESSAGE_CMDTYP_POS])
551         {
552             case CMDTYP_EXECUTELOOP:
553                 ret_value = V3OP_SetLoop(str, V3OP_LOOP_WAIT_FLAG);
554                 break;
555             case CMDTYP_EXECUTEEVER:
556                 ret_value = V3OP_SetLoop(str, 0);
557                 break;
558             case CMDTYP_KILL:
559                 ret_value = V3OP_KillLoop(str[MESSAGE_EXECUTE_CALL_ADDR_POS+2]);
560                 break;
561            case CMDTYP_KILL_ALL:
562                 V3OP_KillAllLoops();
563                 ret_value = 1;
564                 break;
565             case CMDTYP_PAUSE_LOOP:
566                 {
567                     unsigned char msgId = str[MESSAGE_EXECUTE_CALL_ADDR_POS+2];
568                     ret_value = V3OP_PauseLoop( msgId | 0x40 );
569                 }
570                 break;
571             case CMDTYP_RESUME_LOOP:
572                 {
573                     unsigned char msgId = str[MESSAGE_EXECUTE_CALL_ADDR_POS+2];
574                     ret_value = V3OP_ResumeLoop( msgId | 0x40 );
575                 }
576                 break;
577             case CMDTYP_UPINIT:   // init update
578                 ret_value = V3OP_CoreFlashFunctionInit(str);
579                 break;
580             case CMDTYP_UPERASE:  // erase HAL part
581                 ret_value = V3OP_CoreFlashFunctionErase(str);
582                 if(ret_value == 1) // tell Bios that Hal is dead
583                 {
584                     V3OP_HalInterfaceClear();
585                 }
586                 break;
587             case CMDTYP_UPWRITE:  // write into HAL part
588                 ret_value = V3OP_CoreFlashFunctionWrite(str,v30p_stream_flags_);
589                 break;
590             case CMDTYP_UPREAD:   // read HAL part
591                 ret_value = V3OP_CoreFlashFunctionRead(str);
592                 break;
593             case CMDTYP_UPCORE:
594                 // Erase Segment with Core Signature, to start install new core on restart
595                 V3OP_UpCore();
596                 break;
597             case CMDTYP_DCDC_RESTART:
598                 // restart sub mcu
599                 ret_value =  dcdcInfos_.dcdcRestart(*(unsigned short*)&str[4]);
600                 break;
601             case CMDTYP_DCDC_CALIBRATE:
602                 // Start DCDC mcu calibaration function
603                 ret_value = V3OP_Calibrate(str);
604                break;
605             case CMDTYP_DCDC_INIT_INTERFACE:
606                 V3OP_DcdcInterfaceInit();
607                 break;
608             case CMDTYP_DCDC_SUB_MCU_VERSION:
609                 ret_value = dcdcInfos_.getSubMcuVersion();
610                 break;
611             case CMDTYP_DCDC_LAYER_VERSION:
612                 ret_value = dcdcInfos_.getLayerVersion();
613                 break;
614             case CMDTYP_DCDC_POWER_DOWN:
615                 ret_value = dcdcInfos_.dcdcPowerDown();
616                 break;
617             case CMDTYP_DCDC_SET_VCC:
618                 STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
619                 ret_value = dcdcInfos_.dcdcSetVcc(*(unsigned short*)&str[6]);
620                 break;
621             case CMDTYP_OVER_CURRENT:
622                 {
623                     unsigned short state = 0;
624                     STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
625                     state = (*(unsigned short*)&str[6]);
626                     if(state)
627                     {
628                         IccMonitor_StartVoltageSupervision();
629                     }
630                     else
631                     {
632                         IccMonitor_StopVoltageSupervision();
633                     }
634                     break;
635                 }
636             case CMDTYP_HIL_SET_VCC:
637               {
638                     STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
639                     if(_edt_Common_Methods.SetVcc)
640                     {
641                         ret_value = _edt_Common_Methods.SetVcc(*(unsigned short*)&str[6]);
642                     }
643                     break;
644               }
645             case CMDTYP_HIL_GET_VCC:
646               {
647                     double vcc = 0;
648                     double ext_vcc = 0;
649                     if(_edt_Common_Methods.GetVcc)
650                     {
651                         ret_value = _edt_Common_Methods.GetVcc(&vcc, &ext_vcc);
652                     }
653                     STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
654                     STREAM_put_word((unsigned short)vcc);
655                     STREAM_put_word((unsigned short)ext_vcc);
656                     STREAM_flush();
657                     break;
658               }
659 
660             case CMDTYP_HIL_SWITCH_FET:
661               {
662                     STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
663                     if(_edt_Common_Methods.SwitchVccFET)
664                     {
665                         _edt_Common_Methods.SwitchVccFET(*(unsigned short*)&str[6]);
666                     }
667                     ret_value = 0;
668                     break;
669               }
670           case CMDTYP_CMP_VERSIONS:
671               {
672                     STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
673                     if(Bios_getHal_signature() == 0xBEEFBEEF && V3OP_HalCrcOk() &&
674                     Bios_getHil_signature() == 0xF00DF00D && V3OP_HilCrcOk())
675                     {
676                         STREAM_put_word((*hal_infos_).swCmp_0);
677                         STREAM_put_word((*hal_infos_).swCmp_1);
678                         STREAM_put_word((unsigned short)(*hal_infos_).hil_versionCmp);
679                     }
680                     else
681                     {
682                         STREAM_put_word(0);
683                         STREAM_put_word(0);
684                         STREAM_put_word(0);
685                     }
686                     STREAM_put_word((unsigned short) dcdcInfos_.getLayerVersionCmp());
687                     STREAM_put_word((unsigned short) comInfos_.comGetLayerVersionCmp());
688                     STREAM_flush();
689 
690                     ret_value = 0;
691                     break;
692               }
693          }
694     }
695 
696     if(ret_value != MESSAGE_NO_RESPONSE)
697     {
698         if(ret_value >= 0)
699         {
700             if(STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_ACKNOWLEDGE) >= 0)
701             {
702                 STREAM_put_word(ret_value);
703                 STREAM_flush();
704             }
705         }
706         else
707         {
708             STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_EXCEPTION);
709             STREAM_put_word(ret_value);
710             if(ret_value == EXCEPTION_MSGID_ERR)
711             {
712                 tmp_char = (bios_rx_record_.last_msg_id + 1) & 0x3F;
713                 if(!tmp_char)
714                 {
715                     tmp_char++;
716                 }
717                 STREAM_put_word(tmp_char);
718             }
719             STREAM_flush();
720         }
721     }
722     return(0);
723 }
724 
V3OP_Calibrate(unsigned char * str)725 short V3OP_Calibrate(unsigned char *str)
726 {   // Calibration values retreived form the DCDC
727     unsigned long ticks;
728     unsigned long time;
729     // Start DCDC mcu calibaration function
730     STREAM_out_init(str[MESSAGE_MSG_ID_POS], RESPTYP_DATA);
731 
732     unsigned short countRes = *(unsigned short*)&str[4];
733     unsigned short res[5] = {0,0,0,0,0};
734     unsigned short vcc = 0;
735     short ret_value = -1;
736     // Resistors
737     int i, pos;
738     for (i = 0, pos = 6; i < countRes; ++i, pos += 2)
739     {
740         res[i] = *(unsigned short*)&str[pos];
741     }
742     vcc = *(unsigned short*)&str[pos];
743 
744     ret_value =  dcdcInfos_.dcdcCalibrate(res, countRes, vcc);
745     if(!ret_value)
746     {
747         int y = 0;
748         for(y =0; y < countRes; y++)
749         {
750             dcdcInfos_.dcdc_getCalibrationValues(vcc, res[y], countRes, &ticks, &time);
751             STREAM_put_long(ticks);
752             STREAM_put_long(time);
753         }
754         STREAM_flush();
755         ret_value = MESSAGE_NO_RESPONSE;
756     }
757     else
758     {
759         STREAM_put_long(0xDEAD);
760         STREAM_put_long(0xBABE);
761         STREAM_flush();
762         ret_value = MESSAGE_NO_RESPONSE;
763     }
764     return ret_value;
765 }
766 
767 //! \brief sends exceptions with details in payload
768 //! \param[in] msg_id message id
769 //! \param[in] code if payload = NULL, 'code' is sendet in as payload
770 //! \param[in] *payload if !=NULL payload is sendet with the length 'code'
771 //! \return 0 exception sended
772 //! \return -1 exception not sended, no output buffer aviable
V3OP_SendException(unsigned char msg_id,unsigned short code,unsigned short * payload)773 short V3OP_SendException(unsigned char msg_id, unsigned short code, unsigned short *payload)
774 {
775     unsigned short i;
776 
777     if(STREAM_out_init(msg_id, RESPTYP_EXCEPTION) >= 0)
778     {
779         if(payload == NULL)
780         {
781             STREAM_put_word(code);
782         }
783         else
784         {
785             for(i = 0;(i < code) && (i < 126); i++)
786             {
787                 STREAM_put_word(payload[i]);
788             }
789         }
790         STREAM_flush();
791         return(0);
792     }
793     return(-1);
794 }
795 
796 // Sw layer init
797 
798 //*****************************************
V3OP_HalInterfaceClear(void)799 short V3OP_HalInterfaceClear(void)
800 {
801 	V3OP_KillAllLoops();
802 	hal_infos_ = &no_hal_infos_;
803     hal_ptr_ = NULL;
804     return(0);
805 }
806 
807 typedef void (*HilInitFunc)();
808 
V3OP_HalInterfaceInit(void)809 short V3OP_HalInterfaceInit(void)
810 {
811     HalMainFunc halStartUpCode = NULL;
812     HilInitFunc hilInit = NULL;
813 
814     unsigned char cmd[6] = {0x05, CMDTYP_EXECUTELOOP, 0, 0, 0, 0};
815     unsigned char i;
816 
817     V3OP_HalInterfaceClear();
818     //set shared mem Variables to 0x00
819     STREAM_resetSharedVariables();
820 
821 
822      // if hil is not loaded - did not make sence to init hal
823     if(Bios_getHil_signature() != 0xF00DF00D || Bios_getHil_intvec() == 0xFFFF || !V3OP_HilCrcOk())
824     {
825          _edt_Common_Methods.Init = _dummy_InitHil;
826          _edt_Common_Methods.SetVcc = _dummy_SetVcc;
827          _edt_Common_Methods.GetVcc = _dummy_GetVcc;
828          _edt_Common_Methods.setFpgaTimeOut = _dummy_setFpgaTimeOut;
829          _edt_Common_Methods.SwitchVccFET = _dummy_SwitchVccFET;
830          _edt_Common_Methods.regulateVcc = _dummy_regulateVcc;
831          _edt_Common_Methods.SetToolID = _dummy_SwitchVccFET;
832           return -1;
833     }
834     hilInit = (HilInitFunc)Bios_getHil_intvec();
835     // call startup of HIL layer
836     hilInit();
837     hilEdtCom = (HilInitGetEdtCommenFunc)0x18A0;
838     hilEdtCom(&_edt_Common_Methods);
839 
840     // check if rest vector is not FFFF and if a valid Hal/Programm signature was found
841     if(Bios_getHal_intvec() == 0xFFFF || Bios_getHal_signature() != 0xBEEFBEEF || !V3OP_HalCrcOk())
842     {
843         return -1;
844     }
845 
846     _edt_Common_Methods.SetToolID(Bios_getTool_id());
847 
848     halStartUpCode = (HalMainFunc)Bios_getHal_intvec(); // calls the (modified) startup code of HAL
849     hal_infos_ = halStartUpCode((struct stream_funcs*)&_stream_Funcs, 0, V3OP_HilCrcOk(), V3OP_DcdcCrcOk()); // return HAL sw infos
850     hal_ptr_ = (HAL_REC_ARRAY)(*hal_infos_).hal_list_ptr;
851 
852     IccMonitor_setHilIterface(&_edt_Common_Methods);
853     comInfos_.comSetHil(&_edt_Common_Methods);
854 
855     if(hal_ptr_ != NULL)
856     {
857         //configure ICC monitor process
858         (*hal_ptr_)[(*hal_infos_).hal_size-1].id = 0xFFFE;
859         (*hal_ptr_)[(*hal_infos_).hal_size-1].function = (void*)IccMonitor_Process;
860 
861         for(i=0; i <(*hal_infos_).hal_size; i++)
862         {
863             if(((*hal_ptr_)[i].id != 0xFFFF) && ((*hal_ptr_)[i].id >= 0xFF00))
864             {
865                 cmd[4] = i;
866                 cmd[5] = 0;
867                 V3OP_SetLoop(cmd, 0);
868                 break;
869             }
870         }
871     }
872     return 0;
873 }
874 
V3OP_DcdcInterfaceClear(void)875 void V3OP_DcdcInterfaceClear(void)
876 {
877     dcdcInfos_.getSubMcuVersion = _dummy_shortOutVoidIn;
878     dcdcInfos_.getLayerVersion = _dummy_shortOutVoidIn;
879     dcdcInfos_.dcdcCalibrate =  _dummy_dcdcCalibrate;
880     dcdcInfos_.dcdcPowerDown = _dummy_shortOutVoidIn;
881     dcdcInfos_.dcdcSetVcc = _dummy_dcdcSetVcc;
882     dcdcInfos_.dcdcRestart = _dummy_dcdcRestart;
883     dcdcInfos_.dcdc_getCalibrationValues = _dummy_dcdc_getCalibrationValues;
884     dcdcInfos_.getLayerVersionCmp = _dummy_shortOutVoidIn;
885     //dcdcInfos_.getLayerVersion  = _dummy_shortOutVoidIn;
886     comInfos_.comSetDcdc(&dcdcInfos_);
887 
888 }
889 
V3OP_DcdcInterfaceInit(void)890 short V3OP_DcdcInterfaceInit(void)
891 {
892     DcdcInit dcdc_Init_ = NULL;
893     if(Bios_getDcdc_intvec() == 0xFFFF  || Bios_getDcdc_signature() != 0xABBAABBA || !V3OP_DcdcCrcOk())
894     {
895         V3OP_DcdcInterfaceClear();
896         return -1;
897     }
898     dcdc_Init_ = (DcdcInit)Bios_getDcdc_intvec(); // calls the (modified) startup code of HAL
899     dcdc_Init_(&dcdcInfos_);
900 
901     comInfos_.comSetDcdc(&dcdcInfos_);
902     dcdcInfos_.dcdcRestart(Bios_getTool_id());
903 
904     return 0;
905 }
906 
907 //******************** Module Implementation **************
V3OP_ComInterfaceInit(void)908 short V3OP_ComInterfaceInit(void)
909 {
910     ComInit com_Init_ = NULL;
911     if((Bios_getCom_intvec() == 0xFFFF) || (Bios_getCom_signature() != 0xACDCACDC)|| ! V3OP_ComChannelCrcOk())
912     {
913         V3OP_ComInterfaceClear();
914         return -1;
915     }
916     com_Init_ = (ComInit)Bios_getCom_intvec();
917     com_Init_(&comInfos_);
918 
919     UsbMain_setComIterface(&comInfos_);
920     comInfos_.comSetUSB(&fetUsbInfos_);
921 
922     comInfos_.comSetHil(&_edt_Common_Methods);
923     comInfos_.comSetDcdc(&dcdcInfos_);
924 
925     return 0;
926 }
927 
V3OP_ComInterfaceClear(void)928 void V3OP_ComInterfaceClear(void)
929 {
930     comInfos_.comGetLayerVersion      = _dummy_shortOutVoidIn;
931     comInfos_.comGetLayerVersionCmp   = _dummy_shortOutVoidIn;
932     comInfos_.comConfig               = _dummy_comConfig;
933     comInfos_.comTransmit             = _dummy_comTransmit;
934     comInfos_.comReceive              = _dummy_comReceive;
935     comInfos_.comClose                = _dummy_voidOutVoidIn;
936     comInfos_.comSetHil               = _dummy_comSetHil;
937     comInfos_.comSetDcdc              = _dummy_comSetDcdc;
938     comInfos_.comSetUSB               = _dummy_comSetUSB;
939     comInfos_.comLoop                 = _dummy_comLoop;
940     comInfos_.comSetCts               = _dummy_comTransmit;
941     comInfos_.comClearCts             = _dummy_comTransmit;
942     comInfos_.comSetRts               = _dummy_voidOutVoidIn;
943     UsbMain_setComIterface(&comInfos_);
944 }
945 
946 //*****************************************
V3OP_HalFpgaUpdate(void)947 short V3OP_HalFpgaUpdate(void)
948 {
949     HalFpgaUpdateFunc halFpgaUpdateCode = NULL;
950     short retVal;
951 
952     // check if rest vector is not FFFF and if a valid Hal/Programm signature was found
953     if(Bios_getHal_intvec() == 0xFFFF || Bios_getHal_signature() != 0xADACADAC || !V3OP_HalFpgaCrcOk())
954     {
955         return -1;
956     }
957 
958     halFpgaUpdateCode = (HalFpgaUpdateFunc)Bios_getHal_intvec(); // calls the (modified) startup code of HAL
959     retVal = halFpgaUpdateCode(); // return update status, input parameters are don't care
960 
961     return retVal;
962 }
963 
964 //******************************************
V3OP_Scheduler(void)965 void V3OP_Scheduler(void)
966 {
967     unsigned char loop_array_counter;
968     unsigned char rx_queu_counter = 0;
969     unsigned char rx_queu_counter_tmp;
970     StreamSafe stream_tmp;
971     HalFuncInOut pCallAddr;
972 
973     BIOS_ResetCts(); // release CTS line
974     {
975         // send error messages
976         if(BIOS_IsUsbRxError())
977         {
978             V3OP_SendException(BIOS_getRxError().bios_rx_err_id_, BIOS_getRxError().bios_rx_err_code_, BIOS_getRxError().bios_rx_err_payload_);
979             BIOS_ClearUsbRxError();
980             BIOS_ResetCts();
981         }
982         // search for and execute "commands in loop"
983 
984         for(loop_array_counter = 0; loop_array_counter < V3OP_LOOP_ARRAY_COUNT; loop_array_counter++)
985         {
986             if((v3op_loop_array_[loop_array_counter].active) &&
987                (v3op_loop_array_[loop_array_counter].addr <  (*hal_infos_).hal_size))
988             {
989                 pCallAddr = (HalFuncInOut)(*hal_ptr_)[v3op_loop_array_[loop_array_counter].addr].function;
990                 if(pCallAddr != NULL)
991                 {
992                     if(STREAM_out_init(v3op_loop_array_[loop_array_counter].msg_id, v3op_loop_array_[loop_array_counter].msg_type) >= 0)
993                     {
994                         STREAM_internal_stream(&v3op_loop_array_[loop_array_counter].indata[MESSAGE_EXECUTE_PAYLOAD_POS], v3op_loop_array_[loop_array_counter].indata[0]-3, (unsigned char*)0x0001, 0, &stream_tmp);
995                         if(pCallAddr(MESSAGE_NEW_MSG | MESSAGE_LAST_MSG) == 1)
996                         {
997                             STREAM_flush();
998                             if(v3op_loop_array_[loop_array_counter].flags & V3OP_LOOP_WAIT_FLAG)
999                             {
1000                                 V3OP_KillLoop(v3op_loop_array_[loop_array_counter].msg_id);
1001                             }
1002                         }
1003                         STREAM_external_stream(&stream_tmp);
1004                     }
1005                 }
1006             }
1007         }
1008 
1009         // test on new messages from dll and execute
1010         rx_queu_counter_tmp = rx_queu_counter;
1011         do
1012         {
1013             if(bios_rx_record_.state[rx_queu_counter] & BIOS_RX_RDY)
1014             {
1015                 BIOS_LedFlash(BIOS_LED_MODE,20);
1016                 STREAM_in_init((BiosRxRecord*)&bios_rx_record_, rx_queu_counter);
1017                 rx_queu_counter_public_ = rx_queu_counter;
1018                 V3OP_Rx(bios_rx_record_.data[rx_queu_counter]);
1019                 rx_queu_counter = rx_queu_counter_public_;
1020                 bios_rx_record_.state[rx_queu_counter] &= ~BIOS_RX_RDY;
1021                 break;
1022             }
1023             rx_queu_counter++;
1024             if(rx_queu_counter >= BIOS_RX_QUEUS)
1025             {
1026               rx_queu_counter = 0;
1027             }
1028         }
1029         while(rx_queu_counter_tmp != rx_queu_counter);
1030     }
1031 }
1032 
1033 // System events
1034 typedef enum FET_UPDATE_CONFIG
1035 {
1036     FET_INIT_ALL_MODULES = 0,
1037     FET_DE_INIT_ALL_MODULES,
1038     FET_DE_INIT_DCDC_MCU,
1039     FET_FPGA_UPDATE,
1040     FET_STOP_VOLTAGE_SUPERVISION,
1041     FET_START_VOLTAGE_SUPERVISION,
1042 } FetUpdateConfig;
1043 
1044 
1045 //! \brief lock/unlock write/erase to UIF (HAL) flash memory
1046 //! \param[in] *payload pointer to receive buffer
1047 //! \return 0 -> flash write/erase locked
1048 //! \return 1 -> flash write/erase released
1049 //! \return <0 -> error
V3OP_CoreFlashFunctionInit(unsigned char * payload)1050 short V3OP_CoreFlashFunctionInit(unsigned char *payload)
1051 {
1052     short ret_value = -1;
1053 
1054     if(payload[4] == FET_INIT_ALL_MODULES)
1055     {
1056         // init communicaiton to DCDC sub mcu
1057         V3OP_DcdcInterfaceInit();
1058         dcdcInfos_.dcdcRestart(Bios_getTool_id());
1059         // will init hil layer as well if valid
1060         V3OP_HalInterfaceInit();
1061         V3OP_ComInterfaceInit();
1062 
1063         BIOS_LedAlternate(0);
1064         BIOS_LedOff(BIOS_LED_MODE);
1065         BIOS_LedOn(BIOS_LED_POWER);
1066         ret_value = 1;
1067     }
1068     else if(payload[4] == FET_DE_INIT_ALL_MODULES)//used for HAL HIL DCDC & COM Channel update
1069     {
1070         V3OP_KillAllLoops();
1071         V3OP_HalInterfaceClear();
1072         STREAM_resetSharedVariables();
1073         dcdcInfos_.dcdcPowerDown();
1074         V3OP_ComInterfaceClear();
1075         V3OP_DcdcInterfaceClear();
1076         BIOS_LedAlternate(30);
1077         ret_value = 1;
1078     }
1079     else if(payload[4] == FET_DE_INIT_DCDC_MCU) // Just for Sub MCU update don't clear Hal HIl you need it for SBW communication
1080     {
1081         V3OP_KillAllLoops();
1082         STREAM_resetSharedVariables();
1083         dcdcInfos_.dcdcPowerDown();
1084         V3OP_DcdcInterfaceClear();
1085         BIOS_LedAlternate(30);
1086         ret_value = 1;
1087     }
1088     else if(payload[4] == FET_FPGA_UPDATE) // Used for FPGA updates
1089     {
1090         V3OP_KillAllLoops();
1091         V3OP_HalInterfaceClear();
1092         STREAM_resetSharedVariables();
1093         dcdcInfos_.dcdcPowerDown();
1094         V3OP_ComInterfaceClear();
1095         V3OP_DcdcInterfaceClear();
1096         IccMonitor_StopDcdcOvercurrentDetection();
1097         BIOS_LedAlternate(5);
1098         ret_value = V3OP_HalFpgaUpdate() ? -1 : 1;
1099     }
1100     else if(payload[4] == FET_STOP_VOLTAGE_SUPERVISION) // Used for FPGA updates
1101     {
1102         V3OP_KillAllLoops();
1103         IccMonitor_StopVoltageSupervision();
1104         IccMonitor_StopDcdcOvercurrentDetection();
1105         BIOS_LedAlternate(30);
1106         ret_value = 1;
1107     }
1108     else if(payload[4] == FET_START_VOLTAGE_SUPERVISION) // Used for FPGA updates
1109     {
1110         IccMonitor_StartDcdcOvercurrentDetection();
1111         BIOS_LedOff(BIOS_LED_MODE);
1112         BIOS_LedOn(BIOS_LED_POWER);
1113         //~1.6 s delay
1114         __delay_cycles(40000000);
1115         IccMonitor_StartVoltageSupervision();
1116         __delay_cycles(40000000);
1117         ret_value = 1;
1118     }
1119     return(ret_value);
1120 }
1121 
1122 #ifdef MSP_FET
1123 #pragma optimize = low
1124 #pragma vector=WDT_VECTOR
TimeoutFpgaShift_(void)1125 __interrupt void TimeoutFpgaShift_(void)
1126 {
1127     SFRIFG1 &= ~WDTIFG;
1128 
1129     if(STREAM_out_init(0, RESPTYP_STATUS) != EXCEPTION_TX_NO_BUFFER)
1130     {
1131         STREAM_put_word(FET_FPGA_TIMOUT);
1132         STREAM_flush();
1133     }
1134     _edt_Common_Methods.setFpgaTimeOut(1);
1135 }
1136 #endif
1137