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