source: test2.git/TraceLeUart.c

Last change on this file was b6aa0ba, checked in by andib <andi.b@…>, 2 years ago

test with more files

  • Property mode set to 100644
File size: 28.9 KB
RevLine 
[b6aa0ba]1/******************************************************************************
2MODULE : TraceLeUart.c
3DESCRIPTION : Traceging facility via LEUART
4 Enable in trace.h globally and/or module basis
5 TRACE messages are written out via LEUART
6
720101005 AB Initial (derived from much older project)
820180808 AB Adapted to CAN-Tester, every 1s alive character to retrigger
9 STOP_FAST_START
1020191107 AB Adapted to EFM32JG1 (VC+ Ersatz), remove old references to DMA
11 as it is all IRQ driven without DMA now, Baud rate changed from
12 9600 to 115200 as JADE LFRCO has to much jitter so using HFRCO
13******************************************************************************/
14// --- Includes ---------------------------------------------------------------
15#define LOGGING_TOKEN TRA_LOGGING
16#include "TraceLeUart.h"
17
18#include <em_chip.h>
19#include <efm32.h>
20#include <em_cmu.h>
21#include <em_emu.h>
22#include <em_leuart.h>
23#include <em_gpio.h>
24#include <em_rtc.h>
25
26#include <stdio.h>
27#include <string.h>
28
29#include "types.h"
30#include "Hardware.h"
31#include "Leds.h"
32
33// --- Defines ----------------------------------------------------------------
34#define BUF_MAX 7
35#define WAKEUP_INTERVAL_MS 2000
36
37
38#define LOG_MAX_MESSAGE_LEN 128 // max. lenght for a single TRACE message is FIXED here !!!!
39// even when sprintf works with longer messages, additional character
40// are not copied to the UART output buffer
41#define LOG_TX_RING_BUF_SIZE 740 // logging transmit ring buffer size
42#define LOG_RX_RING_BUF_SIZE 32 // logging receive ring buffer size (= max. input command len)
43
44//#define LOG_TEST_PIN_DIRECTION(value) {Nop(); TRISCbits.TRISC12=(value);} // TEST PIN
45//#define LOG_TEST_PIN_ON _RC12 = 1; // TEST PIN
46//#define LOG_TEST_PIN_OFF _RC12 = 0; // TEST PIN
47
48#define TESTPIN_INIT() { GPIO_PinModeSet(gpioPortF, 7, gpioModePushPull, 0);}
49#define TESTPIN( x ) { if ( x ) GPIO->P[gpioPortF].DOUT |= 1 << 7; else GPIO->P[gpioPortF].DOUT &= ~(1 << 7); }
50
51#define TRACE_NEW_LINE 0x0001 // for trace_LowLevel()
52#define TRACE_CARRIAGE_RETURN 0x0002
53
54// --- Typedefs ---------------------------------------------------------------
55
56// --- PUBLIC Variables -------------------------------------------------------
57
58#ifndef NO_TRACE
59 //int iTraceBufLen; // last log message actual lenght
60 char szTraceBuf[LOG_MAX_MESSAGE_LEN]; // log message buffer for user space
61
62 //static char szTraceInCommand[LOG_RX_RING_BUF_SIZE]; // command input via log interface for user space
63#else
64
65#endif // NO_TRACE
66
67// --- Variables --------------------------------------------------------------
68static volatile int iTxIrqCount ;
69static volatile int iRxIrqCount ;
70static volatile int iGpioIrqCount;
71
72#ifndef NO_TRACE
73 static volatile char sTxRingBuf[LOG_TX_RING_BUF_SIZE];
74 static volatile char sRxRingBuf[LOG_RX_RING_BUF_SIZE];
75
76 static volatile int iNewCommands;
77
78 static volatile int iTxBufWritePos ;
79 static volatile int iTxBufReadPos ;
80 static volatile int iRxBufWritePos ;
81 static volatile int iRxBufReadPos ;
82
83 static const char sAliveChars[] = "-\\|/"; // character which are logged every 1s if no user input (ALIVE)
84
85 static volatile int iAliveCount;
86 static int iCount10s;
87 static int iSec;
88 static int iMin;
89 static int iHours;
90 static int iDays;
91
92 // counters for uptime write into NVM
93 static int iSecToWriteUptime; // time between two update write (increases dynamically)
94 static int iCountUpdateWrite; // count seconds till next update write
95
96 static int iCurAliveChar; // current alive character, changed about every second
97
98 static volatile int iTxRunning = FALSE; // indicates running transmission (needed for JADE)
99 static volatile int iRxRunning = FALSE; // indicates running reception (needed for JADE)
100#else
101#endif // NO_TRACE
102
103// startup time
104struct
105 {
106 BYTE bNonValid;
107 BYTE bSec;
108 BYTE bMin;
109 BYTE bHour;
110 BYTE bDay0;
111 BYTE bDay1;
112 } sStartupTime;
113
114// --- Macros -----------------------------------------------------------------
115#define TX_INC_WRITE_POS(); {iTxBufWritePos++; if (iTxBufWritePos > LOG_TX_RING_BUF_SIZE - 1) iTxBufWritePos = 0; }
116#define TX_INC_READ_POS(); {iTxBufReadPos++; if (iTxBufReadPos > LOG_TX_RING_BUF_SIZE - 1) iTxBufReadPos = 0; }
117#define RX_INC_WRITE_POS(); {iRxBufWritePos++; if (iRxBufWritePos > LOG_RX_RING_BUF_SIZE - 1) iRxBufWritePos = 0; }
118#define RX_INC_READ_POS(); {iRxBufReadPos++; if (iRxBufReadPos > LOG_RX_RING_BUF_SIZE - 1) iRxBufReadPos = 0; }
119
120// --- Functionprototypes -----------------------------------------------------
121void trace_LowLevel (int iLen, int iFlags);
122void trace_NoLF (int iLen);
123
124// --- Code -------------------------------------------------------------------
125#ifndef NO_TRACE
126
127/**************************************************************************//**
128 * @brief Initialize Low Energy UART 1
129 *
130 * Here the LEUART is initialized with the chosen settings. It is then routed
131 * to location xx. Finally the GPIO mode is set to push pull.
132 *
133 *****************************************************************************/
134void initLeuart(void)
135 {
136
137 /* Start LFRCO, and use LFRCO for low-energy modules */
138 //CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFRCO);
139 //CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFRCO); // 20191112 does not work good enough with JADE, to much jitter
140 // with 9600 baud. 2400 baud is okay but to slow
141
142 // Enable LE (low energy) clocks
143 CMU_ClockEnable(cmuClock_HFLE, true); // Necessary for accessing LE modules JADE
144 CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_HFCLKLE);
145
146 // Enable clocks for LEUART0
147 CMU_ClockEnable(cmuClock_LEUART0, true);
148 CMU_ClockDivSet(cmuClock_LEUART0, cmuClkDiv_1); // Don't prescale LEUART clock JADE
149
150 // Initialize the LEUART0 module
151 LEUART_Init_TypeDef init = LEUART_INIT_DEFAULT;
152 init.baudrate = 115200;
153 LEUART_Init(LEUART0, &init);
154
155 // work around for -B errate - set divider to 270
156 /* LF register about to be modified require sync. busy check */
157 //while (LEUART0->SYNCBUSY & LEUART_SYNCBUSY_CLKDIV); //LEUART_Sync(LEUART0, LEUART_SYNCBUSY_CLKDIV);
158 //LEUART0->CLKDIV = 0x267;
159 // work around end
160
161 // Enable LEUART0 RX/TX pins on PF[4] PF[3]
162 LEUART0->ROUTEPEN = LEUART_ROUTEPEN_RXPEN | LEUART_ROUTEPEN_TXPEN;
163 LEUART0->ROUTELOC0 = LEUART_ROUTELOC0_RXLOC_LOC27 | LEUART_ROUTELOC0_TXLOC_LOC27;
164
165 /* Enable GPIO for LEUART0. TX is on PF3 */
166 GPIO_PinModeSet(gpioPortF, /* GPIO port */
167 3, /* GPIO port number */
168 gpioModePushPull, /* Pin mode is set to push pull */
169 1); /* High idle state */
170
171 /* Enable GPIO for LEUART0. RX is on PF4 */
172 GPIO_PinModeSet(gpioPortF, /* Port */
173 4, /* Port number */
174 gpioModeInputPull, /* Pin mode is set to input only, with pull direction given bellow */
175 1); /* Pull direction is set to pull-up */
176
177 // and generate IRQ on falling edge in addition to RX function
178 // this is to wake up from EM2 on falling edge so LEUART can take over reception afterwards
179 // Configure PF4 interrupt on falling edge
180 GPIO_IntConfig(gpioPortF, 4, false, true, true);
181
182 /* Enable GPIO_EVEN interrupt vector in NVIC and priority */
183 NVIC_SetPriority(GPIO_EVEN_IRQn, 7); // same priority as UART IRQ below, don't set different priority!
184 NVIC_EnableIRQ(GPIO_EVEN_IRQn);
185
186 // enable receive IRQ and TX buffer low and (JADE, HFCLK) TX completed
187 LEUART_IntEnable(LEUART0, LEUART_IEN_RXDATAV | LEUART_IEN_TXBL | LEUART_IF_TXC);
188
189 /* Enable LEUART0 interrupt vector and set priority */
190 NVIC_SetPriority(LEUART0_IRQn, 7); // same priority as GPIO IRQ above, don't set different priority!
191 NVIC_EnableIRQ(LEUART0_IRQn);
192 }
193
194/******************************************************************************
195void GPIO_EVEN_IRQHandler(void)
196 Interrupt handler GPIO even numbered pins
197******************************************************************************/
198void GPIO_EVEN_IRQHandler(void)
199 {
200
201 LedOn(2);
202 iRxRunning = TRUE;
203 iGpioIrqCount++;
204 /* clear flag for PF4 RX interrupt */
205 if ( GPIO_IntGet() & (1 << 4) )
206 {
207 GPIO_IntClear( (1 << 4) );
208 }
209 NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
210
211 }
212
213/**************************************************************************//**
214* @brief LEUART IRQ handler
215*
216* Called either when TX fifo is empty or RX buffer has data and transmission
217* is over (JADE)
218*
219******************************************************************************/
220void LEUART0_IRQHandler(void)
221 {
222 char c;
223 LEUART_TypeDef *leuart;
224
225 LedOn(2);
226 leuart = LEUART0;
227
228 if ( LEUART_IntGet(leuart) & LEUART_IF_TXC )
229 { // JADE: trasmission completed, save to go into EM2
230 iTxRunning = FALSE;
231 TESTPIN(0);
232 LEUART_IntClear(leuart, LEUART_IF_TXC);
233 }
234
235
236 if ( LEUART_IntGet(leuart) & LEUART_IF_TXBL )
237 { // trasmitter buffer empty
238 iTxIrqCount++;
239
240 while ( (iTxBufReadPos != iTxBufWritePos) && (LEUART_StatusGet(leuart) & LEUART_STATUS_TXBL) ) // as long as char are in ring buffer and transmitter ready
241 {
242 iTxRunning = TRUE;
243 TESTPIN(1);
244 LEUART_Tx(leuart, sTxRingBuf[iTxBufReadPos]);
245 TX_INC_READ_POS();
246 }
247
248 if ( iTxBufReadPos == iTxBufWritePos )
249 { // transmission completed
250 LEUART_IntDisable(leuart, LEUART_IF_TXBL);
251 }
252
253 LEUART_IntClear(leuart, LEUART_IF_TXBL);
254 }
255
256
257 if ( LEUART_IntGet(LEUART0) & LEUART_IF_RXDATAV )
258 { // Read the receive buffer while a character is available
259 iRxIrqCount++;
260 while ( leuart->STATUS & LEUART_STATUS_RXDATAV )
261 {
262 c = (char)(leuart->RXDATAX);
263 if ( c == '\r' || c == '\n' )
264 {
265 iNewCommands++;
266 }
267 sRxRingBuf[iRxBufWritePos] = c;
268 RX_INC_WRITE_POS();
269 }
270
271 iAliveCount = -9; // disable alive output for another 10s when characters are received
272 iRxRunning = FALSE;
273 LEUART_IntClear(leuart, LEUART_IF_RXDATAV);
274 }
275
276 // clear all LEUART IRQs
277 //LEUART_IntClear(leuart, _LEUART_IFC_RESETVALUE);
278 NVIC_ClearPendingIRQ(LEUART0_IRQn);
279 }
280
281/******************************************************************************
282char * TraceGetBuildTime (void)
283 Returns pointer to string which holds build time
284******************************************************************************/
285char * TraceGetBuildTime(void)
286 {
287 return __TIME__;
288 }
289
290/******************************************************************************
291char * TraceGetBuildDate (void)
292 Returns pointer to string which holds build time
293******************************************************************************/
294char * TraceGetBuildDate(void)
295 {
296 return __DATE__;
297 }
298
299/******************************************************************************
300void TraceInit (void)
301 Initializes UART and logging ring buffer counters and sends startup message.
302******************************************************************************/
303
304void TraceInit (void)
305 {
306 TESTPIN_INIT();
307
308 // clear/set variables
309 iAliveCount = 1;
310 iCount10s = 1;
311 iSec = 0;
312 iMin = 0;
313 iHours = 0;
314 iDays = 0;
315
316 // clear buffer position pointers
317 iTxBufWritePos = 0;
318 iTxBufReadPos = 0;
319 iRxBufWritePos = 0;
320 iRxBufReadPos = 0;
321 iTxIrqCount = 0;
322 iRxIrqCount = 0;
323 iGpioIrqCount = 0;
324
325 iCurAliveChar = 0;
326
327 CMU_ClockEnable(cmuClock_GPIO, true); /* Enable GPIO clock */
328
329 /* Initialize LEUART */
330 initLeuart();
331
332 TRACE ("\n"); // 2 \n cause the pin maybe not in idle state so receiver would possibly ignore first char
333 // and at least one new line is desired
334 TRACE ("*************************************************");
335 TracePrintFirmwareVersion();
336 // ROWLEY Crossworks - __DEBUG__ is set in Project - Properties - DEBUG - PreProcessor... for debug builds
337 // MPLAB - __DEBUG will be set with debug builds
338 #if defined (__DEBUG__) || defined (DEBUG) || defined (__DEBUG)
339 TRACE (" DEBUG");
340 #endif
341 TracePrintHwInfo();
342 TRACE ("*************************************************");
343
344 // init counters for uptime write into NVM
345 iSecToWriteUptime = 4;
346 iCountUpdateWrite = 4;
347 }
348
349/******************************************************************************
350void TraceInit2 (void)
351 Initialization second part (uptime, startup time)
352******************************************************************************/
353void TraceInit2 (void)
354 {
355 // get uptime from EEPROM
356 TRACE("TRA: init2");
357/* if (NvmGiveBootStatus() != NVM_INIT_CHECK_VIRGIN)// device started with valid NVM config
358 {
359 TraceReadUptimeFromNvm();
360 }
361 else // NVM config not valid, clear time,
362 { // variables are initialized to 0, so
363 TraceWriteUptimeToNvm(); // Uptime can safely be written
364 }
365
366
367 TraceWriteStartupTimeToNvm();
368 TracePrintStartTime();
369*/ }
370
371/******************************************************************************
372void TraceTicker1s(void)
373 Called every 1s (app.). Simple SW clock and alive signalling.
374******************************************************************************/
375void TraceTicker1s(void)
376 {
377 if ( TRA_LOGGING > 2 )
378 {
379 TracePrintIRQs();
380 }
381 iSec++;
382 if ( iSec > 59 )
383 {
384 iSec = 0;
385 iMin++;
386 if ( iMin > 59 )
387 {
388 iMin = 0;
389 iHours++;
390 if ( iHours > 23 )
391 {
392 iHours = 0;
393 iDays++;
394 }
395 }
396 }
397 iCount10s++;
398 if ( iCount10s > 10 )
399 {
400 iCount10s = 1;
401 }
402
403 // alive signaling - if no logging input/output for more than 1s, send alive character (to retrigger STOP_FAST_START)
404 iAliveCount++;
405 if ( iAliveCount > 1 ) // every 1 seconds, but only when no character input on logging interface !!!!!!
406 {
407 iAliveCount = 1;
408 if ( TRA_LOGGING > 1 )
409 {
410 TracePrintUptime();
411 }
412 else
413 {
414 TRACE_NOLF("%c", sAliveChars[iCurAliveChar]); // alive
415 iCurAliveChar++;
416 if ( iCurAliveChar >= (int) strlen(sAliveChars) )
417 {
418 iCurAliveChar = 0;
419 }
420 TRACE_NOLF("%c", 0x08); // backspace
421 }
422 }
423
424 iCountUpdateWrite--; // check if uptime should be written
425 if ( !iCountUpdateWrite )
426 {
427 TRACE_L2("TRA: write uptime to NVM");
428 TraceWriteUptimeToNvm();
429 if ( iSecToWriteUptime < 50000 ) // time between uptime write is dynamically increased till 50000sec (about 14h)
430 // in steps of 1/16 of current time step. So at max. 1/16 time since bLogLevel will
431 // be lost in case of power loss, but never more than 14h
432 {
433 iSecToWriteUptime += iSecToWriteUptime / 16 + 8;
434 TRACE_L2("TRA: next uptime write in %us", iSecToWriteUptime);
435 }
436 iCountUpdateWrite = iSecToWriteUptime;
437 }
438 }
439/******************************************************************************
440void trace (int)
441 Forwarder to trace_LowLevel with new line and carriage return
442******************************************************************************/
443void trace (int iLen)
444 {
445 trace_LowLevel(iLen, TRACE_NEW_LINE | TRACE_CARRIAGE_RETURN);
446 }
447
448/******************************************************************************
449void trace_NoLF (int)
450 Forwarder to trace_LowLevel without new line and carriage return
451******************************************************************************/
452void trace_NoLF (int iLen)
453 {
454 trace_LowLevel(iLen, 0);
455 }
456
457/******************************************************************************
458void trace_LowLevel (int)
459 Used with macro TRACE. Copies new output string to transmit buffer and
460 appends \n\r
461 !!!! CHARACTERS ARE LOST/OVERWRITTEN WHEN TOO MUCH NEW CHARs are filled in
462
463iLen: Lenght of string (excluding \n\r) as delivered by sprintf in macro
464 definition, Message is in global var szTraceBuf[]
465iFlags: TRACE_NEW_LINE or TRACE_CARRIAGE_RETURN are honored
466******************************************************************************/
467void trace_LowLevel (int iLen, int iFlags)
468 {
469 WORD i;
470 BYTE bOverflow = FALSE;
471
472 LEUART_IntDisable(LEUART0, LEUART_IF_TXBL); // disable TX IRQ while pointer increment
473 for ( i = 0; i < iLen; i++ )
474 {
475 ITM_SendChar(szTraceBuf[i]); // put it out at SWO too
476
477 sTxRingBuf[iTxBufWritePos] = szTraceBuf[i]; // put char from TraceBuf to output ring buffer
478 TX_INC_WRITE_POS();
479 if ( iTxBufWritePos == iTxBufReadPos ) bOverflow = TRUE;
480 }
481
482 // append \r\n to trace messages if desired
483 if ( iFlags & TRACE_NEW_LINE )
484 {
485 ITM_SendChar('\n'); // put it out at SWO too
486
487 sTxRingBuf[iTxBufWritePos] = '\n'; // put \n in ring buffer
488 TX_INC_WRITE_POS();
489 if ( iTxBufWritePos == iTxBufReadPos ) bOverflow = TRUE;
490 }
491
492 if ( iFlags & TRACE_CARRIAGE_RETURN )
493 {
494 ITM_SendChar('\r'); // put it out at SWO too
495
496 sTxRingBuf[iTxBufWritePos] = '\r'; // put \r in ring buffer
497 TX_INC_WRITE_POS();
498 if ( iTxBufWritePos == iTxBufReadPos ) bOverflow = TRUE;
499 }
500
501
502 if ( bOverflow ) // mark overflow in output stream with ***
503 {
504 sTxRingBuf[iTxBufWritePos] = '\n'; // put \n in ring buffer
505 TX_INC_WRITE_POS();
506 sTxRingBuf[iTxBufWritePos] = '\r'; // put \n in ring buffer
507 TX_INC_WRITE_POS();
508 sTxRingBuf[iTxBufWritePos] = '*'; // put \r in ring buffer
509 TX_INC_WRITE_POS();
510 sTxRingBuf[iTxBufWritePos] = '*'; // put \r in ring buffer
511 TX_INC_WRITE_POS();
512 sTxRingBuf[iTxBufWritePos] = '*'; // put \r in ring buffer
513 TX_INC_WRITE_POS();
514 sTxRingBuf[iTxBufWritePos] = '\n'; // put \r in ring buffer
515 TX_INC_WRITE_POS();
516 sTxRingBuf[iTxBufWritePos] = '\r'; // put \r in ring buffer
517 TX_INC_WRITE_POS();
518 }
519
520 iTxRunning = TRUE;
521 LEUART_IntSet(LEUART0, LEUART_IF_TXBL); // activate TX IRQ
522 LEUART_IntEnable(LEUART0, LEUART_IF_TXBL);; // reenable TX IRQ
523
524 iAliveCount = 1; // disable alive character for another 1s //10s
525 }
526
527
528/******************************************************************************
529char TraceGetKey (void)
530 Returns next byte in logging input stream
531******************************************************************************/
532char TraceGetKey(void)
533 {
534 char c;
535
536 LEUART_IntDisable(LEUART0, LEUART_IF_RXDATAV); // disable RX IRQ while pointer increment
537 if ( iRxBufReadPos != iRxBufWritePos ) // character available ?
538 {
539 c = sRxRingBuf[iRxBufReadPos];
540 RX_INC_READ_POS();
541 }
542 else c = 0; // indicate read error
543 LEUART_IntEnable(LEUART0, LEUART_IF_RXDATAV); // reenable RX IRQ
544 return c;
545 }
546
547/******************************************************************************
548void TracePrintUptime (void)
549 Sends uptime string to logging interface
550******************************************************************************/
551void TracePrintUptime(void)
552 {
553 TRACE("TRA: uptime %5d days %02d:%02d:%02d", iDays, iHours, iMin, iSec);
554 }
555
556/******************************************************************************
557void TracePrintStartTime (void)
558 Sends start time string to logging interface
559******************************************************************************/
560void TracePrintStartTime(void)
561 {
562 WORD wD = 0;
563 BYTE bS = 0, bM = 0, bH = 0;
564 BYTE *pbPos;
565
566 pbPos = &sStartupTime.bNonValid;
567
568 // write time
569 bS = *(pbPos + 1);
570 bM = *(pbPos + 2);
571 bH = *(pbPos + 3);
572 wD = *(pbPos + 4);
573 wD += *(pbPos + 5) * 256;
574
575 TRACE("TRA: boot at%5d days %02d:%02d:%02d", wD, bH, bM, bS);
576 }
577
578/******************************************************************************
579void TracePrintIRQs (void)
580 Prints out number of uart IRQs at logging interface
581******************************************************************************/
582void TracePrintIRQs(void)
583 {
584 LEUART_IntDisable(LEUART0, LEUART_IF_TXBL | LEUART_IF_RXDATAV);
585 TRACE("TRA: IRQs TX: %u, RX: %u, GPIO: %u", iTxIrqCount, iRxIrqCount, iGpioIrqCount);
586 LEUART_IntEnable(LEUART0, LEUART_IF_TXBL | LEUART_IF_RXDATAV);
587 }
588
589/******************************************************************************
590void TraceReadUptimeFromNvm (void)
591 Reads uptime info from NVM to RAM. Uptime is stored in 2 arrays. A NONVALID
592 flag indicates the valid array. If both are valid, last write was interrupted
593 and set1 is used.
594******************************************************************************/
595void TraceReadUptimeFromNvm(void)
596 {
597/* BYTE bPos = 0;
598
599
600 // check which position is VALID
601 if ( NvmGetChar(NVM_UPTIME1_NONVALID) == FALSE )
602 {
603 bPos = NVM_UPTIME1_NONVALID;
604 }
605 else
606 {
607 if ( NvmGetChar(NVM_UPTIME2_NONVALID) == FALSE )
608 {
609 bPos = NVM_UPTIME2_NONVALID;
610 }
611 }
612
613 // read time from valid position, if both are invalid, clear time
614 if ( bPos ) // at least on array is valid
615 {
616 iSec = NvmGetChar(bPos + 1);
617 iMin = NvmGetChar(bPos + 2);
618 iHours = NvmGetChar(bPos + 3);
619 iDays = NvmGetChar(bPos + 4);
620 iDays += NvmGetChar(bPos + 5) * 256;
621 TracePrintUptime();
622 }
623 else // no valid array found, clear time
624 {
625 iSec = 0;
626 iMin = 0;
627 iHours = 0;
628 iDays = 0;
629 TraceWriteUptimeToNvm(); // write valid uptime to NVM
630 TRACE("TRA: no valid uptime found in NVM");
631 }
632*/ }
633
634/******************************************************************************
635void TraceWriteUptimeToNvm (void)
636 Stores uptime info to NVM. Uptime is stored in 2 arrays. A NONVALID flag is
637 cleard after sucessful write. NOVALID flag of other set is set. So usually
638 only one set is valid. If both are valid, last write was interrupted.
639******************************************************************************/
640void TraceWriteUptimeToNvm(void)
641 {
642/* BYTE bPosNew, bPosOld;
643
644 // check which position is NONVALID
645 if ( NvmGetChar(NVM_UPTIME1_NONVALID) )
646 {
647 bPosNew = NVM_UPTIME1_NONVALID;
648 bPosOld = NVM_UPTIME2_NONVALID;
649 }
650 else
651 {
652 bPosNew = NVM_UPTIME2_NONVALID;
653 bPosOld = NVM_UPTIME1_NONVALID;
654 }
655
656 // write time to currently NONVALID position
657 NvmStoreChar(bPosNew + 1, iSec);
658 NvmStoreChar(bPosNew + 2, iMin);
659 NvmStoreChar(bPosNew + 3, iHours);
660 NvmStoreChar(bPosNew + 4, iDays & 0xFF);
661 NvmStoreChar(bPosNew + 5, iDays >> 8);
662
663 // set written array to valid, and older array to NONVALID
664 NvmStoreChar(bPosNew, FALSE);
665 NvmStoreChar(bPosOld, 0x55); // for better readabiliy in EEProm list
666 TRACE_L2("TRA: uptime written to NVM (pos: 0x%02X)", bPosNew);
667*/ TRACE_L2("TRA: No NVM - no uptime");
668 }
669
670/******************************************************************************
671void TraceWriteStartupTimeToNvm (void)
672 Stores startup time info to NVM. NONVALID flag is not used here!
673******************************************************************************/
674void TraceWriteStartupTimeToNvm (void)
675 {
676 BYTE *pbPos;
677
678 pbPos = &sStartupTime.bNonValid;
679
680 // write time
681 *(pbPos + 1) = iSec;
682 *(pbPos + 2) = iMin;
683 *(pbPos + 3) = iHours;
684 *(pbPos + 4) = iDays & 0xFF;
685 *(pbPos + 5) = iDays >> 8;
686
687 //TRACE_L2("TRA: startup time written to NVM (pos: 0x%02X)", bPos);
688 }
689
690
691/******************************************************************************
692void TracePrintHwInfo(void);
693 Prints hardware info
694******************************************************************************/
695void TracePrintHwInfo(void)
696 {
697// TRACE (" %s: %d, DIP-Switch: 0x%02X", HwGetType() == 0 ? "Master" : "Slave ", HwGetType(), HwGetType()); //, HwGetDescription() );
698// TRACE (" HW-Ver: %2d Rev: %2d, MAC-Address: 0x%04X", HwGetVersion(), HwGetRevision(), HwGetMacAddr() );
699 TRACE (" HW-Ver: %2d Rev: %2d", HwGetVersion(), HwGetRevision() );
700 }
701
702/******************************************************************************
703void TracePrintFirmwareVersion(void);
704 Prints info about firmware software version
705******************************************************************************/
706void TracePrintFirmwareVersion()
707 {
708 TRACE (" JADE ADC-Test Build: "__DATE__" "__TIME__"" );
709 return;
710 }
711
712/******************************************************************************
713int TraCommandAvail(void)
714 Returns number of available commands in input buffer
715
716ToDo: - interface to command.c should better be changed to TraGetCommand so no
717TraceCommandAvailxxx would be needed anymore
718******************************************************************************/
719int TraceCommandAvail()
720 {
721 if ( iNewCommands < 0 ) iNewCommands = 0;
722 return iNewCommands;
723 }
724
725/******************************************************************************
726void TraceCommandAvailDec (void)
727 Decreases number of available commands in input buffer
728
729ToDo: - interface to command.c should better be changed to TraGetCommand so no
730TraceCommandAvailxxx would be needed anymore
731******************************************************************************/
732void TraceCommandAvailDec(void)
733 {
734 if ( iNewCommands > 0 ) iNewCommands--;
735 }
736
737/******************************************************************************
738int TraceTxIsRunning(void)
739 Returns TRUE when data trasminssion is not finished until last bit is
740 shifted out.
741******************************************************************************/
742__INLINE int TraceIsRunning(void)
743 {
744 return iTxRunning | iRxRunning;
745 }
746
747/******************************************************************************
748__asm void hard_fault_handler_asm(void)
749 Cortex-M3 fault handler
750 Hard fault handler wrapper in assembly
751 Extracts the location of stack frame and pass it to handler in C as pointer.
752******************************************************************************/
753void HardFault_Handler(void) __attribute__( ( naked ) );
754void HardFault_Handler(void)
755 {
756 __ASM("TST LR, #4");
757 __ASM("ITE EQ");
758 __ASM("MRSEQ R0, MSP");
759 __ASM("MRSNE R0, PSP");
760 __ASM("B hard_fault_handler_c");
761 }
762
763/******************************************************************************
764void hard_fault_handler_c(unsigned int * hardfault_args)
765 Cortex-M3 fault handler
766 The second part of the handler is in C. Here, we demonstrate how the stacked
767 register contents and the Fault Status registers can be accessed.
768 with stack frame location as input parameter
769
770 The logging buffer is flushed with direct calls to UART IRQ service routine.
771 As the systems crashed hard anyway, any dirty hacks can be done here. System
772 restarts afterwards.
773******************************************************************************/
774void hard_fault_handler_c(unsigned int * hardfault_args)
775 {
776 unsigned int stacked_r0;
777 unsigned int stacked_r1;
778 unsigned int stacked_r2;
779 unsigned int stacked_r3;
780 unsigned int stacked_r12;
781 unsigned int stacked_lr;
782 unsigned int stacked_pc;
783 unsigned int stacked_psr;
784
785 stacked_r0 = ((unsigned long) hardfault_args[0]);
786 stacked_r1 = ((unsigned long) hardfault_args[1]);
787 stacked_r2 = ((unsigned long) hardfault_args[2]);
788 stacked_r3 = ((unsigned long) hardfault_args[3]);
789 stacked_r12 = ((unsigned long) hardfault_args[4]);
790 stacked_lr = ((unsigned long) hardfault_args[5]);
791 stacked_pc = ((unsigned long) hardfault_args[6]);
792 stacked_psr = ((unsigned long) hardfault_args[7]);
793
794 TRACE ("\n#####################################");
795 TRACE ("[Cortex-M3 Hard fault handler]");
796 TRACE (" R0 = 0x%08X", stacked_r0);
797 TRACE (" R1 = 0x%08X", stacked_r1);
798 TRACE (" R2 = 0x%08X", stacked_r2);
799 TRACE (" R3 = 0x%08X", stacked_r3);
800 TRACE (" R12= 0x%08X", stacked_r12);
801 TRACE (" LR = 0x%08X - LinkRegister", stacked_lr);
802 TRACE (" PC = 0x%08X", stacked_pc);
803 TRACE ("\n");
804 TRACE (" PSR = 0x%08X - ProgramStatus", stacked_psr);
805 TRACE (" BFAR= 0x%08X - BusFaultAddress", (*((volatile unsigned long *)(0xE000ED38))));
806 TRACE (" CFSR= 0x%08X - UsageFault1|UsageFault0|BusFault|MemManFault", (*((volatile unsigned long *)(0xE000ED28))));
807 TRACE (" HFSR= 0x%08X - HardFaultStatus", (*((volatile unsigned long *)(0xE000ED2C))));
808 TRACE (" DFSR= 0x%08X - DebugFaultStatus", (*((volatile unsigned long *)(0xE000ED30))));
809 TRACE (" AFSR= 0x%08X - AuxFaultStatus", (*((volatile unsigned long *)(0xE000ED3C))));
810 TRACE ("#####################################\n");
811
812 while ( (iTxBufReadPos != iTxBufWritePos) )
813 {
814 LEUART0_IRQHandler(); // flush TX buffer to logging console
815 }
816
817 // restart system
818 NVIC_SystemReset();
819 return;
820 }
821
822//******************************************************************************
823//******************************************************************************
824// empty function definitions in case NO_TRACE is selected
825#else
826 void trace (int i) { return; };
827 void TraceInit (void) { return; };
828 void TraceInit2 (void) { return; };
829 void TraceTicker1s() { return; };
830 char TraceGetKey(void) { return 0; };
831 void TracePrintUptime(void) { return; };
832 void TracePrintStartTime(void) { return; };
833 void TracePrintIRQs(void) { return; };
834 void TracePrintHwInfo(void) { return; };
835 void TracePrintKeypadInfo(void) { return; };
836 void TracePrintFirmwareVersion(void) { return; };
837#endif // NO_TRACE
Note: See TracBrowser for help on using the repository browser.