mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 02:35:23 +03:00
cont
This commit is contained in:
parent
2465cd9bd4
commit
02c6bd124f
@ -44,7 +44,7 @@ static volatile uint16_t dma_remain = 0; // remain bytes of DMA read/write
|
|||||||
static inline int isI2Cbusy(){
|
static inline int isI2Cbusy(){
|
||||||
cntr = Tms;
|
cntr = Tms;
|
||||||
do{
|
do{
|
||||||
if(Tms - cntr > I2C_TIMEOUT){ U("Timeout, DMA transfer in progress?"); return 1;}
|
if(Tms - cntr > I2C_TIMEOUT){ USND("Timeout, DMA transfer in progress?"); return 1;}
|
||||||
}while(I2Cbusy);
|
}while(I2Cbusy);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -329,6 +329,7 @@ void i2c_bufdudump(){
|
|||||||
|
|
||||||
// get DMA buffer with conversion to little-endian (if transfer was for 16-bit)
|
// get DMA buffer with conversion to little-endian (if transfer was for 16-bit)
|
||||||
uint16_t *i2c_dma_getbuf(uint16_t *len){
|
uint16_t *i2c_dma_getbuf(uint16_t *len){
|
||||||
|
if(i2c_got_DMA) USND("DMA GOT!");
|
||||||
if(!i2c_got_DMA || i2cbuflen < 1) return NULL;
|
if(!i2c_got_DMA || i2cbuflen < 1) return NULL;
|
||||||
i2c_got_DMA = 0;
|
i2c_got_DMA = 0;
|
||||||
i2cbuflen >>= 1; // for hexdump16 - now buffer have uint16_t!
|
i2cbuflen >>= 1; // for hexdump16 - now buffer have uint16_t!
|
||||||
|
|||||||
@ -44,7 +44,8 @@ int main(void){
|
|||||||
i2c_setup(I2C_SPEED_100K);
|
i2c_setup(I2C_SPEED_100K);
|
||||||
USB_setup();
|
USB_setup();
|
||||||
USBPU_ON();
|
USBPU_ON();
|
||||||
uint32_t ctr = Tms, Tlastima = 0;
|
uint32_t ctr = Tms, Tlastima[N_SESORS] = {0};
|
||||||
|
mlx_continue(); // init state machine
|
||||||
while(1){
|
while(1){
|
||||||
if(Tms - ctr > 499){
|
if(Tms - ctr > 499){
|
||||||
ctr = Tms;
|
ctr = Tms;
|
||||||
@ -66,13 +67,13 @@ int main(void){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mlx_process();
|
mlx_process();
|
||||||
if(cartoon){
|
if(cartoon) for(int i = 0; i < N_SESORS; ++i){
|
||||||
uint32_t Tnow = mlx_lastimT();
|
uint32_t Tnow = mlx_lastimT(i);
|
||||||
if(Tnow != Tlastima){
|
if(Tnow != Tlastima[i]){
|
||||||
fp_t *i = mlx_getimage(&Tnow);
|
fp_t *im = mlx_getimage(i);
|
||||||
if(i){
|
if(im){
|
||||||
U("Timage="); USND(u2str(Tnow)); drawIma(i);
|
U("Timage="); USND(u2str(Tnow)); drawIma(im);
|
||||||
Tlastima = Tnow;
|
Tlastima[i] = Tnow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@ -264,7 +264,8 @@ int get_parameters(const uint16_t dataarray[MLX_DMA_MAXLEN], MLX90640_params *pa
|
|||||||
fp_t *process_image(const MLX90640_params *params, const int16_t subpage1[REG_IMAGEDATA_LEN]){
|
fp_t *process_image(const MLX90640_params *params, const int16_t subpage1[REG_IMAGEDATA_LEN]){
|
||||||
#define IMD_VAL(reg) subpage1[IMD_IDX(reg)]
|
#define IMD_VAL(reg) subpage1[IMD_IDX(reg)]
|
||||||
// 11.2.2.1. Resolution restore
|
// 11.2.2.1. Resolution restore
|
||||||
fp_t resol_corr = (fp_t)(1<<params->resolEE) / (1<<mlx_getresolution()); // calibrated resol/current resol
|
//fp_t resol_corr = (fp_t)(1<<params->resolEE) / (1<<mlx_getresolution()); // calibrated resol/current resol
|
||||||
|
fp_t resol_corr = (fp_t)(1<<params->resolEE) / (1<<2); // ONLY DEFAULT!
|
||||||
int16_t i16a;
|
int16_t i16a;
|
||||||
fp_t dvdd, dTa, Kgain, pixOS[2]; // values for both subpages
|
fp_t dvdd, dTa, Kgain, pixOS[2]; // values for both subpages
|
||||||
// 11.2.2.2. Supply voltage value calculation
|
// 11.2.2.2. Supply voltage value calculation
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 17.0.1, 2025-09-22T23:16:50. -->
|
<!-- Written by QtCreator 17.0.1, 2025-09-23T22:23:26. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@ -21,36 +21,44 @@
|
|||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "mlxproc.h"
|
#include "mlxproc.h"
|
||||||
#include "mlx90640_regs.h"
|
#include "mlx90640_regs.h"
|
||||||
//#include "usb_dev.h"
|
#include "usb_dev.h"
|
||||||
//#include "strfunc.h"
|
#include "strfunc.h"
|
||||||
|
|
||||||
extern volatile uint32_t Tms;
|
extern volatile uint32_t Tms;
|
||||||
|
|
||||||
// current state and state before `stop` called
|
// current state and state before `stop` called
|
||||||
static mlx_state_t MLX_state = MLX_NOTINIT, MLX_oldstate = MLX_NOTINIT;
|
static mlx_state_t MLX_state = MLX_RELAX, MLX_oldstate = MLX_RELAX;
|
||||||
static MLX90640_params p;
|
|
||||||
static int parsrdy = 0;
|
|
||||||
static uint8_t MLX_address = 0x33 << 1;
|
|
||||||
static int errctr = 0; // errors counter - cleared by mlx_continue
|
static int errctr = 0; // errors counter - cleared by mlx_continue
|
||||||
static uint32_t Tlastimage = 0;
|
static uint32_t Tlastimage[N_SESORS] = {0};
|
||||||
static uint8_t resolution = 2; // default: 18bit
|
|
||||||
|
|
||||||
static int16_t subpage1[REG_IMAGEDATA_LEN];
|
// subpages and configs of all sensors
|
||||||
|
static int16_t imdata[N_SESORS][REG_IMAGEDATA_LEN];
|
||||||
|
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];
|
||||||
|
|
||||||
|
static int sensno = -1;
|
||||||
|
|
||||||
// get current state
|
// get current state
|
||||||
mlx_state_t mlx_state(){ return MLX_state; }
|
mlx_state_t mlx_state(){ return MLX_state; }
|
||||||
// set address
|
// set address
|
||||||
int mlx_setaddr(uint8_t addr){
|
int mlx_setaddr(int n, uint8_t addr){
|
||||||
|
if(n < 0 || n > N_SESORS) return 0;
|
||||||
if(addr > 0x7f) return 0;
|
if(addr > 0x7f) return 0;
|
||||||
MLX_address = addr << 1;
|
sens_addresses[n] = addr << 1;
|
||||||
Tlastimage = Tms; // refresh counter for autoreset I2C in case of error
|
Tlastimage[n] = Tms; // refresh counter for autoreset I2C in case of error
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// temporary stop
|
// pause state machine and stop
|
||||||
void mlx_stop(){
|
void mlx_pause(){
|
||||||
MLX_oldstate = MLX_state;
|
MLX_oldstate = MLX_state;
|
||||||
MLX_state = MLX_RELAX;
|
MLX_state = MLX_RELAX;
|
||||||
}
|
}
|
||||||
|
void mlx_stop(){
|
||||||
|
MLX_oldstate = MLX_NOTINIT;
|
||||||
|
MLX_state = MLX_RELAX;
|
||||||
|
}
|
||||||
|
|
||||||
// continue processing
|
// continue processing
|
||||||
void mlx_continue(){
|
void mlx_continue(){
|
||||||
errctr = 0;
|
errctr = 0;
|
||||||
@ -62,96 +70,145 @@ void mlx_continue(){
|
|||||||
//case MLX_NOTINIT:
|
//case MLX_NOTINIT:
|
||||||
//case MLX_WAITPARAMS:
|
//case MLX_WAITPARAMS:
|
||||||
default:
|
default:
|
||||||
|
memcpy(sensaddr, sens_addresses, sizeof(sens_addresses));
|
||||||
MLX_state = MLX_NOTINIT;
|
MLX_state = MLX_NOTINIT;
|
||||||
|
sensno = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nextsensno(int s){
|
||||||
|
if(mlx_nactive() == 0){
|
||||||
|
mlx_stop();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// count active sensors
|
||||||
|
int mlx_nactive(){
|
||||||
|
int N = 0;
|
||||||
|
for(int i = 0; i < N_SESORS; ++i) if(sensaddr[i]) ++N;
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mlx_process - main state machine
|
||||||
|
* 1. Process conf data for each sensor
|
||||||
|
* 2. Start image processing and store subpage1 for each sensor
|
||||||
|
*/
|
||||||
void mlx_process(){
|
void mlx_process(){
|
||||||
|
static uint32_t TT = 0;
|
||||||
|
if(Tms == TT) return;
|
||||||
|
TT = Tms;
|
||||||
// static uint32_t Tlast = 0;
|
// static uint32_t Tlast = 0;
|
||||||
static int subpage = 0;
|
static int subpage = 0;
|
||||||
|
if(MLX_state == MLX_RELAX) return;
|
||||||
|
if(sensno == -1){ // init
|
||||||
|
sensno = nextsensno(-1);
|
||||||
|
if(-1 == sensno) return; // no sensors found
|
||||||
|
}
|
||||||
switch(MLX_state){
|
switch(MLX_state){
|
||||||
case MLX_NOTINIT: // start reading parameters
|
case MLX_NOTINIT: // start reading parameters
|
||||||
if(i2c_read_reg16(MLX_address, REG_CALIDATA, MLX_DMA_MAXLEN, 1)){
|
if(i2c_read_reg16(sensaddr[sensno], REG_CALIDATA, MLX_DMA_MAXLEN, 1)){
|
||||||
|
U(i2str(sensno)); USND(" wait conf");
|
||||||
errctr = 0;
|
errctr = 0;
|
||||||
MLX_state = MLX_WAITPARAMS;
|
MLX_state = MLX_WAITPARAMS;
|
||||||
}else ++errctr;
|
}else ++errctr;
|
||||||
break;
|
break;
|
||||||
case MLX_WAITPARAMS: // check DMA ends and calculate parameters
|
case MLX_WAITPARAMS: // check DMA ends and calculate parameters
|
||||||
if(i2c_dma_haderr()) MLX_state = MLX_NOTINIT;
|
if(i2c_dma_haderr()){ MLX_state = MLX_NOTINIT; USND("DMA err");}
|
||||||
else{
|
else{
|
||||||
uint16_t len, *buf = i2c_dma_getbuf(&len);
|
uint16_t len, *buf = i2c_dma_getbuf(&len);
|
||||||
if(buf){
|
if(buf) USND("READ");
|
||||||
if(len != MLX_DMA_MAXLEN) MLX_state = MLX_NOTINIT;
|
else break;
|
||||||
else if(get_parameters(buf, &p)){
|
if(len != MLX_DMA_MAXLEN){ MLX_state = MLX_NOTINIT; break; }
|
||||||
errctr = 0;
|
memcpy(confdata[sensno], buf, MLX_DMA_MAXLEN * sizeof(uint16_t));
|
||||||
MLX_state = MLX_WAITSUBPAGE; // fine! we could wait subpage
|
U(i2str(sensno)); USND(" got conf");
|
||||||
parsrdy = 1;
|
int next = nextsensno(sensno);
|
||||||
}
|
errctr = 0;
|
||||||
}
|
if(next <= sensno) MLX_state = MLX_WAITSUBPAGE; // all configuration read
|
||||||
|
else MLX_state = MLX_NOTINIT; // read next
|
||||||
|
sensno = next;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MLX_WAITSUBPAGE: // wait for subpage 1 ready
|
case MLX_WAITSUBPAGE: // wait for subpage 1 ready
|
||||||
{uint16_t *got = i2c_read_reg16(MLX_address, REG_STATUS, 1, 0);
|
{uint16_t *got = i2c_read_reg16(sensaddr[sensno], REG_STATUS, 1, 0);
|
||||||
if(got && *got & REG_STATUS_NEWDATA){
|
if(got && *got & REG_STATUS_NEWDATA){
|
||||||
if(subpage == (*got & REG_STATUS_SPNO)){
|
if(subpage == (*got & REG_STATUS_SPNO)){
|
||||||
if(subpage == 0){ subpage = 1; break; }
|
errctr = 0;
|
||||||
if(i2c_read_reg16(MLX_address, REG_IMAGEDATA, REG_IMAGEDATA_LEN, 1)){
|
if(subpage == 0){ // omit zero subpage for each sensor
|
||||||
|
int next = nextsensno(sensno);
|
||||||
|
if(next <= sensno) subpage = 1; // all scanned - now wait for page 1
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(i2c_read_reg16(sensaddr[sensno], REG_IMAGEDATA, REG_IMAGEDATA_LEN, 1)){
|
||||||
errctr = 0;
|
errctr = 0;
|
||||||
MLX_state = MLX_READSUBPAGE;
|
MLX_state = MLX_READSUBPAGE;
|
||||||
// U("spstart"); USB_putbyte('0'+subpage); USB_putbyte('='); USND(u2str(Tms - Tlast));
|
// U("spstart"); USB_putbyte('0'+subpage); USB_putbyte('='); USND(u2str(Tms - Tlast));
|
||||||
}else ++errctr;
|
}else ++errctr;
|
||||||
}
|
}
|
||||||
}}
|
}else ++errctr;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MLX_READSUBPAGE: // wait ends of DMA read and calculate subpage
|
case MLX_READSUBPAGE: // wait ends of DMA read and calculate subpage
|
||||||
if(i2c_dma_haderr()) MLX_state = MLX_NOTINIT;
|
if(i2c_dma_haderr()) MLX_state = MLX_WAITSUBPAGE;
|
||||||
else{
|
else{
|
||||||
uint16_t len, *buf = i2c_dma_getbuf(&len);
|
uint16_t len, *buf = i2c_dma_getbuf(&len);
|
||||||
if(buf){
|
if(buf){
|
||||||
// U("spread="); USND(u2str(Tms - Tlast));
|
// U("spread="); USND(u2str(Tms - Tlast));
|
||||||
if(len != REG_IMAGEDATA_LEN){
|
if(len != REG_IMAGEDATA_LEN){
|
||||||
MLX_state = MLX_WAITSUBPAGE;
|
++errctr;
|
||||||
}else{
|
}else{ // fine! we could check next sensor
|
||||||
errctr = 0;
|
errctr = 0;
|
||||||
memcpy(subpage1, buf, REG_IMAGEDATA_LEN * sizeof(int16_t));
|
memcpy(imdata[sensno], buf, REG_IMAGEDATA_LEN * sizeof(int16_t));
|
||||||
MLX_state = MLX_WAITSUBPAGE; // fine! we could wait next subpage
|
|
||||||
// U("spgot="); USND(u2str(Tms - Tlast));
|
// U("spgot="); USND(u2str(Tms - Tlast));
|
||||||
Tlastimage = Tms;
|
Tlastimage[sensno] = Tms;
|
||||||
// U("imgot="); USND(u2str(Tms - Tlast)); Tlast = Tms;
|
// U("imgot="); USND(u2str(Tms - Tlast)); Tlast = Tms;
|
||||||
|
int next = nextsensno(sensno);
|
||||||
|
if(next <= sensno) subpage = 0; // roll to start - omit page 0 for all
|
||||||
}
|
}
|
||||||
subpage = 0;
|
MLX_state = MLX_WAITSUBPAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(MLX_state != MLX_RELAX && Tms - Tlastimage > MLX_I2CERR_TMOUT){ i2c_setup(i2c_curspeed); Tlastimage = Tms; }
|
if(MLX_state != MLX_RELAX && Tms - Tlastimage[sensno] > MLX_I2CERR_TMOUT){ i2c_setup(i2c_curspeed); Tlastimage[sensno] = Tms; }
|
||||||
if(errctr > MLX_MAX_ERRORS) mlx_stop();
|
if(errctr > MLX_MAX_ERRORS){
|
||||||
|
errctr = 0;
|
||||||
|
sensaddr[sensno] = 0; // throw out this value
|
||||||
|
sensno = nextsensno(sensno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get parameters - memcpy to user's
|
// recalculate parameters
|
||||||
int mlx_getparams(MLX90640_params *pars){
|
int mlx_getparams(int n, MLX90640_params *pars){
|
||||||
if(!pars || !parsrdy) return 0;
|
if(!pars) return 0;
|
||||||
memcpy(pars, &p, sizeof(p));
|
if(!get_parameters(confdata[n], pars)) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mlx_lastimT(){ return Tlastimage; }
|
uint32_t mlx_lastimT(int n){ return Tlastimage[n]; }
|
||||||
|
|
||||||
fp_t *mlx_getimage(uint32_t *Tgot){
|
fp_t *mlx_getimage(int n){
|
||||||
fp_t *ready_image = process_image(&p, subpage1);
|
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]);
|
||||||
if(!ready_image) return NULL;
|
if(!ready_image) return NULL;
|
||||||
if(Tgot) *Tgot = Tlastimage;
|
|
||||||
return ready_image;
|
return ready_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mlx_getresolution(){
|
// this function can be run only when state machine is paused/stopped!
|
||||||
return resolution;
|
// WARNING: `MLX_address` is shifted, `addr` - NOT!
|
||||||
}
|
int mlx_sethwaddr(uint8_t MLX_address, uint8_t addr){
|
||||||
|
|
||||||
int mlx_sethwaddr(uint8_t addr){
|
|
||||||
if(addr > 0x7f) return 0;
|
if(addr > 0x7f) return 0;
|
||||||
uint16_t data[2], *ptr;
|
uint16_t data[2], *ptr;
|
||||||
if(!(ptr = i2c_read_reg16(MLX_address, REG_MLXADDR, 1, 0))) return 0;
|
if(!(ptr = i2c_read_reg16(MLX_address, REG_MLXADDR, 1, 0))) return 0;
|
||||||
@ -179,13 +236,3 @@ int mlx_sethwaddr(uint8_t addr){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx_setresolution(uint8_t newresol){
|
|
||||||
if(newresol > 3) return 0;
|
|
||||||
uint16_t data[2], *ptr;
|
|
||||||
if(!(ptr = i2c_read_reg16(MLX_address, REG_CONTROL, 1, 0))) return 0;
|
|
||||||
data[0] = REG_CONTROL;
|
|
||||||
data[1] = (*ptr & ~REG_CONTROL_RESMASK) | (newresol << 10);
|
|
||||||
if(!i2c_write(MLX_address, data, 2)) return 0;
|
|
||||||
resolution = newresol;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
#include "mlx90640.h"
|
#include "mlx90640.h"
|
||||||
|
|
||||||
|
// amount of sensors processing
|
||||||
|
#define N_SESORS (5)
|
||||||
|
|
||||||
// maximal errors number to stop processing
|
// maximal errors number to stop processing
|
||||||
#define MLX_MAX_ERRORS (11)
|
#define MLX_MAX_ERRORS (11)
|
||||||
// if there's no new data by this time - reset bus
|
// if there's no new data by this time - reset bus
|
||||||
@ -35,14 +38,14 @@ typedef enum{
|
|||||||
MLX_RELAX // do nothing - pause
|
MLX_RELAX // do nothing - pause
|
||||||
} mlx_state_t;
|
} mlx_state_t;
|
||||||
|
|
||||||
int mlx_setaddr(uint8_t addr);
|
int mlx_setaddr(int n, uint8_t addr);
|
||||||
mlx_state_t mlx_state();
|
mlx_state_t mlx_state();
|
||||||
|
int mlx_nactive();
|
||||||
|
void mlx_pause();
|
||||||
void mlx_stop();
|
void mlx_stop();
|
||||||
void mlx_continue();
|
void mlx_continue();
|
||||||
void mlx_process();
|
void mlx_process();
|
||||||
int mlx_getparams(MLX90640_params *pars);
|
int mlx_getparams(int sensno, MLX90640_params *pars);
|
||||||
fp_t *mlx_getimage(uint32_t *Tgot);
|
fp_t *mlx_getimage(int sensno);
|
||||||
int mlx_setresolution(uint8_t newresol);
|
int mlx_sethwaddr(uint8_t MLX_address, uint8_t addr);
|
||||||
uint8_t mlx_getresolution();
|
uint32_t mlx_lastimT(int sensno);
|
||||||
int mlx_sethwaddr(uint8_t addr);
|
|
||||||
uint32_t mlx_lastimT();
|
|
||||||
|
|||||||
@ -41,12 +41,12 @@ const char *helpstring =
|
|||||||
"d - draw image in ASCII\n"
|
"d - draw image in ASCII\n"
|
||||||
"i0..4 - setup I2C with speed 10k, 100k, 400k, 1M or 2M (experimental!)\n"
|
"i0..4 - setup I2C with speed 10k, 100k, 400k, 1M or 2M (experimental!)\n"
|
||||||
"p - pause MLX\n"
|
"p - pause MLX\n"
|
||||||
"r0..3 - change resolution (0 - 16bit, 3 - 19-bit)\n"
|
"s - stop MLX (and start from zero @ 'c'\n"
|
||||||
"t - show temperature map\n"
|
"t - show temperature map\n"
|
||||||
"C - \"cartoon\" mode on/off (show each new image)\n"
|
"C - \"cartoon\" mode on/off (show each new image)\n"
|
||||||
"D - dump MLX parameters\n"
|
"Dn - dump MLX parameters for sensor number n\n"
|
||||||
"G - get MLX state\n"
|
"G - get MLX state\n"
|
||||||
"Ia addr - set device address\n"
|
"Ia addr [n] - set device address for interactive work or (with n) change address of n'th sensor\n"
|
||||||
"Ir reg n - read n words from 16-bit register\n"
|
"Ir reg n - read n words from 16-bit register\n"
|
||||||
"Iw words - send words (hex/dec/oct/bin) to I2C\n"
|
"Iw words - send words (hex/dec/oct/bin) to I2C\n"
|
||||||
"Is - scan I2C bus\n"
|
"Is - scan I2C bus\n"
|
||||||
@ -78,7 +78,7 @@ TRUE_INLINE const char *chhwaddr(const char *buf){
|
|||||||
if(buf && *buf){
|
if(buf && *buf){
|
||||||
const char *nxt = getnum(buf, &a);
|
const char *nxt = getnum(buf, &a);
|
||||||
if(nxt && nxt != buf){
|
if(nxt && nxt != buf){
|
||||||
if(!mlx_sethwaddr(a)) return ERR;
|
if(!mlx_sethwaddr(I2Caddress, a)) return ERR;
|
||||||
}else{
|
}else{
|
||||||
USND("Wrong number");
|
USND("Wrong number");
|
||||||
return ERR;
|
return ERR;
|
||||||
@ -90,24 +90,16 @@ TRUE_INLINE const char *chhwaddr(const char *buf){
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRUE_INLINE const char *chres(const char *buf){
|
|
||||||
uint32_t r;
|
|
||||||
if(buf && *buf){
|
|
||||||
const char *nxt = getnum(buf, &r);
|
|
||||||
if(nxt && nxt != buf) if(!mlx_setresolution(r)) return ERR;
|
|
||||||
}
|
|
||||||
r = mlx_getresolution();
|
|
||||||
U("MLXRESOLUTION="); USND(u2str(r));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRUE_INLINE const char *chaddr(const char *buf){
|
TRUE_INLINE const char *chaddr(const char *buf){
|
||||||
uint32_t addr;
|
uint32_t addr, num;
|
||||||
const char *nxt = getnum(buf, &addr);
|
const char *nxt = getnum(buf, &addr);
|
||||||
if(nxt && nxt != buf){
|
if(nxt && nxt != buf){
|
||||||
if(addr > 0x7f) return ERR;
|
if(addr > 0x7f) return ERR;
|
||||||
mlx_setaddr(addr);
|
|
||||||
I2Caddress = (uint8_t) addr << 1;
|
I2Caddress = (uint8_t) addr << 1;
|
||||||
|
buf = getnum(nxt, &num);
|
||||||
|
if(buf && nxt != buf && num < N_SESORS){
|
||||||
|
mlx_setaddr(num, addr);
|
||||||
|
}
|
||||||
}else addr = I2Caddress >> 1;
|
}else addr = I2Caddress >> 1;
|
||||||
U("I2CADDR="); USND(uhex2str(addr));
|
U("I2CADDR="); USND(uhex2str(addr));
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -163,9 +155,13 @@ static void dumpfarr(float *arr){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// dump MLX parameters
|
// dump MLX parameters
|
||||||
TRUE_INLINE void dumpparams(){
|
TRUE_INLINE void dumpparams(const char *buf){
|
||||||
|
uint32_t N = 0;
|
||||||
|
const char *nxt = getnum(buf, &N);
|
||||||
|
U(u2str(N)); USND("sn");
|
||||||
|
if(!nxt || buf == nxt || N > N_SESORS){ U(ERR); return; }
|
||||||
MLX90640_params params;
|
MLX90640_params params;
|
||||||
if(!mlx_getparams(¶ms)){ U(ERR); return; }
|
if(!mlx_getparams(N, ¶ms)){ U(ERR); return; }
|
||||||
U("\nkVdd="); printi(params.kVdd);
|
U("\nkVdd="); printi(params.kVdd);
|
||||||
U("\nvdd25="); printi(params.vdd25);
|
U("\nvdd25="); printi(params.vdd25);
|
||||||
U("\nKvPTAT="); printfl(params.KvPTAT, 4);
|
U("\nKvPTAT="); printfl(params.KvPTAT, 4);
|
||||||
@ -221,17 +217,35 @@ TRUE_INLINE void getst(){
|
|||||||
USND(states[s]);
|
USND(states[s]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `draw`==1 - draw, ==0 - show T map
|
||||||
|
static const char *drawimg(const char *buf, int draw){
|
||||||
|
uint32_t sensno;
|
||||||
|
const char *nxt = getnum(buf, &sensno);
|
||||||
|
if(nxt && nxt != buf && sensno < N_SESORS){
|
||||||
|
uint32_t T = mlx_lastimT(sensno);
|
||||||
|
fp_t *img = mlx_getimage(sensno);
|
||||||
|
if(img){
|
||||||
|
U("Timage="); USND(u2str(T));
|
||||||
|
if(draw) drawIma(img);
|
||||||
|
else dumpIma(img);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ERR;
|
||||||
|
}
|
||||||
|
|
||||||
const char *parse_cmd(char *buf){
|
const char *parse_cmd(char *buf){
|
||||||
if(!buf || !*buf) return NULL;
|
if(!buf || !*buf) return NULL;
|
||||||
uint32_t u32;
|
|
||||||
if(buf[1]){
|
if(buf[1]){
|
||||||
switch(*buf){ // "long" commands
|
switch(*buf){ // "long" commands
|
||||||
case 'a':
|
case 'a':
|
||||||
return chhwaddr(buf + 1);
|
return chhwaddr(buf + 1);
|
||||||
case 'i':
|
case 'i':
|
||||||
return setupI2C(buf + 1);
|
return setupI2C(buf + 1);
|
||||||
case 'r':
|
case 'D':
|
||||||
return chres(buf + 1);
|
dumpparams(buf + 1);
|
||||||
|
return;
|
||||||
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
buf = omit_spaces(buf + 1);
|
buf = omit_spaces(buf + 1);
|
||||||
switch(*buf){
|
switch(*buf){
|
||||||
@ -257,25 +271,19 @@ const char *parse_cmd(char *buf){
|
|||||||
mlx_continue(); return OK;
|
mlx_continue(); return OK;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
{fp_t *i = mlx_getimage(&u32);
|
return drawimg(buf+1, 1);
|
||||||
if(i){ U("Timage="); USND(u2str(u32)); drawIma(i); }
|
|
||||||
else U(ERR);}
|
|
||||||
break;
|
break;
|
||||||
case 'i': return setupI2C(NULL); // current settings
|
case 'i': return setupI2C(NULL); // current settings
|
||||||
case 'p':
|
case 'p':
|
||||||
mlx_stop(); return OK;
|
mlx_pause(); return OK;
|
||||||
break;
|
break;
|
||||||
case 'r': return chres(NULL);
|
case 's':
|
||||||
|
mlx_stop(); return OK;
|
||||||
case 't':
|
case 't':
|
||||||
{fp_t *i = mlx_getimage(&u32);
|
return drawimg(buf+1, 0);
|
||||||
if(i){ U("Timage="); USND(u2str(u32)); dumpIma(i); }
|
|
||||||
else U(ERR);}
|
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
cartoon = !cartoon; return OK;
|
cartoon = !cartoon; return OK;
|
||||||
case 'D':
|
|
||||||
dumpparams();
|
|
||||||
break;
|
|
||||||
case 'G':
|
case 'G':
|
||||||
getst();
|
getst();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "14"
|
#define BUILD_NUMBER "30"
|
||||||
#define BUILD_DATE "2025-09-22"
|
#define BUILD_DATE "2025-09-23"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user