Log

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Jan 11 17:39:18 2018 +0000
Revision:
12:19c2d4943124
Parent:
log.cpp@10:cf815db8ed57
Child:
13:fb7f40c2e446
Removed dependence on Mbed OS

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 12:19c2d4943124 6 #include "uart.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 12:19c2d4943124 16
andrewboyson 12:19c2d4943124 17 bool LogUart = true;
andrewboyson 6:b98aa0ec75a1 18
andrewboyson 0:9907e344c82a 19 static char* incrementPushPullPointer(char* p, char* buffer, int bufferLength)
andrewboyson 0:9907e344c82a 20 {
andrewboyson 0:9907e344c82a 21 p++; //increment the pointer by one
andrewboyson 0:9907e344c82a 22 if (p == buffer + bufferLength) p = buffer; //if the pointer is now beyond the end then point it back to the start
andrewboyson 0:9907e344c82a 23 return p;
andrewboyson 0:9907e344c82a 24 }
andrewboyson 6:b98aa0ec75a1 25 static void push(char c)
andrewboyson 6:b98aa0ec75a1 26 {
andrewboyson 6:b98aa0ec75a1 27 //Move the pull position if about to run into it
andrewboyson 6:b98aa0ec75a1 28 char* pNext = incrementPushPullPointer(pPush, buffer, BUFFER_LENGTH);
andrewboyson 6:b98aa0ec75a1 29 if (pNext == pPull) pPull = incrementPushPullPointer(pPull, buffer, BUFFER_LENGTH);
andrewboyson 6:b98aa0ec75a1 30
andrewboyson 6:b98aa0ec75a1 31 //Add the character at the push position
andrewboyson 6:b98aa0ec75a1 32 *pPush = c;
andrewboyson 6:b98aa0ec75a1 33 pPush = incrementPushPullPointer(pPush, buffer, BUFFER_LENGTH);
andrewboyson 6:b98aa0ec75a1 34 }
andrewboyson 0:9907e344c82a 35 void LogPush(char c)
andrewboyson 0:9907e344c82a 36 {
andrewboyson 0:9907e344c82a 37 //Only add if allowed
andrewboyson 0:9907e344c82a 38 if (!enable) return;
andrewboyson 0:9907e344c82a 39
andrewboyson 6:b98aa0ec75a1 40 //Work out if the character needs to be delimited
andrewboyson 2:ee4ec2d72525 41 bool delimited = false;
andrewboyson 2:ee4ec2d72525 42 if (c < ' ' && c != '\r' && c != '\n') delimited = true;
andrewboyson 12:19c2d4943124 43 if (c > 126) delimited = false;
andrewboyson 2:ee4ec2d72525 44
andrewboyson 6:b98aa0ec75a1 45 //Push the delimiter or the character
andrewboyson 6:b98aa0ec75a1 46 if (delimited) push('^');
andrewboyson 6:b98aa0ec75a1 47 else push(c);
andrewboyson 2:ee4ec2d72525 48
andrewboyson 6:b98aa0ec75a1 49 //Stop if its not delimited
andrewboyson 2:ee4ec2d72525 50 if (!delimited) return;
andrewboyson 2:ee4ec2d72525 51
andrewboyson 6:b98aa0ec75a1 52 //Push the first digit
andrewboyson 2:ee4ec2d72525 53 char h = c >> 4;
andrewboyson 2:ee4ec2d72525 54 if (h < 10) h += '0';
andrewboyson 2:ee4ec2d72525 55 else h += 'A' - 10;
andrewboyson 6:b98aa0ec75a1 56 push(h);
andrewboyson 6:b98aa0ec75a1 57
andrewboyson 6:b98aa0ec75a1 58 //Push the second digit
andrewboyson 2:ee4ec2d72525 59 h = c & 0x0F;
andrewboyson 2:ee4ec2d72525 60 if (h < 10) h += '0';
andrewboyson 2:ee4ec2d72525 61 else h += 'A' - 10;
andrewboyson 6:b98aa0ec75a1 62 push(h);
andrewboyson 2:ee4ec2d72525 63
andrewboyson 0:9907e344c82a 64 }
andrewboyson 0:9907e344c82a 65 static char *pEnumerate;
andrewboyson 0:9907e344c82a 66 void LogEnumerateStart()
andrewboyson 0:9907e344c82a 67 {
andrewboyson 0:9907e344c82a 68 pEnumerate = pPull;
andrewboyson 0:9907e344c82a 69 }
andrewboyson 0:9907e344c82a 70 int LogEnumerate()
andrewboyson 0:9907e344c82a 71 {
andrewboyson 12:19c2d4943124 72 if (pEnumerate == pPush) return -1;
andrewboyson 0:9907e344c82a 73 char c = *pEnumerate;
andrewboyson 0:9907e344c82a 74 pEnumerate = incrementPushPullPointer(pEnumerate, buffer, BUFFER_LENGTH);
andrewboyson 2:ee4ec2d72525 75 return c;
andrewboyson 0:9907e344c82a 76 }
andrewboyson 12:19c2d4943124 77 void LogEnable(bool value)
andrewboyson 0:9907e344c82a 78 {
andrewboyson 12:19c2d4943124 79 enable = value;
andrewboyson 0:9907e344c82a 80 }
andrewboyson 12:19c2d4943124 81 void LogInit()
andrewboyson 0:9907e344c82a 82 {
andrewboyson 12:19c2d4943124 83 Uart0Init();
andrewboyson 0:9907e344c82a 84 pPush = buffer;
andrewboyson 0:9907e344c82a 85 pPull = buffer;
andrewboyson 12:19c2d4943124 86 pUart = buffer;
andrewboyson 12:19c2d4943124 87 }
andrewboyson 12:19c2d4943124 88 void LogMain()
andrewboyson 12:19c2d4943124 89 {
andrewboyson 12:19c2d4943124 90 if (!LogUart) return; //Do nothing if uart is not enabled
andrewboyson 12:19c2d4943124 91 if (pUart == pPush) return; //Do nothing if all characters have been sent
andrewboyson 12:19c2d4943124 92 int result = Uart0PutC(*pUart); //Attempt to write the character
andrewboyson 12:19c2d4943124 93 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 94 }
andrewboyson 10:cf815db8ed57 95 int Log(char* snd)
andrewboyson 8:e793e9005f89 96 {
andrewboyson 10:cf815db8ed57 97 char* ptr = snd;
andrewboyson 10:cf815db8ed57 98 while (*ptr) LogPush(*ptr++); //Send the string to the log buffer
andrewboyson 10:cf815db8ed57 99 return ptr - snd;
andrewboyson 8:e793e9005f89 100 }
andrewboyson 10:cf815db8ed57 101 int LogV(char *fmt, va_list argptr)
andrewboyson 0:9907e344c82a 102 {
andrewboyson 8:e793e9005f89 103 int size = vsnprintf(NULL, 0, fmt, argptr); //Find the size required
andrewboyson 8:e793e9005f89 104 char snd[size + 1]; //Allocate enough memory for the size required with an extra byte for the terminating null
andrewboyson 8:e793e9005f89 105 vsprintf(snd, fmt, argptr); //Fill the new buffer
andrewboyson 10:cf815db8ed57 106 return Log(snd); //Send the string to the log buffer
andrewboyson 0:9907e344c82a 107 }
andrewboyson 10:cf815db8ed57 108 int LogF(char *fmt, ...)
andrewboyson 0:9907e344c82a 109 {
andrewboyson 0:9907e344c82a 110 va_list argptr;
andrewboyson 0:9907e344c82a 111 va_start(argptr, fmt);
andrewboyson 10:cf815db8ed57 112 int size = LogV(fmt, argptr);
andrewboyson 0:9907e344c82a 113 va_end(argptr);
andrewboyson 10:cf815db8ed57 114 return size;
andrewboyson 0:9907e344c82a 115 }
andrewboyson 0:9907e344c82a 116 static void pushuint4(int value)
andrewboyson 0:9907e344c82a 117 {
andrewboyson 0:9907e344c82a 118 if (value > 9999) { LogPush('+'); LogPush('+'); LogPush('+'); LogPush('+'); }
andrewboyson 0:9907e344c82a 119 else if (value < 0) { LogPush('-'); LogPush('-'); LogPush('-'); LogPush('-'); }
andrewboyson 0:9907e344c82a 120 else
andrewboyson 0:9907e344c82a 121 {
andrewboyson 0:9907e344c82a 122 div_t divres;
andrewboyson 0:9907e344c82a 123 int k, c, t, u;
andrewboyson 0:9907e344c82a 124 divres = div(value , 10); u = divres.rem;
andrewboyson 0:9907e344c82a 125 divres = div(divres.quot, 10); t = divres.rem;
andrewboyson 0:9907e344c82a 126 divres = div(divres.quot, 10); c = divres.rem;
andrewboyson 0:9907e344c82a 127 k = divres.quot;
andrewboyson 0:9907e344c82a 128 LogPush(k + '0'); LogPush(c + '0'); LogPush(t + '0'); LogPush(u + '0');
andrewboyson 0:9907e344c82a 129 }
andrewboyson 0:9907e344c82a 130 }
andrewboyson 0:9907e344c82a 131 static void pushuint3(int value)
andrewboyson 0:9907e344c82a 132 {
andrewboyson 0:9907e344c82a 133 if (value > 999) { LogPush('+'); LogPush('+'); LogPush('+'); }
andrewboyson 0:9907e344c82a 134 else if (value < 0) { LogPush('-'); LogPush('-'); LogPush('-'); }
andrewboyson 0:9907e344c82a 135 else
andrewboyson 0:9907e344c82a 136 {
andrewboyson 0:9907e344c82a 137 div_t divres;
andrewboyson 0:9907e344c82a 138 int c, t, u;
andrewboyson 0:9907e344c82a 139 divres = div(value , 10); u = divres.rem;
andrewboyson 0:9907e344c82a 140 divres = div(divres.quot, 10); t = divres.rem;
andrewboyson 0:9907e344c82a 141 c = divres.quot;
andrewboyson 0:9907e344c82a 142 LogPush(c + '0'); LogPush(t + '0'); LogPush(u + '0');
andrewboyson 0:9907e344c82a 143 }
andrewboyson 0:9907e344c82a 144 }
andrewboyson 0:9907e344c82a 145 static void pushuint2(int value)
andrewboyson 0:9907e344c82a 146 {
andrewboyson 0:9907e344c82a 147 if (value > 99) { LogPush('+'); LogPush('+'); }
andrewboyson 0:9907e344c82a 148 else if (value < 0) { LogPush('-'); LogPush('-'); }
andrewboyson 0:9907e344c82a 149 else
andrewboyson 0:9907e344c82a 150 {
andrewboyson 0:9907e344c82a 151 div_t divres;
andrewboyson 0:9907e344c82a 152 int t, u;
andrewboyson 0:9907e344c82a 153 divres = div(value , 10); u = divres.rem;
andrewboyson 0:9907e344c82a 154 t = divres.quot;
andrewboyson 0:9907e344c82a 155 LogPush(t + '0'); LogPush(u + '0');
andrewboyson 0:9907e344c82a 156 }
andrewboyson 0:9907e344c82a 157 }
andrewboyson 12:19c2d4943124 158 void (*LogTmFunction)(struct tm* ptm);
andrewboyson 12:19c2d4943124 159
andrewboyson 10:cf815db8ed57 160 static int logTimeOnly()
andrewboyson 0:9907e344c82a 161 {
andrewboyson 12:19c2d4943124 162 if (!LogTmFunction) return 0;
andrewboyson 12:19c2d4943124 163
andrewboyson 0:9907e344c82a 164 struct tm tm;
andrewboyson 12:19c2d4943124 165 LogTmFunction(&tm);
andrewboyson 0:9907e344c82a 166
andrewboyson 0:9907e344c82a 167 pushuint4(tm.tm_year + 1900);
andrewboyson 0:9907e344c82a 168 LogPush('-');
andrewboyson 0:9907e344c82a 169 pushuint3(tm.tm_yday + 1);
andrewboyson 0:9907e344c82a 170 LogPush(' ');
andrewboyson 0:9907e344c82a 171 pushuint2(tm.tm_hour);
andrewboyson 0:9907e344c82a 172 LogPush(':');
andrewboyson 0:9907e344c82a 173 pushuint2(tm.tm_min);
andrewboyson 0:9907e344c82a 174 LogPush(':');
andrewboyson 0:9907e344c82a 175 pushuint2(tm.tm_sec);
andrewboyson 10:cf815db8ed57 176 return 17;
andrewboyson 0:9907e344c82a 177 }
andrewboyson 10:cf815db8ed57 178 int LogTime(char *snd)
andrewboyson 0:9907e344c82a 179 {
andrewboyson 10:cf815db8ed57 180 int size = 0;
andrewboyson 10:cf815db8ed57 181 size += logTimeOnly();
andrewboyson 10:cf815db8ed57 182 size++; LogPush(' ');
andrewboyson 10:cf815db8ed57 183 size += Log(snd);
andrewboyson 10:cf815db8ed57 184 return size;
andrewboyson 0:9907e344c82a 185 }
andrewboyson 10:cf815db8ed57 186 int LogTimeF(char *fmt, ...)
andrewboyson 0:9907e344c82a 187 {
andrewboyson 10:cf815db8ed57 188 int size = 0;
andrewboyson 0:9907e344c82a 189 va_list argptr;
andrewboyson 0:9907e344c82a 190 va_start(argptr, fmt);
andrewboyson 10:cf815db8ed57 191 size == logTimeOnly();
andrewboyson 10:cf815db8ed57 192 size++; LogPush(' ');
andrewboyson 10:cf815db8ed57 193 size += LogV(fmt, argptr);
andrewboyson 0:9907e344c82a 194 va_end(argptr);
andrewboyson 10:cf815db8ed57 195 return size;
andrewboyson 0:9907e344c82a 196 }