From 5260ddb3bb5754a18e15133aa1517fbaf358de63 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Sat, 4 Feb 2023 12:01:02 +0300 Subject: [PATCH] some remake about stringHash4MCU_: modified to test with parameter and argument --- MLX90640_OrangePi/Makefile | 53 -- MLX90640_OrangePi/cmdlnopts.c | 86 ---- MLX90640_OrangePi/cmdlnopts.h | 32 -- MLX90640_OrangePi/main.c | 95 ---- MLX90640_OrangePi/mlx | Bin 21576 -> 0 bytes MLX90640_OrangePi/mlx90640.c | 535 --------------------- MLX90640_OrangePi/mlx90640.h | 72 --- MLX90640_OrangePi/mlx90640_regs.h | 87 ---- MLX90640_OrangePi/mxl90640OPi.cflags | 1 - MLX90640_OrangePi/mxl90640OPi.config | 4 - MLX90640_OrangePi/mxl90640OPi.creator | 1 - MLX90640_OrangePi/mxl90640OPi.creator.user | 174 ------- MLX90640_OrangePi/mxl90640OPi.cxxflags | 1 - MLX90640_OrangePi/mxl90640OPi.files | 6 - MLX90640_OrangePi/mxl90640OPi.includes | 2 - stringHash4MCU_/Readme | 5 +- stringHash4MCU_/hashgen.c | 37 +- stringHash4MCU_/run | 10 + stringHash4MCU_/strfunc.c | 256 ++++++++++ stringHash4MCU_/strfunc.h | 13 + stringHash4MCU_/test.c | 61 ++- stringHash4MCU_/testdic | 21 +- 22 files changed, 366 insertions(+), 1186 deletions(-) delete mode 100644 MLX90640_OrangePi/Makefile delete mode 100644 MLX90640_OrangePi/cmdlnopts.c delete mode 100644 MLX90640_OrangePi/cmdlnopts.h delete mode 100644 MLX90640_OrangePi/main.c delete mode 100755 MLX90640_OrangePi/mlx delete mode 100644 MLX90640_OrangePi/mlx90640.c delete mode 100644 MLX90640_OrangePi/mlx90640.h delete mode 100644 MLX90640_OrangePi/mlx90640_regs.h delete mode 100644 MLX90640_OrangePi/mxl90640OPi.cflags delete mode 100644 MLX90640_OrangePi/mxl90640OPi.config delete mode 100644 MLX90640_OrangePi/mxl90640OPi.creator delete mode 100644 MLX90640_OrangePi/mxl90640OPi.creator.user delete mode 100644 MLX90640_OrangePi/mxl90640OPi.cxxflags delete mode 100644 MLX90640_OrangePi/mxl90640OPi.files delete mode 100644 MLX90640_OrangePi/mxl90640OPi.includes create mode 100755 stringHash4MCU_/run create mode 100644 stringHash4MCU_/strfunc.c create mode 100644 stringHash4MCU_/strfunc.h diff --git a/MLX90640_OrangePi/Makefile b/MLX90640_OrangePi/Makefile deleted file mode 100644 index 9ab7bd3..0000000 --- a/MLX90640_OrangePi/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# run `make DEF=...` to add extra defines -PROGRAM := mlx -LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all -LDFLAGS += -lwiringPi -lusefull_macros -L/usr/local/lib -lm -lcrypt -SRCS := $(wildcard *.c) -DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111 -OBJDIR := mk -CFLAGS += -O2 -Wall -Wextra -Wno-trampolines -std=gnu99 -OBJS := $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o)) -DEPS := $(OBJS:.o=.d) -TARGFILE := $(OBJDIR)/TARGET -CC = gcc -#TARGET := RELEASE - -ifeq ($(shell test -e $(TARGFILE) && echo -n yes),yes) - TARGET := $(file < $(TARGFILE)) -else - TARGET := RELEASE -endif - -release: $(PROGRAM) - -debug: CFLAGS += -DEBUG -Werror -debug: TARGET := DEBUG -debug: $(PROGRAM) - -$(TARGFILE): $(OBJDIR) - @echo -e "\t\tTARGET: $(TARGET)" - @echo "$(TARGET)" > $(TARGFILE) - -$(PROGRAM) : $(TARGFILE) $(OBJS) - @echo -e "\t\tLD $(PROGRAM)" - $(CC) $(OBJS) $(LDFLAGS) -o $(PROGRAM) - -$(OBJDIR): - @mkdir $(OBJDIR) - -ifneq ($(MAKECMDGOALS),clean) --include $(DEPS) -endif - -$(OBJDIR)/%.o: %.c - @echo -e "\t\tCC $<" - $(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $< - -clean: - @echo -e "\t\tCLEAN" - @rm -rf $(OBJDIR) 2>/dev/null || true - -xclean: clean - @rm -f $(PROGRAM) - -.PHONY: clean xclean diff --git a/MLX90640_OrangePi/cmdlnopts.c b/MLX90640_OrangePi/cmdlnopts.c deleted file mode 100644 index 07b8baf..0000000 --- a/MLX90640_OrangePi/cmdlnopts.c +++ /dev/null @@ -1,86 +0,0 @@ -/* geany_encoding=koi8-r - * cmdlnopts.c - the only function that parse cmdln args and returns glob parameters - * - * Copyright 2013 Edward V. Emelianoff - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include "cmdlnopts.h" -#include "usefull_macros.h" - -/* - * here are global parameters initialisation - */ -static int help; -static glob_pars G; - -// default PID filename: -#define DEFAULT_PIDFILE "/tmp/testcmdlnopts.pid" -#define DEFAULT_I2C "/dev/i2c-3" - -// DEFAULTS -// default global parameters -static glob_pars const Gdefault = { - .device = DEFAULT_I2C, - .pidfile = DEFAULT_PIDFILE, - .logfile = NULL // don't save logs -}; - -/* - * Define command line options by filling structure: - * name has_arg flag val type argptr help -*/ -static myoption cmdlnopts[] = { -// common options - {"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")}, - {"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")}, - {"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")}, - {"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("I2C device path (default: " DEFAULT_I2C ")")}, - end_option -}; - -/** - * Parse command line options and return dynamically allocated structure - * to global parameters - * @param argc - copy of argc from main - * @param argv - copy of argv from main - * @return allocated structure with global parameters - */ -glob_pars *parse_args(int argc, char **argv){ - int i; - void *ptr; - ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr); - size_t hlen = 1024; - char helpstring[1024], *hptr = helpstring; - snprintf(hptr, hlen, "Usage: %%s [args]\n\n\tWhere args are:\n"); - // format of help: "Usage: progname [args]\n" - change_helpstring(helpstring); - // parse arguments - parseargs(&argc, &argv, cmdlnopts); - if(help) showhelp(-1, cmdlnopts); - if(argc > 0){ - WARNX("Ignoring arguments:"); - for (i = 0; i < argc; i++) - printf("\t%s\n", argv[i]); - } - return &G; -} - diff --git a/MLX90640_OrangePi/cmdlnopts.h b/MLX90640_OrangePi/cmdlnopts.h deleted file mode 100644 index 3d37d41..0000000 --- a/MLX90640_OrangePi/cmdlnopts.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the mxl90640wPi project. - * Copyright 2022 Edward V. Emelianov . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -/* - * here are some typedef's for global data - */ -typedef struct{ - char *device; // I2C device - char *pidfile; // name of PID file - char *logfile; // logging to this file -} glob_pars; - - -glob_pars *parse_args(int argc, char **argv); - diff --git a/MLX90640_OrangePi/main.c b/MLX90640_OrangePi/main.c deleted file mode 100644 index f4fc2bc..0000000 --- a/MLX90640_OrangePi/main.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of the mxl90640wPi project. - * Copyright 2022 Edward V. Emelianov . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "cmdlnopts.h" -#include "mlx90640.h" - -#define DEVICE_ID 0x33 - -static glob_pars *GP = NULL; - -void signals(int sig){ - if(sig){ - signal(sig, SIG_IGN); - DBG("Get signal %d, quit.\n", sig); - } - LOGERR("Exit with status %d", sig); - if(GP && GP->pidfile) // remove unnesessary PID file - unlink(GP->pidfile); - exit(sig); -} - -static double image[MLX_PIXNO]; -static double image2[MLX_PIXNO]; -static void pushima(const double *img){ - for(int i = 0; i < MLX_PIXNO; ++i){ - double val = *img++; - image[i] += val; - image2[i] += val*val; - } -} - -int main (int argc, char **argv){ - initial_setup(); - char *self = strdup(argv[0]); - GP = parse_args(argc, argv); - check4running(self, GP->pidfile); - FREE(self); - if(GP->logfile) OPENLOG(GP->logfile, LOGLEVEL_ANY, 1); - - if(!mlx90640_init(GP->device, DEVICE_ID)) ERR("Can't open device"); - //mlx90640_dump_parameters(); -#define N 9 - double T0 = dtime(); - uint8_t simple = 2; - //for(uint8_t simple = 0; simple < 3; ++simple){ - memset(image, 0, sizeof(image)); - memset(image2, 0, sizeof(image)); - for(int i = 0; i < N; ++i){ - double *ima = NULL; - if(!mlx90640_take_image(simple, &ima) || !ima) ERRX("Can't take image"); - pushima(ima); - printf("Got image %d, T=%g\n", i, dtime() - T0); - } - double *im = image, *im2 = image2; - green("\nImage (simple=%d):\n", simple); - for(int row = 0; row < MLX_H; ++row){ - for(int col = 0; col < MLX_W; ++col){ - double v = *im++, v2 = *im2; - v /= N; v2 /= N; - printf("%5.1f ", v); - *im2++ = v2 - v*v; - } - printf("\n"); - } - green("\nRMS:\n"); - im2 = image2; - for(int row = 0; row < MLX_H; ++row){ - for(int col = 0; col < MLX_W; ++col){ - printf("%5.1f ", *im2++); - } - printf("\n"); - } - //} - return 0; -} diff --git a/MLX90640_OrangePi/mlx b/MLX90640_OrangePi/mlx deleted file mode 100755 index 4d751ef87023301cfb297e9b2be4ba6b71e09e90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21576 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. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mlx90640.h" -#include "mlx90640_regs.h" - - -static int I2Cfd = -1; -static uint8_t lastaddr = 0; -static MLX90640_params params; - -static uint16_t dataarray[MLX_DMA_MAXLEN]; // array for raw data from sensor -static double mlx_image[MLX_PIXNO]; // ready image - -#define CREG_VAL(reg) dataarray[CREG_IDX(reg)] -#define IMD_VAL(reg) dataarray[IMD_IDX(reg)] - -// reg_control values for subpage #0 and #1 -static const uint16_t reg_control_val[2] = { - REG_CONTROL_CHESS | REG_CONTROL_RES18 | REG_CONTROL_REFR_64HZ | REG_CONTROL_SUBPSEL | REG_CONTROL_DATAHOLD | REG_CONTROL_SUBPEN, - REG_CONTROL_CHESS | REG_CONTROL_RES18 | REG_CONTROL_REFR_64HZ | REG_CONTROL_SUBP1 | REG_CONTROL_SUBPSEL | REG_CONTROL_DATAHOLD | REG_CONTROL_SUBPEN -}; - - -static int errctr = 0; -static double Tlast = 0.; -#define chstate() do{errctr = 0; Tlast = dtime(); DBG("chstate()");}while(0) -#define chkerr() do{DBG("chkerr(), T=%g", dtime()-Tlast); if(++errctr > MLX_MAXERR_COUNT){ DBG("-> M_ERROR"); return FALSE;}else continue;}while(0) -#define chktmout() do{DBG("chktmout, T=%g", dtime()-Tlast); if(dtime() - Tlast > MLX_TIMEOUT){ DBG("Timeout! -> M_ERROR"); return FALSE;}else continue;}while(0) - - -// read register value -static int read_reg(uint16_t regaddr, uint16_t *data){ - if(I2Cfd < 1) return FALSE; - struct i2c_msg m[2]; - struct i2c_rdwr_ioctl_data x = {.msgs = m, .nmsgs = 2}; - m[0].addr = lastaddr; m[1].addr = lastaddr; - m[0].flags = 0; - m[1].flags = I2C_M_RD; - m[0].len = 2; m[1].len = 2; - uint8_t a[2], d[2] = {0}; - a[0] = regaddr >> 8; - a[1] = regaddr & 0xff; - m[0].buf = a; m[1].buf = d; - if(ioctl(I2Cfd, I2C_RDWR, &x) < 0) return FALSE; - if(data) *data = (uint16_t)((d[0] << 8) | (d[1])); - return TRUE; -} - - -//#if 0 - // Sometimes don't work :( -// read N values starting from regaddr -static int read_regN(uint16_t regaddr, uint16_t *data, uint16_t N){ - if(I2Cfd < 1 || N > 128 || N == 0) return FALSE; - struct i2c_msg m[2]; - struct i2c_rdwr_ioctl_data x = {.msgs = m, .nmsgs = 2}; - m[0].addr = lastaddr; m[1].addr = lastaddr; - m[0].flags = 0; - m[1].flags = I2C_M_RD; - m[0].len = 2; m[1].len = N * 2; - uint8_t a[2], d[256] = {0}; - a[0] = regaddr >> 8; - a[1] = regaddr & 0xff; - m[0].buf = a; m[1].buf = d; - if(ioctl(I2Cfd, I2C_RDWR, &x) < 0) return FALSE; - if(data) for(int i = 0; i < N; ++i){ - *data++ = (uint16_t)((d[2*i] << 8) | (d[2*i + 1])); - } - return TRUE; -} - -// blocking read N uint16_t values starting from `reg` -// @param reg - register to read -// @param N (io) - amount of bytes to read / bytes read -// @return `dataarray` or NULL if failed -static uint16_t *read_data(uint16_t reg, uint16_t *N){ - if(I2Cfd < 1 || !N || *N < 1) return NULL; - uint16_t n = *N; - if(n < 1 || n > MLX_DMA_MAXLEN) return NULL; - uint16_t *data = dataarray; - uint16_t got = 0, rest = *N; - do{ - uint8_t l = (rest > 128) ? 128 : (uint8_t)rest; - if(!read_regN(reg, data, l)){ - DBG("can't read"); - break; - } - rest -= l; - reg += l; - data += l; - got += l; - }while(rest); - *N = got; - return dataarray; -} -//#endif -#if 0 -// blocking read N uint16_t values starting from `reg` -// @param reg - register to read -// @param N (io) - amount of bytes to read / bytes read -// @return `dataarray` or NULL if failed -static uint16_t *read_data(uint16_t reg, uint16_t *N){ - if(I2Cfd < 1 || !N || *N < 1) return NULL; - uint16_t n = *N; - if(n < 1 || n > MLX_DMA_MAXLEN) return NULL; - uint16_t i, *data = dataarray; - for(i = 0; i < n; ++i){ - if(!read_reg(reg++, data++)){ - DBG("can't read"); - break; - } - } - *N = i; - return dataarray; -} -#endif - - -// write register value -static int write_reg(uint16_t regaddr, uint16_t data){ - if(I2Cfd < 1) return FALSE; - union i2c_smbus_data d; - d.block[0] = 3; - d.block[1] = regaddr & 0xff; - d.block[2] = data >> 8; - d.block[3] = data & 0xff; - struct i2c_smbus_ioctl_data args; - args.read_write = I2C_SMBUS_WRITE; - args.command = regaddr >> 8; - args.size = I2C_SMBUS_I2C_BLOCK_DATA; - args.data = &d; - if(ioctl(I2Cfd, I2C_SMBUS, &args) < 0) return FALSE; - return TRUE; -} - -int mlx90640_set_slave_address(uint8_t addr){ - if(I2Cfd < 1) return FALSE; - if(ioctl (I2Cfd, I2C_SLAVE, addr) < 0) return FALSE; - lastaddr = addr; - return TRUE; -} - -static void dumpIma(double *im){ - for(int row = 0; row < MLX_H; ++row){ - for(int col = 0; col < MLX_W; ++col){ - printf("%5.1f ", *im++); - } - printf("\n"); - } -} - -void mlx90640_dump_parameters(){ - printf("kVdd=%d\nvdd25=%d\nKvPTAT=%g\nKtPTAT=%g\nvPTAT25=%d\n", params.kVdd, params.vdd25, params.KvPTAT, params.KtPTAT, params.vPTAT25); - printf("alphaPTAT=%g\ngainEE=%d\ntgc=%g\ncpKv=%g\ncpKta=%g\n", params.alphaPTAT, params.gainEE, params.tgc, params.cpKta, params.cpKta); - printf("KsTa=%g\nCT[]={%g, %g, %g}\n", params.KsTa, params.CT[0], params.CT[1], params.CT[2]); - printf("ksTo[]={"); for(int i = 0; i < 4; ++i) printf("%s%g", (i) ? ", " : "", params.ksTo[i]); printf("}\n"); - printf("alphacorr[]={"); for(int i = 0; i < 4; ++i) printf("%s%g", (i) ? ", " : "", params.alphacorr[i]); printf("}\n"); - printf("alpha[]=\n"); dumpIma(params.alpha); - printf("offset[]=\n"); dumpIma(params.offset); - printf("kta[]=\n"); dumpIma(params.kta); - printf("kv[]={"); for(int i = 0; i < 4; ++i) printf("%s%g", (i) ? ", " : "", params.kv[i]); printf("}\n"); - printf("cpAlpha[]={%g, %g}\n", params.cpAlpha[0], params.cpAlpha[1]); - printf("cpOffset[]={%d, %d}\n", params.cpOffset[0], params.cpOffset[1]); - printf("outliers[]=\n"); - uint8_t *o = params.outliers; - for(int row = 0; row < MLX_H; ++row){ - for(int col = 0; col < MLX_W; ++col){ - printf("%d ", *o++); - } - printf("\n"); - } -} - -/***************************************************************************** - Calculate parameters & values - *****************************************************************************/ - -// fill OCC/ACC row/col arrays -static void occacc(int8_t *arr, int l, uint16_t *regstart){ - int n = l >> 2; // divide by 4 - int8_t *p = arr; - for(int i = 0; i < n; ++i){ - register uint16_t val = *regstart++; - *p++ = (val & 0x000F) >> 0; - *p++ = (val & 0x00F0) >> 4; - *p++ = (val & 0x0F00) >> 8; - *p++ = (val ) >> 12; - } - for(int i = 0; i < l; ++i, ++arr){ - if(*arr > 0x07) *arr -= 0x10; - } -} - -// get all parameters' values from `dataarray`, return FALSE if something failed -static int get_parameters(){ - int8_t i8; - int16_t i16; - uint16_t *pu16; - uint16_t val = CREG_VAL(REG_VDD); - i8 = (int8_t) (val >> 8); - params.kVdd = i8 * 32; // keep sign - if(params.kVdd == 0) return FALSE; - i16 = val & 0xFF; - params.vdd25 = ((i16 - 0x100) * 32) - (1<<13); - val = CREG_VAL(REG_KVTPTAT); - i16 = (val & 0xFC00) >> 10; - if(i16 > 0x1F) i16 -= 0x40; - params.KvPTAT = (double)i16 / (1<<12); - i16 = (val & 0x03FF); - if(i16 > 0x1FF) i16 -= 0x400; - params.KtPTAT = (double)i16 / 8.; - params.vPTAT25 = (int16_t) CREG_VAL(REG_PTAT); - val = CREG_VAL(REG_APTATOCCS) >> 12; - params.alphaPTAT = val / 4. + 8.; - params.gainEE = (int16_t)CREG_VAL(REG_GAIN); - if(params.gainEE == 0) return FALSE; - int8_t occRow[MLX_H]; - int8_t occColumn[MLX_W]; - occacc(occRow, MLX_H, &CREG_VAL(REG_OCCROW14)); - occacc(occColumn, MLX_W, &CREG_VAL(REG_OCCCOL14)); - int8_t accRow[MLX_H]; - int8_t accColumn[MLX_W]; - occacc(accRow, MLX_H, &CREG_VAL(REG_ACCROW14)); - occacc(accColumn, MLX_W, &CREG_VAL(REG_ACCCOL14)); - val = CREG_VAL(REG_APTATOCCS); - // need to do multiplication instead of bitshift, so: - double occRemScale = 1<<(val&0x0F), - occColumnScale = 1<<((val>>4)&0x0F), - occRowScale = 1<<((val>>8)&0x0F); - int16_t offavg = (int16_t) CREG_VAL(REG_OSAVG); - // even/odd column/row numbers are for starting from 1, so for starting from 0 we chould swap them: - // even - for 1,3,5,...; odd - for 0,2,4,... etc - int8_t ktaavg[4]; - // 0 - odd row, odd col; 1 - odd row even col; 2 - even row, odd col; 3 - even row, even col - val = CREG_VAL(REG_KTAAVGODDCOL); - ktaavg[2] = (int8_t)(val & 0xFF); // odd col, even row -> col 0,2,..; row 1,3,.. - ktaavg[0] = (int8_t)(val >> 8); // odd col, odd row -> col 0,2,..; row 0,2,.. - val = CREG_VAL(REG_KTAAVGEVENCOL); - ktaavg[3] = (int8_t)(val & 0xFF); // even col, even row -> col 1,3,..; row 1,3,.. - ktaavg[1] = (int8_t)(val >> 8); // even col, odd row -> col 1,3,..; row 0,2,.. - // so index of ktaavg is 2*(row&1)+(col&1) - val = CREG_VAL(REG_KTAVSCALE); - uint8_t scale1 = ((val & 0xFF)>>4) + 8, scale2 = (val&0xF); - if(scale1 == 0 || scale2 == 0) return FALSE; - double mul = (double)(1<> 12); - diva *= (double)(1<<30); // alpha_scale - double accRowScale = 1<<((val & 0x0f00)>>8), - accColumnScale = 1<<((val & 0x00f0)>>4), - accRemScale = 1<<(val & 0x0f); - pu16 = &CREG_VAL(REG_OFFAK1); - double *kta = params.kta, *offset = params.offset; - uint8_t *ol = params.outliers; - for(int row = 0; row < MLX_H; ++row){ - int idx = (row&1)<<1; - for(int col = 0; col < MLX_W; ++col){ - // offset - register uint16_t rv = *pu16++; - i16 = (rv & 0xFC00) >> 10; - if(i16 > 0x1F) i16 -= 0x40; - *offset++ = (double)offavg + (double)occRow[row]*occRowScale + (double)occColumn[col]*occColumnScale + (double)i16*occRemScale; - // kta - i16 = (rv & 0xF) >> 1; - if(i16 > 0x03) i16 -= 0x08; - *kta++ = (ktaavg[idx|(col&1)] + i16*mul) / div; - // alpha - i16 = (rv & 0x3F0) >> 4; - if(i16 > 0x1F) i16 -= 0x40; - double oft = (double)a_r + accRow[row]*accRowScale + accColumn[col]*accColumnScale +i16*accRemScale; - *a++ = oft / diva; - *ol++ = (rv&1) ? 1 : 0; - } - } - scale1 = (CREG_VAL(REG_KTAVSCALE) >> 8) & 0xF; // kvscale - div = (double)(1<> 12; if(i16 > 0x07) i16 -= 0x10; - ktaavg[0] = (int8_t)i16; // odd col, odd row - i16 = (val & 0xF0) >> 4; if(i16 > 0x07) i16 -= 0x10; - ktaavg[1] = (int8_t)i16; // even col, odd row - i16 = (val & 0x0F00) >> 8; if(i16 > 0x07) i16 -= 0x10; - ktaavg[2] = (int8_t)i16; // odd col, even row - i16 = val & 0x0F; if(i16 > 0x07) i16 -= 0x10; - ktaavg[3] = (int8_t)i16; // even col, even row - for(int i = 0; i < 4; ++i) params.kv[i] = ktaavg[i] / div; - val = CREG_VAL(REG_CPOFF); - params.cpOffset[0] = (val & 0x03ff); - if(params.cpOffset[0] > 0x1ff) params.cpOffset[0] -= 0x400; - params.cpOffset[1] = val >> 10; - if(params.cpOffset[1] > 0x1f) params.cpOffset[1] -= 0x40; - params.cpOffset[1] += params.cpOffset[0]; - val = ((CREG_VAL(REG_KTAVSCALE) & 0xF0) >> 4) + 8; - i8 = (int8_t)(CREG_VAL(REG_KVTACP) & 0xFF); - params.cpKta = (double)i8 / (1<> 8; - i16 = CREG_VAL(REG_KVTACP) >> 8; - if(i16 > 0x7F) i16 -= 0x100; - params.cpKv = (double)i16 / (1< 0x7F) i16 -= 0x100; - params.tgc = (double)i16; - params.tgc /= 32.; - val = (CREG_VAL(REG_SCALEACC)>>12); // alpha_scale_CP - i16 = CREG_VAL(REG_ALPHA)>>10; // cp_P1_P0_ratio - if(i16 > 0x1F) i16 -= 0x40; - div = (double)(1<> 8); - params.KsTa = (double)i8/(1<<13); - div = 1<<((CREG_VAL(REG_CT34) & 0x0F) + 8); // kstoscale - DBG("kstoscale=%g (regct34=0x%04x)", div, CREG_VAL(REG_CT34)); - val = CREG_VAL(REG_KSTO12); - DBG("ksto12=0x%04x", val); - i8 = (int8_t)(val & 0xFF); - DBG("To1ee=%d", i8); - params.ksTo[0] = i8 / div; - i8 = (int8_t)(val >> 8); - DBG("To2ee=%d", i8); - params.ksTo[1] = i8 / div; - val = CREG_VAL(REG_KSTO34); - DBG("ksto34=0x%04x", val); - i8 = (int8_t)(val & 0xFF); - DBG("To3ee=%d", i8); - params.ksTo[2] = i8 / div; - i8 = (int8_t)(val >> 8); - DBG("To4ee=%d", i8); - params.ksTo[3] = i8 / div; - params.CT[0] = 0.; // 0degr - between ranges 1 and 2 - val = CREG_VAL(REG_CT34); - mul = ((val & 0x3000)>>12)*10.; // step - params.CT[1] = ((val & 0xF0)>>4)*mul; // CT3 - between ranges 2 and 3 - params.CT[2] = ((val & 0x0F00) >> 8)*mul + params.CT[1]; // CT4 - between ranges 3 and 4 - params.alphacorr[0] = 1./(1. + params.ksTo[0] * 40.); - params.alphacorr[1] = 1.; - params.alphacorr[2] = (1. + params.ksTo[2] * params.CT[1]); - params.alphacorr[3] = (1. + params.ksTo[3] * (params.CT[2] - params.CT[1])) * params.alphacorr[2]; - // Don't forget to check 'outlier' flags for wide purpose - return TRUE; -} - -/** - * @brief process_subpage - calculate all parameters from `dataarray` into `mlx_image` - * @param subpageno - number of subpage - * @param simpleimage == 0 - simplest, 1 - narrow range, 2 - extended range - */ -static void process_subpage(int subpageno, int simpleimage){ - DBG("\nprocess_subpage(%d)", subpageno); -#ifdef EBUG - chstate(); -#endif - int16_t i16a = (int16_t)IMD_VAL(REG_IVDDPIX); - double dvdd = i16a - params.vdd25; - dvdd = dvdd / params.kVdd; - DBG("Vd=%g", dvdd+3.3); - i16a = (int16_t)IMD_VAL(REG_ITAPTAT); - int16_t i16b = (int16_t)IMD_VAL(REG_ITAVBE); - double dTa = (double)i16a / (i16a * params.alphaPTAT + i16b); // vptatart - dTa *= (double)(1<<18); - dTa = (dTa / (1 + params.KvPTAT*dvdd) - params.vPTAT25); - dTa = dTa / params.KtPTAT; // without 25degr - Ta0 - DBG("Ta=%g", dTa+25.); - i16a = (int16_t)IMD_VAL(REG_IGAIN); - double Kgain = params.gainEE / (double)i16a; - DBG("Kgain=%g", Kgain); - // now make first approximation to image - uint16_t pixno = 0; // current pixel number - for indexing in parameters etc - for(int row = 0; row < MLX_H; ++row){ - int idx = (row&1)<<1; // index for params.kv - for(int col = 0; col < MLX_W; ++col, ++pixno){ - uint8_t sp = (row&1)^(col&1); // subpage of current pixel - if(sp != subpageno) continue; - double curval = (double)((int16_t)dataarray[pixno]) * Kgain; // gain compensation - curval -= params.offset[pixno] * (1. + params.kta[pixno]*dTa) * - (1. + params.kv[idx|(col&1)]*dvdd); // add offset - double IRcompens = curval; // IR_compensated - if(simpleimage == 0){ - curval -= params.cpOffset[subpageno] * (1. - params.cpKta * dTa) * - (1. + params.cpKv * dvdd); // CP - curval = IRcompens - params.tgc * curval; // IR gradient compens - }else{ - double alphaComp = params.alpha[pixno] - params.tgc * params.cpAlpha[subpageno]; - alphaComp /= 1. + params.KsTa * dTa; - // calculate To for basic range - double Tar = dTa + 273.15 + 25.; - Tar = Tar*Tar*Tar*Tar; - double ac3 = alphaComp*alphaComp*alphaComp; - double Sx = ac3*IRcompens + alphaComp*ac3*Tar; - Sx = params.KsTa * sqrt(sqrt(Sx)); - double To = IRcompens / (alphaComp * (1. - 273.15*params.ksTo[1]) + Sx) + Tar; - curval = sqrt(sqrt(To)) - 273.15; // To - // extended range - if(simpleimage == 2){ - int idx = 0; // range 1 by default - double ctx = -40.; - if(curval > params.CT[0] && curval < params.CT[1]){ // range 2 - idx = 1; ctx = params.CT[0]; - }else if(curval < params.CT[2]){ // range 3 - idx = 2; ctx = params.CT[1]; - }else{ // range 4 - idx = 3; ctx = params.CT[2]; - } - To = IRcompens / (alphaComp * params.alphacorr[idx] * (1. + params.ksTo[idx]*(curval - ctx))) + Tar; - curval = sqrt(sqrt(To)) - 273.15; - } - } - mlx_image[pixno] = curval; - } - } - DBG("Time: %g", dtime()-Tlast); -} - -static int process_readconf(){ - chstate(); - while(1){ - if(get_parameters()) return TRUE; - else chkerr(); - } -} -static int process_firstrun(){ - uint16_t reg, N; - write_reg(REG_CONTROL, REG_CONTROL_DEFAULT); - usleep(50); - write_reg(REG_CONTROL, REG_CONTROL_DEFAULT); - usleep(50); - chstate(); - while(1){ - if(write_reg(REG_CONTROL, reg_control_val[0]) - && read_reg(REG_CONTROL, ®)){ - DBG("REG_CTRL=0x%04x, T=%g", reg, dtime()-Tlast); - if(read_reg(REG_STATUS, ®)) DBG("REG_STATUS=0x%04x", reg); - N = REG_CALIDATA_LEN; - if(read_data(REG_CALIDATA, &N)){ - DBG("-> M_READCONF, T=%g", dtime()-Tlast); - return process_readconf(); - }else chkerr(); - }else chkerr(); - } - return FALSE; -} -// start image acquiring for next subpage -static int process_startima(int subpageno){ - chstate(); - DBG("startima(%d)", subpageno); - uint16_t reg, N; - while(1){ - // write `overwrite` flag twice - if(!write_reg(REG_CONTROL, reg_control_val[subpageno]) || - !write_reg(REG_STATUS, REG_STATUS_OVWEN) || - !write_reg(REG_STATUS, REG_STATUS_OVWEN)) chkerr(); - while(1){ - if(read_reg(REG_STATUS, ®)){ - if(reg & REG_STATUS_NEWDATA){ - DBG("got newdata: %g", dtime() - Tlast); - if(subpageno != (reg & REG_STATUS_SPNO)){ - DBG("wrong subpage number -> M_ERROR"); - return FALSE; - }else{ // all OK, run image reading - chstate(); - write_reg(REG_STATUS, 0); // clear rdy bit - N = MLX_PIXARRSZ; - if(read_data(REG_IMAGEDATA, &N) && N == MLX_PIXARRSZ){ - DBG("got readoutm N=%d: %g", N, dtime() - Tlast); - return TRUE; - }else chkerr(); - } - }else chktmout(); - }else chkerr(); - } - } - return FALSE; -} - -void mlx90640_restart(){ - memset(¶ms, 0, sizeof(params)); - process_firstrun(); -} - -// if state of MLX allows, make an image else return error -// @param simple ==1 for simplest image processing (without T calibration) -int mlx90640_take_image(uint8_t simple, double **image){ - if(I2Cfd < 1) return FALSE; - if(params.kVdd == 0){ // no parameters -> make first run - if(!process_firstrun()) return FALSE; - } - DBG("\n\n\n-> M_STARTIMA"); - for(int sp = 0; sp < 2; ++sp){ - if(!process_startima(sp)) return FALSE; // get first subpage - process_subpage(sp, simple); - } - if(image) *image = mlx_image; - return TRUE; -} - -int mlx90640_init(const char *dev, uint8_t ID){ - if(I2Cfd > 0) close(I2Cfd); - I2Cfd = open(dev, O_RDWR); - if(I2Cfd < 1) return FALSE; - if(!mlx90640_set_slave_address(ID)) return FALSE; - if(!read_reg(0, NULL)) return FALSE; - if(!process_firstrun()) return FALSE; - return TRUE; -} - diff --git a/MLX90640_OrangePi/mlx90640.h b/MLX90640_OrangePi/mlx90640.h deleted file mode 100644 index e906462..0000000 --- a/MLX90640_OrangePi/mlx90640.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of the mxl90640wPi project. - * Copyright 2022 Edward V. Emelianov . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include - -// timeout for reading operations, s -#define MLX_TIMEOUT 5. -// counter of errors, when > max -> M_ERROR -#define MLX_MAXERR_COUNT 10 -// wait after power off, s -#define MLX_POWOFF_WAIT 0.5 -// wait after power on, s -#define MLX_POWON_WAIT 2. - -// amount of pixels -#define MLX_W (32) -#define MLX_H (24) -#define MLX_PIXNO (MLX_W*MLX_H) -// pixels + service data -#define MLX_PIXARRSZ (MLX_PIXNO + 64) - -typedef struct{ - int16_t kVdd; - int16_t vdd25; - double KvPTAT; - double KtPTAT; - int16_t vPTAT25; - double alphaPTAT; - int16_t gainEE; - double tgc; - double cpKv; // K_V_CP - double cpKta; // K_Ta_CP - double KsTa; - double CT[3]; // range borders (0, 160, 320 degrC?) - double ksTo[4]; // K_S_To for each range * 273.15 - double alphacorr[4]; // Alpha_corr for each range - double alpha[MLX_PIXNO]; // full - with alpha_scale - double offset[MLX_PIXNO]; - double kta[MLX_PIXNO]; // full K_ta - with scale1&2 - double kv[4]; // full - with scale; 0 - odd row, odd col; 1 - odd row even col; 2 - even row, odd col; 3 - even row, even col - double cpAlpha[2]; // alpha_CP_subpage 0 and 1 - int16_t cpOffset[2]; - uint8_t outliers[MLX_PIXNO]; // outliers - bad pixels (if == 1) -} MLX90640_params; - -// default I2C address -#define MLX_DEFAULT_ADDR (0x33) -// max datalength by one read (in 16-bit values) -#define MLX_DMA_MAXLEN (832) - -void mlx90640_dump_parameters(); -int mlx90640_init(const char *dev, uint8_t ID); -int mlx90640_set_slave_address(uint8_t addr); -int mlx90640_take_image(uint8_t simple, double **image); -void mlx90640_restart(); diff --git a/MLX90640_OrangePi/mlx90640_regs.h b/MLX90640_OrangePi/mlx90640_regs.h deleted file mode 100644 index d5b657c..0000000 --- a/MLX90640_OrangePi/mlx90640_regs.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the mxl90640wPi project. - * Copyright 2022 Edward V. Emelianov . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#define REG_STATUS 0x8000 -#define REG_STATUS_OVWEN (1<<4) -#define REG_STATUS_NEWDATA (1<<3) -#define REG_STATUS_SPNO (1<<0) -#define REG_STATUS_SPMASK (3<<0) -#define REG_CONTROL 0x800D -#define REG_CONTROL_CHESS (1<<12) -#define REG_CONTROL_RES18 (2<<10) -#define REG_CONTROL_RESMASK (3<<10) -#define REG_CONTROL_REFR_05HZ (0<<7) -#define REG_CONTROL_REFR_1HZ (1<<7) -#define REG_CONTROL_REFR_2HZ (2<<7) -#define REG_CONTROL_REFR_4HZ (3<<7) -#define REG_CONTROL_REFR_8HZ (4<<7) -#define REG_CONTROL_REFR_16HZ (5<<7) -#define REG_CONTROL_REFR_32HZ (6<<7) -#define REG_CONTROL_REFR_64HZ (7<<7) -#define REG_CONTROL_SUBP1 (1<<4) -#define REG_CONTROL_SUBPMASK (3<<4) -#define REG_CONTROL_SUBPSEL (1<<3) -#define REG_CONTROL_DATAHOLD (1<<2) -#define REG_CONTROL_SUBPEN (1<<0) - -// default value -#define REG_CONTROL_DEFAULT (REG_CONTROL_CHESS|REG_CONTROL_RES18|REG_CONTROL_REFR_2HZ|REG_CONTROL_SUBPEN) - -// calibration data start & len -#define REG_CALIDATA 0x2410 -#define REG_CALIDATA_LEN 816 - -#define REG_APTATOCCS 0x2410 -#define REG_OSAVG 0x2411 -#define REG_OCCROW14 0x2412 -#define REG_OCCCOL14 0x2418 -#define REG_SCALEACC 0x2420 -#define REG_SENSIVITY 0x2421 -#define REG_ACCROW14 0x2422 -#define REG_ACCCOL14 0x2428 -#define REG_GAIN 0x2430 -#define REG_PTAT 0x2431 -#define REG_KVTPTAT 0x2432 -#define REG_VDD 0x2433 -#define REG_KVAVG 0x2434 -#define REG_ILCHESS 0x2435 -#define REG_KTAAVGODDCOL 0x2436 -#define REG_KTAAVGEVENCOL 0x2437 -#define REG_KTAVSCALE 0x2438 -#define REG_ALPHA 0x2439 -#define REG_CPOFF 0x243A -#define REG_KVTACP 0x243B -#define REG_KSTATGC 0x243C -#define REG_KSTO12 0x243D -#define REG_KSTO34 0x243E -#define REG_CT34 0x243F -#define REG_OFFAK1 0x2440 -// index of register in array (from REG_CALIDATA) -#define CREG_IDX(addr) ((addr)-REG_CALIDATA) - -#define REG_IMAGEDATA 0x0400 -#define REG_ITAVBE 0x0700 -#define REG_ICPSP0 0x0708 -#define REG_IGAIN 0x070A -#define REG_ITAPTAT 0x0720 -#define REG_ICPSP1 0x0728 -#define REG_IVDDPIX 0x072A -// indeg of register in array (from REG_IMAGEDATA) -#define IMD_IDX(addr) ((addr)-REG_IMAGEDATA) diff --git a/MLX90640_OrangePi/mxl90640OPi.cflags b/MLX90640_OrangePi/mxl90640OPi.cflags deleted file mode 100644 index 68d5165..0000000 --- a/MLX90640_OrangePi/mxl90640OPi.cflags +++ /dev/null @@ -1 +0,0 @@ --std=c17 \ No newline at end of file diff --git a/MLX90640_OrangePi/mxl90640OPi.config b/MLX90640_OrangePi/mxl90640OPi.config deleted file mode 100644 index e93f8a9..0000000 --- a/MLX90640_OrangePi/mxl90640OPi.config +++ /dev/null @@ -1,4 +0,0 @@ -#define GNU_SOURCE 1 -#define _XOPEN_SOURCE 1111 -#define EBUG - diff --git a/MLX90640_OrangePi/mxl90640OPi.creator b/MLX90640_OrangePi/mxl90640OPi.creator deleted file mode 100644 index e94cbbd..0000000 --- a/MLX90640_OrangePi/mxl90640OPi.creator +++ /dev/null @@ -1 +0,0 @@ -[General] diff --git a/MLX90640_OrangePi/mxl90640OPi.creator.user b/MLX90640_OrangePi/mxl90640OPi.creator.user deleted file mode 100644 index 88d3f4b..0000000 --- a/MLX90640_OrangePi/mxl90640OPi.creator.user +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - EnvironmentId - {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - KOI8-R - false - 4 - false - 80 - true - true - 1 - false - true - false - 0 - true - true - 0 - 8 - true - false - 1 - true - false - true - *.md, *.MD, Makefile - false - true - - - - ProjectExplorer.Project.PluginSettings - - - true - false - true - true - true - true - - - 0 - true - - true - Builtin.BuildSystem - - true - true - Builtin.DefaultTidyAndClazy - 2 - - - - true - - - - - ProjectExplorer.Project.Target.0 - - Desktop - Desktop - Desktop - {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} - 0 - 0 - 0 - - /tmp/1/home/eddy/MLX90640_wiringPi - - - - all - - true - GenericProjectManager.GenericMakeStep - - 1 - Сборка - Сборка - ProjectExplorer.BuildSteps.Build - - - - - clean - - true - GenericProjectManager.GenericMakeStep - - 1 - Очистка - Очистка - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - По умолчанию - GenericProjectManager.GenericBuildConfiguration - - 1 - - - 0 - Развёртывание - Развёртывание - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - 2 - - ProjectExplorer.CustomExecutableRunConfiguration - - false - true - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - - diff --git a/MLX90640_OrangePi/mxl90640OPi.cxxflags b/MLX90640_OrangePi/mxl90640OPi.cxxflags deleted file mode 100644 index 6435dfc..0000000 --- a/MLX90640_OrangePi/mxl90640OPi.cxxflags +++ /dev/null @@ -1 +0,0 @@ --std=c++17 \ No newline at end of file diff --git a/MLX90640_OrangePi/mxl90640OPi.files b/MLX90640_OrangePi/mxl90640OPi.files deleted file mode 100644 index d70565e..0000000 --- a/MLX90640_OrangePi/mxl90640OPi.files +++ /dev/null @@ -1,6 +0,0 @@ -cmdlnopts.c -cmdlnopts.h -main.c -mlx90640.c -mlx90640.h -mlx90640_regs.h diff --git a/MLX90640_OrangePi/mxl90640OPi.includes b/MLX90640_OrangePi/mxl90640OPi.includes deleted file mode 100644 index 774cf29..0000000 --- a/MLX90640_OrangePi/mxl90640OPi.includes +++ /dev/null @@ -1,2 +0,0 @@ -/usr/local/include -. diff --git a/stringHash4MCU_/Readme b/stringHash4MCU_/Readme index 4e7cf15..53cb74b 100644 --- a/stringHash4MCU_/Readme +++ b/stringHash4MCU_/Readme @@ -1,6 +1,7 @@ -hashtest.c allows to test different hash functions on your dictionary +hashtest.c allows to test different hash functions on your dictionary (test En_words for example) hashgen.c will generate two files by dictionary: source and header -use test.c to test generated files + +another files used for test: use script ./run for it Compile: gcc -lusefull_macro file.c -o file gcc -lusefull_macro test.c hash.c -o test diff --git a/stringHash4MCU_/hashgen.c b/stringHash4MCU_/hashgen.c index f922161..ac4ee7f 100644 --- a/stringHash4MCU_/hashgen.c +++ b/stringHash4MCU_/hashgen.c @@ -169,21 +169,39 @@ static char *fnname(const char *cmd){ } static const char *fhdr = -"int parsecmd(char *cmd, char *args){\n\ - if(!cmd || !args) return 0;\n\ - uint32_t h = hashf(cmd);\n\ - switch(h){\n" +"int parsecmd(const char *str){\n\ + char cmd[CMD_MAXLEN + 1];\n\ + if(!str || !*str) return RET_CMDNOTFOUND;\n\ + int i = 0;\n\ + while(*str > '@' && i < CMD_MAXLEN){ cmd[i++] = *str++; }\n\ + cmd[i] = 0;\n\ + if(*str){\n\ + while(*str <= ' ') ++str;\n\ + }\n\ + char *args = (char*) str;\n\ + uint32_t h = hashf(cmd);\n\ + switch(h){\n\n" ; static const char *ffooter = -" default: return 0;\n\ +" default: break;\n\ }\n\ - return 0;\n\ + return RET_CMDNOTFOUND;\n\ }\n\n" ; static const char *fns = "int fn_%s(_U_ uint32_t hash, _U_ char *args) WAL; // \"%s\" (%u)\n\n" ; -static const char *fproto = "int parsecmd(char *cmdwargs, char *args);\n\n"; +static const char *headercontent = "#ifndef _U_\n\ +#define _U_ __attribute__((__unused__))\n\ +#endif\n\n\ +#define CMD_MAXLEN (32)\n\n\ +enum{\n\ + RET_CMDNOTFOUND = -2,\n\ + RET_WRONGCMD = -1,\n\ + RET_BAD = 0,\n\ + RET_GOOD = 1\n\ +};\n\n\ +int parsecmd(const char *cmdwargs);\n\n"; static const char *sw = " case CMD_%s:\n\ return fn_%s(h, args);\n\ @@ -192,9 +210,6 @@ static const char *srchdr = "#include \n\ #include \n\ #include \"%s\"\n\n\ -#ifndef _U_\n\ -#define _U_ __attribute__((__unused__))\n\ -#endif\n\n\ #ifndef WAL\n\ #define WAL __attribute__ ((weak, alias (\"__f1\")))\n\ #endif\n\nstatic int __f1(_U_ uint32_t h, _U_ char *a){return 1;}\n\n" @@ -220,7 +235,7 @@ static void build(strhash *H, int hno, int hlen){ fprintf(source, fns, H[i].fname, H[i].str, H[i].hash); } } - fprintf(header, "%s", fproto); + fprintf(header, "%s", headercontent); fprintf(source, "%s\n", hashsources[hno]); fprintf(source, "%s", fhdr); for(int i = 0; i < hlen; ++i){ diff --git a/stringHash4MCU_/run b/stringHash4MCU_/run new file mode 100755 index 0000000..e79297c --- /dev/null +++ b/stringHash4MCU_/run @@ -0,0 +1,10 @@ +#!/bin/bash + +gcc hashgen.c -o hashgen -lusefull_macros +./hashgen -d testdic -H hdr.h -S hdr.c -F +gcc hdr.c test.c strfunc.c -o test +./test "time 54 = some" +./test "voltage12 more" +./test "esw45 = some text" +./test "goto 55 = " +./test "stop 3256" diff --git a/stringHash4MCU_/strfunc.c b/stringHash4MCU_/strfunc.c new file mode 100644 index 0000000..5b9e9f1 --- /dev/null +++ b/stringHash4MCU_/strfunc.c @@ -0,0 +1,256 @@ +#include "strfunc.h" + +/** + * @brief hexdump - dump hex array by 16 bytes in string + * @param sendfun - function to send data + * @param arr - array to dump + * @param len - length of `arr` + */ +void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len){ + char buf[52], *bptr = buf; + for(uint16_t l = 0; l < len; ++l, ++arr){ + for(int16_t j = 1; j > -1; --j){ + register uint8_t half = (*arr >> (4*j)) & 0x0f; + if(half < 10) *bptr++ = half + '0'; + else *bptr++ = half - 10 + 'a'; + } + if(l % 16 == 15){ + *bptr++ = '\n'; + *bptr = 0; + sendfun(buf); + bptr = buf; + }else *bptr++ = ' '; + } + if(bptr != buf){ + *bptr++ = '\n'; + *bptr = 0; + sendfun(buf); + } +} + +/** + * @brief _2str - convert value into string buffer + * @param val - |value| + * @param minus - ==0 if value > 0 + * @return buffer with number + */ +static char *_2str(uint32_t val, uint8_t minus){ + static char strbuf[12]; + char *bufptr = &strbuf[11]; + *bufptr = 0; + if(!val){ + *(--bufptr) = '0'; + }else{ + while(val){ + uint32_t x = val / 10; + *(--bufptr) = (val - 10*x) + '0'; + val = x; + //*(--bufptr) = val % 10 + '0'; + //val /= 10; + } + } + if(minus) *(--bufptr) = '-'; + return bufptr; +} + +// return string with number `val` +char *u2str(uint32_t val){ + return _2str(val, 0); +} +char *i2str(int32_t i){ + uint8_t minus = 0; + uint32_t val; + if(i < 0){ + minus = 1; + val = -i; + }else val = i; + return _2str(val, minus); +} + +/** + * @brief uhex2str - print 32bit unsigned int as hex + * @param val - value + * @return string with number + */ +char *uhex2str(uint32_t val){ + static char buf[12] = "0x"; + int npos = 2; + uint8_t *ptr = (uint8_t*)&val + 3; + int8_t i, j, z=1; + for(i = 0; i < 4; ++i, --ptr){ + if(*ptr == 0){ // omit leading zeros + if(i == 3) z = 0; + if(z) continue; + } + else z = 0; + for(j = 1; j > -1; --j){ + uint8_t half = (*ptr >> (4*j)) & 0x0f; + if(half < 10) buf[npos++] = half + '0'; + else buf[npos++] = half - 10 + 'a'; + } + } + buf[npos] = 0; + return buf; +} + +/** + * @brief omit_spaces - eliminate leading spaces and other trash in string + * @param buf - string + * @return - pointer to first character in `buf` > ' ' + */ +const char *omit_spaces(const char *buf){ + while(*buf){ + if(*buf > ' ') break; + ++buf; + } + return buf; +} + +/** + * @brief getdec - read decimal number & return pointer to next non-number symbol + * @param buf - string + * @param N - number read + * @return Next non-number symbol. In case of overflow return `buf` and N==0xffffffff + */ +static const char *getdec(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '9'){ + break; + } + if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow + *N = 0xffffff; + return start; + } + num *= 10; + num += c - '0'; + ++buf; + } + *N = num; + return buf; +} +// read hexadecimal number (without 0x prefix!) +static const char *gethex(const char *buf, uint32_t *N){ + const char *start = buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + uint8_t M = 0; + if(c >= '0' && c <= '9'){ + M = '0'; + }else if(c >= 'A' && c <= 'F'){ + M = 'A' - 10; + }else if(c >= 'a' && c <= 'f'){ + M = 'a' - 10; + } + if(M){ + if(num & 0xf0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 4; + num += c - M; + }else{ + break; + } + ++buf; + } + *N = num; + return buf; +} +// read octal number (without 0 prefix!) +static const char *getoct(const char *buf, uint32_t *N){ + const char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '7'){ + break; + } + if(num & 0xe0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 3; + num += c - '0'; + ++buf; + } + *N = num; + return buf; +} +// read binary number (without b prefix!) +static const char *getbin(const char *buf, uint32_t *N){ + const char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '1'){ + break; + } + if(num & 0x80000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 1; + if(c == '1') num |= 1; + ++buf; + } + *N = num; + return buf; +} + +/** + * @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111) + * @param buf - buffer with number and so on + * @param N - the number read + * @return pointer to first non-number symbol in buf + * (if it is == buf, there's no number or if *N==0xffffffff there was overflow) + */ +const char *getnum(const char *txt, uint32_t *N){ + const char *nxt = NULL; + const char *s = omit_spaces(txt); + if(*s == '0'){ // hex, oct or 0 + if(s[1] == 'x' || s[1] == 'X'){ // hex + nxt = gethex(s+2, N); + if(nxt == s+2) nxt = (char*)txt; + }else if(s[1] > '0'-1 && s[1] < '8'){ // oct + nxt = getoct(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ // 0 + nxt = s+1; + *N = 0; + } + }else if(*s == 'b' || *s == 'B'){ + nxt = getbin(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ + nxt = getdec(s, N); + if(nxt == s) nxt = (char*)txt; + } + return nxt; +} + +// get signed integer +const char *getint(const char *txt, int32_t *I){ + const char *s = omit_spaces(txt); + int32_t sign = 1; + uint32_t U; + if(*s == '-'){ + sign = -1; + ++s; + } + const char *nxt = getnum(s, &U); + if(nxt == s) return txt; + if(U & 0x80000000) return txt; // overfull + *I = sign * (int32_t)U; + return nxt; +} + +/* +void mymemcpy(char *dest, const char *src, int len){ + if(len < 1) return; + while(len--) *dest++ = *src++; +} +*/ diff --git a/stringHash4MCU_/strfunc.h b/stringHash4MCU_/strfunc.h new file mode 100644 index 0000000..a067ff8 --- /dev/null +++ b/stringHash4MCU_/strfunc.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len); +char *u2str(uint32_t val); +char *i2str(int32_t i); +char *uhex2str(uint32_t val); +const char *getnum(const char *txt, uint32_t *N); +const char *omit_spaces(const char *buf); +const char *getint(const char *txt, int32_t *I); +//void mymemcpy(char *dest, const char *src, int len); diff --git a/stringHash4MCU_/test.c b/stringHash4MCU_/test.c index 0f6f881..3dc0dda 100644 --- a/stringHash4MCU_/test.c +++ b/stringHash4MCU_/test.c @@ -2,22 +2,61 @@ #include #include -#include "hash.h" +#include "hdr.h" +#include "strfunc.h" -int fn_hello(uint32_t hash, char *args){ - printf("HELLO! Hash=%u, param=%s\n", hash, args); +static int noargs(uint32_t hash){ + switch(hash){ + case CMD_REBOOT: printf("REBOOT\n"); break; + case CMD_TIME: printf("TIME!\n"); break; + case CMD_TEMP: printf("Temp\n"); break; + default: printf("Unknown hash 0x%x\n", hash); return 0; + } return 1; } -int fn_world(uint32_t hash, char *args){ - printf("WORLD: %u - %s\n", hash, args); - return 1; +static int withparno(uint32_t hash, char *args){ + uint32_t N; + //printf("args=%s\n", args); + const char *nxt = getnum((const char*)args, &N); + if(nxt == args){ printf("need arg\n"); return RET_WRONGCMD; } + args = (char*)omit_spaces(nxt); + if(*args){ + if(*args != '='){ printf("need nothing or '=' after par\n"); return RET_WRONGCMD; } + args = (char*)omit_spaces(args+1); + // we can check in next functions what if `args` will be an empty string + } + else args = NULL; + const char *fname = NULL; + switch(hash){ + case CMD_ESW: fname = "ESW"; break; + case CMD_GOTO: fname = "GOTO"; break; + case CMD_POS: fname = "POS"; break; + case CMD_STOP: fname = "STOP"; break; + default: fname = "unknown"; + } + if(!args) printf("We want a getter '%s' with par %u\n", fname, N); + else printf("We want a setter '%s' with par %u and arg '%s'\n", fname, N, args); + if(N > 255){ printf("N should be 0..255\n"); return RET_BAD;} + return RET_GOOD; } +// these functions should be global to substitute weak aliases +int fn_esw(uint32_t hash, char *args){return withparno(hash, args);} +int fn_goto(uint32_t hash, char *args){return withparno(hash, args);} +int fn_pos(uint32_t hash, char *args){return withparno(hash, args);} +int fn_stop(uint32_t hash, char *args){return withparno(hash, args);} +int fn_voltage(uint32_t hash, char *args){return withparno(hash, args);} +int fn_reboot(uint32_t hash, _U_ char *args){return noargs(hash);} +int fn_time(uint32_t hash, _U_ char *args){return noargs(hash);} +int fn_temp(uint32_t hash, _U_ char *args){return noargs(hash);} int main(int argc, char **argv){ - if(argc < 2) return 1; - char *args = ""; - if(argc > 2) args = argv[2]; - if(!parsecmd(argv[1], args)) printf("%s not found\n", argv[1]); - else printf("All OK\n"); + if(argc != 2) return 1; + int ret = parsecmd(argv[1]); + switch(ret){ + case RET_CMDNOTFOUND: printf("'%s' not found\n", argv[1]); break; + case RET_WRONGCMD: printf("Wrong sintax of '%s'\n", argv[1]); break; + case RET_GOOD: printf("'%s' - OK\n", argv[1]); break; + default: printf("'%s' - bad\n", argv[1]); + } return 0; } diff --git a/stringHash4MCU_/testdic b/stringHash4MCU_/testdic index 153cc32..bb2b5b1 100644 --- a/stringHash4MCU_/testdic +++ b/stringHash4MCU_/testdic @@ -1,13 +1,8 @@ -hello -world -what -put -sim key -change ip -change param -set - clear -reset - get -out -in +pos +temp +voltage +time +reboot +stop +goto +esw