mirror of
https://github.com/eddyem/eddys_snippets.git
synced 2025-12-06 10:45:12 +03:00
add MLX test; not fully works yet, try to find my error in calculations due to datashit
This commit is contained in:
parent
664566aa47
commit
dfdc4222fd
58
MLX90640_test/Makefile
Normal file
58
MLX90640_test/Makefile
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# run `make DEF=...` to add extra defines
|
||||||
|
PROGRAM := mlx
|
||||||
|
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
|
||||||
|
LDFLAGS += -lusefull_macros -L/usr/local/lib -lm -flto
|
||||||
|
SRCS := $(wildcard *.c)
|
||||||
|
DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111
|
||||||
|
OBJDIR := mk
|
||||||
|
CFLAGS += -O2 -Wall -Wextra -Wno-trampolines -std=gnu99 -flto
|
||||||
|
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
|
||||||
|
|
||||||
|
ifeq ($(TARGET), DEBUG)
|
||||||
|
.DEFAULT_GOAL := debug
|
||||||
|
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
|
||||||
2
MLX90640_test/Readme
Normal file
2
MLX90640_test/Readme
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
device-independent MLX90640 processing & test
|
||||||
|
based on data example from melexis
|
||||||
1
MLX90640_test/alpha.csv
Normal file
1
MLX90640_test/alpha.csv
Normal file
File diff suppressed because one or more lines are too long
1
MLX90640_test/eeprom.csv
Normal file
1
MLX90640_test/eeprom.csv
Normal file
File diff suppressed because one or more lines are too long
1
MLX90640_test/frame0.csv
Normal file
1
MLX90640_test/frame0.csv
Normal file
File diff suppressed because one or more lines are too long
1
MLX90640_test/frame1.csv
Normal file
1
MLX90640_test/frame1.csv
Normal file
File diff suppressed because one or more lines are too long
1
MLX90640_test/kta.csv
Normal file
1
MLX90640_test/kta.csv
Normal file
File diff suppressed because one or more lines are too long
1
MLX90640_test/kv.csv
Normal file
1
MLX90640_test/kv.csv
Normal file
File diff suppressed because one or more lines are too long
41
MLX90640_test/main.c
Normal file
41
MLX90640_test/main.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the mlxtest project.
|
||||||
|
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "mlx90640.h"
|
||||||
|
#include "testdata.h"
|
||||||
|
|
||||||
|
int main (int _U_ argc, char _U_ **argv){
|
||||||
|
sl_init();
|
||||||
|
MLX90640_params p;
|
||||||
|
if(!get_parameters(EEPROM, &p)) ERRX("Can't get parameters from test data");
|
||||||
|
dump_parameters(&p, &extracted_parameters);
|
||||||
|
for(int i = 0; i < 2; ++i){
|
||||||
|
printf("Process subpage %d\n", i);
|
||||||
|
fp_t *sp = process_subpage(&p, FRAME0, i, 2);
|
||||||
|
if(!sp) ERRX("WTF?");
|
||||||
|
dumpIma(sp);
|
||||||
|
chkImage(sp, ToFrame[i]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
487
MLX90640_test/mlx90640.c
Normal file
487
MLX90640_test/mlx90640.c
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the mlxtest project.
|
||||||
|
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "mlx90640.h"
|
||||||
|
#include "mlx90640_regs.h"
|
||||||
|
|
||||||
|
// tolerance of floating point comparison
|
||||||
|
#define FP_TOLERANCE (1e-3)
|
||||||
|
|
||||||
|
static fp_t mlx_image[MLX_PIXNO] = {0}; // ready image
|
||||||
|
|
||||||
|
#ifdef EBUG
|
||||||
|
static double Tlast = 0.;
|
||||||
|
#define chstate() do{Tlast = sl_dtime(); DBG("chstate()");}while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void dumpIma(const fp_t im[MLX_PIXNO]){
|
||||||
|
for(int row = 0; row < MLX_H; ++row){
|
||||||
|
for(int col = 0; col < MLX_W; ++col){
|
||||||
|
printf("%5.1f ", *im++);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void chki(const char *name, int16_t param, int16_t standard){
|
||||||
|
printf("%*s | %-16d | %-16d - ", -16, name, param, standard);
|
||||||
|
if(param != standard){
|
||||||
|
red("NOT equal!\n"); exit(1);
|
||||||
|
}
|
||||||
|
printf("OK\n");
|
||||||
|
}
|
||||||
|
static void chkf(const char *name, fp_t param, fp_t standard){
|
||||||
|
printf("%*s | %-16g | %-16g - ", -16, name, param, standard);
|
||||||
|
fp_t diff = (fabs(param) + fabs(standard)) * FP_TOLERANCE;
|
||||||
|
if(fabs(param - standard) > diff){
|
||||||
|
// DBG("diff = %g", diff);
|
||||||
|
red("NOT equal!\n"); exit(1);
|
||||||
|
}
|
||||||
|
printf("OK\n");
|
||||||
|
}
|
||||||
|
static void chkfa(const char *name, const fp_t *ap, const fp_t *as, int n){
|
||||||
|
char buf[16];
|
||||||
|
snprintf(buf, 15, "(size %d)", n);
|
||||||
|
printf("%*s | %-16s | %-16s - ", -16, name, "(array)", buf);
|
||||||
|
for(int i = 0; i < n; ++i){
|
||||||
|
fp_t diff = (fabs(as[i]) + fabs(ap[i])) * FP_TOLERANCE;
|
||||||
|
if(fabs(ap[i] - as[i]) > diff){
|
||||||
|
// DBG("diff = %g", diff);
|
||||||
|
red("NOT equal on index %d (%g and %g)\n", i, ap[i], as[i]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("OK");
|
||||||
|
if(n < 10){
|
||||||
|
for(int i = 0; i < n; ++i) printf(" %g", as[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
static void chku8a(const char *name, const uint8_t *ap, const uint8_t *as, int n){
|
||||||
|
char buf[16];
|
||||||
|
snprintf(buf, 15, "(size %d)", n);
|
||||||
|
printf("%*s | %-16s | %-16s - ", -16, name, "(array)", buf);
|
||||||
|
for(int i = 0; i < n; ++i){
|
||||||
|
if(ap[i] != as[i]){
|
||||||
|
red("NOT equal on index %d (%d and %d)\n", i, ap[i], as[i]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("OK");
|
||||||
|
if(n < 10){
|
||||||
|
for(int i = 0; i < n; ++i) printf(" %d", as[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
void chkImage(const fp_t Image[MLX_PIXNO], const fp_t ToFrame[MLX_PIXNO]){
|
||||||
|
chkfa("Image", Image, ToFrame, MLX_PIXNO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_parameters(MLX90640_params *params, const MLX90640_params *standard){
|
||||||
|
printf("###########################################################\n");
|
||||||
|
printf("%*s | %*s | %*s\n###########################################################\n",
|
||||||
|
-16, "# name", -16, "value", -16, "standard");
|
||||||
|
#define CHKI(f) do{chki(#f, params->f, standard->f);}while(0)
|
||||||
|
#define CHKF(f) do{chkf(#f, params->f, standard->f);}while(0)
|
||||||
|
#define CHKFA(f, n) do{chkfa(#f, params->f, standard->f, n);}while(0)
|
||||||
|
#define CHKU8A(f, n) do{chku8a(#f, params->f, standard->f, n);}while(0)
|
||||||
|
CHKI(kVdd);
|
||||||
|
CHKI(vdd25);
|
||||||
|
CHKF(KvPTAT);
|
||||||
|
CHKI(vPTAT25);
|
||||||
|
CHKF(alphaPTAT);
|
||||||
|
CHKI(gainEE);
|
||||||
|
CHKF(tgc);
|
||||||
|
CHKF(cpKv);
|
||||||
|
CHKF(cpKta);
|
||||||
|
CHKF(KsTa);
|
||||||
|
CHKFA(CT, 3);
|
||||||
|
CHKFA(KsTo, 4);
|
||||||
|
CHKFA(alpha, MLX_PIXNO);
|
||||||
|
CHKFA(offset, MLX_PIXNO);
|
||||||
|
CHKFA(kta, MLX_PIXNO);
|
||||||
|
CHKFA(kv, 4);
|
||||||
|
CHKFA(cpAlpha, 2);
|
||||||
|
CHKI(resolEE);
|
||||||
|
CHKI(cpOffset[0]); CHKI(cpOffset[1]);
|
||||||
|
CHKU8A(outliers, MLX_PIXNO);
|
||||||
|
#if 0
|
||||||
|
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->cpKv, 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");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#undef CHKI
|
||||||
|
#undef CHKF
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Calculate parameters & values
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// fill OCC/ACC row/col arrays
|
||||||
|
static void occacc(int8_t *arr, int l, const 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
|
||||||
|
int get_parameters(const uint16_t dataarray[MLX_DMA_MAXLEN], MLX90640_params *params){
|
||||||
|
#define CREG_VAL(reg) dataarray[CREG_IDX(reg)]
|
||||||
|
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 = (fp_t)i16 / (1<<12);
|
||||||
|
i16 = (val & 0x03FF);
|
||||||
|
if(i16 > 0x1FF) i16 -= 0x400;
|
||||||
|
params->KtPTAT = (fp_t)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:
|
||||||
|
fp_t 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 should 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 (1,3,..), even row (2,4,..) -> 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;
|
||||||
|
fp_t mul = (fp_t)(1<<scale2), div = (fp_t)(1<<scale1); // kta_scales
|
||||||
|
uint16_t a_r = CREG_VAL(REG_SENSIVITY); // alpha_ref
|
||||||
|
val = CREG_VAL(REG_SCALEACC);
|
||||||
|
fp_t *a = params->alpha;
|
||||||
|
uint32_t diva32 = 1 << (val >> 12);
|
||||||
|
fp_t diva = (fp_t)(diva32);
|
||||||
|
diva *= (fp_t)(1<<30); // alpha_scale
|
||||||
|
DBG("diva: %g", diva);
|
||||||
|
fp_t accRowScale = 1<<((val & 0x0f00)>>8),
|
||||||
|
accColumnScale = 1<<((val & 0x00f0)>>4),
|
||||||
|
accRemScale = 1<<(val & 0x0f);
|
||||||
|
pu16 = (uint16_t*)&CREG_VAL(REG_OFFAK1);
|
||||||
|
fp_t *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++ = (fp_t)offavg + (fp_t)occRow[row]*occRowScale + (fp_t)occColumn[col]*occColumnScale + (fp_t)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;
|
||||||
|
fp_t oft = (fp_t)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 = (fp_t)(1<<scale1);
|
||||||
|
val = CREG_VAL(REG_KVAVG);
|
||||||
|
// kv indexes: +2 for odd (ÎÅÞÅÔÎÙÈ) rows, +1 for odd columns, so:
|
||||||
|
// [ 3, 2; 1, 0] for left upper corner (because datashit counts from 1, not from 0!)
|
||||||
|
i16 = val >> 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 = (fp_t)i8 / (1<<val);
|
||||||
|
val = (CREG_VAL(REG_KTAVSCALE) & 0x0F00) >> 8;
|
||||||
|
i16 = CREG_VAL(REG_KVTACP) >> 8;
|
||||||
|
if(i16 > 0x7F) i16 -= 0x100;
|
||||||
|
params->cpKv = (fp_t)i16 / (1<<val);
|
||||||
|
i16 = CREG_VAL(REG_KSTATGC) & 0xFF;
|
||||||
|
if(i16 > 0x7F) i16 -= 0x100;
|
||||||
|
params->tgc = (fp_t)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 = (fp_t)(1<<val);
|
||||||
|
div *= (fp_t)(1<<27);
|
||||||
|
params->cpAlpha[0] = (fp_t)(CREG_VAL(REG_ALPHA) & 0x03FF) / div;
|
||||||
|
div = (fp_t)(1<<7);
|
||||||
|
params->cpAlpha[1] = params->cpAlpha[0] * (1. + (fp_t)i16/div);
|
||||||
|
i8 = (int8_t)(CREG_VAL(REG_KSTATGC) >> 8);
|
||||||
|
params->KsTa = (fp_t)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;
|
||||||
|
// CT1 = -40, CT2 = 0 -> start from zero index, so CT[0] is CT2, CT[1] is CT3, CT[2] is CT4
|
||||||
|
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
|
||||||
|
// alphacorr for each range: 11.1.11
|
||||||
|
params->alphacorr[0] = 1./(1. + params->KsTo[0] * 40.);
|
||||||
|
params->alphacorr[1] = 1.;
|
||||||
|
params->alphacorr[2] = (1. + params->KsTo[1] * params->CT[1]);
|
||||||
|
params->alphacorr[3] = (1. + params->KsTo[2] * (params->CT[2] - params->CT[1])) * params->alphacorr[2];
|
||||||
|
params->resolEE = (uint8_t)((CREG_VAL(REG_KTAVSCALE) & 0x3000) >> 12);
|
||||||
|
// Don't forget to check 'outlier' flags for wide purpose
|
||||||
|
return TRUE;
|
||||||
|
#undef CREG_VAL
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
fp_t *process_subpage(MLX90640_params *params, const int16_t Frame[MLX_DMA_MAXLEN], int subpageno, int simpleimage){
|
||||||
|
#define IMD_VAL(reg) Frame[IMD_IDX(reg)]
|
||||||
|
DBG("\nprocess_subpage(%d)", subpageno);
|
||||||
|
#ifdef EBUG
|
||||||
|
chstate();
|
||||||
|
#endif
|
||||||
|
// 11.2.2.1. Resolution restore
|
||||||
|
// temporary:
|
||||||
|
fp_t resol_corr = (fp_t)(1<<params->resolEE) / (1<<2); // calibrated resol/current resol
|
||||||
|
DBG("resolEE=%d, resolCur=%d", params->resolEE, 2);
|
||||||
|
//fp_t resol_corr = (fp_t)(1<<params->resolEE) / (1<<((reg_control_val[subpageno]&0x0C00)>>10)); // calibrated resol/current resol
|
||||||
|
//DBG("resolEE=%d, resolCur=%d", params->resolEE, ((reg_control_val[subpageno]&0x0C00)>>10));
|
||||||
|
// 11.2.2.2. Supply voltage value calculation
|
||||||
|
int16_t i16a = (int16_t)IMD_VAL(REG_IVDDPIX);
|
||||||
|
fp_t dvdd = resol_corr*i16a - params->vdd25;
|
||||||
|
dvdd /= params->kVdd;
|
||||||
|
fp_t dV = i16a - params->vdd25; // for next step
|
||||||
|
dV /= params->kVdd;
|
||||||
|
DBG("ram=%d, vdd25=%d, dvdd=%g, resol=%g", i16a, params->vdd25, dvdd, resol_corr);
|
||||||
|
DBG("Vd=%g", dvdd+3.3);
|
||||||
|
// 11.2.2.3. Ambient temperature calculation
|
||||||
|
i16a = (int16_t)IMD_VAL(REG_ITAPTAT);
|
||||||
|
int16_t i16b = (int16_t)IMD_VAL(REG_ITAVBE);
|
||||||
|
fp_t dTa = (fp_t)i16a / (i16a * params->alphaPTAT + i16b); // vptatart
|
||||||
|
dTa *= (fp_t)(1<<18);
|
||||||
|
dTa = (dTa / (1. + params->KvPTAT*dV)) - params->vPTAT25;
|
||||||
|
dTa = dTa / params->KtPTAT; // without 25degr - Ta0
|
||||||
|
DBG("Ta=%g", dTa+25.);
|
||||||
|
// 11.2.2.4. Gain parameter calculation
|
||||||
|
i16a = (int16_t)IMD_VAL(REG_IGAIN);
|
||||||
|
fp_t Kgain = params->gainEE / (fp_t)i16a;
|
||||||
|
DBG("Kgain=%g", Kgain);
|
||||||
|
fp_t pixOS[2]; // pix_gain_CP_SPx
|
||||||
|
// 11.2.2.6.1
|
||||||
|
pixOS[0] = ((int16_t)IMD_VAL(REG_ICPSP0))*Kgain; // pix_OS_CP_SPx
|
||||||
|
pixOS[1] = ((int16_t)IMD_VAL(REG_ICPSP1))*Kgain;
|
||||||
|
DBG("pixGain: %g/%g", pixOS[0], pixOS[1]);
|
||||||
|
for(int i = 0; i < 2; ++i){ // calc pixOS by gain
|
||||||
|
// 11.2.2.6.2
|
||||||
|
pixOS[i] -= params->cpOffset[i]*(1. + params->cpKta*dTa)*(1. + params->cpKv*dvdd);
|
||||||
|
}
|
||||||
|
// now make first approximation to image
|
||||||
|
uint16_t pixno = 0; // current pixel number - for indexing in parameters etc
|
||||||
|
for(int row = 0, rowidx = 0; row < MLX_H; ++row, rowidx ^= 2){
|
||||||
|
for(int col = 0, idx = rowidx; col < MLX_W; ++col, ++pixno, idx ^= 1){
|
||||||
|
uint8_t sp = (row&1)^(col&1); // subpage of current pixel
|
||||||
|
if(sp != subpageno) continue;
|
||||||
|
// 11.2.2.5.1
|
||||||
|
fp_t curval = (fp_t)(Frame[pixno]) * Kgain; // gain compensation
|
||||||
|
// 11.2.2.5.3
|
||||||
|
curval -= params->offset[pixno] * (1. + params->kta[pixno]*dTa) *
|
||||||
|
(1. + params->kv[idx]*dvdd); // add offset
|
||||||
|
// now `curval` is pix_OS == V_IR_emiss_comp
|
||||||
|
// 11.2.2.7
|
||||||
|
fp_t IRcompens = curval - params->tgc * pixOS[subpageno]; // IR_compensated
|
||||||
|
if(simpleimage == 0){ // ???
|
||||||
|
curval = IRcompens;
|
||||||
|
/*
|
||||||
|
curval -= params->cpOffset[subpageno] * (1. - params->cpKta * dTa) *
|
||||||
|
(1. + params->cpKv * dvdd); // CP
|
||||||
|
curval = IRcompens - params->tgc * curval; // IR gradient compens
|
||||||
|
*/
|
||||||
|
}else{
|
||||||
|
// 11.2.2.8
|
||||||
|
fp_t alphaComp = params->alpha[pixno] - params->tgc * params->cpAlpha[subpageno];
|
||||||
|
alphaComp /= 1. + params->KsTa * dTa;
|
||||||
|
// 11.2.2.9: calculate To for basic range
|
||||||
|
fp_t Tar = dTa + 273.15 + 25.; // Ta+273.15
|
||||||
|
Tar = Tar*Tar*Tar*Tar; // T_aK4 (when \epsilon==1 this is T_{a-r} too)
|
||||||
|
fp_t ac3 = alphaComp*alphaComp*alphaComp;
|
||||||
|
fp_t Sx = ac3*IRcompens + alphaComp*ac3*Tar;
|
||||||
|
Sx = params->KsTo[1] * SQRT(SQRT(Sx));
|
||||||
|
fp_t To;
|
||||||
|
if(simpleimage == 1){
|
||||||
|
To = IRcompens / (alphaComp * (1. - 273.15*params->KsTo[1]) + Sx) + Tar;
|
||||||
|
}else{ // extended range
|
||||||
|
int idx = 0; // range 1 by default
|
||||||
|
fp_t 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", sl_dtime()-Tlast);
|
||||||
|
return mlx_image;
|
||||||
|
#undef IMD_VAL
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
// 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", sl_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, sl_dtime() - Tlast);
|
||||||
|
return TRUE;
|
||||||
|
}else chkerr();
|
||||||
|
}
|
||||||
|
}else chktmout();
|
||||||
|
}else chkerr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, fp_t **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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
66
MLX90640_test/mlx90640.h
Normal file
66
MLX90640_test/mlx90640.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the mlxtest project.
|
||||||
|
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// floating type & sqrt operator
|
||||||
|
typedef double fp_t;
|
||||||
|
#define SQRT(x) sqrt((x))
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
fp_t KvPTAT;
|
||||||
|
fp_t KtPTAT;
|
||||||
|
int16_t vPTAT25;
|
||||||
|
fp_t alphaPTAT;
|
||||||
|
int16_t gainEE;
|
||||||
|
fp_t tgc;
|
||||||
|
fp_t cpKv; // K_V_CP
|
||||||
|
fp_t cpKta; // K_Ta_CP
|
||||||
|
fp_t KsTa;
|
||||||
|
fp_t CT[3]; // range borders (0, 160, 320 degrC?)
|
||||||
|
fp_t KsTo[4]; // K_S_To for each range * 273.15
|
||||||
|
fp_t alphacorr[4]; // Alpha_corr for each range
|
||||||
|
fp_t alpha[MLX_PIXNO]; // full - with alpha_scale
|
||||||
|
fp_t offset[MLX_PIXNO];
|
||||||
|
fp_t kta[MLX_PIXNO]; // full K_ta - with scale1&2
|
||||||
|
fp_t 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
|
||||||
|
fp_t cpAlpha[2]; // alpha_CP_subpage 0 and 1
|
||||||
|
uint8_t resolEE; // resolution_EE
|
||||||
|
int16_t cpOffset[2];
|
||||||
|
uint8_t outliers[MLX_PIXNO]; // outliers - bad pixels (if == 1)
|
||||||
|
} MLX90640_params;
|
||||||
|
|
||||||
|
// full amount of IMAGE data + EXTRA data (counts of uint16_t!)
|
||||||
|
#define MLX_DMA_MAXLEN (834)
|
||||||
|
|
||||||
|
int get_parameters(const uint16_t dataarray[MLX_DMA_MAXLEN], MLX90640_params *params);
|
||||||
|
void dump_parameters(MLX90640_params *params, const MLX90640_params *standard);
|
||||||
|
fp_t *process_subpage(MLX90640_params *params, const int16_t Frame[MLX_DMA_MAXLEN], int subpageno, int simpleimage);
|
||||||
|
void chkImage(const fp_t Image[MLX_PIXNO], const fp_t ToFrame[MLX_PIXNO]);
|
||||||
|
void dumpIma(const fp_t im[MLX_PIXNO]);
|
||||||
90
MLX90640_test/mlx90640_regs.h
Normal file
90
MLX90640_test/mlx90640_regs.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the mlxtest project.
|
||||||
|
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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_RES16 (0<<10)
|
||||||
|
#define REG_CONTROL_RES17 (1<<10)
|
||||||
|
#define REG_CONTROL_RES18 (2<<10)
|
||||||
|
#define REG_CONTROL_RES19 (3<<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 0x2400
|
||||||
|
#define REG_CALIDATA_LEN 832
|
||||||
|
|
||||||
|
#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
|
||||||
|
// index of register in array (from REG_IMAGEDATA)
|
||||||
|
#define IMD_IDX(addr) ((addr)-REG_IMAGEDATA)
|
||||||
1
MLX90640_test/mlxtest.cflags
Normal file
1
MLX90640_test/mlxtest.cflags
Normal file
@ -0,0 +1 @@
|
|||||||
|
-std=c17
|
||||||
4
MLX90640_test/mlxtest.config
Normal file
4
MLX90640_test/mlxtest.config
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#define GNU_SOURCE 1
|
||||||
|
#define _XOPEN_SOURCE 1111
|
||||||
|
#define EBUG
|
||||||
|
|
||||||
1
MLX90640_test/mlxtest.creator
Normal file
1
MLX90640_test/mlxtest.creator
Normal file
@ -0,0 +1 @@
|
|||||||
|
[General]
|
||||||
218
MLX90640_test/mlxtest.creator.user
Normal file
218
MLX90640_test/mlxtest.creator.user
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 17.0.1, 2025-09-09T23:05:00. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">{7bd84e39-ca37-46d3-be9d-99ebea85bc0d}</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="qlonglong">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||||
|
<value type="QString" key="language">QmlJS</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
||||||
|
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="bool" key="AutoTest.ApplyFilter">false</value>
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
||||||
|
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
|
||||||
|
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
||||||
|
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||||
|
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||||
|
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.BuildSystem</value>
|
||||||
|
<valuemap type="QVariantMap" key="ClangTools">
|
||||||
|
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
||||||
|
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
||||||
|
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
||||||
|
<value type="int" key="ClangTools.ParallelJobs">2</value>
|
||||||
|
<value type="bool" key="ClangTools.PreferConfigFile">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{65a14f9e-e008-4c1b-89df-4eaa4774b6e3}</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/tmp/1/home/eddy/MLX90640_wiringPi</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
|
||||||
|
<value type="QString">all</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
|
||||||
|
<value type="QString">clean</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="qlonglong">1</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
||||||
1
MLX90640_test/mlxtest.cxxflags
Normal file
1
MLX90640_test/mlxtest.cxxflags
Normal file
@ -0,0 +1 @@
|
|||||||
|
-std=c++17
|
||||||
5
MLX90640_test/mlxtest.files
Normal file
5
MLX90640_test/mlxtest.files
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
main.c
|
||||||
|
mlx90640.c
|
||||||
|
mlx90640.h
|
||||||
|
mlx90640_regs.h
|
||||||
|
testdata.h
|
||||||
2
MLX90640_test/mlxtest.includes
Normal file
2
MLX90640_test/mlxtest.includes
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/usr/local/include
|
||||||
|
.
|
||||||
1
MLX90640_test/offset.csv
Normal file
1
MLX90640_test/offset.csv
Normal file
@ -0,0 +1 @@
|
|||||||
|
-54,-56,-50,-60,-50,-56,-48,-60,-49,-57,-48,-61,-49,-59,-48,-63,-46,-59,-48,-65,-49,-61,-49,-66,-47,-64,-50,-69,-53,-66,-51,-75,-61,-64,-65,-61,-57,-63,-63,-61,-56,-63,-63,-62,-56,-65,-63,-64,-53,-65,-63,-65,-55,-66,-63,-66,-53,-69,-63,-69,-58,-70,-64,-74,-53,-56,-50,-60,-51,-55,-48,-60,-48,-56,-47,-61,-47,-58,-47,-62,-45,-58,-48,-64,-47,-59,-47,-67,-46,-62,-49,-68,-52,-65,-50,-75,-60,-62,-65,-61,-58,-61,-63,-61,-55,-62,-62,-61,-54,-64,-62,-62,-51,-64,-62,-63,-53,-66,-62,-66,-52,-67,-63,-67,-59,-71,-64,-75,-50,-54,-49,-58,-48,-54,-48,-59,-46,-55,-47,-60,-47,-55,-47,-61,-43,-57,-46,-62,-46,-59,-47,-65,-46,-61,-48,-67,-52,-65,-50,-74,-57,-63,-65,-60,-56,-62,-64,-61,-54,-63,-62,-62,-54,-62,-62,-63,-51,-64,-62,-63,-52,-66,-62,-65,-53,-69,-62,-69,-59,-71,-64,-75,-53,-54,-49,-59,-49,-54,-47,-58,-45,-54,-47,-60,-47,-55,-46,-62,-46,-57,-47,-62,-47,-58,-47,-64,-46,-61,-48,-66,-50,-64,-49,-73,-62,-64,-66,-62,-59,-63,-64,-61,-54,-63,-64,-62,-55,-63,-63,-63,-54,-65,-63,-64,-55,-65,-63,-65,-54,-68,-64,-68,-58,-72,-64,-75,-52,-53,-49,-58,-50,-53,-47,-58,-48,-54,-47,-60,-47,-55,-46,-61,-45,-57,-47,-63,-46,-58,-48,-65,-46,-61,-49,-67,-50,-64,-50,-73,-62,-65,-67,-63,-59,-63,-65,-63,-57,-64,-64,-63,-56,-65,-64,-64,-54,-66,-64,-65,-55,-68,-64,-66,-54,-69,-65,-69,-58,-72,-66,-75,-50,-54,-49,-58,-47,-53,-49,-59,-45,-55,-48,-60,-45,-55,-49,-62,-44,-57,-47,-63,-45,-58,-48,-65,-47,-62,-51,-69,-52,-65,-52,-75,-61,-66,-68,-64,-58,-65,-67,-64,-56,-66,-66,-65,-55,-66,-65,-65,-54,-67,-64,-66,-55,-68,-65,-68,-54,-71,-66,-71,-60,-73,-67,-77,-54,-54,-52,-59,-51,-54,-50,-59,-49,-55,-49,-60,-48,-55,-49,-62,-46,-58,-49,-65,-48,-60,-49,-66,-46,-63,-50,-68,-52,-64,-52,-75,-66,-69,-73,-66,-62,-68,-69,-65,-60,-67,-68,-65,-59,-67,-69,-66,-56,-69,-67,-68,-57,-69,-66,-69,-54,-71,-66,-70,-60,-73,-69,-77,-56,-54,-52,-59,-53,-54,-51,-60,-50,-56,-51,-61,-49,-56,-50,-63,-47,-58,-50,-65,-48,-59,-51,-66,-47,-62,-52,-68,-54,-66,-53,-76,-69,-71,-73,-69,-66,-69,-72,-68,-62,-69,-71,-67,-61,-69,-70,-68,-58,-70,-68,-70,-58,-70,-68,-69,-56,-71,-68,-71,-62,-74,-69,-79,-54,-55,-53,-60,-52,-55,-53,-61,-51,-57,-54,-63,-50,-57,-53,-64,-49,-59,-51,-65,-50,-60,-53,-66,-49,-63,-54,-71,-55,-66,-55,-76,-69,-73,-76,-70,-66,-71,-75,-69,-65,-72,-74,-71,-63,-71,-71,-71,-60,-71,-70,-70,-61,-71,-70,-70,-59,-74,-70,-75,-63,-76,-70,-80,-62,-57,-58,-62,-59,-57,-56,-62,-56,-59,-54,-64,-55,-60,-54,-65,-52,-61,-54,-67,-53,-62,-54,-68,-53,-64,-56,-71,-55,-67,-56,-75,-77,-77,-83,-74,-74,-74,-79,-73,-70,-74,-76,-73,-68,-74,-75,-73,-64,-75,-74,-73,-64,-74,-73,-74,-63,-76,-74,-75,-64,-78,-74,-80,-66,-58,-61,-65,-61,-59,-57,-64,-57,-60,-56,-66,-55,-60,-56,-67,-55,-63,-57,-69,-54,-63,-56,-69,-54,-64,-57,-72,-59,-67,-58,-77,-82,-80,-86,-78,-77,-78,-81,-76,-73,-78,-79,-76,-69,-76,-78,-75,-68,-78,-78,-76,-67,-76,-77,-76,-66,-78,-77,-77,-70,-80,-77,-84,-67,-60,-65,-66,-62,-61,-63,-68,-62,-62,-62,-67,-60,-64,-61,-70,-57,-65,-59,-69,-56,-65,-59,-71,-58,-67,-62,-74,-63,-69,-63,-78,-94,-91,-100,-88,-88,-88,-95,-87,-85,-87,-92,-86,-82,-88,-90,-88,-78,-87,-88,-84,-77,-87,-87,-86,-76,-89,-87,-90,-80,-90,-87,-93
|
||||||
|
81
MLX90640_test/testdata.h
Normal file
81
MLX90640_test/testdata.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the mlxtest project.
|
||||||
|
* Copyright 2025 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// data from MLX documentation for algorithms testing
|
||||||
|
// this file should be included only once!
|
||||||
|
|
||||||
|
#ifdef _TESTDATA_H__
|
||||||
|
#error "Don't include this file several times!"
|
||||||
|
#endif
|
||||||
|
#define _TESTDATA_H__
|
||||||
|
|
||||||
|
#include "mlx90640.h"
|
||||||
|
|
||||||
|
static const uint16_t EEPROM[MLX_DMA_MAXLEN] = {
|
||||||
|
#include "eeprom.csv"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int16_t FRAME0[MLX_DMA_MAXLEN] = {
|
||||||
|
#include "frame0.csv"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int16_t FRAME1[MLX_DMA_MAXLEN] = {
|
||||||
|
#include "frame1.csv"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const MLX90640_params extracted_parameters = {
|
||||||
|
.kVdd = -3200
|
||||||
|
,.vdd25 = -12544
|
||||||
|
,.KvPTAT = 0.002197
|
||||||
|
,.KtPTAT = 42.625000
|
||||||
|
,.vPTAT25 = 12196
|
||||||
|
,.alphaPTAT = 9.0
|
||||||
|
,.gainEE = 5580
|
||||||
|
,.tgc = 0.000000
|
||||||
|
,.cpKv = 0.3750
|
||||||
|
,.cpKta = 0.004272
|
||||||
|
// ,.calibrationModeEE = 128
|
||||||
|
,.KsTa = -0.002441
|
||||||
|
,.CT = {0., 300., 500.}
|
||||||
|
,.KsTo = {-0.0002, -0.0002, -0.0002, -0.0002}
|
||||||
|
,.alphacorr = {}
|
||||||
|
,.alpha = {
|
||||||
|
#include "alpha.csv"
|
||||||
|
}
|
||||||
|
,.offset = {
|
||||||
|
#include "offset.csv"
|
||||||
|
}
|
||||||
|
,.kta = {
|
||||||
|
#include "kta.csv"
|
||||||
|
}
|
||||||
|
,.kv = {0.4375, 0.3750, 0.3750, 0.3750}
|
||||||
|
,.cpAlpha = {0.0000000028812792152, 0.0000000029037892091}
|
||||||
|
,.resolEE = 2
|
||||||
|
,.cpOffset = {-69, -65}
|
||||||
|
,.outliers = {0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const fp_t ToFrame[2][MLX_PIXNO] = {
|
||||||
|
{
|
||||||
|
#include "to_frame0.csv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
#include "to_frame0.csv"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
1
MLX90640_test/to_frame0.csv
Normal file
1
MLX90640_test/to_frame0.csv
Normal file
@ -0,0 +1 @@
|
|||||||
|
28.711,0.000,28.178,0.000,28.313,0.000,28.631,0.000,28.295,0.000,28.586,0.000,28.336,0.000,28.683,0.000,28.248,0.000,28.573,0.000,29.127,0.000,28.629,0.000,29.070,0.000,28.894,0.000,28.883,0.000,29.687,0.000,0.000,28.618,0.000,28.134,0.000,28.517,0.000,27.982,0.000,28.092,0.000,27.914,0.000,28.156,0.000,28.261,0.000,28.198,0.000,28.528,0.000,28.837,0.000,28.730,0.000,28.814,0.000,28.558,0.000,28.605,0.000,29.005,28.513,0.000,28.482,0.000,28.428,0.000,27.946,0.000,28.248,0.000,28.387,0.000,28.340,0.000,28.128,0.000,28.544,0.000,28.321,0.000,28.986,0.000,28.445,0.000,28.728,0.000,28.778,0.000,29.035,0.000,28.639,0.000,0.000,28.116,0.000,28.237,0.000,28.173,0.000,28.519,0.000,28.303,0.000,28.049,0.000,28.246,0.000,28.466,0.000,28.247,0.000,28.378,0.000,28.835,0.000,28.480,0.000,28.828,0.000,28.428,0.000,28.528,0.000,29.030,28.163,0.000,28.719,0.000,28.268,0.000,28.439,0.000,28.607,0.000,28.199,0.000,28.440,0.000,28.730,0.000,28.361,0.000,28.256,0.000,28.253,0.000,28.563,0.000,28.593,0.000,28.962,0.000,28.746,0.000,28.917,0.000,0.000,28.112,0.000,27.955,0.000,28.365,0.000,28.291,0.000,28.335,0.000,28.610,0.000,28.281,0.000,28.303,0.000,28.246,0.000,28.710,0.000,28.723,0.000,28.532,0.000,28.493,0.000,28.686,0.000,28.565,0.000,28.197,28.489,0.000,28.295,0.000,28.610,0.000,28.497,0.000,29.183,0.000,29.365,0.000,28.763,0.000,28.320,0.000,28.594,0.000,28.641,0.000,28.629,0.000,28.950,0.000,27.980,0.000,28.349,0.000,28.453,0.000,28.852,0.000,0.000,28.364,0.000,28.244,0.000,28.023,0.000,28.247,0.000,29.572,0.000,30.034,0.000,28.667,0.000,28.642,0.000,28.316,0.000,28.311,0.000,28.444,0.000,28.168,0.000,28.403,0.000,28.438,0.000,28.800,0.000,27.913,28.091,0.000,28.598,0.000,28.313,0.000,28.813,0.000,30.533,0.000,32.362,0.000,31.328,0.000,29.314,0.000,28.126,0.000,28.517,0.000,28.644,0.000,28.679,0.000,28.485,0.000,28.714,0.000,28.549,0.000,28.739,0.000,0.000,28.275,0.000,27.955,0.000,28.448,0.000,28.965,0.000,31.879,0.000,32.094,0.000,31.286,0.000,29.814,0.000,28.593,0.000,28.303,0.000,28.808,0.000,28.596,0.000,28.363,0.000,28.585,0.000,28.420,0.000,28.341,28.595,0.000,28.668,0.000,28.724,0.000,29.526,0.000,32.332,0.000,32.878,0.000,32.587,0.000,32.080,0.000,30.319,0.000,29.259,0.000,28.347,0.000,28.371,0.000,28.591,0.000,28.779,0.000,28.650,0.000,28.577,0.000,0.000,28.330,0.000,28.480,0.000,28.753,0.000,30.412,0.000,33.225,0.000,33.175,0.000,32.848,0.000,31.967,0.000,30.751,0.000,29.090,0.000,28.461,0.000,28.636,0.000,28.437,0.000,28.707,0.000,28.479,0.000,28.493,28.450,0.000,28.205,0.000,28.945,0.000,30.841,0.000,33.628,0.000,34.155,0.000,33.454,0.000,32.621,0.000,32.219,0.000,31.181,0.000,28.945,0.000,28.535,0.000,28.354,0.000,28.338,0.000,28.487,0.000,28.645,0.000,0.000,28.420,0.000,28.235,0.000,29.189,0.000,32.258,0.000,34.054,0.000,34.386,0.000,33.366,0.000,32.502,0.000,32.534,0.000,30.553,0.000,28.703,0.000,28.123,0.000,28.465,0.000,28.435,0.000,28.666,0.000,28.458,28.412,0.000,28.618,0.000,29.437,0.000,32.515,0.000,33.633,0.000,34.348,0.000,33.460,0.000,33.297,0.000,32.441,0.000,30.583,0.000,28.901,0.000,28.751,0.000,28.455,0.000,28.551,0.000,28.674,0.000,28.816,0.000,0.000,28.379,0.000,28.929,0.000,30.135,0.000,32.781,0.000,33.364,0.000,33.703,0.000,33.035,0.000,32.681,0.000,32.508,0.000,29.271,0.000,28.813,0.000,28.176,0.000,28.281,0.000,28.308,0.000,28.441,0.000,28.851,28.266,0.000,28.759,0.000,30.103,0.000,32.329,0.000,32.560,0.000,32.963,0.000,32.587,0.000,32.781,0.000,32.408,0.000,29.431,0.000,28.536,0.000,28.849,0.000,28.187,0.000,28.597,0.000,29.227,0.000,28.880,0.000,0.000,28.259,0.000,28.992,0.000,30.442,0.000,32.244,0.000,32.250,0.000,32.312,0.000,32.854,0.000,32.680,0.000,31.065,0.000,28.621,0.000,28.344,0.000,28.447,0.000,28.667,0.000,28.698,0.000,29.718,0.000,28.963,28.429,0.000,28.570,0.000,29.163,0.000,29.828,0.000,31.671,0.000,32.379,0.000,32.265,0.000,32.592,0.000,31.175,0.000,29.218,0.000,28.587,0.000,28.508,0.000,28.957,0.000,29.226,0.000,31.199,0.000,31.547,0.000,0.000,28.137,0.000,28.463,0.000,28.557,0.000,29.704,0.000,30.460,0.000,31.603,0.000,31.990,0.000,32.004,0.000,29.626,0.000,28.473,0.000,28.220,0.000,28.694,0.000,28.703,0.000,29.831,0.000,32.548,0.000,32.176,28.473,0.000,28.264,0.000,28.662,0.000,28.372,0.000,29.225,0.000,29.797,0.000,30.999,0.000,31.244,0.000,29.575,0.000,28.510,0.000,28.530,0.000,28.449,0.000,28.642,0.000,30.602,0.000,32.418,0.000,34.239,0.000,0.000,28.322,0.000,28.078,0.000,28.183,0.000,28.517,0.000,28.593,0.000,29.005,0.000,30.394,0.000,30.257,0.000,28.746,0.000,28.295,0.000,28.561,0.000,28.250,0.000,28.593,0.000,31.333,0.000,33.254,0.000,33.224,28.516,0.000,28.317,0.000,28.465,0.000,28.845,0.000,28.642,0.000,28.464,0.000,28.858,0.000,28.979,0.000,29.039,0.000,28.832,0.000,28.280,0.000,28.837,0.000,29.056,0.000,31.946,0.000,33.101,0.000,32.988,0.000,0.000,28.161,0.000,28.257,0.000,28.346,0.000,28.301,0.000,28.101,0.000,28.288,0.000,28.615,0.000,28.926,0.000,28.512,0.000,28.178,0.000,28.392,0.000,28.412,0.000,30.166,0.000,32.614,0.000,32.530,0.000,32.028
|
||||||
|
1
MLX90640_test/to_frame1.csv
Normal file
1
MLX90640_test/to_frame1.csv
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user