mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
244 lines
8.0 KiB
C
244 lines
8.0 KiB
C
/*
|
|
* This file is part of the MLX90640 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 "i2c.h"
|
|
#include "mlx90640.h"
|
|
#include "proto.h"
|
|
#include "strfunct.h"
|
|
#include "usb.h"
|
|
#include "version.inc"
|
|
|
|
extern uint32_t Tms;
|
|
|
|
static const char* _states[M_STATES_AMOUNT] = {
|
|
[M_ERROR] = "error",
|
|
[M_RELAX] = "do nothing",
|
|
[M_FIRSTSTART] = "first start",
|
|
[M_READCONF] = "read config",
|
|
[M_STARTIMA] = "start image",
|
|
[M_PROCESS] = "process subframe",
|
|
[M_READOUT] = "read subpage data",
|
|
[M_POWERON] = "wait after power on",
|
|
[M_POWEROFF1] = "turn power off",
|
|
[M_POWEROFF] = "wait without power",
|
|
};
|
|
|
|
// dump floating point array 24x32
|
|
static void dumpfarr(float *arr){
|
|
for(int row = 0; row < 24; ++row){
|
|
for(int col = 0; col < 32; ++col){
|
|
float2str(*arr++, 2); bufputchar(' ');
|
|
}
|
|
newline();
|
|
}
|
|
}
|
|
|
|
static void dumpparams(){
|
|
SEND("\nkVdd="); printi(params.kVdd);
|
|
SEND("\nvdd25="); printi(params.vdd25);
|
|
SEND("\nKvPTAT="); float2str(params.KvPTAT, 4);
|
|
SEND("\nKtPTAT="); float2str(params.KtPTAT, 4);
|
|
SEND("\nvPTAT25="); printi(params.vPTAT25);
|
|
SEND("\nalphaPTAT="); float2str(params.alphaPTAT, 2);
|
|
SEND("\ngainEE="); printi(params.gainEE);
|
|
SEND("\nPixel offset parameters:\n");
|
|
float *offset = params.offset;
|
|
for(int row = 0; row < 24; ++row){
|
|
for(int col = 0; col < 32; ++col){
|
|
float2str(*offset++, 2); bufputchar(' ');
|
|
}
|
|
newline();
|
|
}
|
|
SEND("K_talpha:\n");
|
|
dumpfarr(params.kta);
|
|
SEND("Kv: ");
|
|
for(int i = 0; i < 4; ++i){
|
|
float2str(params.kv[i], 2); bufputchar(' ');
|
|
}
|
|
SEND("\ncpOffset=");
|
|
printi(params.cpOffset[0]); SEND(", "); printi(params.cpOffset[1]);
|
|
SEND("\ncpKta="); float2str(params.cpKta, 2);
|
|
SEND("\ncpKv="); float2str(params.cpKv, 2);
|
|
SEND("\ntgc="); float2str(params.tgc, 2);
|
|
SEND("\ncpALpha="); float2str(params.cpAlpha[0], 2);
|
|
SEND(", "); float2str(params.cpAlpha[1], 2);
|
|
SEND("\nKsTa="); float2str(params.KsTa, 2);
|
|
SEND("\nAlpha:\n");
|
|
dumpfarr(params.alpha);
|
|
SEND("\nCT3="); float2str(params.CT[1], 2);
|
|
SEND("\nCT4="); float2str(params.CT[2], 2);
|
|
for(int i = 0; i < 4; ++i){
|
|
SEND("\nKsTo"); bufputchar('0'+i); bufputchar('=');
|
|
float2str(params.ksTo[i], 2);
|
|
SEND("\nalphacorr"); bufputchar('0'+i); bufputchar('=');
|
|
float2str(params.alphacorr[i], 2);
|
|
}
|
|
NL();
|
|
}
|
|
|
|
static void dumpimage(){
|
|
float *idata = mlx_image;
|
|
for(int row = 0; row < MLX_H; ++row){
|
|
for(int col = 0; col < MLX_W; ++col, ++idata){
|
|
float2str(*idata,1); bufputchar(' ');
|
|
}
|
|
newline();
|
|
}
|
|
NL();
|
|
}
|
|
|
|
const char *parse_cmd(char *buf){
|
|
int32_t Num = 0;
|
|
uint16_t r, d;
|
|
uint16_t *data;
|
|
const float pi = 3.1415927f, e = 2.7182818f;
|
|
char *ptr, cmd = *buf++;
|
|
switch(cmd){
|
|
case 'a':
|
|
if(buf != getnum(buf, &Num)){
|
|
if(Num & 0x80) return "Enter 7bit address";
|
|
i2c_set_addr7(Num);
|
|
return "Changed";
|
|
}else return "Wrong address";
|
|
break;
|
|
case 'd':
|
|
if(buf != (ptr = getnum(buf, &Num))){
|
|
r = Num;
|
|
if(ptr != getnum(ptr, &Num)){
|
|
if(Num < 1 || Num > MLX_DMA_MAXLEN) return "0<N<=832";
|
|
if(!read_data_dma(r, Num)) return("Can't read");
|
|
else return "OK";
|
|
}else return "Need amount";
|
|
}else return "Need reg";
|
|
break;
|
|
case 'E':
|
|
case 'e':
|
|
if(!mlx90640_take_image(cmd == 'e')) return "FAILED";
|
|
else return "OK";
|
|
break;
|
|
case 'f':
|
|
SEND("Float test: ");
|
|
float2str(0.f, 2); addtobuf(", ");
|
|
float2str(pi, 1); addtobuf(", ");
|
|
float2str(-e, 2); addtobuf(", ");
|
|
float2str(-pi, 3); addtobuf(", ");
|
|
float2str(e, 4); addtobuf(", ");
|
|
uint32_t uu = INF | 0x80000000;
|
|
float *f = (float*)&uu;
|
|
float2str(*f, 4); addtobuf(", ");
|
|
uu = NAN;
|
|
f = (float*)&uu;
|
|
float2str(*f, 4);
|
|
NL();
|
|
return NULL;
|
|
break;
|
|
case 'g':
|
|
if(buf != (ptr = getnum(buf, &Num))){
|
|
r = Num;
|
|
if(ptr != getnum(ptr, &Num)){
|
|
if(Num < 1 || Num > MLX_DMA_MAXLEN) return "N from 0 to 832";
|
|
uint16_t od = d = Num;
|
|
if(!(data = read_data(r, &d))){
|
|
SEND("Can't read\n");
|
|
return NULL;
|
|
}
|
|
if(d != od){
|
|
addtobuf("Got only ");
|
|
printu(d);
|
|
addtobuf(" values\n");
|
|
}
|
|
for(uint16_t i = 0; i < d; ++i){
|
|
printuhex(r + i);
|
|
addtobuf(" ");
|
|
printuhex(data[i]);
|
|
newline();
|
|
}
|
|
sendbuf();
|
|
return NULL;
|
|
}else return "Need amount";
|
|
}else return "Need reg";
|
|
break;
|
|
case 'I':
|
|
i2c_setup(TRUE);
|
|
return "I2C restarted";
|
|
break;
|
|
case 'M':
|
|
SEND("MLX state: "); SEND(_states[mlx_state]);
|
|
SEND("\npower="); printu(MLXPOW_VAL()); NL();
|
|
return NULL;
|
|
break;
|
|
case 'O':
|
|
mlx90640_restart();
|
|
return "Power off/on";
|
|
break;
|
|
case 'P':
|
|
dumpparams();
|
|
return NULL;
|
|
break;
|
|
case 'r':
|
|
if(buf != (ptr = getnum(buf, &Num))){
|
|
if(read_reg(Num, &d)){
|
|
printuhex(d); NL();
|
|
return NULL;
|
|
}else return "Can't read";
|
|
}else return "Need register address";
|
|
break;
|
|
case 'R':
|
|
USB_sendstr("Soft reset\n");
|
|
NVIC_SystemReset();
|
|
break;
|
|
case 'S':
|
|
dumpimage();
|
|
return NULL;
|
|
break;
|
|
case 'T':
|
|
SEND("Tms="); printu(Tms); NL();
|
|
return NULL;
|
|
break;
|
|
case 'w':
|
|
if(buf == (ptr = getnum(buf, &Num))) return "Need register";
|
|
r = Num;
|
|
if(ptr == getnum(ptr, &Num)) return "Need data";
|
|
if(write_reg(r, Num)) return "OK";
|
|
else return "Failed";
|
|
break;
|
|
default: // help
|
|
addtobuf(
|
|
"MLX90640 build #" BUILD_NUMBER " @" BUILD_DATE "\n\n"
|
|
"'a addr' - change MLX I2C address to `addr`\n"
|
|
"'d reg N' - read registers starting from `reg` using DMA\n"
|
|
"'Ee' - expose image: E - full, e - simple\n"
|
|
"'f' - test float printf (0.00, 3.1, -2.72, -3.142, 2.7183, -INF, NAN)\n"
|
|
"'g reg N' - read N registers starting from `reg`\n"
|
|
"'I' - restart I2C\n"
|
|
"'M' - MLX state\n"
|
|
"'O' - turn On or restart MLX sensor\n"
|
|
"'P' - dump params\n"
|
|
"'r reg' - read `reg`\n"
|
|
"'R' - software reset\n"
|
|
"'S' - show image\n"
|
|
"'T' - get Tms\n"
|
|
"'w reg dword' - write `dword` to `reg`\n"
|
|
);
|
|
NL();
|
|
return NULL;
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|