Log

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Jun 27 21:19:33 2019 +0000
Revision:
17:7acb89d71f48
Parent:
16:5c41b457c7f3
Child:
18:617791ed3d8e
Added functions to log hex bytes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 12:19c2d4943124 1 #include <stdlib.h>
andrewboyson 12:19c2d4943124 2 #include <stdarg.h>
andrewboyson 12:19c2d4943124 3 #include <stdio.h>
andrewboyson 12:19c2d4943124 4 #include <time.h>
andrewboyson 12:19c2d4943124 5 #include <stdbool.h>
andrewboyson 15:e490fce9b6ef 6 #include "serialpc.h"
andrewboyson 0:9907e344c82a 7
andrewboyson 12:19c2d4943124 8 #define BUFFER_LENGTH 0x4000
andrewboyson 12:19c2d4943124 9
andrewboyson 12:19c2d4943124 10 __attribute__((section("AHBSRAM0"))) static char buffer[BUFFER_LENGTH]; //Pop the buffer into the USB area
andrewboyson 0:9907e344c82a 11 static char* pPush; //Initialised in init
andrewboyson 0:9907e344c82a 12 static char* pPull; //Initialised in init
andrewboyson 12:19c2d4943124 13 static char *pUart; //Initialised in init
andrewboyson 6:b98aa0ec75a1 14
andrewboyson 12:19c2d4943124 15 static bool enable = true;
andrewboyson 13:fb7f40c2e446 16 static void (*tmFunction)(struct tm* ptm);
andrewboyson 13:fb7f40c2e446 17 static bool useUart = false; //This is set during initialisation
andrewboyson 13:fb7f40c2e446 18 bool LogUart = true; //Always start off with the uart running
andrewboyson 13:fb7f40c2e446 19
andrewboyson 0:9907e344c82a 20 static char* incrementPushPullPointer(char* p, char* buffer, int bufferLength)
andrewboyson 0:9907e344c82a 21 {
andrewboyson 0:9907e344c82a 22 p++; //increment the pointer by one
andrewboyson 0:9907e344c82a 23 if (p == buffer + bufferLength) p = buffer; //if the pointer is now beyond the end then point it back to the start
andrewboyson 0:9907e344c82a 24 return p;
andrewboyson 0:9907e344c82a 25 }
andrewboyson 16:5c41b457c7f3 26 static void push(const char c)
andrewboyson 6:b98aa0ec75a1 27 {
andrewboyson 6:b98aa0ec75a1 28 //Move the pull position if about to run into it
andrewboyson 6:b98aa0ec75a1 29 char* pNext = incrementPushPullPointer(pPush, buffer, BUFFER_LENGTH);
andrewboyson 6:b98aa0ec75a1 30 if (pNext == pPull) pPull = incrementPushPullPointer(pPull, buffer, BUFFER_LENGTH);
andrewboyson 6:b98aa0ec75a1 31
andrewboyson 6:b98aa0ec75a1 32 //Add the character at the push position
andrewboyson 6:b98aa0ec75a1 33 *pPush = c;
andrewboyson 6:b98aa0ec75a1 34 pPush = incrementPushPullPointer(pPush, buffer, BUFFER_LENGTH);
andrewboyson 6:b98aa0ec75a1 35 }
andrewboyson 16:5c41b457c7f3 36 void LogChar(const char c)
andrewboyson 0:9907e344c82a 37 {
andrewboyson 0:9907e344c82a 38 //Only add if allowed
andrewboyson 0:9907e344c82a 39 if (!enable) return;
andrewboyson 0:9907e344c82a 40
andrewboyson 6:b98aa0ec75a1 41 //Work out if the character needs to be delimited
andrewboyson 2:ee4ec2d72525 42 bool delimited = false;
andrewboyson 2:ee4ec2d72525 43 if (c < ' ' && c != '\r' && c != '\n') delimited = true;
andrewboyson 12:19c2d4943124 44 if (c > 126) delimited = false;
andrewboyson 2:ee4ec2d72525 45
andrewboyson 6:b98aa0ec75a1 46 //Push the delimiter or the character
andrewboyson 6:b98aa0ec75a1 47 if (delimited) push('^');
andrewboyson 6:b98aa0ec75a1 48 else push(c);
andrewboyson 2:ee4ec2d72525 49
andrewboyson 6:b98aa0ec75a1 50 //Stop if its not delimited
andrewboyson 2:ee4ec2d72525 51 if (!delimited) return;
andrewboyson 2:ee4ec2d72525 52
andrewboyson 6:b98aa0ec75a1 53 //Push the first digit
andrewboyson 2:ee4ec2d72525 54 char h = c >> 4;
andrewboyson 2:ee4ec2d72525 55 if (h < 10) h += '0';
andrewboyson 2:ee4ec2d72525 56 else h += 'A' - 10;
andrewboyson 6:b98aa0ec75a1 57 push(h);
andrewboyson 6:b98aa0ec75a1 58
andrewboyson 6:b98aa0ec75a1 59 //Push the second digit
andrewboyson 2:ee4ec2d72525 60 h = c & 0x0F;
andrewboyson 2:ee4ec2d72525 61 if (h < 10) h += '0';
andrewboyson 2:ee4ec2d72525 62 else h += 'A' - 10;
andrewboyson 6:b98aa0ec75a1 63 push(h);
andrewboyson 2:ee4ec2d72525 64
andrewboyson 0:9907e344c82a 65 }
andrewboyson 0:9907e344c82a 66 static char *pEnumerate;
andrewboyson 0:9907e344c82a 67 void LogEnumerateStart()
andrewboyson 0:9907e344c82a 68 {
andrewboyson 0:9907e344c82a 69 pEnumerate = pPull;
andrewboyson 0:9907e344c82a 70 }
andrewboyson 0:9907e344c82a 71 int LogEnumerate()
andrewboyson 0:9907e344c82a 72 {
andrewboyson 12:19c2d4943124 73 if (pEnumerate == pPush) return -1;
andrewboyson 0:9907e344c82a 74 char c = *pEnumerate;
andrewboyson 0:9907e344c82a 75 pEnumerate = incrementPushPullPointer(pEnumerate, buffer, BUFFER_LENGTH);
andrewboyson 2:ee4ec2d72525 76 return c;
andrewboyson 0:9907e344c82a 77 }
andrewboyson 12:19c2d4943124 78 void LogEnable(bool value)
andrewboyson 0:9907e344c82a 79 {
andrewboyson 12:19c2d4943124 80 enable = value;
andrewboyson 0:9907e344c82a 81 }
andrewboyson 13:fb7f40c2e446 82 void LogClear()
andrewboyson 0:9907e344c82a 83 {
andrewboyson 0:9907e344c82a 84 pPush = buffer;
andrewboyson 0:9907e344c82a 85 pPull = buffer;
andrewboyson 12:19c2d4943124 86 pUart = buffer;
andrewboyson 12:19c2d4943124 87 }
andrewboyson 13:fb7f40c2e446 88 void LogInit(void (*tmFunctionParam)(struct tm* ptm), int baud)
andrewboyson 13:fb7f40c2e446 89 {
andrewboyson 13:fb7f40c2e446 90 useUart = baud;
andrewboyson 15:e490fce9b6ef 91 if (useUart) SerialPcInit(baud);
andrewboyson 13:fb7f40c2e446 92 tmFunction = tmFunctionParam;
andrewboyson 13:fb7f40c2e446 93 LogClear();
andrewboyson 13:fb7f40c2e446 94 }
andrewboyson 12:19c2d4943124 95 void LogMain()
andrewboyson 12:19c2d4943124 96 {
andrewboyson 13:fb7f40c2e446 97 if (!useUart) return;
andrewboyson 13:fb7f40c2e446 98 if (!LogUart) return; //Do nothing if uart is not enabled
andrewboyson 13:fb7f40c2e446 99 if (pUart == pPush) return; //Do nothing if all characters have been sent
andrewboyson 15:e490fce9b6ef 100 int result = SerialPcPutC(*pUart); //Attempt to write the character
andrewboyson 12:19c2d4943124 101 if (result == 0) pUart = incrementPushPullPointer(pUart, buffer, BUFFER_LENGTH); //If the character was written to the uart then move to the next
andrewboyson 0:9907e344c82a 102 }
andrewboyson 16:5c41b457c7f3 103 int Log(const char* snd)
andrewboyson 8:e793e9005f89 104 {
andrewboyson 16:5c41b457c7f3 105 const char* ptr = snd;
andrewboyson 16:5c41b457c7f3 106 while (*ptr) LogChar(*ptr++); //Send the string to the log buffer
andrewboyson 10:cf815db8ed57 107 return ptr - snd;
andrewboyson 8:e793e9005f89 108 }
andrewboyson 16:5c41b457c7f3 109 int LogV(const char *fmt, va_list argptr)
andrewboyson 0:9907e344c82a 110 {
andrewboyson 8:e793e9005f89 111 int size = vsnprintf(NULL, 0, fmt, argptr); //Find the size required
andrewboyson 8:e793e9005f89 112 char snd[size + 1]; //Allocate enough memory for the size required with an extra byte for the terminating null
andrewboyson 8:e793e9005f89 113 vsprintf(snd, fmt, argptr); //Fill the new buffer
andrewboyson 10:cf815db8ed57 114 return Log(snd); //Send the string to the log buffer
andrewboyson 0:9907e344c82a 115 }
andrewboyson 16:5c41b457c7f3 116 int LogF(const char *fmt, ...)
andrewboyson 0:9907e344c82a 117 {
andrewboyson 0:9907e344c82a 118 va_list argptr;
andrewboyson 0:9907e344c82a 119 va_start(argptr, fmt);
andrewboyson 10:cf815db8ed57 120 int size = LogV(fmt, argptr);
andrewboyson 0:9907e344c82a 121 va_end(argptr);
andrewboyson 10:cf815db8ed57 122 return size;
andrewboyson 0:9907e344c82a 123 }
andrewboyson 0:9907e344c82a 124 static void pushuint4(int value)
andrewboyson 0:9907e344c82a 125 {
andrewboyson 16:5c41b457c7f3 126 if (value > 9999) { LogChar('+'); LogChar('+'); LogChar('+'); LogChar('+'); }
andrewboyson 16:5c41b457c7f3 127 else if (value < 0) { LogChar('-'); LogChar('-'); LogChar('-'); LogChar('-'); }
andrewboyson 0:9907e344c82a 128 else
andrewboyson 0:9907e344c82a 129 {
andrewboyson 0:9907e344c82a 130 div_t divres;
andrewboyson 0:9907e344c82a 131 int k, c, t, u;
andrewboyson 0:9907e344c82a 132 divres = div(value , 10); u = divres.rem;
andrewboyson 0:9907e344c82a 133 divres = div(divres.quot, 10); t = divres.rem;
andrewboyson 0:9907e344c82a 134 divres = div(divres.quot, 10); c = divres.rem;
andrewboyson 0:9907e344c82a 135 k = divres.quot;
andrewboyson 16:5c41b457c7f3 136 LogChar(k + '0'); LogChar(c + '0'); LogChar(t + '0'); LogChar(u + '0');
andrewboyson 0:9907e344c82a 137 }
andrewboyson 0:9907e344c82a 138 }
andrewboyson 0:9907e344c82a 139 static void pushuint3(int value)
andrewboyson 0:9907e344c82a 140 {
andrewboyson 16:5c41b457c7f3 141 if (value > 999) { LogChar('+'); LogChar('+'); LogChar('+'); }
andrewboyson 16:5c41b457c7f3 142 else if (value < 0) { LogChar('-'); LogChar('-'); LogChar('-'); }
andrewboyson 0:9907e344c82a 143 else
andrewboyson 0:9907e344c82a 144 {
andrewboyson 0:9907e344c82a 145 div_t divres;
andrewboyson 0:9907e344c82a 146 int c, t, u;
andrewboyson 0:9907e344c82a 147 divres = div(value , 10); u = divres.rem;
andrewboyson 0:9907e344c82a 148 divres = div(divres.quot, 10); t = divres.rem;
andrewboyson 0:9907e344c82a 149 c = divres.quot;
andrewboyson 16:5c41b457c7f3 150 LogChar(c + '0'); LogChar(t + '0'); LogChar(u + '0');
andrewboyson 0:9907e344c82a 151 }
andrewboyson 0:9907e344c82a 152 }
andrewboyson 0:9907e344c82a 153 static void pushuint2(int value)
andrewboyson 0:9907e344c82a 154 {
andrewboyson 16:5c41b457c7f3 155 if (value > 99) { LogChar('+'); LogChar('+'); }
andrewboyson 16:5c41b457c7f3 156 else if (value < 0) { LogChar('-'); LogChar('-'); }
andrewboyson 0:9907e344c82a 157 else
andrewboyson 0:9907e344c82a 158 {
andrewboyson 0:9907e344c82a 159 div_t divres;
andrewboyson 0:9907e344c82a 160 int t, u;
andrewboyson 0:9907e344c82a 161 divres = div(value , 10); u = divres.rem;
andrewboyson 0:9907e344c82a 162 t = divres.quot;
andrewboyson 16:5c41b457c7f3 163 LogChar(t + '0'); LogChar(u + '0');
andrewboyson 0:9907e344c82a 164 }
andrewboyson 0:9907e344c82a 165 }
andrewboyson 12:19c2d4943124 166
andrewboyson 10:cf815db8ed57 167 static int logTimeOnly()
andrewboyson 0:9907e344c82a 168 {
andrewboyson 13:fb7f40c2e446 169 if (!tmFunction) return 0;
andrewboyson 12:19c2d4943124 170
andrewboyson 0:9907e344c82a 171 struct tm tm;
andrewboyson 13:fb7f40c2e446 172 tmFunction(&tm);
andrewboyson 0:9907e344c82a 173
andrewboyson 0:9907e344c82a 174 pushuint4(tm.tm_year + 1900);
andrewboyson 16:5c41b457c7f3 175 LogChar('-');
andrewboyson 0:9907e344c82a 176 pushuint3(tm.tm_yday + 1);
andrewboyson 16:5c41b457c7f3 177 LogChar(' ');
andrewboyson 0:9907e344c82a 178 pushuint2(tm.tm_hour);
andrewboyson 16:5c41b457c7f3 179 LogChar(':');
andrewboyson 0:9907e344c82a 180 pushuint2(tm.tm_min);
andrewboyson 16:5c41b457c7f3 181 LogChar(':');
andrewboyson 0:9907e344c82a 182 pushuint2(tm.tm_sec);
andrewboyson 10:cf815db8ed57 183 return 17;
andrewboyson 0:9907e344c82a 184 }
andrewboyson 16:5c41b457c7f3 185 int LogTime(const char *snd)
andrewboyson 0:9907e344c82a 186 {
andrewboyson 10:cf815db8ed57 187 int size = 0;
andrewboyson 10:cf815db8ed57 188 size += logTimeOnly();
andrewboyson 16:5c41b457c7f3 189 size++; LogChar(' ');
andrewboyson 10:cf815db8ed57 190 size += Log(snd);
andrewboyson 10:cf815db8ed57 191 return size;
andrewboyson 0:9907e344c82a 192 }
andrewboyson 16:5c41b457c7f3 193 int LogTimeF(const char *fmt, ...)
andrewboyson 0:9907e344c82a 194 {
andrewboyson 10:cf815db8ed57 195 int size = 0;
andrewboyson 0:9907e344c82a 196 va_list argptr;
andrewboyson 0:9907e344c82a 197 va_start(argptr, fmt);
andrewboyson 10:cf815db8ed57 198 size == logTimeOnly();
andrewboyson 16:5c41b457c7f3 199 size++; LogChar(' ');
andrewboyson 10:cf815db8ed57 200 size += LogV(fmt, argptr);
andrewboyson 0:9907e344c82a 201 va_end(argptr);
andrewboyson 10:cf815db8ed57 202 return size;
andrewboyson 0:9907e344c82a 203 }
andrewboyson 17:7acb89d71f48 204
andrewboyson 17:7acb89d71f48 205 void LogNibbleAsHex(int nibble)
andrewboyson 17:7acb89d71f48 206 {
andrewboyson 17:7acb89d71f48 207 nibble &= 0x0F;
andrewboyson 17:7acb89d71f48 208 char c;
andrewboyson 17:7acb89d71f48 209 if (nibble < 0x0A) c = nibble + '0';
andrewboyson 17:7acb89d71f48 210 else if (nibble < 0x10) c = nibble - 0xA + 'A';
andrewboyson 17:7acb89d71f48 211 else c = '0';
andrewboyson 17:7acb89d71f48 212 LogChar(c);
andrewboyson 17:7acb89d71f48 213 }
andrewboyson 17:7acb89d71f48 214
andrewboyson 17:7acb89d71f48 215 void LogByteAsHex(int value)
andrewboyson 17:7acb89d71f48 216 {
andrewboyson 17:7acb89d71f48 217 LogNibbleAsHex(value >> 4);
andrewboyson 17:7acb89d71f48 218 LogNibbleAsHex(value >> 0);
andrewboyson 17:7acb89d71f48 219 }
andrewboyson 17:7acb89d71f48 220 void LogBytesAsHex(char* value, int size)
andrewboyson 17:7acb89d71f48 221 {
andrewboyson 17:7acb89d71f48 222 int i = 0;
andrewboyson 17:7acb89d71f48 223 while(true)
andrewboyson 17:7acb89d71f48 224 {
andrewboyson 17:7acb89d71f48 225 LogByteAsHex(value[size - 1 - i]); //Display big end first
andrewboyson 17:7acb89d71f48 226 i++;
andrewboyson 17:7acb89d71f48 227 if (i >= size) break;
andrewboyson 17:7acb89d71f48 228 if (i % 32 == 0) Log("\r\n");
andrewboyson 17:7acb89d71f48 229 else LogChar(' ');
andrewboyson 17:7acb89d71f48 230 }
andrewboyson 17:7acb89d71f48 231 }