From e16407d773929ec6efc97a187e5494cbee13a0ea Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Wed, 21 Aug 2024 18:52:53 +0300 Subject: [PATCH] More code, but sensor seems dead: don't run antenna --- LightningSensor/Makefile | 2 +- LightningSensor/as3935.c | 121 +++++++++++++++++-------- LightningSensor/as3935.h | 36 ++++++-- LightningSensor/lightning.creator.user | 2 +- LightningSensor/main.c | 120 +++++++++++++++++++++++- 5 files changed, 233 insertions(+), 48 deletions(-) diff --git a/LightningSensor/Makefile b/LightningSensor/Makefile index bf7f58d..d47481c 100644 --- a/LightningSensor/Makefile +++ b/LightningSensor/Makefile @@ -1,7 +1,7 @@ # run `make DEF=...` to add extra defines PROGRAM := lightning LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all -LDFLAGS += -lusefull_macros +LDFLAGS += -lusefull_macros -lm SRCS := $(wildcard *.c) DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111 OBJDIR := mk diff --git a/LightningSensor/as3935.c b/LightningSensor/as3935.c index 497aa68..042c878 100644 --- a/LightningSensor/as3935.c +++ b/LightningSensor/as3935.c @@ -16,49 +16,94 @@ * along with this program. If not, see . */ -#pragma once +#include +#include #include "as3935.h" #include "i2c.h" static int dev_fd = -1; +#define I2Cread(reg, val) i2c_read_reg(dev_fd, reg, (uint8_t*)val) +#define I2Cwrite(reg, val) i2c_write_reg(dev_fd, reg, (uint8_t)val) + // open device and set slave address int as3935_open(const char *path, uint8_t id){ dev_fd = i2c_open(path); if(dev_fd < 0) return FALSE; if(!i2c_set_slave_address(dev_fd, id)){ - WARNX("Can't set slave address 0x%02x", G.slaveaddr); + WARNX("Can't set slave address 0x%02x", id); return FALSE; } - return as3935_wakeup(); + return TRUE; } // common getter int as3935_getter(uint8_t reg, uint8_t *data){ - return i2c_read_reg(dev_fd, reg, data); + return I2Cread(reg, data); } // and common setter int as3935_setter(uint8_t reg, uint8_t data){ - return i2c_write_reg(dev_fd, reg, data); + return I2Cwrite(reg, data); } +// display ont IRQ: nothing (0), TRCO (1), SRCO (2) or LCO (3) +int as3935_displco(uint8_t n){ + if(n > 3) return FALSE; + t_tun_disp t; + if(!I2Cread(TUN_DISP, &t)) return FALSE; + t.DISP_LCO = t.DISP_SRCO = t.DISP_TRCO = 0; + switch(n){ + case 1: + t.DISP_TRCO = 1; + break; + case 2: + t.DISP_SRCO = 1; + break; + case 3: + t.DISP_LCO = 1; + break; + default: + break; + } + return I2Cwrite(TUN_DISP, t.u8); +} + +// tune LCO: change capasitor value +int as3935_tuncap(uint8_t n){ + if(n > 0xf) return FALSE; + t_tun_disp t; + if(!I2Cread(TUN_DISP, &t)) return FALSE; + t.TUN_CAP = n; + return I2Cwrite(TUN_DISP, t.u8); +} + +// set gain +int as3935_gain(uint8_t n){ + if(n > 0x1f) return FALSE; + t_afe_gain g; + if(!I2Cread(AFE_GAIN, &g)) return FALSE; + g.AFE_GB = n; + return I2Cwrite(AFE_GAIN, g.u8); +} // starting calibration int as3935_calib_rco(){ t_tun_disp t; - if(!i2c_read_reg(dev_fd, TUN_DISP, &t)) return FALSE; - if(!i2c_write_reg(dev_fd, CALIB_RCO, DIRECT_COMMAND)) return FALSE; + if(!I2Cread(TUN_DISP, &t)) return FALSE; + if(!I2Cwrite(CALIB_RCO, DIRECT_COMMAND)) return FALSE; + t.DISP_LCO = t.DISP_TRCO = 0; t.DISP_SRCO = 1; - if(!i2c_write_reg(dev_fd, TUN_DISP, &t)) return FALSE; + if(!I2Cwrite(TUN_DISP, t.u8)) return FALSE; double t0 = dtime(); - while(dtime() - t0 < 0.002); + while(dtime() - t0 < 0.005); t.DISP_SRCO = 0; - if(!i2c_write_reg(dev_fd, TUN_DISP, &t)) return FALSE; + if(!I2Cwrite(TUN_DISP, t.u8)) return FALSE; t_calib srco, trco; - if(!i2c_read_reg(dev_fd, CALIB_TRCO, &trco)) return FALSE; - if(!i2c_read_reg(dev_fd, CALIB_SRCO, &srco)) return FALSE; + if(!I2Cread(CALIB_TRCO, &trco)) return FALSE; + if(!I2Cread(CALIB_SRCO, &srco)) return FALSE; + DBG("srco=%d, trco=%d", srco.u8, trco.u8); if(!srco.CALIB_DONE || !trco.CALIB_DONE) return FALSE; return TRUE; } @@ -66,10 +111,10 @@ int as3935_calib_rco(){ // wakeup - call this function after first run int as3935_wakeup(){ t_afe_gain g; - if(!i2c_read_reg(dev_fd, AFE_GAIN, &g)) return FALSE; + if(!I2Cread(AFE_GAIN, &g)) return FALSE; g.PWD = 0; - if(!i2c_write_reg(dev_fd, AFE_GAIN, g)) return FALSE; - return as3935_calib_rco; + if(!I2Cwrite(AFE_GAIN, g.u8)) return FALSE; + return as3935_calib_rco(); } // set amplifier gain @@ -77,59 +122,58 @@ int as3935_set_gain(uint8_t g){ if(g > 0x1f) return FALSE; t_afe_gain a = {0}; a.AFE_GB = g; - return i2c_write_reg(dev_fd, AFE_GAIN, a); + return I2Cwrite(AFE_GAIN, a.u8); } // watchdog threshold int as3935_wdthres(uint8_t t){ if(t > 0x0f) return FALSE; t_threshold thres; - if(!i2c_read_reg(dev_fd, THRESHOLD, &thres)) return FALSE; + if(!I2Cread(THRESHOLD, &thres)) return FALSE; thres.WDTH = t; - return i2c_write_reg(dev_fd, THRESHOLD, thres); + return I2Cwrite(THRESHOLD, thres.u8); } // noice floor level int as3935_nflev(uint8_t l){ if(l > 7) return FALSE; t_threshold thres; - if(!i2c_read_reg(dev_fd, THRESHOLD, &thres)) return FALSE; + if(!I2Cread(THRESHOLD, &thres)) return FALSE; thres.NF_LEV = l; - return i2c_write_reg(dev_fd, THRESHOLD, thres); + return I2Cwrite(THRESHOLD, thres.u8); } // spike rejection int as3935_srej(uint8_t s){ if(s > 0xf) return FALSE; t_lightning_reg lr; - if(!i2c_read_reg(dev_fd, LIGHTNING_REG, &lr)) return FALSE; + if(!I2Cread(LIGHTNING_REG, &lr)) return FALSE; lr.SREJ = s; - return i2c_write_reg(dev_fd, LIGHTNING_REG, lr); + return I2Cwrite(LIGHTNING_REG, lr.u8); } // minimal lighting number int as3935_minnumlig(uint8_t n){ if(n > 3) return FALSE; t_lightning_reg lr; - if(!i2c_read_reg(dev_fd, LIGHTNING_REG, &lr)) return FALSE; + if(!I2Cread(LIGHTNING_REG, &lr)) return FALSE; lr.MIN_NUM_LIG = n; - return i2c_write_reg(dev_fd, LIGHTNING_REG, lr); + return I2Cwrite(LIGHTNING_REG, lr.u8); } // clear amount of lightnings for last 15 min int as3935_clearstat(){ - if(n > 3) return FALSE; t_lightning_reg lr; - if(!i2c_read_reg(dev_fd, LIGHTNING_REG, &lr)) return FALSE; + if(!I2Cread(LIGHTNING_REG, &lr)) return FALSE; lr.CL_STAT = 1; - return i2c_write_reg(dev_fd, LIGHTNING_REG, lr); + return I2Cwrite(LIGHTNING_REG, lr.u8); } // get interrupt code int as3935_intcode(uint8_t *code){ if(!code) return FALSE; t_int_mask_ant i; - if(!i2c_read_reg(dev_fd, INT_MASK_ANT, &i)) return FALSE; + if(!I2Cread(INT_MASK_ANT, &i)) return FALSE; *code = i.INT; return TRUE; } @@ -138,18 +182,18 @@ int as3935_intcode(uint8_t *code){ int as3935_mask_disturber(uint8_t m){ if(m > 1) return FALSE; t_int_mask_ant i; - if(!i2c_read_reg(dev_fd, INT_MASK_ANT, &i)) return FALSE; + if(!I2Cread(INT_MASK_ANT, &i)) return FALSE; i.MASK_DIST = m; - return i2c_write_reg(dev_fd, INT_MASK_ANT, i); + return I2Cwrite(INT_MASK_ANT, i.u8); } // set Fdiv of antenna LCO int as3935_lco_fdiv(uint8_t d){ if(d > 3) return FALSE; t_int_mask_ant i; - if(!i2c_read_reg(dev_fd, INT_MASK_ANT, &i)) return FALSE; + if(!I2Cread(INT_MASK_ANT, &i)) return FALSE; i.LCO_FDIV = d; - return i2c_write_reg(dev_fd, INT_MASK_ANT, i); + return I2Cwrite(INT_MASK_ANT, i.u8); } // calculate last lightning energy @@ -157,22 +201,27 @@ int as3935_energy(uint32_t *E){ if(!E) return FALSE; uint8_t u8; uint32_t energy; t_s_lig_mm mm; - if(!i2c_read_reg(dev_fd, S_LIG_MM, &mm)) return FALSE; + if(!I2Cread(S_LIG_MM, &mm)) return FALSE; energy = mm.S_LIG_MM << 8; - if(!i2c_read_reg(dev_fd, S_LIG_M, &u8)) return FALSE; + if(!I2Cread(S_LIG_M, &u8)) return FALSE; energy |= u8; energy <<= 8; - if(!i2c_read_reg(dev_fd, S_LIG_L, &u8)) return FALSE; + if(!I2Cread(S_LIG_L, &u8)) return FALSE; energy |= u8; *E = energy; return TRUE; } +// get distance int as3935_distance(uint8_t *d){ if(!d) return FALSE; t_distance dist; - if(!i2c_read_reg(dev_fd, DISTANCE, &dist)) return FALSE; + if(!I2Cread(DISTANCE, &dist)) return FALSE; *d = dist.DISTANCE; return TRUE; } +// reset to factory settings +int as3935_resetdef(){ + return I2Cwrite(PRESET_DEFAULT, DIRECT_COMMAND); +} diff --git a/LightningSensor/as3935.h b/LightningSensor/as3935.h index b063610..a8d86e8 100644 --- a/LightningSensor/as3935.h +++ b/LightningSensor/as3935.h @@ -38,19 +38,24 @@ enum AS3935_REGISTERS{ // REGISTERS -typedef struct{ +typedef union{ + struct{ uint8_t PWD : 1; uint8_t AFE_GB : 5; uint8_t RESERVED : 2; + }; uint8_t u8; } t_afe_gain; -typedef struct{ +typedef union{ + struct{ uint8_t WDTH : 4; uint8_t NF_LEV : 3; uint8_t RESERVED : 1; + }; uint8_t u8; } t_threshold; -typedef struct{ +typedef union{ + struct{ uint8_t SREJ : 4; // minimal number of lightnings #define NUM_LIG_1 (0) @@ -60,9 +65,11 @@ typedef struct{ uint8_t MIN_NUM_LIG : 2; uint8_t CL_STAT : 1; uint8_t RESERVED : 1; + }; uint8_t u8; } t_lightning_reg; -typedef struct{ +typedef union{ + struct{ // interrupt flags // noice level too high #define INT_NH (1) @@ -74,30 +81,39 @@ typedef struct{ uint8_t RESERVED : 1; uint8_t MASK_DIST : 1; uint8_t LCO_FDIV : 2; + }; uint8_t u8; } t_int_mask_ant; -typedef struct{ +typedef union{ + struct{ uint8_t S_LIG_MM : 5; uint8_t RESERVED : 3; + }; uint8_t u8; } t_s_lig_mm; -typedef struct{ +typedef union{ + struct{ uint8_t DISTANCE : 6; uint8_t RESERVED : 2; + }; uint8_t u8; } t_distance; -typedef struct{ +typedef union{ + struct{ uint8_t TUN_CAP : 4; uint8_t RESERVED : 1; uint8_t DISP_TRCO : 1; uint8_t DISP_SRCO : 1; uint8_t DISP_LCO : 1; + }; uint8_t u8; } t_tun_disp; -typedef struct{ +typedef union{ + struct{ uint8_t RESERVED : 6; uint8_t CALIB_NOK : 1; uint8_t CALIB_DONE : 1; + }; uint8_t u8; } t_calib; // direct command send to PRESET_DEFAULT and CALIB_RCO @@ -108,6 +124,9 @@ typedef struct{ int as3935_open(const char *path, uint8_t id); int as3935_getter(uint8_t reg, uint8_t *data); int as3935_setter(uint8_t reg, uint8_t data); +int as3935_displco(uint8_t n); +int as3935_tuncap(uint8_t n); +int as3935_gain(uint8_t n); int as3935_wakeup(); int as3935_calib_rco(); int as3935_set_gain(uint8_t g); @@ -121,3 +140,4 @@ int as3935_mask_disturber(uint8_t m); int as3935_lco_fdiv(uint8_t d); int as3935_energy(uint32_t *E); int as3935_distance(uint8_t *d); +int as3935_resetdef(); diff --git a/LightningSensor/lightning.creator.user b/LightningSensor/lightning.creator.user index d898ea0..f66d763 100644 --- a/LightningSensor/lightning.creator.user +++ b/LightningSensor/lightning.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/LightningSensor/main.c b/LightningSensor/main.c index eaeb96c..8b11e38 100644 --- a/LightningSensor/main.c +++ b/LightningSensor/main.c @@ -23,23 +23,115 @@ typedef struct{ char *device; + int gain; int slaveaddr; int verbose; + int wakeup; + int dumpregs; + int monitnew; + int reset; int help; + int tunelco; + int irqdisp; + int lcofdiv; char *logfile; } glob_pars; -static glob_pars G = {.device = "/dev/i2c-3", .slaveaddr = 0}; +static glob_pars G = { + .device = "/dev/i2c-0", + .gain = -1, + .irqdisp = -1, + .lcofdiv = -1, + .slaveaddr = 0, + .tunelco=-1, +}; static myoption cmdlnopts[] = { {"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), "I2C device path"}, + {"dumpregs",NO_ARGS, NULL, 'D', arg_int, APTR(&G.dumpregs), "dump all registers of device"}, + {"fdiv", NEED_ARG, NULL, 'f', arg_int, APTR(&G.lcofdiv), "change LCO_FDIV value"}, + {"gain", NEED_ARG, NULL, 'g', arg_int, APTR(&G.gain), "change AFE_GB (gain) value"}, {"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"}, + {"irqdisp", NEED_ARG, NULL, 0, arg_int, APTR(&G.irqdisp), "show LCO on IRQ: nothing (0), TRCO (1), SRCO (2) or LCO (3)"}, + {"monitnew",NO_ARGS, NULL, 'n', arg_int, APTR(&G.monitnew), "monitor changed values"}, {"slave", NEED_ARG, NULL, 'a', arg_int, APTR(&G.slaveaddr), "I2C slave address"}, {"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose), "Verbose (each -v increase)"}, {"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), "file for logging"}, + {"reset", NO_ARGS, NULL, 'R', arg_int, APTR(&G.reset), "reset to factory settings"}, + {"tunelco", NEED_ARG, NULL, 't', arg_int, APTR(&G.tunelco), "tune LCO with given value"}, + {"wakeup", NO_ARGS, NULL, 'w', arg_int, APTR(&G.wakeup), "wakeup device"}, end_option }; +#ifndef STRINGIFY +#define STRINGIFY(x) #x +#endif +static uint8_t oldvals[256] = {0}; +#define TRY(reg) if(as3935_getter(reg, &u8)){if(!onlynew || u8 != oldvals[reg]){ green(STRINGIFY(reg) ": "); oldvals[reg] = u8; +#define EL(reg) }}else WARNX("Can't read " STRINGIFY(reg) ); +void dumpregs(int onlynew){ + uint8_t u8; + TRY(AFE_GAIN) + t_afe_gain g = (t_afe_gain)u8; + printf("PWD=%d, AFE_GB=%d\n", g.PWD, g.AFE_GB); + EL(AFE_GAIN) + TRY(THRESHOLD) + t_threshold t = (t_threshold) u8; + printf("WDTH=%d, NF_LEV=%d\n", t.WDTH, t.NF_LEV); + EL(THRESHOLD) + TRY(LIGHTNING_REG) + t_lightning_reg l = (t_lightning_reg) u8; + printf("SREJ=%d, MIN_NUM_LIG=%d, CL_STAT=%d\n", l.SREJ, l.MIN_NUM_LIG, l.CL_STAT); + EL(LIGHTNING_REG) + TRY(INT_MASK_ANT) + t_int_mask_ant i = (t_int_mask_ant) u8; + printf("INT=%d ", i.INT); + const char *intw; + switch(i.INT){ + case 0: + intw = "no interrupts"; + break; + case INT_NH: + intw = "noice too high"; + break; + case INT_D: + intw = "disturber"; + break; + case INT_L: + intw = "lightning"; + break; + default: intw = "unknown"; + } + printf("(%s), MASK_DIST=%d, LCO_FDIV=%d\n", intw, i.MASK_DIST, i.LCO_FDIV); + EL(INT_MASK_ANT) + TRY(S_LIG_L) + printf("%d\n", u8); + EL(S_LIG_L) + TRY(S_LIG_M) + printf("%d\n", u8); + EL(S_LIG_M) + TRY(S_LIG_MM) + printf("%d\n", u8); + EL(S_LIG_MM) + TRY(DISTANCE) + printf("%d\n", u8); + EL(DISTANCE) + TRY(TUN_DISP) + t_tun_disp t = (t_tun_disp) u8; + printf("TUN_CAP=%d, DISP_TRCO=%d, DISP_SRCO=%d, DISP_LCO=%d\n", t.TUN_CAP, t.DISP_TRCO, t.DISP_SRCO, t.DISP_LCO); + EL(TUN_DISP) + TRY(CALIB_TRCO) + t_calib c = (t_calib) u8; + printf("CALIB_NOK=%d, CALIB_DONE=%d\n", c.CALIB_NOK, c.CALIB_DONE); + EL(CALIB_TRCO) + TRY(CALIB_SRCO) + t_calib c = (t_calib) u8; + printf("CALIB_NOK=%d, CALIB_DONE=%d\n", c.CALIB_NOK, c.CALIB_DONE); + EL(CALIB_SRCO) +} +#undef TRY +#undef EL + int main(int argc, char **argv){ initial_setup(); parseargs(&argc, &argv, cmdlnopts); @@ -55,7 +147,31 @@ int main(int argc, char **argv){ if(!globlog) ERRX("Can't open logfile %s", G.logfile); } LOGMSG("Connected to slave 0x%02x\n", G.slaveaddr); - ; + if(G.dumpregs || G.monitnew) dumpregs(0); + if(G.reset) if(!as3935_resetdef()) ERRX("Can't reset to default settings"); + if(G.wakeup){ + if(!as3935_wakeup()) ERRX("Can't wakeup sensor"); + } + if(G.gain > -1){ + if(!as3935_gain(G.gain)) ERRX("Can't set gain"); + else green("AFE_GB=%d\n", G.gain); + } + if(G.irqdisp > -1){ + if(!as3935_displco(G.irqdisp)) ERRX("Can't change DISP_xx"); + else green("DISP changed\n"); + } + if(G.tunelco > -1){ + if(!as3935_tuncap(G.tunelco)) ERRX("Can't set TUN_CAP to %d", G.tunelco); + else green("TUN_CAP = %d\n", G.tunelco); + } + if(G.lcofdiv > -1){ + if(!as3935_lco_fdiv(G.lcofdiv)) ERRX("Can't change FDIV"); + else green("LCO_FDIV=%d\n", G.lcofdiv); + } + if(G.monitnew) while(1){ + dumpregs(1); + sleep(1); + } return 0; }