Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

rprintf.c

Go to the documentation of this file.
00001 /*! \file rprintf.c \brief printf routine and associated routines. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'rprintf.c'
00005 // Title        : printf routine and associated routines
00006 // Author       : Pascal Stang - Copyright (C) 2000-2002
00007 // Created      : 2000.12.26
00008 // Revised      : 2003.5.1
00009 // Version      : 1.0
00010 // Target MCU   : Atmel AVR series and other targets
00011 // Editor Tabs  : 4
00012 //
00013 // NOTE: This code is currently below version 1.0, and therefore is considered
00014 // to be lacking in some functionality or documentation, or may not be fully
00015 // tested.  Nonetheless, you can expect most functions to work.
00016 //
00017 // This code is distributed under the GNU Public License
00018 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00019 //
00020 //*****************************************************************************
00021 
00022 #include <avr/pgmspace.h>
00023 //#include <string-avr.h>
00024 //#include <stdlib.h>
00025 #include <stdarg.h>
00026 #include "global.h"
00027 #include "rprintf.h"
00028 
00029 #ifndef TRUE
00030     #define TRUE    -1
00031     #define FALSE   0
00032 #endif
00033 
00034 #define INF     32766   // maximum field size to print
00035 #define READMEMBYTE(a,char_ptr) ((a)?(pgm_read_byte(char_ptr)):(*char_ptr))
00036 
00037 #ifdef RPRINTF_COMPLEX
00038     static unsigned char buf[128];
00039 #endif
00040 
00041 // use this to store hex conversion in RAM
00042 //static char HexChars[] = "0123456789ABCDEF";
00043 // use this to store hex conversion in program memory
00044 //static prog_char HexChars[] = "0123456789ABCDEF";
00045 static char __attribute__ ((progmem)) HexChars[] = "0123456789ABCDEF";
00046 
00047 #define hexchar(x)  pgm_read_byte( HexChars+((x)&0x0f) )
00048 //#define hexchar(x)    ((((x)&0x0F)>9)?((x)+'A'-10):((x)+'0'))
00049 
00050 // function pointer to single character output routine
00051 static void (*rputchar)(unsigned char c);
00052 
00053 // *** rprintf initialization ***
00054 // you must call this function once and supply the character output
00055 // routine before using other functions in this library
00056 void rprintfInit(void (*putchar_func)(unsigned char c))
00057 {
00058     rputchar = putchar_func;
00059 }
00060 
00061 // *** rprintfChar ***
00062 // send a character/byte to the current output device
00063 void rprintfChar(unsigned char c)
00064 {
00065     // do LF -> CR/LF translation
00066     if(c == '\n')
00067         rputchar('\r');
00068     // send character
00069     rputchar(c);
00070 }
00071 
00072 // *** rprintfStr ***
00073 // prints a null-terminated string stored in RAM
00074 void rprintfStr(char str[])
00075 {
00076     // send a string stored in RAM
00077     // check to make sure we have a good pointer
00078     if (!str) return;
00079 
00080     // print the string until a null-terminator
00081     while (*str)
00082         rprintfChar(*str++);
00083 }
00084 
00085 // *** rprintfStrLen ***
00086 // prints a section of a string stored in RAM
00087 // begins printing at position indicated by <start>
00088 // prints number of characters indicated by <len>
00089 void rprintfStrLen(char str[], unsigned int start, unsigned int len)
00090 {
00091     register int i=0;
00092 
00093     // check to make sure we have a good pointer
00094     if (!str) return;
00095     // spin through characters up to requested start
00096     // keep going as long as there's no null
00097     while((i++<start) && (*str++));
00098 //  for(i=0; i<start; i++)
00099 //  {
00100 //      // keep steping through string as long as there's no null
00101 //      if(*str) str++;
00102 //  }
00103 
00104     // then print exactly len characters
00105     for(i=0; i<len; i++)
00106     {
00107         // print data out of the string as long as we haven't reached a null yet
00108         // at the null, start printing spaces
00109         if(*str)
00110             rprintfChar(*str++);
00111         else
00112             rprintfChar(' ');
00113     }
00114 
00115 }
00116 
00117 // *** rprintfProgStr ***
00118 // prints a null-terminated string stored in program ROM
00119 void rprintfProgStr(const prog_char str[])
00120 {
00121     // print a string stored in program memory
00122     register char c;
00123 
00124     // check to make sure we have a good pointer
00125     if (!str) return;
00126     
00127     // print the string until the null-terminator
00128     while((c = pgm_read_byte(str++)))
00129         rprintfChar(c);
00130 }
00131 
00132 // *** rprintfCRLF ***
00133 // prints carriage return and line feed
00134 void rprintfCRLF(void)
00135 {
00136     // print CR/LF
00137     //rprintfChar('\r');
00138     // LF -> CR/LF translation built-in to rprintfChar()
00139     rprintfChar('\n');
00140 }
00141 
00142 // *** rprintfu04 ***
00143 // prints an unsigned 4-bit number in hex (1 digit)
00144 void rprintfu04(unsigned char data)
00145 {
00146     // print 4-bit hex value
00147 //  char Character = data&0x0f;
00148 //  if (Character>9)
00149 //      Character+='A'-10;
00150 //  else
00151 //      Character+='0';
00152     rprintfChar(hexchar(data));
00153 }
00154 
00155 // *** rprintfu08 ***
00156 // prints an unsigned 8-bit number in hex (2 digits)
00157 void rprintfu08(unsigned char data)
00158 {
00159     // print 8-bit hex value
00160     rprintfu04(data>>4);
00161     rprintfu04(data);
00162 }
00163 
00164 // *** rprintfu16 ***
00165 // prints an unsigned 16-bit number in hex (4 digits)
00166 void rprintfu16(unsigned short data)
00167 {
00168     // print 16-bit hex value
00169     rprintfu08(data>>8);
00170     rprintfu08(data);
00171 }
00172 
00173 // *** rprintfu32 ***
00174 // prints an unsigned 32-bit number in hex (8 digits)
00175 void rprintfu32(unsigned long data)
00176 {
00177     // print 32-bit hex value
00178     rprintfu16(data>>16);
00179     rprintfu16(data);
00180 }
00181 
00182 // *** rprintfNum ***
00183 // special printf for numbers only
00184 // see formatting information below
00185 //  Print the number "n" in the given "base"
00186 //  using exactly "numDigits"
00187 //  print +/- if signed flag "isSigned" is TRUE
00188 //  use the character specified in "padchar" to pad extra characters
00189 //
00190 //  Examples:
00191 //  uartPrintfNum(10, 6,  TRUE, ' ',   1234);  -->  " +1234"
00192 //  uartPrintfNum(10, 6, FALSE, '0',   1234);  -->  "001234"
00193 //  uartPrintfNum(16, 6, FALSE, '.', 0x5AA5);  -->  "..5AA5"
00194 void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n)
00195 {
00196     // define a global HexChars or use line below
00197     //static char HexChars[16] = "0123456789ABCDEF";
00198     char *p, buf[32];
00199     unsigned long x;
00200     unsigned char count;
00201 
00202     // prepare negative number
00203     if( isSigned && (n < 0) )
00204     {
00205         x = -n;
00206     }
00207     else
00208     {
00209         x = n;
00210     }
00211 
00212     // setup little string buffer
00213     count = (numDigits-1)-(isSigned?1:0);
00214     p = buf + sizeof (buf);
00215     *--p = '\0';
00216     
00217     // force calculation of first digit
00218     // (to prevent zero from not printing at all!!!)
00219     *--p = hexchar(x%base); x /= base;
00220     // calculate remaining digits
00221     while(count--)
00222     {
00223         if(x != 0)
00224         {
00225             // calculate next digit
00226             *--p = hexchar(x%base); x /= base;
00227         }
00228         else
00229         {
00230             // no more digits left, pad out to desired length
00231             *--p = padchar;
00232         }
00233     }
00234 
00235     // apply signed notation if requested
00236     if( isSigned )
00237     {
00238         if(n < 0)
00239         {
00240             *--p = '-';
00241         }
00242         else if(n > 0)
00243         {
00244             *--p = '+';
00245         }
00246         else
00247         {
00248             *--p = ' ';
00249         }
00250     }
00251 
00252     // print the string right-justified
00253     count = numDigits;
00254     while(count--)
00255     {
00256         rprintfChar(*p++);
00257     }
00258 }
00259 
00260 #ifdef RPRINTF_FLOAT
00261 // *** rprintfFloat ***
00262 // floating-point print
00263 void rprintfFloat(char numDigits, double x)
00264 {
00265     unsigned char firstplace = FALSE;
00266     unsigned char negative;
00267     unsigned char i, digit;
00268     double place = 1.0;
00269     
00270     // save sign
00271     negative = (x<0);
00272     // convert to absolute value
00273     x = (x>0)?(x):(-x);
00274     
00275     // find starting digit place
00276     for(i=0; i<15; i++)
00277     {
00278         if((x/place) < 10.0)
00279             break;
00280         else
00281             place *= 10.0;
00282     }
00283     // print polarity character
00284     if(negative)
00285         rprintfChar('-');
00286     else
00287         rprintfChar('+');
00288 
00289     // print digits
00290     for(i=0; i<numDigits; i++)
00291     {
00292         digit = (x/place);
00293 
00294         if(digit | firstplace | (place == 1.0))
00295         {
00296             firstplace = TRUE;
00297             rprintfChar(digit+0x30);
00298         }
00299         else
00300             rprintfChar(' ');
00301         
00302         if(place == 1.0)
00303         {
00304             rprintfChar('.');
00305         }
00306         
00307         x -= (digit*place);
00308         place /= 10.0;
00309     }
00310 }
00311 #endif
00312 
00313 #ifdef RPRINTF_SIMPLE
00314 // *** rprintf1RamRom ***
00315 // called by rprintf() - does a simple printf (supports %d, %x, %c)
00316 // Supports:
00317 // %d - decimal
00318 // %x - hex
00319 // %c - character
00320 int rprintf1RamRom(unsigned char stringInRom, const char *format, ...)
00321 {
00322     // simple printf routine
00323     // define a global HexChars or use line below
00324     //static char HexChars[16] = "0123456789ABCDEF";
00325     char format_flag;
00326     unsigned int u_val, div_val, base;
00327     va_list ap;
00328 
00329     va_start(ap, format);
00330     for (;;)
00331     {
00332         while ((format_flag = READMEMBYTE(stringInRom,format++) ) != '%')
00333         {   // Until '%' or '\0'
00334             if (!format_flag)
00335             {
00336                 va_end(ap);
00337                 return(0);
00338             }
00339             rprintfChar(format_flag);
00340         }
00341 
00342         switch (format_flag = READMEMBYTE(stringInRom,format++) )
00343         {
00344             case 'c': format_flag = va_arg(ap,int);
00345             default:  rprintfChar(format_flag); continue;
00346             case 'd': base = 10; div_val = 10000; goto CONVERSION_LOOP;
00347 //          case 'x': base = 16; div_val = 0x10;
00348             case 'x': base = 16; div_val = 0x1000;
00349 
00350             CONVERSION_LOOP:
00351             u_val = va_arg(ap,int);
00352             if (format_flag == 'd')
00353             {
00354                 if (((int)u_val) < 0)
00355                 {
00356                     u_val = - u_val;
00357                     rprintfChar('-');
00358                 }
00359                 while (div_val > 1 && div_val > u_val) div_val /= 10;
00360             }
00361             do
00362             {
00363                 //rprintfChar(pgm_read_byte(HexChars+(u_val/div_val)));
00364                 rprintfu04(u_val/div_val);
00365                 u_val %= div_val;
00366                 div_val /= base;
00367             } while (div_val);
00368         }
00369     }
00370     va_end(ap);
00371 }
00372 #endif
00373 
00374 
00375 #ifdef RPRINTF_COMPLEX
00376 // *** rprintf2RamRom ***
00377 // called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s)
00378 // Supports:
00379 // %d - decimal
00380 // %u - unsigned decimal
00381 // %o - octal
00382 // %x - hex
00383 // %c - character
00384 // %s - strings
00385 // and the width,precision,padding modifiers
00386 // **this printf does not support floating point numbers
00387 int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...)
00388 {
00389     register unsigned char *f, *bp;
00390     register long l;
00391     register unsigned long u;
00392     register int i;
00393     register int fmt;
00394     register unsigned char pad = ' ';
00395     int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
00396     int sign = 0;
00397 
00398     va_list ap;
00399     va_start(ap, sfmt);
00400 
00401     f = (unsigned char *) sfmt;
00402 
00403     for (; READMEMBYTE(stringInRom,f); f++)
00404     {
00405         if (READMEMBYTE(stringInRom,f) != '%')
00406         {   // not a format character
00407             // then just output the char
00408             rprintfChar(READMEMBYTE(stringInRom,f));
00409         }
00410         else 
00411         {
00412             f++;                        // if we have a "%" then skip it
00413             if (READMEMBYTE(stringInRom,f) == '-')
00414             {
00415                 flush_left = 1; // minus: flush left
00416                 f++;
00417             }
00418             if (READMEMBYTE(stringInRom,f) == '0'
00419                  || READMEMBYTE(stringInRom,f) == '.')
00420                 {
00421                     // padding with 0 rather than blank
00422                     pad = '0';
00423                     f++;
00424             }
00425             if (READMEMBYTE(stringInRom,f) == '*')
00426                 {   // field width
00427                     f_width = va_arg(ap, int);
00428                     f++;
00429             }
00430             else if (Isdigit(READMEMBYTE(stringInRom,f)))
00431                 {
00432                     f_width = atoiRamRom(stringInRom, (char *) f);
00433                     while (Isdigit(READMEMBYTE(stringInRom,f)))
00434                         f++;        // skip the digits
00435             }
00436             if (READMEMBYTE(stringInRom,f) == '.')
00437                 {   // precision
00438                     f++;
00439                     if (READMEMBYTE(stringInRom,f) == '*')
00440                     {
00441                         prec = va_arg(ap, int);
00442                         f++;
00443                     }
00444                     else if (Isdigit(READMEMBYTE(stringInRom,f)))
00445                     {
00446                         prec = atoiRamRom(stringInRom, (char *) f);
00447                         while (Isdigit(READMEMBYTE(stringInRom,f)))
00448                             f++;    // skip the digits
00449                     }
00450                 }
00451             if (READMEMBYTE(stringInRom,f) == '#')
00452                 {   // alternate form
00453                     hash = 1;
00454                     f++;
00455             }
00456             if (READMEMBYTE(stringInRom,f) == 'l')
00457                 {   // long format
00458                     do_long = 1;
00459                     f++;
00460             }
00461 
00462                 fmt = READMEMBYTE(stringInRom,f);
00463                 bp = buf;
00464                 switch (fmt) {      // do the formatting
00465                 case 'd':           // 'd' signed decimal
00466                     if (do_long)
00467                         l = va_arg(ap, long);
00468                     else
00469                         l = (long) (va_arg(ap, int));
00470                     if (l < 0)
00471                     {
00472                         sign = 1;
00473                         l = -l;
00474                     }
00475                     do  {
00476                         *bp++ = l % 10 + '0';
00477                     } while ((l /= 10) > 0);
00478                     if (sign)
00479                         *bp++ = '-';
00480                     f_width = f_width - (bp - buf);
00481                     if (!flush_left)
00482                         while (f_width-- > 0)
00483                             rprintfChar(pad);
00484                     for (bp--; bp >= buf; bp--)
00485                         rprintfChar(*bp);
00486                     if (flush_left)
00487                         while (f_width-- > 0)
00488                             rprintfChar(' ');
00489                     break;
00490             case 'o':           // 'o' octal number
00491             case 'x':           // 'x' hex number
00492             case 'u':           // 'u' unsigned decimal
00493                     if (do_long)
00494                         u = va_arg(ap, unsigned long);
00495                     else
00496                         u = (unsigned long) (va_arg(ap, unsigned));
00497                     if (fmt == 'u')
00498                     {   // unsigned decimal
00499                         do {
00500                             *bp++ = u % 10 + '0';
00501                         } while ((u /= 10) > 0);
00502                     }
00503                     else if (fmt == 'o')
00504                     {  // octal
00505                         do {
00506                             *bp++ = u % 8 + '0';
00507                         } while ((u /= 8) > 0);
00508                         if (hash)
00509                             *bp++ = '0';
00510                     }
00511                     else if (fmt == 'x')
00512                     {   // hex
00513                         do {
00514                             i = u % 16;
00515                             if (i < 10)
00516                                 *bp++ = i + '0';
00517                             else
00518                                 *bp++ = i - 10 + 'a';
00519                         } while ((u /= 16) > 0);
00520                         if (hash)
00521                         {
00522                             *bp++ = 'x';
00523                             *bp++ = '0';
00524                         }
00525                     }
00526                     i = f_width - (bp - buf);
00527                     if (!flush_left)
00528                         while (i-- > 0)
00529                             rprintfChar(pad);
00530                     for (bp--; bp >= buf; bp--)
00531                         rprintfChar((int) (*bp));
00532                     if (flush_left)
00533                         while (i-- > 0)
00534                             rprintfChar(' ');
00535                     break;
00536             case 'c':           // 'c' character
00537                     i = va_arg(ap, int);
00538                     rprintfChar((int) (i));
00539                     break;
00540             case 's':           // 's' string
00541                     bp = va_arg(ap, unsigned char *);
00542                     if (!bp)
00543                         bp = (unsigned char *) "(nil)";
00544                     f_width = f_width - strlen((char *) bp);
00545                     if (!flush_left)
00546                         while (f_width-- > 0)
00547                             rprintfChar(pad);
00548                     for (i = 0; *bp && i < prec; i++)
00549                     {
00550                         rprintfChar(*bp);
00551                         bp++;
00552                     }
00553                     if (flush_left)
00554                         while (f_width-- > 0)
00555                             rprintfChar(' ');
00556                     break;
00557             case '%':           // '%' character
00558                     rprintfChar('%');
00559                     break;
00560             }
00561             flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
00562             sign = 0;
00563             pad = ' ';
00564         }
00565     }
00566 
00567     va_end(ap);
00568     return 0;
00569 }
00570 
00571 unsigned char Isdigit(char c)
00572 {
00573     if((c >= 0x30) && (c <= 0x39))
00574         return TRUE;
00575     else
00576         return FALSE;
00577 }
00578 
00579 int atoiRamRom(unsigned char stringInRom, char *str)
00580 {
00581     int num = 0;;
00582 
00583     while(Isdigit(READMEMBYTE(stringInRom,str)))
00584     {
00585         num *= 10;
00586         num += ((READMEMBYTE(stringInRom,str++)) - 0x30);
00587     }
00588     return num;
00589 }
00590 
00591 #endif
00592 
00593 //******************************************************************************
00594 // code below this line is commented out and can be ignored
00595 //******************************************************************************
00596 /*
00597 char* sprintf(const char *sfmt, ...)
00598 {
00599     register unsigned char *f, *bp, *str;
00600     register long l;
00601     register unsigned long u;
00602     register int i;
00603     register int fmt;
00604     register unsigned char pad = ' ';
00605     int     flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
00606     int     sign = 0;
00607 
00608     va_list ap;
00609     va_start(ap, sfmt);
00610 
00611     str = bufstring;
00612     f = (unsigned char *) sfmt;
00613 
00614     for (; *f; f++)
00615     {
00616         if (*f != '%')
00617         {                               // not a format character
00618             *str++ = (*f);          // then just output the char
00619         }
00620         else 
00621         {
00622             f++;                        // if we have a "%" then skip it
00623             if (*f == '-')
00624             {
00625                 flush_left = 1; // minus: flush left
00626                 f++;
00627             }
00628             if (*f == '0' || *f == '.')
00629                 {
00630                     // padding with 0 rather than blank
00631                     pad = '0';
00632                     f++;
00633             }
00634             if (*f == '*')
00635                 {   // field width
00636                     f_width = va_arg(ap, int);
00637                     f++;
00638             }
00639             else if (Isdigit(*f))
00640                 {
00641                     f_width = atoi((char *) f);
00642                     while (Isdigit(*f))
00643                         f++;        // skip the digits
00644             }
00645             if (*f == '.')
00646                 {   // precision
00647                     f++;
00648                     if (*f == '*')
00649                     {
00650                         prec = va_arg(ap, int);
00651                         f++;
00652                     }
00653                     else if (Isdigit(*f))
00654                     {
00655                         prec = atoi((char *) f);
00656                         while (Isdigit(*f))
00657                             f++;    // skip the digits
00658                     }
00659                 }
00660             if (*f == '#')
00661                 {   // alternate form
00662                     hash = 1;
00663                     f++;
00664             }
00665             if (*f == 'l')
00666                 {   // long format
00667                     do_long = 1;
00668                     f++;
00669             }
00670 
00671                 fmt = *f;
00672                 bp = buf;
00673                 switch (fmt) {      // do the formatting
00674                 case 'd':           // 'd' signed decimal
00675                     if (do_long)
00676                         l = va_arg(ap, long);
00677                     else
00678                         l = (long) (va_arg(ap, int));
00679                     if (l < 0)
00680                     {
00681                         sign = 1;
00682                         l = -l;
00683                     }
00684                     do  {
00685                         *bp++ = l % 10 + '0';
00686                     } while ((l /= 10) > 0);
00687                     if (sign)
00688                         *bp++ = '-';
00689                     f_width = f_width - (bp - buf);
00690                     if (!flush_left)
00691                         while (f_width-- > 0)
00692                             *str++ = (pad);
00693                     for (bp--; bp >= buf; bp--)
00694                         *str++ = (*bp);
00695                     if (flush_left)
00696                         while (f_width-- > 0)
00697                             *str++ = (' ');
00698                     break;
00699             case 'o':           // 'o' octal number
00700             case 'x':           // 'x' hex number
00701             case 'u':           // 'u' unsigned decimal
00702                     if (do_long)
00703                         u = va_arg(ap, unsigned long);
00704                     else
00705                         u = (unsigned long) (va_arg(ap, unsigned));
00706                     if (fmt == 'u')
00707                     {   // unsigned decimal
00708                         do {
00709                             *bp++ = u % 10 + '0';
00710                         } while ((u /= 10) > 0);
00711                     }
00712                     else if (fmt == 'o')
00713                     {  // octal
00714                         do {
00715                             *bp++ = u % 8 + '0';
00716                         } while ((u /= 8) > 0);
00717                         if (hash)
00718                             *bp++ = '0';
00719                     }
00720                     else if (fmt == 'x')
00721                     {   // hex
00722                         do {
00723                             i = u % 16;
00724                             if (i < 10)
00725                                 *bp++ = i + '0';
00726                             else
00727                                 *bp++ = i - 10 + 'a';
00728                         } while ((u /= 16) > 0);
00729                         if (hash)
00730                         {
00731                             *bp++ = 'x';
00732                             *bp++ = '0';
00733                         }
00734                     }
00735                     i = f_width - (bp - buf);
00736                     if (!flush_left)
00737                         while (i-- > 0)
00738                             *str++ = (pad);
00739                     for (bp--; bp >= buf; bp--)
00740                         *str++ = ((int) (*bp));
00741                     if (flush_left)
00742                         while (i-- > 0)
00743                             *str++ = (' ');
00744                     break;
00745             case 'c':           // 'c' character
00746                     i = va_arg(ap, int);
00747                     *str++ = ((int) (i));
00748                     break;
00749             case 's':           // 's' string
00750                     bp = va_arg(ap, unsigned char *);
00751                     if (!bp)
00752                         bp = (unsigned char *) "(nil)";
00753                     f_width = f_width - strlen((char *) bp);
00754                     if (!flush_left)
00755                         while (f_width-- > 0)
00756                             *str++ = (pad);
00757                     for (i = 0; *bp && i < prec; i++)
00758                     {
00759                         *str++ = (*bp);
00760                         bp++;
00761                     }
00762                     if (flush_left)
00763                         while (f_width-- > 0)
00764                             *str++ = (' ');
00765                     break;
00766             case '%':           // '%' character
00767                     *str++ = ('%');
00768                     break;
00769             }
00770             flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
00771             sign = 0;
00772             pad = ' ';
00773         }
00774     }
00775 
00776     va_end(ap);
00777     // terminate string with null
00778     *str++ = '\0';
00779     return bufstring;
00780 }
00781 
00782 */

Generated on Sun Oct 29 03:41:07 2006 for Procyon AVRlib by  doxygen 1.4.2