mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #1062 from openmv/mlx_driver
Update MLX and FIR drivers.
This commit is contained in:
commit
6e0f5c5d67
@ -53,6 +53,7 @@ MICROPY_DIR=micropython
|
||||
LEPTON_DIR=drivers/lepton
|
||||
LSM6DS3_DIR=drivers/lsm6ds3
|
||||
WINC1500_DIR=drivers/winc1500
|
||||
MLX90621_DIR=drivers/mlx90621
|
||||
MLX90640_DIR=drivers/mlx90640
|
||||
LIBPDM_DIR=lib/libpdm
|
||||
TENSORFLOW_DIR=lib/libtf
|
||||
|
||||
201
src/drivers/mlx90621/LICENSE
Normal file
201
src/drivers/mlx90621/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
25
src/drivers/mlx90621/Makefile
Normal file
25
src/drivers/mlx90621/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# This file is part of the OpenMV project.
|
||||
#
|
||||
# Copyright (c) 2013-2019 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
# Copyright (c) 2013-2019 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
#
|
||||
# This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
#
|
||||
# MLX90621 Makefile
|
||||
SRCS = $(wildcard src/*.c)
|
||||
OBJS = $(addprefix $(BUILD)/, $(SRCS:.c=.o))
|
||||
OBJ_DIRS = $(sort $(dir $(OBJS)))
|
||||
|
||||
all: | $(OBJ_DIRS) $(OBJS)
|
||||
$(OBJ_DIRS):
|
||||
$(MKDIR) -p $@
|
||||
|
||||
$(BUILD)/%.o : %.c
|
||||
$(ECHO) "CC $<"
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(BUILD)/%.o : %.s
|
||||
$(ECHO) "AS $<"
|
||||
$(AS) $(AFLAGS) $< -o $@
|
||||
|
||||
-include $(OBJS:%.o=%.d)
|
||||
54
src/drivers/mlx90621/include/MLX90621_API.h
Normal file
54
src/drivers/mlx90621/include/MLX90621_API.h
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @copyright (C) 2017 Melexis N.V.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef _MLX621_API_H_
|
||||
#define _MLX621_API_H_
|
||||
|
||||
#define SCALEALPHA 0.000001
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t vTh25;
|
||||
float kT1;
|
||||
float kT2;
|
||||
float tgc;
|
||||
float KsTa;
|
||||
float ksTo;
|
||||
float alpha[64];
|
||||
float ai[64];
|
||||
float bi[64];
|
||||
float cpAlpha;
|
||||
float cpA;
|
||||
float cpB;
|
||||
uint16_t brokenPixels[5];
|
||||
uint16_t outlierPixels[5];
|
||||
} paramsMLX90621;
|
||||
|
||||
int MLX90621_DumpEE(uint8_t *eeData);
|
||||
int MLX90621_GetFrameData(uint16_t *frameData);
|
||||
int MLX90621_Configure(uint8_t *eeData);
|
||||
int MLX90621_GetOscillatorTrim(uint16_t *oscTrim);
|
||||
int MLX90621_GetConfiguration(uint16_t *cfgReg);
|
||||
int MLX90621_ExtractParameters(uint8_t *eeData, paramsMLX90621 *mlx90621);
|
||||
float MLX90621_GetTa(uint16_t *frameData, const paramsMLX90621 *params);
|
||||
void MLX90621_GetImage(uint16_t *frameData, const paramsMLX90621 *params, float *result);
|
||||
void MLX90621_CalculateTo(uint16_t *frameData, const paramsMLX90621 *params, float emissivity, float tr, float *result);
|
||||
int MLX90621_SetResolution(uint8_t resolution);
|
||||
int MLX90621_GetCurResolution();
|
||||
int MLX90621_SetRefreshRate(uint8_t refreshRate);
|
||||
int MLX90621_GetRefreshRate();
|
||||
|
||||
#endif
|
||||
25
src/drivers/mlx90621/include/MLX90621_I2C_Driver.h
Normal file
25
src/drivers/mlx90621/include/MLX90621_I2C_Driver.h
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @copyright (C) 2017 Melexis N.V.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef _MLX90621_I2C_Driver_H_
|
||||
#define _MLX90621_I2C_Driver_H_
|
||||
#include <stdint.h>
|
||||
void MLX90621_I2CInit(I2C_HandleTypeDef *i2c);
|
||||
int MLX90621_I2CReadEEPROM(uint8_t slaveAddr, uint8_t startAddress, uint16_t nMemAddressRead, uint8_t *data);
|
||||
int MLX90621_I2CRead(uint8_t slaveAddr, uint8_t command, uint8_t startAddress,
|
||||
uint8_t addressStep, uint8_t nMemAddressRead, uint16_t *data);
|
||||
int MLX90621_I2CWrite(uint8_t slaveAddr, uint8_t command, uint8_t checkValue, uint16_t data);
|
||||
#endif
|
||||
476
src/drivers/mlx90621/src/MLX90621_API.c
Normal file
476
src/drivers/mlx90621/src/MLX90621_API.c
Normal file
@ -0,0 +1,476 @@
|
||||
/**
|
||||
* @copyright (C) 2017 Melexis N.V.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#include STM32_HAL_H
|
||||
#include <MLX90621_I2C_Driver.h>
|
||||
#include <MLX90621_API.h>
|
||||
#include <math.h>
|
||||
#define pow(a,b) powf(a,b)
|
||||
#define sqrt(x) sqrtf(x)
|
||||
|
||||
static void ExtractPTATParameters(uint8_t *eeData, paramsMLX90621 *mlx90621);
|
||||
static void ExtractTgcParameters(uint8_t *eeData, paramsMLX90621 *mlx90621);
|
||||
static void ExtractKsTaParameters(uint8_t *eeData, paramsMLX90621 *mlx90621);
|
||||
static void ExtractKsToParameters(uint8_t *eeData, paramsMLX90621 *mlx90621);
|
||||
static void ExtractAlphaParameters(uint8_t *eeData, paramsMLX90621 *mlx90621);
|
||||
static void ExtractOffsetParameters(uint8_t *eeData, paramsMLX90621 *mlx90621);
|
||||
|
||||
|
||||
int MLX90621_DumpEE(uint8_t *eeData)
|
||||
{
|
||||
return MLX90621_I2CReadEEPROM(0x50, 0, 256, eeData);
|
||||
}
|
||||
|
||||
|
||||
int MLX90621_GetFrameData(uint16_t *frameData)
|
||||
{
|
||||
int error = 1;
|
||||
|
||||
error = MLX90621_I2CRead(0x60, 0x02, 0, 1, 66, frameData);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int MLX90621_Configure(uint8_t *eeData)
|
||||
{
|
||||
int error = 1;
|
||||
uint16_t value;
|
||||
|
||||
error = MLX90621_I2CWrite(0x60, 0x04, 0xAA, eeData[247]);
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
value = 256*eeData[246] + eeData[245];
|
||||
value = value | 0x0400;
|
||||
error = MLX90621_I2CWrite(0x60, 0x03, 0x55, value);
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
int MLX90621_GetOscillatorTrim(uint16_t *oscTrim)
|
||||
{
|
||||
int error = 1;
|
||||
|
||||
error = MLX90621_I2CRead(0x60, 0x02, 0x93, 0, 1, oscTrim);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int MLX90621_GetConfiguration(uint16_t *cfgReg)
|
||||
{
|
||||
int error = 1;
|
||||
|
||||
error = MLX90621_I2CRead(0x60, 0x02, 0x92, 0, 1, cfgReg);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int MLX90621_ExtractParameters(uint8_t *eeData, paramsMLX90621 *mlx90621)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
ExtractPTATParameters(eeData, mlx90621);
|
||||
ExtractTgcParameters(eeData, mlx90621);
|
||||
ExtractKsTaParameters(eeData, mlx90621);
|
||||
ExtractKsToParameters(eeData, mlx90621);
|
||||
ExtractAlphaParameters(eeData, mlx90621);
|
||||
ExtractOffsetParameters(eeData, mlx90621);
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int MLX90621_SetResolution(uint8_t resolution)
|
||||
{
|
||||
uint16_t cfgReg;
|
||||
int value;
|
||||
int error;
|
||||
|
||||
value = (resolution & 0x03) << 4;
|
||||
|
||||
error = MLX90621_GetConfiguration(&cfgReg);
|
||||
|
||||
if(error == 0)
|
||||
{
|
||||
value = (cfgReg & 0xFFCF) | value;
|
||||
error = MLX90621_I2CWrite(0x60, 0x03, 0x55, value);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int MLX90621_GetCurResolution()
|
||||
{
|
||||
uint16_t cfgReg;
|
||||
int resolution;
|
||||
int error;
|
||||
|
||||
error = MLX90621_GetConfiguration(&cfgReg);
|
||||
if(error != 0)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
resolution = (cfgReg & 0x0030) >> 4;
|
||||
|
||||
return resolution;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int MLX90621_SetRefreshRate(uint8_t refreshRate)
|
||||
{
|
||||
uint16_t cfgReg;
|
||||
int value;
|
||||
int error;
|
||||
|
||||
value = refreshRate & 0x0F;
|
||||
|
||||
error = MLX90621_GetConfiguration(&cfgReg);
|
||||
|
||||
if(error == 0)
|
||||
{
|
||||
value = (cfgReg & 0xFFF0) | value;
|
||||
error = MLX90621_I2CWrite(0x60, 0x03, 0x55, value);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int MLX90621_GetRefreshRate()
|
||||
{
|
||||
uint16_t cfgReg;
|
||||
int rr;
|
||||
int error;
|
||||
|
||||
error = MLX90621_GetConfiguration(&cfgReg);
|
||||
if(error != 0)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
rr = (cfgReg & 0x000F);
|
||||
|
||||
return rr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void MLX90621_CalculateTo(uint16_t *frameData, const paramsMLX90621 *params, float emissivity, float tr, float *result)
|
||||
{
|
||||
float ta;
|
||||
float ta4;
|
||||
float tr4;
|
||||
float taTr;
|
||||
float irDataCP;
|
||||
float irData;
|
||||
float alphaCompensated;
|
||||
float Sx;
|
||||
float To;
|
||||
|
||||
ta = MLX90621_GetTa(frameData, params);
|
||||
|
||||
ta4 = (ta + 273.15);
|
||||
ta4 = ta4 * ta4;
|
||||
ta4 = ta4 * ta4;
|
||||
tr4 = (tr + 273.15);
|
||||
tr4 = tr4 * tr4;
|
||||
tr4 = tr4 * tr4;
|
||||
taTr = tr4 - (tr4-ta4)/emissivity;
|
||||
|
||||
//------------------------- To calculation -------------------------------------
|
||||
|
||||
irDataCP = frameData[65];
|
||||
|
||||
if(irDataCP > 32767)
|
||||
{
|
||||
irDataCP = irDataCP - 65536;
|
||||
}
|
||||
|
||||
irDataCP = irDataCP - (params->cpA + params->cpB * (ta - 25));
|
||||
|
||||
for( int pixelNumber = 0; pixelNumber < 64; pixelNumber++)
|
||||
{
|
||||
irData = frameData[pixelNumber];
|
||||
if(irData > 32767)
|
||||
{
|
||||
irData = irData - 65536;
|
||||
}
|
||||
|
||||
irData = irData - (params->ai[pixelNumber] + params->bi[pixelNumber] * (ta - 25));
|
||||
|
||||
irData = irData - params->tgc * irDataCP;
|
||||
irData = irData / emissivity;
|
||||
|
||||
alphaCompensated = params->alpha[pixelNumber] - params->tgc * params->cpAlpha;
|
||||
alphaCompensated = alphaCompensated *(1 + params->KsTa * (ta - 25));
|
||||
|
||||
Sx = alphaCompensated * alphaCompensated * alphaCompensated * (irData + alphaCompensated * taTr);
|
||||
Sx = sqrt(sqrt(Sx)) * params->ksTo;
|
||||
|
||||
To = sqrt(sqrt(irData/(alphaCompensated * (1 - params->ksTo * 273.15) + Sx) + taTr)) - 273.15;
|
||||
|
||||
result[pixelNumber] = To;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void MLX90621_GetImage(uint16_t *frameData, const paramsMLX90621 *params, float *result)
|
||||
{
|
||||
float ta;
|
||||
float irDataCP;
|
||||
float irData;
|
||||
float alphaCompensated;
|
||||
|
||||
ta = MLX90621_GetTa(frameData, params);
|
||||
|
||||
//------------------------- Image calculation -------------------------------------
|
||||
|
||||
irDataCP = frameData[65];
|
||||
|
||||
if(irDataCP > 32767)
|
||||
{
|
||||
irDataCP = irDataCP - 65536;
|
||||
}
|
||||
|
||||
irDataCP = irDataCP - (params->cpA + params->cpB * (ta - 25));
|
||||
|
||||
for( int pixelNumber = 0; pixelNumber < 64; pixelNumber++)
|
||||
{
|
||||
irData = frameData[pixelNumber];
|
||||
if(irData > 32767)
|
||||
{
|
||||
irData = irData - 65536;
|
||||
}
|
||||
|
||||
irData = irData - (params->ai[pixelNumber] + params->bi[pixelNumber] * (ta - 25));
|
||||
|
||||
irData = irData - params->tgc * irDataCP;
|
||||
|
||||
alphaCompensated = params->alpha[pixelNumber] - params->tgc * irDataCP;
|
||||
alphaCompensated = alphaCompensated *(1 + params->KsTa * (ta - 25));
|
||||
|
||||
result[pixelNumber] = irData/alphaCompensated;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
float MLX90621_GetTa(uint16_t *frameData, const paramsMLX90621 *params)
|
||||
{
|
||||
float ptat;
|
||||
float ta;
|
||||
|
||||
ptat = frameData[64];
|
||||
if(ptat > 32767)
|
||||
{
|
||||
ptat = ptat - 65536;
|
||||
}
|
||||
|
||||
ta = params->vTh25 - ptat;
|
||||
ta = 4*params->kT2*ta;
|
||||
ta = params->kT1*params->kT1 - ta;
|
||||
ta = sqrt(ta)-params->kT1;
|
||||
ta = ta / (2*params->kT2);
|
||||
ta = ta + 25;
|
||||
|
||||
return ta;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ExtractPTATParameters(uint8_t *eeData, paramsMLX90621 *mlx90621)
|
||||
{
|
||||
float kt1;
|
||||
float kt2;
|
||||
int16_t vth25;
|
||||
int kt1Scale = 0;
|
||||
int kt2Scale = 0;
|
||||
int resolution = 3;
|
||||
uint16_t data;
|
||||
|
||||
resolution = resolution - MLX90621_GetCurResolution();
|
||||
kt1Scale = (eeData[210] & 0xF0) >> 4;
|
||||
kt2Scale = eeData[210] & 0x0F;
|
||||
kt2Scale = kt2Scale + 10;
|
||||
kt1Scale = kt1Scale + resolution;
|
||||
kt2Scale = kt2Scale + resolution;
|
||||
|
||||
data = (eeData[219]<<8) + eeData[218];
|
||||
vth25 = data;
|
||||
|
||||
kt1 = (eeData[221]<<8) + eeData[220];
|
||||
if (kt1 > 32767)
|
||||
{
|
||||
kt1 = kt1 - 65536;
|
||||
}
|
||||
|
||||
kt1 = kt1 / (1<<kt1Scale);
|
||||
|
||||
kt2 = (eeData[223]<<8) + eeData[222];
|
||||
if (kt2 > 32767)
|
||||
{
|
||||
kt2 = kt2 - 65536;
|
||||
}
|
||||
|
||||
kt2 = kt2 / (1<<kt2Scale);
|
||||
|
||||
mlx90621->vTh25 = vth25;
|
||||
mlx90621->kT1 = kt1;
|
||||
mlx90621->kT2 = kt2;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ExtractTgcParameters(uint8_t *eeData, paramsMLX90621 *mlx90621)
|
||||
{
|
||||
float tgc;
|
||||
tgc = eeData[216]/32.0f;
|
||||
|
||||
mlx90621->tgc = tgc;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ExtractKsTaParameters(uint8_t *eeData, paramsMLX90621 *mlx90621)
|
||||
{
|
||||
float KsTa;
|
||||
KsTa = (eeData[231] << 8) + eeData[230];
|
||||
if(KsTa > 32767)
|
||||
{
|
||||
KsTa = KsTa - 65536;
|
||||
}
|
||||
KsTa = KsTa / (1<<20);
|
||||
|
||||
mlx90621->KsTa = KsTa;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ExtractKsToParameters(uint8_t *eeData, paramsMLX90621 *mlx90621)
|
||||
{
|
||||
int scale;
|
||||
|
||||
scale = eeData[192] & 0x0F;
|
||||
scale = scale + 8;
|
||||
|
||||
mlx90621->ksTo = eeData[196];
|
||||
|
||||
if(mlx90621->ksTo > 127)
|
||||
{
|
||||
mlx90621->ksTo = mlx90621->ksTo - 256;
|
||||
}
|
||||
mlx90621->ksTo = mlx90621->ksTo / (1 << scale);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ExtractAlphaParameters(uint8_t *eeData, paramsMLX90621 *mlx90621)
|
||||
{
|
||||
float alphaScale;
|
||||
float deltaScale;
|
||||
uint8_t resScale;
|
||||
float alphaCom;
|
||||
float alphaTemp;
|
||||
float temp;
|
||||
|
||||
alphaScale = eeData[226];
|
||||
deltaScale = eeData[227];
|
||||
resScale = 3 - MLX90621_GetCurResolution();
|
||||
alphaCom = (eeData[225]<<8) + eeData[224];
|
||||
alphaScale = pow(2,alphaScale);
|
||||
deltaScale = pow(2,deltaScale);
|
||||
alphaCom = alphaCom / alphaScale;
|
||||
|
||||
for(int i = 0; i < 64; i++)
|
||||
{
|
||||
temp = eeData[128+i];
|
||||
temp = temp / deltaScale;
|
||||
alphaTemp = (alphaCom + temp)/(1<<resScale);
|
||||
mlx90621->alpha[i] = alphaTemp;
|
||||
}
|
||||
|
||||
alphaTemp = (eeData[215]<<8) + eeData[214];
|
||||
alphaTemp = alphaTemp / alphaScale;
|
||||
|
||||
mlx90621->cpAlpha = alphaTemp / (1<<resScale);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ExtractOffsetParameters(uint8_t *eeData, paramsMLX90621 *mlx90621)
|
||||
{
|
||||
uint8_t aScale;
|
||||
float bScale;
|
||||
uint8_t resScale;
|
||||
int16_t aCom;
|
||||
float aTemp;
|
||||
float bTemp;
|
||||
uint16_t data;
|
||||
|
||||
aScale = eeData[217]>>4;
|
||||
bScale = eeData[217] & 0x0F;
|
||||
resScale = 3 - MLX90621_GetCurResolution();
|
||||
bScale = pow(2, (float)(bScale+resScale));
|
||||
|
||||
data = (eeData[209]<<8) + eeData[208];
|
||||
aCom = data;
|
||||
|
||||
for(int i=0; i<64; i++)
|
||||
{
|
||||
aTemp = eeData[i]<<aScale;
|
||||
bTemp = eeData[64+i];
|
||||
if (bTemp > 127)
|
||||
{
|
||||
bTemp = bTemp - 256;
|
||||
}
|
||||
bTemp = bTemp / bScale;
|
||||
|
||||
mlx90621->ai[i] = (aCom + aTemp) / (1<<resScale);
|
||||
mlx90621->bi[i] = bTemp;
|
||||
}
|
||||
|
||||
aTemp = (eeData[212]<<8) + eeData[211];
|
||||
if (aTemp > 32767)
|
||||
{
|
||||
aTemp = aTemp - 65536;
|
||||
}
|
||||
aTemp = aTemp / (1<<resScale);
|
||||
|
||||
bTemp = eeData[213];
|
||||
if (bTemp > 127)
|
||||
{
|
||||
bTemp = bTemp - 256;
|
||||
}
|
||||
bTemp = bTemp / bScale;
|
||||
|
||||
mlx90621->cpA = aTemp;
|
||||
mlx90621->cpB = bTemp;
|
||||
}
|
||||
78
src/drivers/mlx90621/src/MLX90621_I2C_Driver.c
Normal file
78
src/drivers/mlx90621/src/MLX90621_I2C_Driver.c
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @copyright (C) 2017 Melexis N.V.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include STM32_HAL_H
|
||||
#include "cambus.h"
|
||||
#include "MLX90621_I2C_Driver.h"
|
||||
|
||||
static I2C_HandleTypeDef *hi2c;
|
||||
|
||||
void MLX90621_I2CInit(I2C_HandleTypeDef *i2c)
|
||||
{
|
||||
hi2c = i2c;
|
||||
}
|
||||
|
||||
int MLX90621_I2CReadEEPROM(uint8_t slaveAddr, uint8_t startAddress, uint16_t nMemAddressRead, uint8_t *data)
|
||||
{
|
||||
if (cambus_write_bytes_seq(hi2c, (slaveAddr << 1), &startAddress, 1, true) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cambus_read_bytes_seq(hi2c, (slaveAddr << 1), data, nMemAddressRead, false) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MLX90621_I2CRead(uint8_t slaveAddr,uint8_t command,
|
||||
uint8_t startAddress, uint8_t addressStep, uint8_t nMemAddressRead, uint16_t *data)
|
||||
{
|
||||
uint8_t cmd[4] = {
|
||||
command,
|
||||
startAddress,
|
||||
addressStep,
|
||||
nMemAddressRead
|
||||
};
|
||||
|
||||
if (cambus_write_bytes_seq(hi2c, (slaveAddr << 1), cmd, 4, true) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cambus_read_bytes_seq(hi2c, (slaveAddr << 1), (uint8_t *) data, nMemAddressRead * 2, false) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MLX90621_I2CWrite(uint8_t slaveAddr, uint8_t command, uint8_t checkValue, uint16_t data)
|
||||
{
|
||||
uint8_t cmd[5] = {
|
||||
command,
|
||||
(data & 0x00FF) - checkValue,
|
||||
(data & 0x00FF),
|
||||
(data >> 8) - checkValue,
|
||||
(data >> 8)
|
||||
};
|
||||
|
||||
if (cambus_write_bytes_seq(hi2c, (slaveAddr << 1), cmd, 5, false) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -10,8 +10,9 @@
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include STM32_HAL_H
|
||||
#include "systick.h"
|
||||
#include "omv_boardconfig.h"
|
||||
#include "cambus.h"
|
||||
#define I2C_TIMEOUT (1000)
|
||||
@ -215,3 +216,56 @@ int cambus_writew_bytes(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint16_t reg_a
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cambus_read_bytes_seq(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint8_t *buf, int len, bool nostop)
|
||||
{
|
||||
int ret = 0;
|
||||
HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);
|
||||
HAL_NVIC_EnableIRQ(I2C2_ER_IRQn);
|
||||
|
||||
if (HAL_I2C_Master_Seq_Receive_IT(i2c, slv_addr, buf, len,
|
||||
(nostop == true) ? I2C_FIRST_FRAME : I2C_FIRST_AND_LAST_FRAME) != HAL_OK) {
|
||||
ret = -1;
|
||||
goto i2c_error;
|
||||
}
|
||||
|
||||
mp_uint_t tick_start = mp_hal_ticks_ms();
|
||||
while (HAL_I2C_GetState(i2c) != HAL_I2C_STATE_READY) {
|
||||
if ((mp_hal_ticks_ms() - tick_start) >= I2C_TIMEOUT) {
|
||||
ret = -1;
|
||||
}
|
||||
__WFI();
|
||||
}
|
||||
|
||||
i2c_error:
|
||||
HAL_NVIC_DisableIRQ(I2C2_EV_IRQn);
|
||||
HAL_NVIC_DisableIRQ(I2C2_ER_IRQn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cambus_write_bytes_seq(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint8_t *buf, int len, bool nostop)
|
||||
{
|
||||
int ret = 0;
|
||||
HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);
|
||||
HAL_NVIC_EnableIRQ(I2C2_ER_IRQn);
|
||||
|
||||
if (HAL_I2C_Master_Seq_Transmit_IT(i2c, slv_addr, buf, len,
|
||||
(nostop == true) ? I2C_FIRST_FRAME : I2C_FIRST_AND_LAST_FRAME) != HAL_OK) {
|
||||
ret = -1;
|
||||
goto i2c_error;
|
||||
}
|
||||
|
||||
mp_uint_t tick_start = mp_hal_ticks_ms();
|
||||
while (HAL_I2C_GetState(i2c) != HAL_I2C_STATE_READY) {
|
||||
if ((mp_hal_ticks_ms() - tick_start) >= I2C_TIMEOUT) {
|
||||
ret = -1;
|
||||
goto i2c_error;
|
||||
}
|
||||
__WFI();
|
||||
}
|
||||
|
||||
i2c_error:
|
||||
HAL_NVIC_DisableIRQ(I2C2_EV_IRQn);
|
||||
HAL_NVIC_DisableIRQ(I2C2_ER_IRQn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#ifndef __CAMBUS_H__
|
||||
#define __CAMBUS_H__
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include STM32_HAL_H
|
||||
#if defined(STM32F4)
|
||||
#define I2C_TIMING_STANDARD (100000U)
|
||||
@ -46,4 +47,6 @@ int cambus_read_bytes(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint8_t reg_addr
|
||||
int cambus_write_bytes(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint8_t reg_addr, uint8_t *buf, int len);
|
||||
int cambus_readw_bytes(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint16_t reg_addr, uint8_t *buf, int len);
|
||||
int cambus_writew_bytes(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint16_t reg_addr, uint8_t *buf, int len);
|
||||
int cambus_read_bytes_seq(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint8_t *buf, int len, bool nostop);
|
||||
int cambus_write_bytes_seq(I2C_HandleTypeDef *i2c, uint8_t slv_addr, uint8_t *buf, int len, bool nostop);
|
||||
#endif // __CAMBUS_H__
|
||||
|
||||
@ -15,10 +15,13 @@
|
||||
#include "py/mphal.h"
|
||||
#include "systick.h"
|
||||
|
||||
#include "soft_i2c.h"
|
||||
#include "cambus.h"
|
||||
#include "MLX90640_I2C_Driver.h"
|
||||
#include "MLX90640_API.h"
|
||||
#include "MLX90640_I2C_Driver.h"
|
||||
|
||||
#include "MLX90621_API.h"
|
||||
#include "MLX90621_I2C_Driver.h"
|
||||
|
||||
#include "omv_boardconfig.h"
|
||||
#include "framebuffer.h"
|
||||
#include "sensor.h"
|
||||
@ -27,80 +30,27 @@
|
||||
#include "py_image.h"
|
||||
#include "py_fir.h"
|
||||
|
||||
#define FIR_EEPROM_ADDR 0xA0
|
||||
#define FIR_MODULE_ADDR 0xC0
|
||||
|
||||
#define FIR_READ_CMD 0x02
|
||||
#define FIR_WR_CFG_REG 0x03
|
||||
#define FIR_WR_TRIM_CMD 0x04
|
||||
|
||||
#define CAL_OSC_TRIM 0xF7
|
||||
|
||||
#define CAL_VTH_L 0xDA
|
||||
#define CAL_VTH_H 0xDB
|
||||
|
||||
#define CAL_KT1_L 0xDC
|
||||
#define CAL_KT1_H 0xDD
|
||||
#define CAL_K_T1_SCALE 0xD2
|
||||
|
||||
#define CAL_KT2_L 0xDE
|
||||
#define CAL_KT2_H 0xDF
|
||||
#define CAL_K_T2_SCALE 0xD2
|
||||
|
||||
#define CAL_ACOMMON_L 0xD0
|
||||
#define CAL_ACOMMON_H 0xD1
|
||||
|
||||
#define CAL_AI_SCALE 0xD9
|
||||
#define CAL_AI_OFFSET 0x00
|
||||
|
||||
#define CAL_BI_SCALE 0xD9
|
||||
#define CAL_BI_OFFSET 0x40
|
||||
|
||||
#define CAL_TGC 0xD8
|
||||
|
||||
#define CAL_EMISS_L 0xE4
|
||||
#define CAL_EMISS_H 0xE5
|
||||
|
||||
#define CAL_KSTA_L 0xE6
|
||||
#define CAL_KSTA_H 0xE7
|
||||
|
||||
#define CAL_A0_L 0xE0
|
||||
#define CAL_A0_H 0xE1
|
||||
#define CAL_A0_SCALE 0xE2
|
||||
#define CAL_D_A_SCALE 0xE3
|
||||
#define CAL_A_CP_OFFSET 0x80
|
||||
|
||||
#define CAL_ALPHA_CP_L 0xD6
|
||||
#define CAL_ALPHA_CP_H 0xD7
|
||||
|
||||
#define CAL_KS_SCALE 0xC0
|
||||
#define CAL_KS4_EE 0xC4
|
||||
|
||||
#define CAL_ACP_L 0xD3
|
||||
#define CAL_ACP_H 0xD4
|
||||
|
||||
#define CAL_BCP 0xD5
|
||||
|
||||
#define MLX90640_ADDR 0x33
|
||||
|
||||
#define AMG8833_ADDR 0xD2
|
||||
|
||||
// MLX variables
|
||||
static float *a_ij = NULL;
|
||||
static float *b_ij = NULL;
|
||||
static float *alpha_ij = NULL;
|
||||
static float v_th, k_t1, k_t2, tgc, emissivity, ksta, alpha_cp, ks4, a_cp, b_cp;
|
||||
|
||||
static uint8_t width = 0;
|
||||
static uint8_t height = 0;
|
||||
static uint8_t IR_refresh_rate = 0;
|
||||
static uint8_t ADC_resolution = 0;
|
||||
static void *mlx_data= NULL;
|
||||
|
||||
static I2C_HandleTypeDef fir_i2c = {0}; // FIR/I2C bus.
|
||||
// TODO temporary hack.
|
||||
#ifdef PORTENTA
|
||||
extern I2C_HandleTypeDef I2CHandle3; // FIR/I2C bus.
|
||||
#define fir_i2c (I2CHandle3)
|
||||
#else
|
||||
extern I2C_HandleTypeDef I2CHandle2; // FIR/I2C bus.
|
||||
#define fir_i2c (I2CHandle2)
|
||||
#endif
|
||||
|
||||
static enum {
|
||||
FIR_NONE,
|
||||
FIR_SHIELD,
|
||||
MLX90621,
|
||||
FIR_MLX90640,
|
||||
FIR_AMG8833
|
||||
} fir_sensor = FIR_NONE;
|
||||
@ -136,95 +86,6 @@ static void generate_scl_train()
|
||||
debug_printf("reset stuck i2c device\n");
|
||||
}
|
||||
|
||||
static float calculate_Ta() // ambient temp
|
||||
{
|
||||
// Code to handle dealing with brown-out conditions.
|
||||
{
|
||||
uint16_t config_reg;
|
||||
test_ack(soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [4]) {FIR_READ_CMD, 0x92, 0x00, 0x01}, 4, false));
|
||||
test_ack(soft_i2c_read_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t*) &config_reg, 2, true));
|
||||
|
||||
if (!(config_reg & 0x0400)) { // brown out
|
||||
uint8_t eeprom;
|
||||
// Read the eeprom.
|
||||
test_ack(soft_i2c_write_bytes(FIR_EEPROM_ADDR,
|
||||
(uint8_t [1]){CAL_OSC_TRIM}, 1, false));
|
||||
test_ack(soft_i2c_read_bytes(FIR_EEPROM_ADDR,
|
||||
&eeprom, 1, true));
|
||||
|
||||
// Write oscillator trimming value.
|
||||
soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [5]){FIR_WR_TRIM_CMD,
|
||||
(uint8_t)(eeprom-0xAA), eeprom,
|
||||
(uint8_t)(0x00-0xAA), 0x00}, 5, true); // no ack here
|
||||
|
||||
// Write device configuration value.
|
||||
uint8_t lsb = (ADC_resolution << 4) | IR_refresh_rate;
|
||||
// Normal Operation Mode - Continuous Measurment Mode
|
||||
uint8_t msb = 0x44;
|
||||
// ADC low reference enabled - EEPROM enabled
|
||||
// I2C FM+ enabled
|
||||
test_ack(soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [5]){FIR_WR_CFG_REG,
|
||||
(uint8_t)(lsb-0x55), lsb,
|
||||
(uint8_t)(msb-0x55), msb}, 5, true));
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ptat;
|
||||
test_ack(soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [4]) {FIR_READ_CMD, 0x40, 0x00, 0x01}, 4, false));
|
||||
test_ack(soft_i2c_read_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t*) &ptat, 2, true));
|
||||
return (((-k_t1)+sqrtf((k_t1*k_t1)-(4*k_t2*(v_th-ptat))))/(2*k_t2))+25;
|
||||
}
|
||||
|
||||
static void calculate_To(float Ta, float *To)
|
||||
{
|
||||
fb_alloc_mark();
|
||||
int16_t *v_ir = fb_alloc(64 * sizeof(int16_t), FB_ALLOC_NO_HINT);
|
||||
// Read IR sensor result
|
||||
test_ack(soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [4]){FIR_READ_CMD, 0x00, 0x01, 0x40}, 4, false));
|
||||
test_ack(soft_i2c_read_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t*) v_ir, 128, true));
|
||||
|
||||
int16_t v_cp;
|
||||
// Read compensation pixel result
|
||||
test_ack(soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [4]){FIR_READ_CMD, 0x41, 0x00, 0x01}, 4, false));
|
||||
test_ack(soft_i2c_read_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t*) &v_cp, 2, true));
|
||||
|
||||
// Calculate Thermal Gradien Compensation (TGC)
|
||||
float v_ir_cp_off_comp = v_cp-(a_cp+(b_cp*(Ta-25)));
|
||||
|
||||
// (Ta+273.15f)^4
|
||||
float Tak4 = (Ta+273.15f)*(Ta+273.15f)*(Ta+273.15f)*(Ta+273.15f);
|
||||
|
||||
for (int i=0; i<64; i++) {
|
||||
// #1: Calculate Offset Compensation
|
||||
float v_ir_off_comp = v_ir[i]-(a_ij[i]+(b_ij[i]*(Ta-25)));
|
||||
|
||||
// #2: Calculate Thermal Gradien Compensation (TGC)
|
||||
float v_ir_tgc_comp = v_ir_off_comp-(tgc*v_ir_cp_off_comp);
|
||||
|
||||
// #3: Calculate Emissivity Compensation
|
||||
float v_ir_comp = v_ir_tgc_comp/emissivity;
|
||||
|
||||
// #4: Calculate Sensitivity Compensation
|
||||
float alpha_comp_ij = (1+(ksta*(Ta-25)))*(alpha_ij[i]-(tgc*alpha_cp));
|
||||
|
||||
// Ks4=0 for BAB and BAD sensors.
|
||||
// float sx = ks4*sqrtf(sqrtf((powf(alpha_comp_ij,3)*v_ir_comp)+(powf(alpha_comp_ij,4)*Ta4)));
|
||||
// To[i] = sqrtf(sqrtf((v_ir_comp/((alpha_comp_ij*(1-(ks4*273.15f)))+sx))+Ta4))-273.15f;
|
||||
To[i] = sqrtf(sqrtf((v_ir_comp/alpha_comp_ij)+Tak4))-273.15f;
|
||||
}
|
||||
fb_alloc_free_till_mark();
|
||||
}
|
||||
|
||||
// img->w == data_w && img->h == data_h && img->bpp == IMAGE_BPP_GRAYSCALE
|
||||
static void fir_fill_image_float_obj(image_t *img, mp_obj_t *data, float min, float max)
|
||||
{
|
||||
@ -255,28 +116,13 @@ static mp_obj_t py_fir_deinit()
|
||||
height = 0;
|
||||
ADC_resolution = 0;
|
||||
IR_refresh_rate = 0;
|
||||
if (a_ij) {
|
||||
a_ij = NULL;
|
||||
if (mlx_data != NULL) {
|
||||
mlx_data = NULL;
|
||||
}
|
||||
if (b_ij) {
|
||||
b_ij = NULL;
|
||||
if (fir_sensor != FIR_NONE) {
|
||||
fir_sensor = FIR_NONE;
|
||||
cambus_deinit(&fir_i2c);
|
||||
}
|
||||
if (alpha_ij) {
|
||||
alpha_ij = NULL;
|
||||
}
|
||||
|
||||
switch (fir_sensor) {
|
||||
case FIR_NONE:
|
||||
break;
|
||||
case FIR_SHIELD:
|
||||
soft_i2c_deinit();
|
||||
break;
|
||||
case FIR_MLX90640:
|
||||
case FIR_AMG8833:
|
||||
cambus_deinit(&fir_i2c);
|
||||
break;
|
||||
}
|
||||
fir_sensor = FIR_NONE;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_deinit_obj, py_fir_deinit);
|
||||
@ -297,16 +143,19 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
py_fir_deinit();
|
||||
bool first_init = true;
|
||||
switch (py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), FIR_SHIELD)) {
|
||||
switch (py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), MLX90621)) {
|
||||
case FIR_NONE: {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
case FIR_SHIELD: {
|
||||
case MLX90621: {
|
||||
FIR_MLX90621:
|
||||
width = 16;
|
||||
height = 4;
|
||||
fir_sensor = FIR_SHIELD;
|
||||
soft_i2c_init();
|
||||
fir_sensor = MLX90621;
|
||||
MLX90621_I2CInit(&fir_i2c);
|
||||
// The EEPROM must be read at <= 400KHz.
|
||||
cambus_init(&fir_i2c, FIR_I2C, I2C_TIMING_FULL);
|
||||
|
||||
// parse refresh rate and ADC resolution
|
||||
IR_refresh_rate = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_refresh), 64); // 64Hz
|
||||
@ -316,85 +165,31 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
ADC_resolution = ((ADC_resolution > 18) ? 18 : (ADC_resolution < 15) ? 15 : ADC_resolution) - 15;
|
||||
IR_refresh_rate = 14 - __CLZ(__RBIT((IR_refresh_rate > 512) ? 512 : (IR_refresh_rate < 1) ? 1 : IR_refresh_rate));
|
||||
|
||||
a_ij = xalloc(64 * sizeof(*a_ij));
|
||||
b_ij = xalloc(64 * sizeof(*b_ij));
|
||||
alpha_ij = xalloc(64 * sizeof(*alpha_ij));
|
||||
mlx_data = xalloc(sizeof(paramsMLX90621));
|
||||
|
||||
fb_alloc_mark();
|
||||
uint8_t *eeprom = fb_alloc(256 * sizeof(uint8_t), FB_ALLOC_NO_HINT);
|
||||
// Read the whole eeprom.
|
||||
test_ack(soft_i2c_write_bytes(FIR_EEPROM_ADDR, (uint8_t [1]){0x00}, 1, false));
|
||||
test_ack(soft_i2c_read_bytes(FIR_EEPROM_ADDR, eeprom, 256, true));
|
||||
uint8_t *eeprom = fb_alloc0(256 * sizeof(uint8_t), FB_ALLOC_NO_HINT);
|
||||
int error = 0;
|
||||
error |= MLX90621_DumpEE(eeprom);
|
||||
error |= MLX90621_Configure(eeprom);
|
||||
error |= MLX90621_SetResolution(ADC_resolution);
|
||||
error |= MLX90621_SetRefreshRate(IR_refresh_rate);
|
||||
error |= MLX90621_ExtractParameters(eeprom, mlx_data);
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
// Write oscillator trimming value.
|
||||
soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [5]){FIR_WR_TRIM_CMD,
|
||||
(uint8_t)(eeprom[CAL_OSC_TRIM]-0xAA), eeprom[CAL_OSC_TRIM],
|
||||
(uint8_t)(0x00-0xAA), 0x00}, 5, true); // no ack here
|
||||
|
||||
// Write device configuration value.
|
||||
// assignment of IR_refresh_rate and ADC_resolution now done above
|
||||
uint8_t lsb = (ADC_resolution << 4) | IR_refresh_rate;
|
||||
// Normal Operation Mode - Continuous Measurment Mode
|
||||
uint8_t msb = 0x44;
|
||||
// ADC low reference enabled - EEPROM enabled
|
||||
// I2C FM+ enabled
|
||||
test_ack(soft_i2c_write_bytes(FIR_MODULE_ADDR,
|
||||
(uint8_t [5]){FIR_WR_CFG_REG,
|
||||
(uint8_t)(lsb-0x55), lsb,
|
||||
(uint8_t)(msb-0x55), msb}, 5, true));
|
||||
|
||||
v_th = ((int16_t)((eeprom[CAL_VTH_H]<<8)|eeprom[CAL_VTH_L])) /
|
||||
powf(2,3-ADC_resolution);
|
||||
|
||||
uint8_t k_t1_scale = (uint8_t)((eeprom[CAL_K_T1_SCALE]&0xF0)>>4);
|
||||
k_t1 = ((int16_t)((eeprom[CAL_KT1_H]<<8)|eeprom[CAL_KT1_L])) /
|
||||
powf(2,k_t1_scale+(3-ADC_resolution));
|
||||
|
||||
uint8_t k_t2_scale = (uint8_t)(eeprom[CAL_K_T2_SCALE]&0x0F);
|
||||
k_t2 = ((int16_t)((eeprom[CAL_KT2_H]<<8)|eeprom[CAL_KT2_L])) /
|
||||
powf(2,k_t2_scale+10+(3-ADC_resolution));
|
||||
|
||||
int16_t a_common = (int16_t)((eeprom[CAL_ACOMMON_H]<<8)|eeprom[CAL_ACOMMON_L]);
|
||||
uint8_t a_i_scale = (uint8_t)((eeprom[CAL_AI_SCALE]&0xF0)>>4);
|
||||
uint8_t b_i_scale = (uint8_t)(eeprom[CAL_BI_SCALE]&0x0F);
|
||||
uint16_t alpha_0 = (uint16_t)((eeprom[CAL_A0_H]<<8)|eeprom[CAL_A0_L]);
|
||||
uint8_t alpha_0_scale = (uint8_t)eeprom[CAL_A0_SCALE];
|
||||
uint8_t delta_a_scale = (uint8_t)eeprom[CAL_D_A_SCALE];
|
||||
|
||||
for (int i=0; i<64; i++) {
|
||||
// Pixel offset
|
||||
a_ij[i] = (a_common+(((uint8_t)eeprom[CAL_AI_OFFSET+i])*powf(2,a_i_scale))) /
|
||||
powf(2,3-ADC_resolution);
|
||||
// Slope coefficient
|
||||
b_ij[i] = ((int8_t)eeprom[CAL_BI_OFFSET+i]) /
|
||||
powf(2,b_i_scale+(3-ADC_resolution));
|
||||
// Sensitivity coefficient
|
||||
float t0 = alpha_0/powf(2,alpha_0_scale);
|
||||
float t1 = ((uint8_t)eeprom[CAL_A_CP_OFFSET+i])/powf(2,delta_a_scale);
|
||||
alpha_ij[i] = (t0+t1) /
|
||||
powf(2,3-ADC_resolution);
|
||||
if (error != 0 && first_init == true) {
|
||||
first_init = false;
|
||||
generate_scl_train();
|
||||
xfree(mlx_data);
|
||||
mlx_data = NULL;
|
||||
goto FIR_MLX90621;
|
||||
}
|
||||
|
||||
tgc = ((int8_t)eeprom[CAL_TGC]) /
|
||||
32.0f;
|
||||
emissivity = ((uint16_t)((eeprom[CAL_EMISS_H]<<8)|eeprom[CAL_EMISS_L])) /
|
||||
32768.0f;
|
||||
ksta = ((int16_t)((eeprom[CAL_KSTA_H]<<8)|eeprom[CAL_KSTA_L])) /
|
||||
1048576.0f;
|
||||
alpha_cp = ((uint16_t)((eeprom[CAL_ALPHA_CP_H]<<8)|eeprom[CAL_ALPHA_CP_L])) /
|
||||
powf(2,alpha_0_scale+(3-ADC_resolution));
|
||||
// Switch to FAST speed
|
||||
cambus_deinit(&fir_i2c);
|
||||
cambus_init(&fir_i2c, FIR_I2C, I2C_TIMING_FAST);
|
||||
|
||||
uint8_t ks_scale = (uint8_t)(eeprom[CAL_KS_SCALE]&0x0F);
|
||||
ks4 = ((int8_t)eeprom[CAL_KS4_EE]) /
|
||||
powf(2,ks_scale+8);
|
||||
|
||||
a_cp = ((int16_t)((eeprom[CAL_ACP_H]<<8)|eeprom[CAL_ACP_L])) /
|
||||
powf(2,3-ADC_resolution);
|
||||
b_cp = ((int8_t)eeprom[CAL_BCP]) /
|
||||
powf(2,b_i_scale+(3-ADC_resolution));
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
PY_ASSERT_TRUE_MSG(error == 0, "Failed to init the MLX90621!");
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@ -415,7 +210,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
ADC_resolution = ((ADC_resolution > 19) ? 19 : (ADC_resolution < 16) ? 16 : ADC_resolution) - 16;
|
||||
IR_refresh_rate = __CLZ(__RBIT((IR_refresh_rate > 64) ? 64 : (IR_refresh_rate < 1) ? 1 : IR_refresh_rate)) + 1;
|
||||
|
||||
alpha_ij = xalloc(sizeof(paramsMLX90640));
|
||||
mlx_data = xalloc(sizeof(paramsMLX90640));
|
||||
|
||||
int error = 0;
|
||||
error |= MLX90640_SetResolution(MLX90640_ADDR, ADC_resolution);
|
||||
@ -424,14 +219,14 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
fb_alloc_mark();
|
||||
uint16_t *eeprom = fb_alloc(832 * sizeof(uint16_t), FB_ALLOC_NO_HINT);
|
||||
error |= MLX90640_DumpEE(MLX90640_ADDR, eeprom);
|
||||
error |= MLX90640_ExtractParameters(eeprom, (paramsMLX90640 *) alpha_ij);
|
||||
error |= MLX90640_ExtractParameters(eeprom, mlx_data);
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (error != 0 && first_init == true) {
|
||||
first_init = false;
|
||||
generate_scl_train();
|
||||
xfree(alpha_ij);
|
||||
alpha_ij = NULL;
|
||||
xfree(mlx_data);
|
||||
mlx_data = NULL;
|
||||
goto FIR_MLX90640;
|
||||
}
|
||||
|
||||
@ -494,7 +289,7 @@ static mp_obj_t py_fir_refresh()
|
||||
const int mlx_90621_refresh_rates[16] = {512, 512, 512, 512, 512, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0};
|
||||
const int mlx_90640_refresh_rates[8] = {0, 1, 2, 4, 8, 16, 32, 64};
|
||||
if (fir_sensor == FIR_NONE) return mp_const_none;
|
||||
if (fir_sensor == FIR_SHIELD) return mp_obj_new_int(mlx_90621_refresh_rates[IR_refresh_rate]);
|
||||
if (fir_sensor == MLX90621) return mp_obj_new_int(mlx_90621_refresh_rates[IR_refresh_rate]);
|
||||
if (fir_sensor == FIR_MLX90640) return mp_obj_new_int(mlx_90640_refresh_rates[IR_refresh_rate]);
|
||||
if (fir_sensor == FIR_AMG8833) return mp_obj_new_int(IR_refresh_rate);
|
||||
return mp_const_none;
|
||||
@ -504,7 +299,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_refresh_obj, py_fir_refresh);
|
||||
static mp_obj_t py_fir_resolution()
|
||||
{
|
||||
if (fir_sensor == FIR_NONE) return mp_const_none;
|
||||
if (fir_sensor == FIR_SHIELD) return mp_obj_new_int(ADC_resolution + 15);
|
||||
if (fir_sensor == MLX90621) return mp_obj_new_int(ADC_resolution + 15);
|
||||
if (fir_sensor == FIR_MLX90640) return mp_obj_new_int(ADC_resolution + 16);
|
||||
if (fir_sensor == FIR_AMG8833) return mp_obj_new_int(ADC_resolution);
|
||||
return mp_const_none;
|
||||
@ -514,20 +309,30 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_resolution_obj, py_fir_resolution);
|
||||
mp_obj_t py_fir_read_ta()
|
||||
{
|
||||
switch(fir_sensor) {
|
||||
case FIR_NONE: return mp_const_none;
|
||||
case FIR_SHIELD: return mp_obj_new_float(calculate_Ta());
|
||||
case FIR_NONE:
|
||||
return mp_const_none;
|
||||
|
||||
case MLX90621: {
|
||||
fb_alloc_mark();
|
||||
uint16_t *data = fb_alloc0(66 * sizeof(uint16_t), FB_ALLOC_NO_HINT);
|
||||
PY_ASSERT_TRUE_MSG(MLX90621_GetFrameData(data) >= 0,
|
||||
"Failed to read the MLX90640 sensor data!");
|
||||
mp_obj_t result = mp_obj_new_float(MLX90621_GetTa(data, mlx_data));
|
||||
fb_alloc_free_till_mark();
|
||||
return result;
|
||||
}
|
||||
case FIR_MLX90640: {
|
||||
fb_alloc_mark();
|
||||
uint16_t *data = fb_alloc(834 * sizeof(uint16_t), FB_ALLOC_NO_HINT);
|
||||
PY_ASSERT_TRUE_MSG(MLX90640_GetFrameData(MLX90640_ADDR, data) >= 0,
|
||||
"Failed to read the MLX90640 sensor data!");
|
||||
mp_obj_t result = mp_obj_new_float(MLX90640_GetTa(data, (paramsMLX90640 *) alpha_ij));
|
||||
mp_obj_t result = mp_obj_new_float(MLX90640_GetTa(data, mlx_data));
|
||||
fb_alloc_free_till_mark();
|
||||
return result;
|
||||
}
|
||||
|
||||
case FIR_AMG8833: {
|
||||
int16_t temp;
|
||||
int16_t temp=0;
|
||||
test_ack(cambus_read_bytes(&fir_i2c, AMG8833_ADDR, 0x0E, (uint8_t *) &temp, 2));
|
||||
if ((temp >> 11) & 1) temp |= 1 << 15;
|
||||
temp &= 0x87FF;
|
||||
@ -545,22 +350,19 @@ mp_obj_t py_fir_read_ir()
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
case FIR_SHIELD: {
|
||||
case MLX90621: {
|
||||
fb_alloc_mark();
|
||||
float *To = fb_alloc(64 * sizeof(float), FB_ALLOC_NO_HINT), *To_rot = fb_alloc(64 * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
float Ta = calculate_Ta();
|
||||
uint16_t *data = fb_alloc0(66 * sizeof(uint16_t), FB_ALLOC_NO_HINT);
|
||||
PY_ASSERT_TRUE_MSG(MLX90621_GetFrameData(data) >= 0,
|
||||
"Failed to read the MLX90621 sensor data!");
|
||||
float Ta = MLX90621_GetTa(data, mlx_data);
|
||||
float *To = fb_alloc0(64 * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
MLX90621_CalculateTo(data, mlx_data, 0.95, Ta - 8, To);
|
||||
float min = FLT_MAX, max = FLT_MIN;
|
||||
|
||||
// Calculate object temperatures
|
||||
calculate_To(Ta, To_rot);
|
||||
|
||||
// Rotate temperatures array (sensor memory is read column wise).
|
||||
for (int x=15, r=0; x>=0; x--) {
|
||||
for (int y=0; y<4; y++) {
|
||||
float temp = To[y*16 + x] = To_rot[r++];
|
||||
min = IM_MIN(min, temp);
|
||||
max = IM_MAX(max, temp);
|
||||
}
|
||||
for (int i=0; i<64; i++) {
|
||||
min = IM_MIN(min, To[i]);
|
||||
max = IM_MAX(max, To[i]);
|
||||
}
|
||||
|
||||
mp_obj_t tuple[4];
|
||||
@ -569,8 +371,10 @@ mp_obj_t py_fir_read_ir()
|
||||
tuple[2] = mp_obj_new_float(min);
|
||||
tuple[3] = mp_obj_new_float(max);
|
||||
|
||||
for (int i=0; i<64; i++) {
|
||||
mp_obj_list_append(tuple[1], mp_obj_new_float(To[i]));
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<16; j++) {
|
||||
mp_obj_list_append(tuple[1], mp_obj_new_float(To[((15-j)*4)+i]));
|
||||
}
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
@ -583,14 +387,14 @@ mp_obj_t py_fir_read_ir()
|
||||
// Calculate 1st sub-frame...
|
||||
PY_ASSERT_TRUE_MSG(MLX90640_GetFrameData(MLX90640_ADDR, data) >= 0,
|
||||
"Failed to read the MLX90640 sensor data!");
|
||||
float Ta = MLX90640_GetTa(data, (paramsMLX90640 *) alpha_ij);
|
||||
float Ta = MLX90640_GetTa(data, mlx_data);
|
||||
float *To = fb_alloc0(768 * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
MLX90640_CalculateTo(data, (paramsMLX90640 *) alpha_ij, 0.95, Ta - 8, To);
|
||||
MLX90640_CalculateTo(data, mlx_data, 0.95, Ta - 8, To);
|
||||
// Calculate 2nd sub-frame...
|
||||
PY_ASSERT_TRUE_MSG(MLX90640_GetFrameData(MLX90640_ADDR, data) >= 0,
|
||||
"Failed to read the MLX90640 sensor data!");
|
||||
Ta = MLX90640_GetTa(data, (paramsMLX90640 *) alpha_ij);
|
||||
MLX90640_CalculateTo(data, (paramsMLX90640 *) alpha_ij, 0.95, Ta - 8, To);
|
||||
Ta = MLX90640_GetTa(data, mlx_data);
|
||||
MLX90640_CalculateTo(data, mlx_data, 0.95, Ta - 8, To);
|
||||
float min = FLT_MAX, max = FLT_MIN;
|
||||
|
||||
for (int i=0; i<768; i++) {
|
||||
@ -881,9 +685,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_snapshot_obj, 0, py_fir_snapshot);
|
||||
STATIC const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_fir) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_NONE), MP_ROM_INT(FIR_NONE) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_SHIELD), MP_ROM_INT(FIR_SHIELD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90620), MP_ROM_INT(FIR_SHIELD) }, // == FIR_SHIELD
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90621), MP_ROM_INT(FIR_SHIELD) }, // == FIR_SHIELD
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_SHIELD), MP_ROM_INT(MLX90621) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90620), MP_ROM_INT(MLX90621) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90621), MP_ROM_INT(MLX90621) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90640), MP_ROM_INT(FIR_MLX90640) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_AMG8833), MP_ROM_INT(FIR_AMG8833) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&py_fir_init_obj) },
|
||||
|
||||
@ -39,10 +39,11 @@ OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/modules/
|
||||
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LEPTON_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(MLX90640_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LSM6DS3_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(TENSORFLOW_DIR)/$(CPU)/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(WINC1500_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(MLX90621_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(MLX90640_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(TENSORFLOW_DIR)/$(CPU)/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LIBPDM_DIR)/
|
||||
|
||||
ifeq ($(OMV_ENABLE_BL), 1)
|
||||
@ -92,13 +93,14 @@ endif
|
||||
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(HAL_DIR)/src/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(LEPTON_DIR)/src/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(MLX90640_DIR)/src/*.o)
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(LSM6DS3_DIR)/src/*.o)
|
||||
endif
|
||||
ifeq ($(MICROPY_PY_WINC1500), 1)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(WINC1500_DIR)/src/*.o)
|
||||
endif
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(MLX90621_DIR)/src/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(MLX90640_DIR)/src/*.o)
|
||||
|
||||
#------------- OpenMV Objects ----------------#
|
||||
FIRM_OBJ += $(addprefix $(BUILD)/$(CMSIS_DIR)/src/, \
|
||||
@ -481,10 +483,11 @@ UVC_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/ports/stm32/,\
|
||||
)
|
||||
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(LEPTON_DIR)/src/*.o)
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(MLX90640_DIR)/src/*.o)
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(LSM6DS3_DIR)/src/*.o)
|
||||
endif
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(MLX90621_DIR)/src/*.o)
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(MLX90640_DIR)/src/*.o)
|
||||
endif
|
||||
|
||||
###################################################
|
||||
@ -522,13 +525,14 @@ FIRMWARE_OBJS: | $(BUILD) $(FW_DIR)
|
||||
$(MAKE) -C $(MICROPY_DIR)/ports/$(PORT) BUILD=$(BUILD)/$(MICROPY_DIR) $(MICROPY_ARGS)
|
||||
$(MAKE) -C $(HAL_DIR) BUILD=$(BUILD)/$(HAL_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(LEPTON_DIR) BUILD=$(BUILD)/$(LEPTON_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(MLX90640_DIR) BUILD=$(BUILD)/$(MLX90640_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
$(MAKE) -C $(LSM6DS3_DIR) BUILD=$(BUILD)/$(LSM6DS3_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
endif
|
||||
ifeq ($(MICROPY_PY_WINC1500), 1)
|
||||
$(MAKE) -C $(WINC1500_DIR) BUILD=$(BUILD)/$(WINC1500_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
endif
|
||||
$(MAKE) -C $(MLX90621_DIR) BUILD=$(BUILD)/$(MLX90621_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(MLX90640_DIR) BUILD=$(BUILD)/$(MLX90640_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(OMV_DIR) BUILD=$(BUILD)/$(OMV_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
ifeq ($(CUBEAI), 1)
|
||||
$(MAKE) -C $(CUBEAI_DIR) BUILD=$(BUILD)/$(CUBEAI_DIR) CFLAGS="$(CFLAGS) -fno-strict-aliasing -MMD"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user