/**
* @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 "MLX90640_SWI2C_Driver.h"
#include "MLX90640_API.h"
#include <math.h>
#include "led.h"
void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640);
int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2);
int CheckEEPROMValid(uint16_t *eeData);
int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData)
{
return MLX90640_I2CRead(slaveAddr, 0x2400, 832, eeData);
}
int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData)
{
uint16_t dataReady = 1;
uint16_t controlRegister1;
uint16_t statusRegister;
int error = 1;
uint8_t cnt = 0;
dataReady = 0;
while(dataReady == 0)
{
error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);//A new data is available in RAM or not
if(error != 0)
{
return error;
}
dataReady = statusRegister & 0x0008;
}
while(dataReady != 0 && cnt < 5)
{
error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);//?
if(error == -1)
{
return error;
}
error = MLX90640_I2CRead(slaveAddr, 0x0400, 832, frameData);
if(error != 0)
{
return error;
}
error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);
if(error != 0)
{
return error;
}
dataReady = statusRegister & 0x0008;
cnt = cnt + 1;
}
if(cnt > 4)
{
return -8;
}
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
frameData[832] = controlRegister1;
frameData[833] = statusRegister & 0x0001;
if(error != 0)
{
return error;
}
// return frameData[833];
LED13_PORT->ODR ^=LED3_PIN;
return 0;
}
int MLX90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
{
int error = CheckEEPROMValid(eeData);
if(error == 0)
{
ExtractVDDParameters(eeData, mlx90640);
ExtractPTATParameters(eeData, mlx90640);
ExtractGainParameters(eeData, mlx90640);
ExtractTgcParameters(eeData, mlx90640);
ExtractResolutionParameters(eeData, mlx90640);
ExtractKsTaParameters(eeData, mlx90640);
ExtractKsToParameters(eeData, mlx90640);
ExtractAlphaParameters(eeData, mlx90640);
ExtractOffsetParameters(eeData, mlx90640);
ExtractKtaPixelParameters(eeData, mlx90640);
ExtractKvPixelParameters(eeData, mlx90640);
ExtractCPParameters(eeData, mlx90640);
ExtractCILCParameters(eeData, mlx90640);
error = ExtractDeviatingPixels(eeData, mlx90640);
}
return error;
}
//------------------------------------------------------------------------------
int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution)
{
uint16_t controlRegister1;
int value;
int error;
value = (resolution & 0x03) << 10;
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
if(error == 0)
{
value = (controlRegister1 & 0xF3FF) | value;
error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
}
return error;
}
//------------------------------------------------------------------------------
int MLX90640_GetCurResolution(uint8_t slaveAddr)
{
uint16_t controlRegister1;
int resolutionRAM;
int error;
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
if(error != 0)
{
return error;
}
resolutionRAM = (controlRegister1 & 0x0C00) >> 10;
return resolutionRAM;
}
//------------------------------------------------------------------------------
int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate)
{
uint16_t controlRegister1;
int value;
int error;
value = (refreshRate & 0x07)<<7;
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
if(error == 0)
{
value = (controlRegister1 & 0xFC7F) | value;
error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
}
return error;
}
//------------------------------------------------------------------------------
int MLX90640_GetRefreshRate(uint8_t slaveAddr)
{
uint16_t controlRegister1;
int refreshRate;
int error;
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
if(error != 0)
{
return error;
}
refreshRate = (controlRegister1 & 0x0380) >> 7;
return refreshRate;
}
//------------------------------------------------------------------------------
int MLX90640_SetInterleavedMode(uint8_t slaveAddr)
{
uint16_t controlRegister1;
int value;
int error;
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
if(error == 0)
{
value = (controlRegister1 & 0xEFFF);
error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
}
return error;
}
//------------------------------------------------------------------------------
int MLX90640_SetChessMode(uint8_t slaveAddr)
{
uint16_t controlRegister1;
int value;
int error;
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
if(error == 0)
{
value = (controlRegister1 | 0x1000);
error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
}
return error;
}
//------------------------------------------------------------------------------
int MLX90640_GetCurMode(uint8_t slaveAddr)
{
uint16_t controlRegister1;
int modeRAM;
int error;
error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
if(error != 0)
{
return error;
}
modeRAM = (controlRegister1 & 0x1000) >> 12;
return modeRAM;
}
//------------------------------------------------------------------------------
__attribute__((section("RAMCODE")))
void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result)
{
float vdd;
float ta;
float ta4;
flo