Works for 5 sensors

This commit is contained in:
Edward Emelianov
2025-09-24 23:36:46 +03:00
parent 02c6bd124f
commit ca0b52493f
12 changed files with 249 additions and 172 deletions

View File

@@ -21,8 +21,20 @@
#include "i2c.h"
#include "mlxproc.h"
#include "mlx90640_regs.h"
//#define DEBUGPROC
#ifdef DEBUGPROC
#include "usb_dev.h"
#include "strfunc.h"
#define D(x) U(x)
#define DN(x) USND(x)
#define DB(x) USB_putbute(x)
#else
#define D(x)
#define DN(x)
#define DB(x)
#endif
extern volatile uint32_t Tms;
@@ -32,11 +44,19 @@ static int errctr = 0; // errors counter - cleared by mlx_continue
static uint32_t Tlastimage[N_SESORS] = {0};
// subpages and configs of all sensors
// 8320 bytes:
static int16_t imdata[N_SESORS][REG_IMAGEDATA_LEN];
// 8340 bytes:
static uint16_t confdata[N_SESORS][MLX_DMA_MAXLEN];
static uint8_t sens_addresses[N_SESORS] = {0x10<<1, 0x11<<1, 0x12<<1, 0x13<<1, 0x14<<1}; // addresses of all sensors (if 0 - omit this one)
static uint8_t sensaddr[N_SESORS];
// get compile-time size: (gcc shows it in error message)
//char (*__kaboom)[sizeof( confdata )] = 1;
// return `sensaddr`
uint8_t *mlx_activeids(){return sensaddr;}
static int sensno = -1;
// get current state
@@ -54,12 +74,14 @@ void mlx_pause(){
MLX_oldstate = MLX_state;
MLX_state = MLX_RELAX;
}
// TODO: add here power management
void mlx_stop(){
MLX_oldstate = MLX_NOTINIT;
MLX_state = MLX_RELAX;
}
// continue processing
// TODO: add here power management
void mlx_continue(){
errctr = 0;
switch(MLX_oldstate){
@@ -70,6 +92,7 @@ void mlx_continue(){
//case MLX_NOTINIT:
//case MLX_WAITPARAMS:
default:
i2c_setup(i2c_curspeed); // restart I2C (what if there was errors?)
memcpy(sensaddr, sens_addresses, sizeof(sens_addresses));
MLX_state = MLX_NOTINIT;
sensno = -1;
@@ -85,7 +108,7 @@ static int nextsensno(int s){
int next = s + 1;
for(; next < N_SESORS; ++next) if(sensaddr[next]) break;
if(next == N_SESORS) return nextsensno(-1); // roll to start
U(i2str(next)); USND(" - new sensor number");
D(i2str(next)); DB('('); D(i2str(s)); DB(')'); DN(" - new sensor number");
return next;
}
@@ -115,20 +138,20 @@ void mlx_process(){
switch(MLX_state){
case MLX_NOTINIT: // start reading parameters
if(i2c_read_reg16(sensaddr[sensno], REG_CALIDATA, MLX_DMA_MAXLEN, 1)){
U(i2str(sensno)); USND(" wait conf");
D(i2str(sensno)); DN(" wait conf");
errctr = 0;
MLX_state = MLX_WAITPARAMS;
}else ++errctr;
break;
case MLX_WAITPARAMS: // check DMA ends and calculate parameters
if(i2c_dma_haderr()){ MLX_state = MLX_NOTINIT; USND("DMA err");}
if(i2c_dma_haderr()){ MLX_state = MLX_NOTINIT; DN("DMA err");}
else{
uint16_t len, *buf = i2c_dma_getbuf(&len);
if(buf) USND("READ");
else break;
if(!buf) break;
DN("READ");
if(len != MLX_DMA_MAXLEN){ MLX_state = MLX_NOTINIT; break; }
memcpy(confdata[sensno], buf, MLX_DMA_MAXLEN * sizeof(uint16_t));
U(i2str(sensno)); USND(" got conf");
D(i2str(sensno)); DN(" got conf");
int next = nextsensno(sensno);
errctr = 0;
if(next <= sensno) MLX_state = MLX_WAITSUBPAGE; // all configuration read
@@ -143,14 +166,20 @@ void mlx_process(){
if(subpage == (*got & REG_STATUS_SPNO)){
errctr = 0;
if(subpage == 0){ // omit zero subpage for each sensor
DN("omit 0 -> next sens");
int next = nextsensno(sensno);
if(next <= sensno) subpage = 1; // all scanned - now wait for page 1
if(next <= sensno){ // all scanned - now wait for page 1
subpage = 1;
DN("Wait for 1");
}
sensno = next;
break;
}
D(i2str(sensno)); DN(" - ask for image");
if(i2c_read_reg16(sensaddr[sensno], REG_IMAGEDATA, REG_IMAGEDATA_LEN, 1)){
errctr = 0;
MLX_state = MLX_READSUBPAGE;
// U("spstart"); USB_putbyte('0'+subpage); USB_putbyte('='); USND(u2str(Tms - Tlast));
// D("spstart"); DB('0'+subpage); DB('='); DN(u2str(Tms - Tlast));
}else ++errctr;
}
}else ++errctr;
@@ -161,17 +190,21 @@ void mlx_process(){
else{
uint16_t len, *buf = i2c_dma_getbuf(&len);
if(buf){
// U("spread="); USND(u2str(Tms - Tlast));
// D("spread="); DN(u2str(Tms - Tlast));
if(len != REG_IMAGEDATA_LEN){
++errctr;
}else{ // fine! we could check next sensor
errctr = 0;
memcpy(imdata[sensno], buf, REG_IMAGEDATA_LEN * sizeof(int16_t));
// U("spgot="); USND(u2str(Tms - Tlast));
// D("spgot="); DN(u2str(Tms - Tlast));
Tlastimage[sensno] = Tms;
// U("imgot="); USND(u2str(Tms - Tlast)); Tlast = Tms;
// D("imgot="); DN(u2str(Tms - Tlast)); Tlast = Tms;
int next = nextsensno(sensno);
if(next <= sensno) subpage = 0; // roll to start - omit page 0 for all
if(next <= sensno){
subpage = 0; // roll to start - omit page 0 for all
DN("All got -> start from 0");
}
sensno = next;
}
MLX_state = MLX_WAITSUBPAGE;
}
@@ -180,7 +213,7 @@ void mlx_process(){
default:
return;
}
if(MLX_state != MLX_RELAX && Tms - Tlastimage[sensno] > MLX_I2CERR_TMOUT){ i2c_setup(i2c_curspeed); Tlastimage[sensno] = Tms; }
//if(MLX_state != MLX_RELAX && Tms - Tlastimage[sensno] > MLX_I2CERR_TMOUT){ i2c_setup(i2c_curspeed); Tlastimage[sensno] = Tms; }
if(errctr > MLX_MAX_ERRORS){
errctr = 0;
sensaddr[sensno] = 0; // throw out this value
@@ -189,19 +222,18 @@ void mlx_process(){
}
// recalculate parameters
int mlx_getparams(int n, MLX90640_params *pars){
if(!pars) return 0;
if(!get_parameters(confdata[n], pars)) return 0;
return 1;
MLX90640_params *mlx_getparams(int n){
MLX90640_params *p = get_parameters(confdata[n]);
return p;
}
uint32_t mlx_lastimT(int n){ return Tlastimage[n]; }
fp_t *mlx_getimage(int n){
if(n < 0 || n >= N_SESORS || !sensaddr[n]) return NULL;
MLX90640_params p;
if(!get_parameters(confdata[n], &p)) return NULL;
fp_t *ready_image = process_image(&p, imdata[n]);
MLX90640_params *p = get_parameters(confdata[n]);
if(!p) return NULL;
fp_t *ready_image = process_image(imdata[n]);
if(!ready_image) return NULL;
return ready_image;
}
@@ -212,7 +244,7 @@ int mlx_sethwaddr(uint8_t MLX_address, uint8_t addr){
if(addr > 0x7f) return 0;
uint16_t data[2], *ptr;
if(!(ptr = i2c_read_reg16(MLX_address, REG_MLXADDR, 1, 0))) return 0;
//U("Old address: "); USND(uhex2str(*ptr));
//D("Old address: "); DN(uhex2str(*ptr));
data[0] = REG_MLXADDR; data[1] = 0;
uint16_t oldreg = *ptr;
if(!i2c_write(MLX_address, data, 2)) return 0; // clear address
@@ -227,11 +259,11 @@ int mlx_sethwaddr(uint8_t MLX_address, uint8_t addr){
}
data[0] = REG_MLXADDR; // i2c_write swaps bytes, so we need init data again
data[1] = (oldreg & ~REG_MLXADDR_MASK) | addr;
//U("Write address: "); U(uhex2str(data[0])); U(", "); USND(uhex2str(data[1]));
//D("Write address: "); D(uhex2str(data[0])); D(", "); DN(uhex2str(data[1]));
if(!i2c_write(MLX_address, data, 2)) return 0;
while(Tms - Told < 10);
if(!(ptr = i2c_read_reg16(MLX_address, REG_MLXADDR, 1, 0))) return 0;
//U("Got address: "); USND(uhex2str(*ptr));
//D("Got address: "); DN(uhex2str(*ptr));
if((*ptr & REG_MLXADDR_MASK) != addr) return 0;
return 1;
}