Files
CCU4-firmware/utils.ino
2023-09-11 18:04:36 +02:00

337 lines
6.9 KiB
C++

static char result[16];
static word eeAdr = 0;
char getCharFromC40(ulong *c40) {
char result = *c40 % 40;
*c40 /= 40;
if (result < 12) {
if (result == 0) return '\0';
return result + ('0' - 1);
}
if (result <= 36) return result + ('a' - 12);
if (result == 37) return '.';
if (result == 38) return '-';
return '_';
}
void c40toString(ulong c40, char *str, byte maxlen) {
byte i = 0;
for (i = 0; i < maxlen; i++) {
if ((str[i] = getCharFromC40(&c40)) == 0) return;
}
str[maxlen - 1] = 0;
}
char *c40(ulong c40) {
c40toString(c40, result, sizeof result);
return result;
}
ulong addCharToC40(ulong in, char chr) {
ulong pos = 1;
if (in >= 40UL*40UL*40UL*40UL*40UL) return in; // throw away superflous chars
while (pos < in) {
pos *= 40;
}
return in + pos * CHAR_TO_C40(chr);
}
ulong addNumToC40(ulong in, byte num) {
// add number in the range 0..99
if (num >= 10) {
in = addCharToC40(in, '0' + num / 10);
}
return addCharToC40(in, '0' + num % 10);
}
boolean expired(ulong *last, long ms) {
if (now - *last > ms) {
*last = now;
return true;
}
return false;
}
byte textcopyuntil(char *dst, byte maxlen, const char *src, char endchar) {
byte reslen = 0;
char ch;
if (maxlen == 0) return 0;
maxlen--;
for (reslen = 0; reslen < maxlen; reslen++, src++, dst++) {
ch = *src;
if (ch == endchar || ch == 0) {
*dst = 0;
return reslen;
}
*dst = ch;
}
*dst = 0;
return maxlen + 1; // indicates overflow
}
byte textcopy(char *dst, byte maxlen, const char *src) {
return textcopyuntil(dst, maxlen, src, 0);
}
boolean textcmpcopy(char *dst, byte maxlen, const char *src) {
byte reslen = 0;
boolean equal = true;
if (maxlen == 0) return true;
maxlen--;
// first compare
dst[maxlen] = 0; // save reslen < maxlen comparison
for (reslen = 0; *src == *dst; reslen++, src++, dst++) {
if (*src == 0) return true;
}
// then copy
for (; reslen < maxlen; reslen++, src++, dst++) {
if ((*dst = *src) == 0) {
return false;
}
}
*dst = 0;
return false;
}
byte textappend(char *dst, byte maxlen, const char *src) {
byte len = strlen(dst);
return len + textcopyuntil(dst + len, maxlen - len, src, 0);
}
byte textequal(const char *a, const char *b) {
if (a == b) return 1;
if (a == 0) {
if (*b == 0) return 1;
return 0;
}
if (b == 0) {
if (*a == 0) return 1;
return 0;
}
for (; *a == *b; a++, b++) {
if (*a == 0) return 1;
}
return 0;
}
boolean textContainsBlanks(const char *text) {
for (; (signed char)*text > ' '; text++);
return (*text != 0);
}
void DummyHandler() {
}
size_t array_out_of_bounds(const char *func, long line, size_t index) {
Serial.println();
Serial.print(F("error in "));
Serial.print(func);
Serial.print(':');
Serial.print(line);
Serial.print('[');
Serial.print(index);
Serial.print(F("] invalid"));
SerialD.handler = DummyHandler;
SerialD.print("\033DL\033TE\014"); // clear display, terminal mode, clear terminal
SerialD.print("index\r\nerror:\r\n");
SerialD.print(func);
SerialD.print(':');
SerialD.print(line);
SerialD.print("\r\n[");
SerialD.print(index);
SerialD.print("]\r\n");
SerialD.send();
while (1);
//DispError("array out","of bounds");
return 0;
}
char *fix2str(long num, char dig, char *buffer, char maxlen) {
long divisor;
long n;
int i=0;
if (buffer == 0) {
buffer = result;
if (maxlen == 0 || maxlen > sizeof result) {
maxlen = sizeof result;
}
}
if (maxlen < 2) {
buffer[0] = 0;
return 0;
}
maxlen--;
if (dig >= 0) {
if (num < 0) {
buffer[i] = '-'; i++;
num = -num;
}
divisor = 1; n = num / 10;
while (n != 0 || dig > 0) {
n /= 10;
divisor *= 10;
dig--;
}
n = num;
while (divisor > 0 && i < maxlen) {
if (dig == 1) {
buffer[i] = '.'; i++;
}
buffer[i] = '0' + (n / divisor) % 10; i++;
divisor /= 10;
dig++;
}
}
if (i > maxlen) {
buffer[maxlen] = 0;
return 0;
}
buffer[i] = 0;
return buffer;
}
char *enum2str(byte value, flash_str flashList, char *buffer, byte maxlen) {
const char *list PROGMEM = (const char PROGMEM *)flashList;
byte len;
byte val = value;
char ch;
if (buffer == 0) {
buffer = result;
if (maxlen == 0 || maxlen > sizeof result) {
maxlen = sizeof result;
}
}
if (maxlen < 2) {
buffer[0] = 0;
return 0;
}
if (list == 0) {
buffer[0] = 0;
return buffer;
}
len = 0;
while (1) {
ch = pgm_read_byte(list);
if (ch == 0) break;
if (ch == '|') {
if (val == 0) break;
val--;
len = -1;
}
list++;
len++;
}
if (val != 0) {
return fix2str(value, 0, buffer, maxlen);
}
while (len >= maxlen) {
len--;
list--;
}
buffer[len] = 0;
while (len > 0) {
len--;
list--;
buffer[len] = pgm_read_byte(list);;
}
return buffer;
}
void eeSetAdr(word adr) {
eeAdr = adr;
}
word eeGetAdr() {
return eeAdr;
}
void eeStore(const void *data, word length, byte mode) {
byte *p;
if (mode == ee_write) {
for (p = (byte *)data; length > 0; length--, p++, eeAdr++) {
//Serial.print(eeAdr); Serial.print(":"); if(*p > ' ' && *p <= 'z') Serial.print((char)*p); Serial.println(*p);
EEPROM.write(eeAdr, *p);
}
} else {
for (p = (byte *)data; length > 0; length--, p++, eeAdr++) {
*p = EEPROM.read(eeAdr);
//Serial.print(eeAdr); Serial.print(":"); if(*p > ' ' && *p <= 'z') Serial.print((char)*p); Serial.println(*p);
}
}
}
void eeStoreText(char *p, word length, byte mode) {
char ch;
char *fini = p + length;
if (mode == ee_write) {
while (p < fini) {
ch = *p;
EEPROM.write(eeAdr, ch);
eeAdr++;
if (ch == 0) break;
p++;
}
} else {
while (p < fini) {
ch = EEPROM.read(eeAdr);
eeAdr++;
if (ch == -1) { // empty EEPROM location
ch = 0;
}
*p = ch;
if (ch == 0) break;
p++;
//Serial.print(eeAdr); Serial.print(":"); if(*p > ' ' && *p <= 'z') Serial.print((char)*p); Serial.println(*p);
}
}
}
long text2fix(const char *str, byte dig, byte *len) {
boolean neg;
long res = 0;
char ch;
const char *p = str;
if (len) *len = 0;
if (*p == '-') {
neg = true;
p++;
} else {
neg = false;
}
for (ch = *p; ch >= '0' && ch <='9'; p++, ch = *p) {
if (res >= 214748364) return 0;
res *= 10;
res += ch - '0';
}
if (ch == '.') {
p++;
for (ch = *p; ch >= '0' && ch <='9'; p++, ch = *p) {
if (dig == 0) {
if (ch >= '5') res++; // round up;
for (; ch >= '0' && ch <='9'; p++, ch = *p);
break;
}
res *= 10;
res += ch - '0';
dig --;
}
}
while (dig > 0) {
if (res >= 214748364) return 0;
res *= 10;
dig--;
}
if (len) {
*len = p - str;
}
if (neg) res = -res;
return res;
}