Log

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Fri Sep 27 11:32:50 2019 +0000
Revision:
20:5b5284c60d3c
Parent:
19:14376c221aec
Removed bug in LogTimeF where the returned size was incorrect.

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