1 /*
2  * bios.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 #include "hw_compiler_specific.h"
37 #include "bios.h"
38 #include <string.h>
39 
40 #include "USB_API/USB_Common/types.h"
41 #include "USB_API/USB_CDC_API/UsbCdc.h"
42 #include "USB_config/descriptors.h"
43 #include "usbConstructs.h"
44 #include "USB_API/USB_Common/usb.h"
45 #include "communicationDefs.h"
46 #include "protocol.h"
47 #include "FetVersion.h"
48 
49 //! \brief count of LED from uif
50 #define BIOS_LED_COUNT 2
51 
52 //! \brief pin (from TUSB) for hardware handshake for TX cannel
53 //! \details also used as TRUE value for bios_xoff_
54 #define BIOS_HARD_RTS_BIT 3
55 
56 //! \brief version of bios code
57 const unsigned short core_version_ @ "COREVERSION" = CORE_VERSION;
58 #pragma required=core_version_
59 
60 unsigned short tool_id_;
61 #pragma required=tool_id_
62 
63 //! \brief chars for flow control
64 const unsigned char BIOS_DLE_CHAR  = 0x10;
65 //! \brief chars for flow control
66 const unsigned char BIOS_XON_CHAR  = 0x11;
67 //! \brief chars for flow control
68 const unsigned char BIOS_XOFF_CHAR = 0x13;
69 
70 //**************************** Internal function prototypes
71 
72 //! \brief clears the TX software buffer
73 void  bios_UsbTxClear(void);
74 
75 //! \brief dummy to catch all irq
76 //! \details biosHalInterfaceClear set all by bios unused irqs to dummy
77 INTERRUPT_PROTO void dummyIsr (void);
78 
79 //! \brief receive char form UART
80 //! \details get chars form hardware RX buffer and stor them in the RX software buffer(s).
81 //! Messages are checked on crc. and ack/exceptions processed in this function.
82 void usbRxIsr (unsigned char receivedByte);
83 
84 //! \brief 10ms timer interrupt
85 //! \details count all 10ms the timer for RX and TX timeouts.
86 //! Also the timer for LED drive.
87 INTERRUPT_PROTO void timerB1Isr (void);
88 
89 //! \brief function is called by hardware interrupt if TX buffer goes empty
90 //! \details move a char from the TX software buffer to the hardware TX buffer.
91 void BIOS_usbTxData (void);
92 
93 //! \brief Buffer for the RX cannel
94 //! \details actual two buffers used, one for working, the second to catch char which receivend before
95 //! the cts signal have an effect.
96 volatile BiosRxRecord bios_rx_record_ = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, 0, {0,0,0,0}, 0, 0, 0, {0,0,0,0}};
97 //! \brief Buffer for the TX cannel
98 //! \details only one buffer in uif. There is no need for a second. The dll play ping pong with the uif
99 volatile BiosTxRecord bios_tx_record_ = {0, 0, {0}, {0}, {0}, {0}, {0}, NULL, 0};
100 
101 //! \brief Timer for RX and TX timeouts
102 //! \details timebase 10ms
103 volatile BiosGlobalTimer bios_global_timer_[BIOS_TIMER_COUNT];
104 //! \brief uif is under control of the eg. workbench
105 //! \details \li 0, not under control, reset by EXCEPTION NULL
106 //! \li 1, set in v3opRx with the first valid command
107 char bios_wb_control_ = 0;
108 
109 //! \brief values for (re)set LEDs
110 const unsigned char BIOS_LED_OFF   = 0x00;
111 //! \brief values for (re)set LEDs
112 const unsigned char BIOS_LED_ON    = 0x01;
113 //! \brief values for (re)set LEDs
114 const unsigned char BIOS_LED_BLINK = 0x02;
115 
116 volatile SystemEventMsp system_event_msp_;
117 
118 //! \brief for LED driving
119 struct _BiosLedTimer_
120 {
121   unsigned char  mode;
122   unsigned short load;
123   unsigned short counter;
124   unsigned char  *addr;
125   unsigned char bit;
126 };
127 typedef struct _BiosLedTimer_ BiosLedTimer;
128 
129 //! \brief for LED driving
130 volatile BiosLedTimer bios_leds_[BIOS_LED_COUNT];
131 
132 //! \brief the LED from the EASY :-)
133 //! \details The EASY haven't LEDs, this var is a replacment for the port to catch
134 //! the LED driving
135 unsigned char bios_led_dummy_;
136 
137 //! \brief Hold the crystal frequency
138 //! \details will set in biosInitSystem depended for the detected hardware
139 //! will used eg. from timers and UART
140 unsigned long crystal_;
141 
142 //! \brief modulation register value
143 //! \details will set in biosInitSystem depended for the detected hardware
144 unsigned char baudmod_ = 0;
145 
146 //! \brief flags for hardware features
147 //! \details will set in biosInitSystem depended for the detected hardware
148 //! \li bit 0 -> handshake xon/xoff = 1, hw handshake = 0
149 //! \li bit 1 -> 4 wire
150 //! \li bit 2 -> 2 wire
151 unsigned long bios_device_flags_ = 0;
152 
153 //! \brief hardware version
154 //! \details will set in biosInitSystem depended for the detected hardware
155 unsigned short bios_info_hw_0_;
156 
157 //! \brief hardware version
158 //! \details will set in biosInitSystem depended for the detected hardware
159 unsigned short bios_info_hw_1_;
160 
161 //! \brief gets the received char
162 unsigned char bios_rx_char_;
163 
164 //! \brief dummy to switch of XON/XOFF in easy
165 const unsigned char bios_rx_char_always_0 = 0;
166 
167 //! \brief points to bios_rx_char_ if XON/XOFF is active
168 //! \details on EASY it points to bios_rx_char_always_0 to disable XON/XOFF functionality
169 //! will set in biosInitSystem depended for the detected hardware
170 unsigned char *bios_rx_char_ptr_;
171 
172 //! \brief Flag for XON/XOFF status
173 //! \li 0, TX can send
174 //! \li 1, TX must not be send
175 //! \details between receiving xoff and sending chars is a delay (by program flow). This
176 //! is not a problem, because the TUSB has enougth reserve in the buffer.
177 unsigned char bios_xoff_ = 0;
178 
179 //! \brief pointer to active TX flow control
180 //! \details \li on EASY it points to the PORT with the handshakesignals
181 //! \li on uif it points to the (software)flag bios_xoff_
182 //! will set in biosInitSystem depended for the detected hardware
183 unsigned char *bios_xoff_ptr_ = &bios_xoff_;
184 
185 //! \brief Flag for error indication
186 //! \details \li 1, an error message is to send. Set by every function which can generate an error
187 //! \li 0, reset in biosmainLoop, if error message was send
188 volatile char  bios_rx_err_set_ = 0;
189 
190 //! \brief Message ID from received message which provoke the error.
191 volatile unsigned char bios_rx_err_id_ = 0;
192 
193 //! \brief error code
194 //! \li EXCEPTION_NOT_IMPLEMENT_ERR 	0x8001
195 //! \li EXCEPTION_MSGID_ERR	        0x8002
196 //! \li EXCEPTION_CRC_ERR	        0x8003
197 //! \li EXCEPTION_RX_TIMEOUT_ERR	0x8004
198 //! \li EXCEPTION_TX_TIMEOUT_ERR	0x8005
199 //! \li EXCEPTION_RX_OVERFLOW_ERR     	0x8006
200 //! \li EXCEPTION_TX_NO_BUFFER	        0x8007
201 //! \li EXCEPTION_COM_RESET	        0x8008
202 //! \li EXCEPTION_RX_NO_BUFFER	        0x8009
203 //! \li EXCEPTION_RX_TO_SMALL_BUFFER	0x800A
204 //! \li EXCEPTION_RX_LENGTH	        0x800B
205 //! \li HAL specific exceptions	0xFFFF to 0xFF00 (-1 to -255)
206 volatile BIOS_RxError_t BIOS_RxEr;
207 
208 //! \brief Pointer to additional information
209 //! \details if an error provide more information about the error
210 volatile unsigned short *bios_rx_err_payload_ = NULL;
211 
212 //! \brief target for dummyread form UART
213 volatile unsigned char usb_read_dummy_;
214 
215 volatile unsigned short CTS_LINE = 0;
216 
217 //**************************** Module Implementation ******************/
BIOS_InitSystem(void)218 void BIOS_InitSystem (void)
219 {    //Init Timer A1 (currently used for TX and RX timeouts and LED's)
220     //generates interrupt every 10ms
221     TA1CCR0 = USB_MCLK_FREQ / (8 * 100) - 1;
222     TA1CTL = TASSEL__SMCLK | ID__8 | MC__UP/*MC__CONTINOUS*/ | TACLR | TAIE;
223 
224 #ifdef eZ_FET
225     // LED assignments for eZ-FET
226     bios_leds_[0].addr = (unsigned char*)&P1OUT;
227     bios_leds_[0].bit = BIT2;
228     bios_leds_[1].addr = (unsigned char*)&P1OUT;
229     bios_leds_[1].bit = BIT3;
230 #endif
231 
232 #ifdef MSP_FET
233     // LED assignments for MSP-FET
234     bios_leds_[0].addr = (unsigned char*)&P6OUT;
235     bios_leds_[0].bit = BIT7;
236     bios_leds_[1].addr = (unsigned char*)&P5OUT;
237     bios_leds_[1].bit = BIT3;
238 #endif
239 
240     /// is detected!!
241     // char set to rx input for xon/xoff
242     bios_rx_char_ptr_ = &bios_rx_char_;
243 
244     // disalbe BSL protection
245     SYSBSLC &= ~SYSBSLPE;
246     // get tool id stored in BSL area
247     tool_id_ = *(unsigned short*)0x100e;
248 
249     // enable BSL protection again
250     SYSBSLC |= SYSBSLPE;
251 
252     bios_info_hw_0_ = tool_id_;
253     bios_info_hw_1_ = tool_id_;
254 }
255 
BIOS_SuspendSystem(void)256 void BIOS_SuspendSystem(void)
257 {}
258 
BIOS_ResumeSystem(void)259 void BIOS_ResumeSystem(void)
260 {}
261 
BIOS_SetCts()262 void BIOS_SetCts()
263 {
264     CTS_LINE = FALSE;  bios_global_timer_[0].state |= BIOS_TIMER_BREAK;
265 }
BIOS_ResetCts()266 void BIOS_ResetCts()
267 {
268     CTS_LINE = TRUE; bios_global_timer_[0].state &= ~BIOS_TIMER_BREAK;
269 }
270 
Bios_getCore_version()271 unsigned short Bios_getCore_version()
272 {
273     return CORE_VERSION;
274 }
Bios_getTool_id()275 unsigned short Bios_getTool_id()
276 {
277     return tool_id_;
278 }
Bios_getInfo_hw_0()279 unsigned short Bios_getInfo_hw_0()
280 {
281     return bios_info_hw_0_;
282 }
Bios_getInfo_hw_1()283 unsigned short Bios_getInfo_hw_1()
284 {
285     return bios_info_hw_1_;
286 }
287 
288 //*************************************
BIOS_LedOn(unsigned char no)289 short BIOS_LedOn(unsigned char no)
290 {
291     if(no < BIOS_LED_COUNT)
292     {
293         bios_leds_[no].mode = BIOS_LED_ON;
294         bios_leds_[no].load = 0;
295         bios_leds_[no].counter = 0;
296     }
297     return(0);
298 }
299 
300 //************************************
BIOS_LedOff(unsigned char no)301 short BIOS_LedOff(unsigned char no)
302 {
303     if(no < BIOS_LED_COUNT)
304     {
305         bios_leds_[no].mode = BIOS_LED_OFF;
306         bios_leds_[no].load = 0;
307         bios_leds_[no].counter = 0;
308     }
309     return(0);
310 }
311 
312 //************************************
BIOS_LedBlink(unsigned char no,unsigned short time)313 short BIOS_LedBlink(unsigned char no,unsigned short time)
314 {
315     if(no < BIOS_LED_COUNT)
316     {
317         bios_leds_[no].load = time * 2;
318         bios_leds_[no].counter = time * 2;
319         bios_leds_[no].mode = BIOS_LED_BLINK;
320     }
321     return(0);
322 }
323 
324 //************************************
BIOS_LedFlash(unsigned char no,unsigned short time)325 short BIOS_LedFlash(unsigned char no,unsigned short time)
326 {
327     if((no < BIOS_LED_COUNT) && !bios_leds_[no].counter)
328     {
329         bios_leds_[no].load = time * 2;
330         bios_leds_[no].counter = time * 2;
331         bios_leds_[no].mode &= ~BIOS_LED_BLINK;
332     }
333     return(0);
334 }
335 
336 //************************************
BIOS_LedAlternate(unsigned short time)337 short BIOS_LedAlternate(unsigned short time)
338 {
339     bios_leds_[0].load = time * 2;
340     bios_leds_[0].counter = time;
341     bios_leds_[1].load = time * 2;
342     bios_leds_[1].counter = time;
343     if(time)
344     {
345         bios_leds_[0].mode = BIOS_LED_ON | BIOS_LED_BLINK;
346         bios_leds_[1].mode = BIOS_LED_OFF | BIOS_LED_BLINK;
347     }
348     else
349     {
350         bios_leds_[0].mode = BIOS_LED_OFF;
351         bios_leds_[1].mode = BIOS_LED_OFF;
352     }
353     return(0);
354     }
355 
356 //************************************
BIOS_GlobalError(void)357 void BIOS_GlobalError(void)
358 {
359     BIOS_LedOn(BIOS_LED_MODE);
360     BIOS_LedOff(BIOS_LED_POWER);
361     while(1);
362 }
363 
364 //INTERRUPT(TIMER1_A1_VECTOR) void timerB1Isr (void)
365 //***********************************************
INTERRUPT(TIMER1_A1_VECTOR)366 INTERRUPT(TIMER1_A1_VECTOR) void timerB1Isr (void)
367 {
368     if(TA1IV == TA1IV_TA1IFG)
369     {
370         // process global timers
371 		if((bios_global_timer_[BIOS_TIMER_RX].count > 1) && !(bios_global_timer_[BIOS_TIMER_RX].state & BIOS_TIMER_BREAK))
372         {
373             bios_global_timer_[BIOS_TIMER_RX].count--;
374         }
375         else if(bios_global_timer_[BIOS_TIMER_RX].count == 1)
376         {
377             bios_global_timer_[0].count = 0;
378             BIOS_UsbRxError(EXCEPTION_RX_TIMEOUT_ERR);
379         }
380         if((bios_global_timer_[BIOS_TIMER_TX].count > 1) && !(bios_xoff_))
381         {
382             bios_global_timer_[BIOS_TIMER_TX].count--;
383         }
384         // LED mode
385         DIAG_SUPPRESS(Pa082)
386         if((bios_leds_[BIOS_LED_MODE].mode & BIOS_LED_ON) ^ (bios_leds_[BIOS_LED_MODE].counter > (bios_leds_[BIOS_LED_MODE].load/2)))
387         {
388             *bios_leds_[BIOS_LED_MODE].addr |= bios_leds_[BIOS_LED_MODE].bit;
389         }
390         else
391         {
392             *bios_leds_[BIOS_LED_MODE].addr &= ~bios_leds_[BIOS_LED_MODE].bit;
393         }
394         DIAG_DEFAULT(Pa082)
395         if(bios_leds_[BIOS_LED_MODE].counter > 0)
396         {
397             bios_leds_[BIOS_LED_MODE].counter--;
398         }
399         else if(bios_leds_[BIOS_LED_MODE].mode & BIOS_LED_BLINK)
400         {
401             bios_leds_[BIOS_LED_MODE].counter = bios_leds_[BIOS_LED_MODE].load;
402         }
403 
404         // LED power
405         DIAG_SUPPRESS(Pa082)
406         if((bios_leds_[BIOS_LED_POWER].mode & BIOS_LED_ON) ^ (bios_leds_[BIOS_LED_POWER].counter > (bios_leds_[BIOS_LED_POWER].load/2)))
407         {
408             *bios_leds_[BIOS_LED_POWER].addr |= bios_leds_[BIOS_LED_POWER].bit;
409         }
410         else
411         {
412             *bios_leds_[BIOS_LED_POWER].addr &= ~bios_leds_[BIOS_LED_POWER].bit;
413         }
414         DIAG_DEFAULT(Pa082)
415         if(bios_leds_[BIOS_LED_POWER].counter > 0)
416         {
417             bios_leds_[BIOS_LED_POWER].counter--;
418         }
419         else if(bios_leds_[BIOS_LED_POWER].mode & BIOS_LED_BLINK)
420         {
421             bios_leds_[BIOS_LED_POWER].counter = bios_leds_[BIOS_LED_POWER].load;
422         }
423     }
424 }
425 
426 //**********************************************************
dummyIsr(void)427 INTERRUPT_PROTO void dummyIsr (void)
428 {
429     ;
430 }
431 const volatile unsigned short *bios_intvec_ = (unsigned short*)0xFF80;
432 
433 //! \brief Pointer to HAL IRQ vector table
434 RO_PLACEMENT_NO_INIT volatile const unsigned long   hal_intvec_    @ "HALINTVEC";
435 RO_PLACEMENT_NO_INIT volatile const unsigned long   hal_signature_ @ "HALSIGNATURE";
436 
437 RO_PLACEMENT_NO_INIT volatile const unsigned long   dcdc_intvec_   @ "DCDCIVEC";
438 RO_PLACEMENT_NO_INIT volatile const unsigned long   dcdc_signature_ @ "DCDCSIGNATURE";
439 
440 RO_PLACEMENT_NO_INIT volatile const unsigned long   hil_signature_ @ "HILSIGNATURE";
441 RO_PLACEMENT_NO_INIT volatile const unsigned short  hil_Start_UP_ @ "HILINIT";
442 
443 RO_PLACEMENT_NO_INIT volatile const unsigned long   com_intvec_   @ "COMINTVEC";
444 RO_PLACEMENT_NO_INIT volatile const unsigned long   com_signature_ @ "COMSIGNATURE";
445 RO_PLACEMENT_NO_INIT volatile const long  com_semaphore_ @ "COM_SEMAPHOREADRESS";
446 
Bios_getHal_intvec()447 unsigned long Bios_getHal_intvec()
448 {
449    return hal_intvec_;
450 }
Bios_getHil_intvec()451 unsigned short Bios_getHil_intvec()
452 {
453    return hil_Start_UP_;
454 }
Bios_getDcdc_intvec()455 unsigned long Bios_getDcdc_intvec()
456 {
457    return dcdc_intvec_;
458 }
Bios_getCom_intvec()459 unsigned long Bios_getCom_intvec()
460 {
461    return com_intvec_;
462 }
Bios_getDcdc_signature()463 unsigned long Bios_getDcdc_signature()
464 {
465    return dcdc_signature_;
466 }
Bios_getHal_signature()467 unsigned long Bios_getHal_signature()
468 {
469     return hal_signature_;
470 }
Bios_getHil_signature()471 unsigned long Bios_getHil_signature()
472 {
473     return hil_signature_;
474 }
Bios_getCom_signature()475 unsigned long Bios_getCom_signature()
476 {
477     return com_signature_;
478 }
479 //***************************************
480 unsigned short tempInDataRx[4][BIOS_RX_SIZE]= {0x0,0x0};
481 
482 //***************************************
BIOS_InitCom(void)483 void BIOS_InitCom(void)
484 {
485     unsigned char i;
486 
487     for(i = 0; i < BIOS_RX_QUEUS; i++)
488     {
489         bios_rx_record_.datas[i] = tempInDataRx[i];
490         if(bios_rx_record_.datas[i] == NULL)
491         {
492             BIOS_GlobalError();
493         }
494         bios_rx_record_.data[i] = (unsigned char*)bios_rx_record_.datas[i];
495     }
496     for(i = 0; i < BIOS_TX_QUEUS; i++)
497     {
498         bios_tx_record_.data[i] = (unsigned char*)bios_tx_record_.datas[i];
499     }
500 }
501 //*****************************************
BIOS_PrepareTx(unsigned int size)502 void BIOS_PrepareTx(unsigned int size)
503 {
504     bios_tx_record_.send_counter[bios_tx_record_.cannel_to_send] = 0;
505     DIAG_SUPPRESS(Pa082)
506     bios_tx_record_.count[bios_tx_record_.active] = size;
507     bios_tx_record_.state[bios_tx_record_.active] |= BIOS_TX_TO_SEND;
508     DIAG_DEFAULT(Pa082)
509 }
510 
511 //********************************************
BIOS_StartTx(void)512 void BIOS_StartTx(void)
513 {
514     bios_global_timer_[BIOS_TIMER_TX].count = BIOS_TX_TIMEOUT;
515     BIOS_usbTxData();
516 }
517 
518 //*********************************************
BIOS_UsbTxError(void)519 void BIOS_UsbTxError(void)
520 {
521     BIOS_UsbTxClear();
522 }
523 
524 //*********************************************
BIOS_UsbTxClear(void)525 void BIOS_UsbTxClear(void)
526 {
527     unsigned char i;
528 
529     memset((unsigned char*)&bios_tx_record_, 0, sizeof(bios_tx_record_));
530     bios_global_timer_[BIOS_TIMER_TX].count = 0;
531     bios_rx_char_ = 0;
532     for(i = 0; i < BIOS_TX_QUEUS; i++)
533     {
534         bios_tx_record_.data[i] = (unsigned char*)bios_tx_record_.datas[i];
535         bios_tx_record_.state[i] = 0;
536     }
537 }
538 
539 //***************************************
BIOS_UsbRxClear(void)540 void BIOS_UsbRxClear(void)
541 {
542     unsigned char i;
543 
544     bios_rx_record_.active = 0;
545     for(i = 0; i < BIOS_RX_QUEUS; i++)
546     {
547         bios_rx_record_.state[i] = 0;
548         bios_rx_record_.last_cmd_typ = 0;
549         bios_rx_record_.last_msg_id = 0;
550         bios_rx_record_.data[i][0] = 0;
551         bios_rx_record_.crc[i] = 0;
552         bios_rx_record_.count[i] = 0;
553         bios_rx_record_.size[i] = 0;
554     }
555     bios_global_timer_[0].count = 0;
556 }
557 
BIOS_IsUsbRxError()558 short BIOS_IsUsbRxError()
559 {
560     if(BIOS_RxEr.bios_rx_err_set_)
561     {
562         return TRUE;
563     }
564     return FALSE;
565 }
566 
BIOS_ClearUsbRxError()567 void BIOS_ClearUsbRxError()
568 {
569     BIOS_RxEr.bios_rx_err_code_ = 0;
570     BIOS_RxEr.bios_rx_err_id_ = 0;
571     BIOS_RxEr.bios_rx_err_payload_ = NULL;
572     BIOS_RxEr.bios_rx_err_set_ = 0;
573 }
574 
BIOS_getRxError()575 BIOS_RxError_t BIOS_getRxError()
576 {
577     return BIOS_RxEr;
578 }
579 //********************************************
BIOS_UsbRxError(unsigned short code)580 void BIOS_UsbRxError(unsigned short code)
581 {
582     BIOS_UsbRxClear();
583     BIOS_RxEr.bios_rx_err_code_ = code;
584     BIOS_RxEr.bios_rx_err_id_ = 0;
585     BIOS_RxEr.bios_rx_err_payload_ = NULL;
586     BIOS_RxEr.bios_rx_err_set_ = 1;
587 }
588 //************************************************************
BIOS_usbTxData(void)589 void BIOS_usbTxData (void)
590 {
591     unsigned char first_cannel;
592     // some thing to send in active send buffer?
593     first_cannel = bios_tx_record_.cannel_to_send;
594     while(!(bios_tx_record_.state[bios_tx_record_.cannel_to_send] & BIOS_TX_TO_SEND))
595     {
596 
597         bios_tx_record_.cannel_to_send++;
598         if(bios_tx_record_.cannel_to_send >= BIOS_TX_QUEUS)
599         {
600             bios_tx_record_.cannel_to_send = 0;
601         }
602 
603         if(bios_tx_record_.cannel_to_send == first_cannel)
604         {
605             return;
606         }
607     }
608     // test on chars in software TX buffer
609     DIAG_SUPPRESS(Pa082)
610     if(bios_tx_record_.send_counter[bios_tx_record_.cannel_to_send] < bios_tx_record_.count[bios_tx_record_.cannel_to_send])
611     {
612         WORD x;
613 
614         // send char from software buffer
615         if(cdcSendDataInBackground((BYTE*)&bios_tx_record_.data[bios_tx_record_.cannel_to_send][0],bios_tx_record_.count[bios_tx_record_.cannel_to_send],0,10)) //Send the response over USB
616         {
617             USBCDC_abortSend(&x,0);                                         // It failed for some reason; abort and leave the main loop
618         }
619         // no char to send ***anymore*** in actual TX software buffer
620         // we don't clear TX software buffer, reset only flags. If need we can
621         // send the buffer again. (resending in not implemented)
622         bios_tx_record_.state[bios_tx_record_.cannel_to_send] &= ~BIOS_TX_TO_SEND;
623         bios_tx_record_.send_counter[bios_tx_record_.cannel_to_send] = 0;
624         first_cannel = bios_tx_record_.cannel_to_send;
625         if(!(bios_tx_record_.state[bios_tx_record_.cannel_to_send] & BIOS_TX_WAIT_ON_ACK))
626         {
627             bios_global_timer_[BIOS_TIMER_TX].count = 0;
628         }
629         // search in TX software buffer for data to send. If no data found, it was the
630         // last TX buffer empty interrupt.
631         do
632         {
633 
634             bios_tx_record_.cannel_to_send++;
635             if(bios_tx_record_.cannel_to_send >= BIOS_TX_QUEUS)
636             {
637                 bios_tx_record_.cannel_to_send = 0;
638             }
639 
640             if(bios_tx_record_.state[bios_tx_record_.cannel_to_send] & BIOS_TX_TO_SEND)
641             {
642                 if(bios_tx_record_.send_counter[bios_tx_record_.cannel_to_send] <= ((unsigned short)bios_tx_record_.data[bios_tx_record_.cannel_to_send][0])) // add left side +1, if crc active
643                 {
644                     bios_global_timer_[BIOS_TIMER_TX].count = BIOS_TX_TIMEOUT;
645                 }
646             }
647         }
648         while(!(bios_tx_record_.state[bios_tx_record_.cannel_to_send] & BIOS_TX_TO_SEND) && (bios_tx_record_.cannel_to_send != first_cannel));
649     }
650     DIAG_DEFAULT(Pa082)
651 }
652 
BIOS_UsbRxData()653 short BIOS_UsbRxData()
654 {
655         BYTE count = 0;
656         BYTE usbDataPointer = 0;
657         BYTE sizeToCopy = 0;
658         short returnError = 0;
659 
660         BIOS_SetCts();
661         count = USBCDC_bytesInUSBBuffer(DEBUG_CHANNEL);
662         if(count)
663         {
664             #pragma data_alignment=4
665             static BYTE recivedData[260] = {0};
666 
667             USBCDC_receiveData(recivedData, count , DEBUG_CHANNEL);
668 
669             while(count)
670             {
671                 // get char from hardwarebuffer
672                 bios_rx_char_ = recivedData[usbDataPointer];
673                 // test for xon/xoff flow control char
674 
675                 // test for free buffer
676                 if(bios_rx_record_.state[bios_rx_record_.active] & BIOS_RX_RDY)
677                 {
678                     BIOS_UsbRxError(EXCEPTION_RX_NO_BUFFER);
679                     returnError = EXCEPTION_RX_NO_BUFFER;
680                     goto usbRxIsrExit;
681                 }
682                 // test for first char in a message
683                 if(!bios_rx_record_.count[bios_rx_record_.active])
684                 {
685                     // a message must received in 100ms completely
686                     // if not a timeout error generate by timerB1Isr
687                     bios_global_timer_[0].count = 50; // start timeout timer 500ms
688                     bios_rx_record_.crc[1] = 0;
689                     // length of messages must be even
690                     if(bios_rx_char_ & 0x01)
691                     {
692                         bios_rx_record_.size[bios_rx_record_.active] = bios_rx_char_ + 0;
693                     }
694                     else
695                     {
696                         bios_rx_record_.size[bios_rx_record_.active] = bios_rx_char_ + 1;
697                     }
698                 }
699                 // test for buffer size
700                 if(bios_rx_record_.size[bios_rx_record_.active] < (BIOS_RX_SIZE + 2))
701                 {
702                     DIAG_SUPPRESS(Pa082)
703                     sizeToCopy = bios_rx_record_.size[bios_rx_record_.active] + 1 - bios_rx_record_.count[bios_rx_record_.active];
704                     if(sizeToCopy > count)
705                     {
706                       sizeToCopy = count;
707                     }
708                     BYTE numWords = sizeToCopy/sizeof(unsigned int);
709                     unsigned int *pDest = (unsigned int*) &bios_rx_record_.data[bios_rx_record_.active][bios_rx_record_.count[bios_rx_record_.active]];
710                     unsigned int *pSrc = (unsigned int*) &recivedData[usbDataPointer];
711                     for(unsigned char i = 0; i < numWords; ++i)
712                     {
713                       *pDest++ = *pSrc++;
714                     }
715                     for(unsigned char i = numWords*sizeof(unsigned int); i < sizeToCopy; ++i)
716                     {
717                       bios_rx_record_.data[bios_rx_record_.active][bios_rx_record_.count[bios_rx_record_.active]+i] = recivedData[usbDataPointer+i];
718                     }
719                     bios_rx_record_.count[bios_rx_record_.active] += sizeToCopy;
720                     usbDataPointer += sizeToCopy;
721                     count -= sizeToCopy;
722                     DIAG_DEFAULT(Pa082)
723                 }
724                 else
725                 {
726                     BIOS_UsbRxError(EXCEPTION_RX_TO_SMALL_BUFFER);
727                     returnError = EXCEPTION_RX_TO_SMALL_BUFFER;
728                     goto usbRxIsrExit;
729                 }
730 
731                 // test for completly message
732                 DIAG_SUPPRESS(Pa082)
733                 if(bios_rx_record_.count[bios_rx_record_.active] > (bios_rx_record_.size[bios_rx_record_.active]))
734                 DIAG_DEFAULT(Pa082)
735                 {
736                     bios_global_timer_[0].count = 0;  // stop timeout timer
737 
738                     if(bios_rx_record_.data[bios_rx_record_.active][MESSAGE_CMDTYP_POS] == RESPTYP_ACKNOWLEDGE)
739                     {
740                         // search for message which are waiting on a ack
741                         for(unsigned char i = 0; i < BIOS_TX_QUEUS; i++)
742                         {
743                             DIAG_SUPPRESS(Pa082)
744                             // waits a transmited message for a ACK?
745                             if((bios_tx_record_.state[i] & BIOS_TX_WAIT_ON_ACK) &&
746                                 ((bios_tx_record_.data[i][MESSAGE_MSG_ID_POS] & 0x3F) == bios_rx_record_.data[bios_rx_record_.active][MESSAGE_MSG_ID_POS]))
747                             {
748                                 // if the transmited message are a member of a multi package message, the ack provide the package number
749                                 if( bios_tx_record_.data[i][3] || (bios_rx_record_.data[bios_rx_record_.active][0] > 3) )
750                                 {
751                                     // package number are in byte 4
752                                     if(bios_tx_record_.data[i][3] == bios_rx_record_.data[bios_rx_record_.active][4])
753                                     DIAG_DEFAULT(Pa082)
754                                     {
755                                         bios_tx_record_.state[i] &= ~(BIOS_TX_WAIT_ON_ACK | BIOS_TX_TO_SEND | BIOS_TX_NO_SEND);
756                                         bios_global_timer_[BIOS_TIMER_TX].count = 0;
757                                         break;
758                                     }
759                                 }
760                                 else
761                                 {
762                                     bios_tx_record_.state[i] &= ~(BIOS_TX_WAIT_ON_ACK | BIOS_TX_TO_SEND | BIOS_TX_NO_SEND);
763                                     break;
764                                 }
765                             }
766                         }
767                     }
768                     else if(bios_rx_record_.data[bios_rx_record_.active][MESSAGE_CMDTYP_POS] ==  RESPTYP_EXCEPTION)
769                     {
770                         // exception with message ID = 0 always reset the communication
771                         // also all user macros in the loop are terminated
772                         if(bios_rx_record_.data[bios_rx_record_.active][MESSAGE_MSG_ID_POS] == 0)
773                         {
774                             BIOS_LedOn(BIOS_LED_POWER);
775                             BIOS_LedOff(BIOS_LED_MODE);
776                             bios_wb_control_ = 0;
777                             returnError = RESPTYP_EXCEPTION;
778 
779                         }
780                         else
781                         {
782                             // search for message which are waiting on a ack
783                             for(unsigned char i = 0; i < BIOS_TX_QUEUS; i++)
784                             {
785                                 DIAG_SUPPRESS(Pa082)
786                                 if(((bios_tx_record_.state[i] & (BIOS_TX_WAIT_ON_ACK | BIOS_TX_TO_SEND)) == (BIOS_TX_WAIT_ON_ACK | BIOS_TX_TO_SEND)) &&
787                                     (bios_tx_record_.data[i][MESSAGE_MSG_ID_POS] == bios_rx_record_.data[bios_rx_record_.active][MESSAGE_MSG_ID_POS]) &&
788                                     (bios_tx_record_.data[i][3] == bios_rx_record_.data[bios_rx_record_.active][4]))
789                                 DIAG_DEFAULT(Pa082)
790                                 {
791                                     bios_tx_record_.state[i] &= ~BIOS_TX_WAIT_ON_ACK;
792                                     break;
793                                 }
794                             }
795                         }
796                     }
797                     else if((bios_rx_record_.data[bios_rx_record_.active][MESSAGE_MSG_ID_POS] == 0) && (bios_rx_record_.data[bios_rx_record_.active][MESSAGE_CMDTYP_POS] ==CMDTYP_COMRESET))
798                     {
799                         // clear RX cannel
800                         BIOS_UsbRxClear();
801                         returnError = CMDTYP_COMRESET;
802                         goto usbRxIsrExit;
803                     }
804                     else
805                     {
806                         // mark message as ready
807                         // BIOS_MainLoop pass the message to v3opRx for macro execution
808                         DIAG_SUPPRESS(Pa082)
809                         bios_rx_record_.state[bios_rx_record_.active] |= BIOS_RX_RDY;
810                         DIAG_DEFAULT(Pa082)
811                         // switch to the next Rx buffer
812 
813                         bios_rx_record_.active++;
814                         if(bios_rx_record_.active >= BIOS_RX_QUEUS)
815                         {
816                             bios_rx_record_.active = 0;
817                         }
818                     }
819                 // no size error
820                 bios_rx_record_.count[bios_rx_record_.active] = 0;
821                 bios_rx_record_.crc[1] = 0;
822                 }
823                 usbRxIsrExit:
824                 _NOP();
825             }
826         }
827         BIOS_ResetCts(); // release TUSB RX
828         return returnError;
829 }
830 
831 // MSP-FET specifc bios ISR
832 #ifdef MSP_FET
833 
834 // Dummy ISR
835 #pragma optimize = low
836 #pragma vector=TIMER2_A1_VECTOR
TIMER2_A1_ISR(void)837 __interrupt void TIMER2_A1_ISR(void)
838 {
839    switch (__even_in_range(TA2IV, TA2IV_TA2IFG))
840    {
841      case TA2IV_TA2IFG:
842             _NOP();
843             break;
844      default:
845             _NOP();
846             break;
847    }
848 }
849 #pragma vector=TIMER0_B0_VECTOR
TIMER0_B0_ISR_(void)850 __interrupt void TIMER0_B0_ISR_(void)
851 {
852     _NOP();
853 }
854 #endif
855 
856 // Dummy ISR
857 #pragma optimize = low
858 #pragma vector=TIMER0_A0_VECTOR
TIMER0_A0_ISR(void)859 __interrupt void TIMER0_A0_ISR(void)
860 {
861     _NOP();
862 }
863 /****************************************
864  * \brief Interrupt function for NMI events
865 */
866 #pragma vector = UNMI_VECTOR
UNMI_ISR(VOID)867 __interrupt VOID UNMI_ISR(VOID)
868 {
869     _DINT_FET();
870     switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG))
871     {
872     case SYSUNIV_NONE:
873       __no_operation();
874       break;
875     case SYSUNIV_NMIIFG:
876       __no_operation();
877       break;
878     case SYSUNIV_OFIFG:
879         UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT2OFFG);         //Clear OSC flaut Flags fault flags
880         SFRIFG1 &= ~OFIFG;                                  //Clear OFIFG fault flag
881         BIOS_LedOn(BIOS_LED_POWER);
882         BIOS_LedOn(BIOS_LED_MODE);
883         break;
884     case SYSUNIV_ACCVIFG:
885       __no_operation();
886       break;
887     case SYSUNIV_BUSIFG:
888       SYSBERRIV = 0;            // clear bus error flag
889       USB_disable();            // Disable
890       BIOS_LedOn(BIOS_LED_POWER);
891       BIOS_LedOn(BIOS_LED_MODE);
892       break;
893     }
894 }
895 
896 #pragma vector=SYSNMI_VECTOR
SysNmiHandler(void)897 __interrupt void SysNmiHandler(void)
898 {
899     switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG))
900     {
901     case SYSUNIV_NONE:
902         __no_operation();
903         break;
904     case SYSUNIV_NMIIFG:
905         __no_operation();
906         break;
907     case SYSUNIV_OFIFG:
908         UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT2OFFG);         //Clear OSC flaut Flags fault flags
909         SFRIFG1 &= ~OFIFG;                                  //Clear OFIFG fault flag
910         BIOS_LedOn(BIOS_LED_POWER);
911         BIOS_LedOn(BIOS_LED_MODE);
912         break;
913     case SYSUNIV_ACCVIFG:
914         __no_operation();
915         break;
916     case SYSUNIV_BUSIFG:                                      //USB is required.
917         SYSBERRIV = 0;                                      //clear bus error flag
918         USB_disable();                                      //Disable
919         BIOS_LedOn(BIOS_LED_POWER);
920         BIOS_LedOn(BIOS_LED_MODE);
921         break;
922     }
923 }
924