OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [syn/] [components/] [sd_card/] [software/] [exe_bsp/] [HAL/] [src/] [alt_log_printf.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
 
2
/* alt_log_printf.c
3
 *
4
 * This file implements the various C functions used for the
5
 * alt_log logging/debugging print functions.  The functions
6
 * sit as is here - the job of hiding them from the compiler
7
 * if logging is disabled is accomplished in the .h file.
8
 *
9
 * All the global variables for alt_log are defined here.
10
 * These include the various flags that turn on additional
11
 * logging options; the strings for assembly printing; and
12
 * other globals needed by different logging options.
13
 *
14
 * There are 4 functions that handle the actual printing:
15
 * alt_log_txchar: Actual function that puts 1 char to UART/JTAG UART.
16
 * alt_log_repchar: Calls alt_log_txchar 'n' times - used by
17
 *            alt_log_private_printf for formatting.
18
 * alt_log_private_printf:
19
 *     Stripped down implementation of printf - no floats.
20
 * alt_log_printf_proc:
21
 *     Wrapper function for private_printf.
22
 *
23
 * The rest of the functions are called by the macros which
24
 * were called by code in the other components.  Each function
25
 * is preceded by a comment, about which file it gets called
26
 * in, and what its purpose is.
27
 *
28
 * author: gkwan
29
 */
30
 
31
/* skip all code if enable is off */
32
#ifdef ALT_LOG_ENABLE
33
 
34
#include <system.h>
35
#include <stdarg.h>
36
#include <string.h>
37
#ifdef __ALTERA_AVALON_JTAG_UART
38
   #include "altera_avalon_jtag_uart.h"
39
   #include <altera_avalon_jtag_uart_regs.h>
40
#endif
41
#include "sys/alt_log_printf.h"
42
 
43
/* strings for assembly puts */
44
char alt_log_msg_bss[] = "[crt0.S] Clearing BSS \r\n";;
45
char alt_log_msg_alt_main[] = "[crt0.S] Calling alt_main.\r\n";
46
char alt_log_msg_stackpointer[] \
47
    = "[crt0.S] Setting up stack and global pointers.\r\n";
48
char alt_log_msg_cache[] = "[crt0.S] Inst & Data Cache Initialized.\r\n";
49
/* char array allocation for alt_write */
50
char alt_log_write_buf[ALT_LOG_WRITE_ECHO_LEN+2];
51
 
52
/* global variables for all 'on' flags */
53
 
54
/*
55
 * The boot message flag is linked into the data (rwdata) section
56
 * because if it is zero, it would otherwise be placed in the bss section.
57
 * alt_log examines this variable before the BSS is cleared in the boot-up
58
 * process.
59
 */
60
volatile alt_u32 alt_log_boot_on_flag \
61
  __attribute__ ((section (".data"))) = ALT_LOG_BOOT_ON_FLAG_SETTING;
62
 
63
volatile alt_u8 alt_log_write_on_flag = ALT_LOG_WRITE_ON_FLAG_SETTING;
64
 
65
volatile alt_u8 alt_log_sys_clk_on_flag = ALT_LOG_SYS_CLK_ON_FLAG_SETTING;
66
 
67
volatile alt_u8 alt_log_jtag_uart_alarm_on_flag = \
68
  ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING;
69
 
70
volatile alt_u8 alt_log_jtag_uart_isr_on_flag = \
71
  ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING;
72
 
73
volatile alt_u8 alt_log_jtag_uart_startup_info_on_flag = \
74
  ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING;
75
 
76
/* Global alarm object for recurrent JTAG UART status printing */
77
alt_alarm alt_log_jtag_uart_alarm_1;
78
 
79
/* Global ints for system clock printing and count */
80
volatile int alt_log_sys_clk_count;
81
volatile int alt_system_clock_in_sec;
82
 
83
/* enum used by alt_log_private_printf */
84
enum
85
{
86
  pfState_chars,
87
  pfState_firstFmtChar,
88
  pfState_otherFmtChar
89
};
90
 
91
 
92
 
93
 
94
/* Function to put one char onto the UART/JTAG UART txdata register. */
95
void alt_log_txchar(int c,char *base)
96
{
97
  /* Wait until the device is ready for a character */
98
  while((ALT_LOG_PRINT_REG_RD(base) & ALT_LOG_PRINT_MSK) == 0)
99
    ;
100
  /* And pop the character into the register */
101
  ALT_LOG_PRINT_TXDATA_WR(base,c);
102
}
103
 
104
 
105
/* Called by alt_log_private_printf to print out characters repeatedly */
106
void alt_log_repchar(char c,int r,int base)
107
{
108
  while(r-- > 0)
109
    alt_log_txchar(c,(char*) base);
110
}
111
 
112
 
113
/* Stripped down printf function */
114
void alt_log_private_printf(const char *fmt,int base,va_list args)
115
  {
116
  const char *w;
117
  char c;
118
  int state;
119
  int fmtLeadingZero = 0; /* init these all to 0 for -W warnings. */
120
  int fmtLong = 0;
121
  int fmtBeforeDecimal = 0;
122
  int fmtAfterDecimal = 0;
123
  int fmtBase = 0;
124
  int fmtSigned = 0;
125
  int fmtCase = 0; /* For hex format, if 1, A-F, else a-f. */
126
 
127
  w = fmt;
128
  state = pfState_chars;
129
 
130
  while(0 != (c = *w++))
131
    {
132
    switch(state)
133
      {
134
      case pfState_chars:
135
        if(c == '%')
136
        {
137
          fmtLeadingZero = 0;
138
          fmtLong = 0;
139
          fmtBase = 10;
140
          fmtSigned = 1;
141
          fmtCase = 0; /* Only %X sets this. */
142
          fmtBeforeDecimal = -1;
143
          fmtAfterDecimal = -1;
144
          state = pfState_firstFmtChar;
145
        }
146
        else
147
        {
148
          alt_log_txchar(c,(char*)base);
149
        }
150
        break;
151
 
152
      case pfState_firstFmtChar:
153
        if(c == '0')
154
        {
155
          fmtLeadingZero = 1;
156
          state = pfState_otherFmtChar;
157
        }
158
        else if(c == '%')
159
        {
160
          alt_log_txchar(c,(char*)base);
161
          state = pfState_chars;
162
        }
163
        else
164
        {
165
          state = pfState_otherFmtChar;
166
          goto otherFmtChar;
167
        }
168
        break;
169
 
170
      case pfState_otherFmtChar:
171
otherFmtChar:
172
        if(c == '.')
173
        {
174
          fmtAfterDecimal = 0;
175
        }
176
        else if('0' <= c && c <= '9')
177
        {
178
          c -= '0';
179
          if(fmtAfterDecimal < 0)     /* still before decimal */
180
          {
181
            if(fmtBeforeDecimal < 0)
182
            {
183
              fmtBeforeDecimal = 0;
184
            }
185
            else
186
            {
187
              fmtBeforeDecimal *= 10;
188
            }
189
            fmtBeforeDecimal += c;
190
          }
191
          else
192
          {
193
            fmtAfterDecimal = (fmtAfterDecimal * 10) + c;
194
          }
195
        }
196
        else if(c == 'l')
197
        {
198
          fmtLong = 1;
199
        }
200
        else                  /* we're up to the letter which determines type */
201
        {
202
          switch(c)
203
          {
204
            case 'd':
205
            case 'i':
206
doIntegerPrint:
207
                {
208
                unsigned long v;
209
                unsigned long p;  /* biggest power of fmtBase */
210
                unsigned long vShrink;  /* used to count digits */
211
                int sign;
212
                int digitCount;
213
 
214
                /* Get the value */
215
                if(fmtLong)
216
                {
217
                  if (fmtSigned)
218
                  {
219
                    v = va_arg(args,long);
220
                  }
221
                  else
222
                  {
223
                    v = va_arg(args,unsigned long);
224
                  }
225
                }
226
                else
227
                {
228
                  if (fmtSigned)
229
                  {
230
                    v = va_arg(args,int);
231
                  }
232
                  else
233
                  {
234
                    v = va_arg(args,unsigned int);
235
                  }
236
                }
237
 
238
                /* Strip sign */
239
                sign = 0;
240
                  /* (assumes sign bit is #31) */
241
                if( fmtSigned && (v & (0x80000000)) )
242
                  {
243
                  v = ~v + 1;
244
                  sign = 1;
245
                  }
246
 
247
                /* Count digits, and get largest place value */
248
                vShrink = v;
249
                p = 1;
250
                digitCount = 1;
251
                while( (vShrink = vShrink / fmtBase) > 0 )
252
                  {
253
                  digitCount++;
254
                  p *= fmtBase;
255
                  }
256
 
257
                /* Print leading characters & sign */
258
                fmtBeforeDecimal -= digitCount;
259
                if(fmtLeadingZero)
260
                  {
261
                  if(sign)
262
                    {
263
                    alt_log_txchar('-',(char*)base);
264
                    fmtBeforeDecimal--;
265
                    }
266
                  alt_log_repchar('0',fmtBeforeDecimal,base);
267
                  }
268
                else
269
                  {
270
                    if(sign)
271
                    {
272
                      fmtBeforeDecimal--;
273
                    }
274
                    alt_log_repchar(' ',fmtBeforeDecimal,base);
275
                    if(sign)
276
                    {
277
                      alt_log_txchar('-',(char*)base);
278
                    }
279
                  }
280
 
281
                /* Print numbery parts */
282
                while(p)
283
                  {
284
                  unsigned char d;
285
 
286
                  d = v / p;
287
                  d += '0';
288
                  if(d > '9')
289
                  {
290
                    d += (fmtCase ? 'A' : 'a') - '0' - 10;
291
                  }
292
                  alt_log_txchar(d,(char*)base);
293
 
294
                  v = v % p;
295
                  p = p / fmtBase;
296
                  }
297
                }
298
 
299
              state = pfState_chars;
300
              break;
301
 
302
            case 'u':
303
              fmtSigned = 0;
304
              goto doIntegerPrint;
305
            case 'o':
306
              fmtSigned = 0;
307
              fmtBase = 8;
308
              goto doIntegerPrint;
309
            case 'x':
310
              fmtSigned = 0;
311
              fmtBase = 16;
312
              goto doIntegerPrint;
313
            case 'X':
314
              fmtSigned = 0;
315
              fmtBase = 16;
316
              fmtCase = 1;
317
              goto doIntegerPrint;
318
 
319
            case 'c':
320
              alt_log_repchar(' ',fmtBeforeDecimal-1,base);
321
              alt_log_txchar(va_arg(args,int),(char*)base);
322
              break;
323
 
324
            case 's':
325
                {
326
                char *s;
327
 
328
                s = va_arg(args,char *);
329
                alt_log_repchar(' ',fmtBeforeDecimal-strlen(s),base);
330
 
331
                while(*s)
332
                  alt_log_txchar(*s++,(char*)base);
333
                }
334
              break;
335
            } /* switch last letter of fmt */
336
          state=pfState_chars;
337
          }
338
        break;
339
      } /* switch */
340
    } /* while chars left */
341
  } /* printf */
342
 
343
/* Main logging printf function */
344
int alt_log_printf_proc(const char *fmt, ... )
345
{
346
    va_list args;
347
 
348
    va_start (args, fmt);
349
    alt_log_private_printf(fmt,ALT_LOG_PORT_BASE,args);
350
    return (0);
351
}
352
 
353
/* Below are the functions called by different macros in various components. */
354
 
355
/* If the system has a JTAG_UART, include JTAG_UART debugging functions */
356
#ifdef __ALTERA_AVALON_JTAG_UART
357
 
358
/* The alarm function in altera_avalon_jtag_uart.c.
359
 * This function, when turned on, prints out the status
360
 * of the JTAG UART Control register, every ALT_LOG_JTAG_UART_TICKS.
361
 * If the flag is off, the alarm should never be registered, and this
362
 * function should never run */
363
alt_u32 altera_avalon_jtag_uart_report_log(void * context)
364
{
365
    if (alt_log_jtag_uart_alarm_on_flag) {
366
    altera_avalon_jtag_uart_state* dev = (altera_avalon_jtag_uart_state*) context;
367
        const char* header="JTAG Alarm:";
368
        alt_log_jtag_uart_print_control_reg(dev, dev->base, header);
369
        return ALT_LOG_JTAG_UART_TICKS;
370
    }
371
    else
372
    {
373
        /* If flag is not on, return 0 to disable future alarms.
374
        * Should never be here, alarm should not be enabled at all. */
375
        return 0;
376
    }
377
}
378
 
379
void alt_log_jtag_uart_print_control_reg(altera_avalon_jtag_uart_state* dev, int base, const char* header)
380
{
381
     unsigned int control, space, ac, wi, ri, we, re;
382
     control = IORD_ALTERA_AVALON_JTAG_UART_CONTROL(base);
383
     space = (control & ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK) >>
384
             ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_OFST;
385
     we= (control & ALTERA_AVALON_JTAG_UART_CONTROL_WE_MSK) >>
386
         ALTERA_AVALON_JTAG_UART_CONTROL_WE_OFST;
387
     re= (control & ALTERA_AVALON_JTAG_UART_CONTROL_RE_MSK) >>
388
         ALTERA_AVALON_JTAG_UART_CONTROL_RE_OFST;
389
     ri= (control & ALTERA_AVALON_JTAG_UART_CONTROL_RI_MSK) >>
390
         ALTERA_AVALON_JTAG_UART_CONTROL_RI_OFST;
391
     wi= (control & ALTERA_AVALON_JTAG_UART_CONTROL_WI_MSK) >>
392
         ALTERA_AVALON_JTAG_UART_CONTROL_WI_OFST;
393
     ac= (control & ALTERA_AVALON_JTAG_UART_CONTROL_AC_MSK) >>
394
         ALTERA_AVALON_JTAG_UART_CONTROL_AC_OFST;
395
 
396
#ifdef ALTERA_AVALON_JTAG_UART_SMALL
397
    ALT_LOG_PRINTF(
398
     "%s HW FIFO wspace=%d AC=%d WI=%d RI=%d WE=%d RE=%d\r\n",
399
         header,space,ac,wi,ri,we,re);
400
#else
401
    ALT_LOG_PRINTF(
402
     "%s SW CirBuf = %d, HW FIFO wspace=%d AC=%d WI=%d RI=%d WE=%d RE=%d\r\n",
403
         header,(dev->tx_out-dev->tx_in),space,ac,wi,ri,we,re);
404
#endif   
405
 
406
     return;
407
 
408
}
409
 
410
/* In altera_avalon_jtag_uart.c
411
 * Same output as the alarm function above, but this is called in the driver
412
 * init function.  Hence, it gives the status of the JTAG UART control register
413
 * right at the initialization of the driver */
414
void alt_log_jtag_uart_startup_info(altera_avalon_jtag_uart_state* dev, int base)
415
{
416
     const char* header="JTAG Startup Info:";
417
     alt_log_jtag_uart_print_control_reg(dev, base, header);
418
     return;
419
}
420
 
421
/* In altera_avalon_jtag_uart.c
422
 * When turned on, this function will print out the status of the jtag uart
423
 * control register every time there is a jtag uart "almost-empty" interrupt. */
424
void alt_log_jtag_uart_isr_proc(int base, altera_avalon_jtag_uart_state* dev)
425
{
426
    if (alt_log_jtag_uart_isr_on_flag) {
427
        const char* header="JTAG IRQ:";
428
        alt_log_jtag_uart_print_control_reg(dev, base, header);
429
    }
430
    return;
431
}
432
 
433
#endif /* __ALTERA_AVALON_JTAG_UART */ 
434
 
435
/* In alt_write.c
436
 * When the alt_log_write_on_flag is turned on, this function gets called
437
 * every time alt_write gets called.  The first
438
 * ALT_LOG_WRITE_ECHO_LEN characters of every printf command (or any command
439
 * that eventually calls write()) gets echoed to the alt_log output. */
440
void alt_log_write(const void *ptr, size_t len)
441
{
442
    if (alt_log_write_on_flag) {
443
    int temp_cnt;
444
        int length=(ALT_LOG_WRITE_ECHO_LEN>len) ? len : ALT_LOG_WRITE_ECHO_LEN;
445
 
446
        if (length < 2) return;
447
 
448
        strncpy (alt_log_write_buf,ptr,length);
449
    alt_log_write_buf[length-1]='\n';
450
    alt_log_write_buf[length]='\r';
451
    alt_log_write_buf[length+1]='\0';
452
 
453
    /* Escape Ctrl-D's. If the Ctrl-D gets sent it might kill the terminal
454
         * connection of alt_log. It will get replaced by 'D'. */
455
        for (temp_cnt=0;temp_cnt < length; temp_cnt++) {
456
        if (alt_log_write_buf[temp_cnt]== 0x4) {
457
            alt_log_write_buf[temp_cnt]='D';
458
        }
459
    }
460
        ALT_LOG_PRINTF("Write Echo: %s",alt_log_write_buf);
461
    }
462
}
463
 
464
/* In altera_avalon_timer_sc
465
 * This function prints out a system clock is alive message
466
 * every ALT_LOG_SYS_CLK_INTERVAL (in ticks).  */
467
void alt_log_system_clock()
468
{
469
    if (alt_log_sys_clk_on_flag) {
470
    alt_log_sys_clk_count++;
471
        if (alt_log_sys_clk_count > ALT_LOG_SYS_CLK_INTERVAL) {
472
            alt_log_sys_clk_count = 0;
473
            ALT_LOG_PRINTF("System Clock On %u\r\n",alt_system_clock_in_sec++);
474
        }
475
    }
476
}
477
 
478
 
479
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.