master
Yorick GEOFFRE 2 years ago
parent cf1d4d2f17
commit 351d6cdd50

@ -1,43 +1,61 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
import harbour.i2ctool.I2cif 1.0
import melexis.driver 1.0
Page {
id: page
id: probePage
property string deviceName: "/dev/i2c-1"
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
SilicaFlickable
{
Grid
{
Button
{
id: probeBTN
text: "check camera present"
onClicked: {probeBTN.text="probing..."; i2cif.tohVddSet("on"); i2cif.i2cProbe(deviceName)}
}
Label
{
// To enable PullDownMenu, place our content in a SilicaFlickable
SilicaFlickable {
anchors.fill: parent
id: resultLabel
text: "0"
}
// PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView
PullDownMenu {
MenuItem {
text: qsTr("Show Page 2")
onClicked: pageStack.animatorPush(Qt.resolvedUrl("SecondPage.qml"))
}
}
I2cif
{
id: i2cif
onI2cProbingChanged:
{
var results = i2cif.i2cProbingStatus;
for (var i=0 ; i<i2cif.i2cProbingStatus.length ; i++)
{
var res = results[i]
if(res === "ok"){
resultLabel.text = i;
break;
}
}
}
// Tell SilicaFlickable the height of its content.
contentHeight: column.height
probeBTN.text = "probe done";
thermal.fuzzyInit();
}
}
// Place our content in a Column. The PageHeader is always placed at the top
// of the page, followed by our content.
Column {
id: column
MLX90640{
id: thermal
width: page.width
spacing: Theme.paddingLarge
PageHeader {
title: qsTr("UI Template")
}
Label {
x: Theme.horizontalPageMargin
text: qsTr("Hello Sailors")
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeExtraLarge
}
onDataReady:
{
var image = thermal.imageVect;
resultLabel.text = image[200];
}
}
}

File diff suppressed because it is too large Load Diff

@ -14,64 +14,71 @@
* limitations under the License.
*
*/
#ifndef _MLX90640_API_H_
#define _MLX90640_API_H_
#define MLX90640_NO_ERROR 0
#define MLX90640_I2C_NACK_ERROR 1
#define MLX90640_I2C_WRITE_ERROR 2
#define MLX90640_BROKEN_PIXELS_NUM_ERROR 3
#define MLX90640_OUTLIER_PIXELS_NUM_ERROR 4
#define MLX90640_BAD_PIXELS_NUM_ERROR 5
#define MLX90640_ADJACENT_BAD_PIXELS_ERROR 6
#define MLX90640_EEPROM_DATA_ERROR 7
#define MLX90640_FRAME_DATA_ERROR 8
#define MLX90640_MEAS_TRIGGER_ERROR 9
#ifndef _mlx90640_API_H_
#define _mlx90640_API_H_
#include <QObject>
#include <QStringList>
#include <QVector>
#include <array>
#define mlx90640_DEV_ADDR 0x33
#define mlx90640_NO_ERROR 0
#define mlx90640_I2C_NACK_ERROR 1
#define mlx90640_I2C_WRITE_ERROR 2
#define mlx90640_BROKEN_PIXELS_NUM_ERROR 3
#define mlx90640_OUTLIER_PIXELS_NUM_ERROR 4
#define mlx90640_BAD_PIXELS_NUM_ERROR 5
#define mlx90640_ADJACENT_BAD_PIXELS_ERROR 6
#define mlx90640_EEPROM_DATA_ERROR 7
#define mlx90640_FRAME_DATA_ERROR 8
#define mlx90640_MEAS_TRIGGER_ERROR 9
#define BIT_MASK(x) (1UL << (x))
#define REG_MASK(sbit,nbits) ~((~(~0UL << (nbits))) << (sbit))
#define MLX90640_EEPROM_START_ADDRESS 0x2400
#define MLX90640_EEPROM_DUMP_NUM 832
#define MLX90640_PIXEL_DATA_START_ADDRESS 0x0400
#define MLX90640_PIXEL_NUM 768
#define MLX90640_LINE_NUM 24
#define MLX90640_COLUMN_NUM 32
#define MLX90640_LINE_SIZE 32
#define MLX90640_COLUMN_SIZE 24
#define MLX90640_AUX_DATA_START_ADDRESS 0x0700
#define MLX90640_AUX_NUM 64
#define MLX90640_STATUS_REG 0x8000
#define MLX90640_INIT_STATUS_VALUE 0x0030
#define MLX90640_STAT_FRAME_MASK BIT_MASK(0)
#define MLX90640_GET_FRAME(reg_value) (reg_value & MLX90640_STAT_FRAME_MASK)
#define MLX90640_STAT_DATA_READY_MASK BIT_MASK(3)
#define MLX90640_GET_DATA_READY(reg_value) (reg_value & MLX90640_STAT_DATA_READY_MASK)
#define MLX90640_CTRL_REG 0x800D
#define MLX90640_CTRL_TRIG_READY_MASK BIT_MASK(15)
#define MLX90640_CTRL_REFRESH_SHIFT 7
#define MLX90640_CTRL_REFRESH_MASK REG_MASK(MLX90640_CTRL_REFRESH_SHIFT,3)
#define MLX90640_CTRL_RESOLUTION_SHIFT 10
#define MLX90640_CTRL_RESOLUTION_MASK REG_MASK(MLX90640_CTRL_RESOLUTION_SHIFT,2)
#define MLX90640_CTRL_MEAS_MODE_SHIFT 12
#define MLX90640_CTRL_MEAS_MODE_MASK BIT_MASK(12)
#define MLX90640_MS_BYTE_SHIFT 8
#define MLX90640_MS_BYTE_MASK 0xFF00
#define MLX90640_LS_BYTE_MASK 0x00FF
#define MLX90640_MS_BYTE(reg16) ((reg16 & MLX90640_MS_BYTE_MASK) >> MLX90640_MS_BYTE_SHIFT)
#define MLX90640_LS_BYTE(reg16) (reg16 & MLX90640_LS_BYTE_MASK)
#define MLX90640_MSBITS_6_MASK 0xFC00
#define MLX90640_LSBITS_10_MASK 0x03FF
#define MLX90640_NIBBLE1_MASK 0x000F
#define MLX90640_NIBBLE2_MASK 0x00F0
#define MLX90640_NIBBLE3_MASK 0x0F00
#define MLX90640_NIBBLE4_MASK 0xF000
#define MLX90640_NIBBLE1(reg16) ((reg16 & MLX90640_NIBBLE1_MASK))
#define MLX90640_NIBBLE2(reg16) ((reg16 & MLX90640_NIBBLE2_MASK) >> 4)
#define MLX90640_NIBBLE3(reg16) ((reg16 & MLX90640_NIBBLE3_MASK) >> 8)
#define MLX90640_NIBBLE4(reg16) ((reg16 & MLX90640_NIBBLE4_MASK) >> 12)
#define mlx90640_EEPROM_START_ADDRESS 0x2400
#define mlx90640_EEPROM_DUMP_NUM 832
#define mlx90640_PIXEL_DATA_START_ADDRESS 0x0400
#define mlx90640_PIXEL_NUM 768
#define mlx90640_LINE_NUM 24
#define mlx90640_COLUMN_NUM 32
#define mlx90640_LINE_SIZE 32
#define mlx90640_COLUMN_SIZE 24
#define mlx90640_AUX_DATA_START_ADDRESS 0x0700
#define mlx90640_AUX_NUM 64
#define mlx90640_STATUS_REG 0x8000
#define mlx90640_INIT_STATUS_VALUE 0x0030
#define mlx90640_STAT_FRAME_MASK BIT_MASK(0)
#define mlx90640_GET_FRAME(reg_value) (reg_value & mlx90640_STAT_FRAME_MASK)
#define mlx90640_STAT_DATA_READY_MASK BIT_MASK(3)
#define mlx90640_GET_DATA_READY(reg_value) (reg_value & mlx90640_STAT_DATA_READY_MASK)
#define mlx90640_CTRL_REG 0x800D
#define mlx90640_CTRL_TRIG_READY_MASK BIT_MASK(15)
#define mlx90640_CTRL_REFRESH_SHIFT 7
#define mlx90640_CTRL_REFRESH_MASK REG_MASK(mlx90640_CTRL_REFRESH_SHIFT,3)
#define mlx90640_CTRL_RESOLUTION_SHIFT 10
#define mlx90640_CTRL_RESOLUTION_MASK REG_MASK(mlx90640_CTRL_RESOLUTION_SHIFT,2)
#define mlx90640_CTRL_MEAS_MODE_SHIFT 12
#define mlx90640_CTRL_MEAS_MODE_MASK BIT_MASK(12)
#define mlx90640_MS_BYTE_SHIFT 8
#define mlx90640_MS_BYTE_MASK 0xFF00
#define mlx90640_LS_BYTE_MASK 0x00FF
#define mlx90640_MS_BYTE(reg16) ((reg16 & mlx90640_MS_BYTE_MASK) >> mlx90640_MS_BYTE_SHIFT)
#define mlx90640_LS_BYTE(reg16) (reg16 & mlx90640_LS_BYTE_MASK)
#define mlx90640_MSBITS_6_MASK 0xFC00
#define mlx90640_LSBITS_10_MASK 0x03FF
#define mlx90640_NIBBLE1_MASK 0x000F
#define mlx90640_NIBBLE2_MASK 0x00F0
#define mlx90640_NIBBLE3_MASK 0x0F00
#define mlx90640_NIBBLE4_MASK 0xF000
#define mlx90640_NIBBLE1(reg16) ((reg16 & mlx90640_NIBBLE1_MASK))
#define mlx90640_NIBBLE2(reg16) ((reg16 & mlx90640_NIBBLE2_MASK) >> 4)
#define mlx90640_NIBBLE3(reg16) ((reg16 & mlx90640_NIBBLE3_MASK) >> 8)
#define mlx90640_NIBBLE4(reg16) ((reg16 & mlx90640_NIBBLE4_MASK) >> 12)
#define POW2(x) pow(2, (double)x)
@ -79,76 +86,98 @@
#include <stdint.h>
typedef struct
{
int16_t kVdd;
int16_t vdd25;
float KvPTAT;
float KtPTAT;
uint16_t vPTAT25;
float alphaPTAT;
int16_t gainEE;
float tgc;
float cpKv;
float cpKta;
uint8_t resolutionEE;
uint8_t calibrationModeEE;
float KsTa;
float ksTo[5];
int16_t ct[5];
uint16_t alpha[768];
uint8_t alphaScale;
int16_t offset[768];
int8_t kta[768];
uint8_t ktaScale;
int8_t kv[768];
uint8_t kvScale;
float cpAlpha[2];
int16_t cpOffset[2];
float ilChessC[3];
uint16_t brokenPixels[5];
uint16_t outlierPixels[5];
} paramsMLX90640;
class MLX90640{
class MLX90640 : public QObject
{
Q_OBJECT
public:
int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData);
int MLX90640_SynchFrame(uint8_t slaveAddr);
int MLX90640_TriggerMeasurement(uint8_t slaveAddr);
int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData);
int MLX90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params);
float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params);
void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result);
void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result);
int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution);
int MLX90640_GetCurResolution(uint8_t slaveAddr);
int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate);
int MLX90640_GetRefreshRate(uint8_t slaveAddr);
int MLX90640_GetSubPageNumber(uint16_t *frameData);
int MLX90640_GetCurMode(uint8_t slaveAddr);
int MLX90640_SetInterleavedMode(uint8_t slaveAddr);
int MLX90640_SetChessMode(uint8_t slaveAddr);
void MLX90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640 *params);
typedef struct
{
int16_t kVdd;
int16_t vdd25;
float KvPTAT;
float KtPTAT;
uint16_t vPTAT25;
float alphaPTAT;
int16_t gainEE;
float tgc;
float cpKv;
float cpKta;
uint8_t resolutionEE;
uint8_t calibrationModeEE;
float KsTa;
float ksTo[5];
int16_t ct[5];
uint16_t alpha[768];
uint8_t alphaScale;
int16_t offset[768];
int8_t kta[768];
uint8_t ktaScale;
int8_t kv[768];
uint8_t kvScale;
float cpAlpha[2];
int16_t cpOffset[2];
float ilChessC[3];
uint16_t brokenPixels[5];
uint16_t outlierPixels[5];
} paramsMLX90640;
int mlx90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData);
int mlx90640_SynchFrame(uint8_t slaveAddr);
int mlx90640_TriggerMeasurement(uint8_t slaveAddr);
Q_INVOKABLE int mlx90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData);
int mlx90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
Q_INVOKABLE float mlx90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params);
Q_INVOKABLE float mlx90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params);
Q_INVOKABLE void mlx90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params);
void mlx90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result);
Q_INVOKABLE int mlx90640_SetResolution(uint8_t slaveAddr, uint8_t resolution);
int mlx90640_GetCurResolution(uint8_t slaveAddr);
Q_INVOKABLE int mlx90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate);
int mlx90640_GetRefreshRate(uint8_t slaveAddr);
int mlx90640_GetSubPageNumber(uint16_t *frameData);
int mlx90640_GetCurMode(uint8_t slaveAddr);
Q_INVOKABLE int mlx90640_SetInterleavedMode(uint8_t slaveAddr);
Q_INVOKABLE int mlx90640_SetChessMode(uint8_t slaveAddr);
void mlx90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640 *params);
Q_INVOKABLE void fuzzyInit(){
unsigned char slaveAddress = 0x33;
static uint16_t eeMLX90640[832];
static uint16_t mlx90640Frame[834];
paramsMLX90640 mlx90640;
int status;
status = mlx90640_DumpEE (slaveAddress, eeMLX90640);
//status = mlx90640_ExtractParameters(eeMLX90640, &mlx90640);
//status = mlx90640_GetFrameData (0x33, mlx90640Frame);
//mlx90640_GetImage(mlx90640Frame, &mlx90640);
}
MLX90640() : imageVect(768){}
QVector<float> imageVect;
protected:
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);
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);
float GetMedian(float *values, int n);
int IsPixelBad(uint16_t pixel,paramsMLX90640 *params);
int ValidateFrameData(uint16_t *frameData);
int ValidateAuxData(uint16_t *auxData);
signals:
void dataReady();
};
#endif

@ -1,38 +1,40 @@
#include "MLX90640_I2C_Driver.h"
#include "mlx90640_I2C_Driver.h"
#include "i2cdriversingleton.h"
#include <QString>
#define DEFAULT_I2C_DEV QString("/dev/i2c-1/")
///
/// \brief MLX90640_I2CInit Setup the I2C lines
/// \brief mlx90640_I2CInit Setup the I2C lines
///
void MLX90640_I2CInit(void){
void mlx90640_I2CInit(void){
i2cDriverSingleton::getinstance()->tohVddSet(QString("on"));
i2cDriverSingleton::getinstance()->i2cProbe(DEFAULT_I2C_DEV);
}
///
/// \brief MLX90640_I2CGeneralReset resets the I2C line and devices
/// \brief mlx90640_I2CGeneralReset resets the I2C line and devices
/// \return 0 if success
///
int MLX90640_I2CGeneralReset(void){
int mlx90640_I2CGeneralReset(void){
}
///
/// \brief MLX90640_I2CFreqSet Sets the frequency for the I2C bus
/// \brief mlx90640_I2CFreqSet Sets the frequency for the I2C bus
/// \param freq
///
void MLX90640_I2CFreqSet(int freq){
void mlx90640_I2CFreqSet(int freq){
}
int MLX90640_I2CRead(uint8_t slaveAddr,uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data){
i2cDriverSingleton::getinstance()->i2cRead(DEFAULT_I2C_DEV,nMemAddressRead,nMemAddressRead);
int mlx90640_I2CRead(uint8_t slaveAddr,uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data){
i2cDriverSingleton::getinstance()->i2cRead(slaveAddr, startAddress, nMemAddressRead, data);
return 0;
}
int MLX90640_I2CWrite(uint8_t slaveAddr,uint16_t writeAddress, uint16_t data)
int mlx90640_I2CWrite(uint8_t slaveAddr,uint16_t writeAddress, uint16_t data)
{
i2cDriverSingleton::getinstance()->i2cWrite(DEFAULT_I2C_DEV,writeAddress,QString(data));
i2cDriverSingleton::getinstance()->i2cWrite(slaveAddr, writeAddress, data);
return 0;
}

@ -14,15 +14,15 @@
* limitations under the License.
*
*/
#ifndef _MLX90640_I2C_Driver_H_
#define _MLX90640_I2C_Driver_H_
#ifndef _mlx90640_I2C_Driver_H_
#define _mlx90640_I2C_Driver_H_
#include <stdint.h>
#include "MLX90640_API.h"
#include "mlx90640_API.h"
extern void MLX90640_I2CInit(void);
extern int MLX90640_I2CGeneralReset(void);
extern int MLX90640_I2CRead(uint8_t slaveAddr,uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data);
extern int MLX90640_I2CWrite(uint8_t slaveAddr,uint16_t writeAddress, uint16_t data);
extern void MLX90640_I2CFreqSet(int freq);
extern void mlx90640_I2CInit(void);
extern int mlx90640_I2CGeneralReset(void);
extern int mlx90640_I2CWrite(uint8_t slaveAddr,uint16_t writeAddress, uint16_t data);
extern int mlx90640_I2CRead(uint8_t slaveAddr,uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data);
extern void mlx90640_I2CFreqSet(int freq);
#endif

@ -1,6 +1,6 @@
#include "i2cdriversingleton.h"
I2cif* i2cDriverSingleton::instance; //instance declaration for the static variable in the singleton
I2cif* i2cDriverSingleton::instance = nullptr; //instance declaration for the static variable in the singleton
I2cif* i2cDriverSingleton::getinstance()
{
@ -13,5 +13,6 @@ I2cif* i2cDriverSingleton::getinstance()
void i2cDriverSingleton::cleanup(){
if(instance != nullptr){
instance->tohVddSet(QString("off"));
delete instance;
}
}

@ -1,5 +1,3 @@
#include "i2cif.h"
#include "i2cif.h"
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
@ -15,6 +13,8 @@
#include <sailfishapp.h>
#include "conv.h"
#include <unistd.h>
#include <errno.h>
#define DEFAULT_I2C_DEV QString("/dev/i2c-1/")
I2cif::I2cif(QObject *parent) :
QObject(parent)
@ -100,6 +100,111 @@ bool I2cif::tohVddGet()
*
*/
Q_INVOKABLE void I2cif::i2cWrite(const uint8_t &slaveAddr, const uint16_t &writeAddress, const uint16_t &data){
int file;
char buf[3];
QByteArray tmpBa = DEFAULT_I2C_DEV.toUtf8();
const char* devNameChar = tmpBa.constData();
fprintf(stderr, "writing to address %02x: ", slaveAddr);
if ((file = open (devNameChar, O_RDWR)) < 0)
{
fprintf(stderr,"open error\n");
emit i2cError();
return;
}
if (ioctl(file, I2C_SLAVE, slaveAddr) < 0)
{
close(file);
fprintf(stderr,"ioctl error\n");
emit i2cError();
return;
}
// prepare buffer to write
buf[0] = (writeAddress >> 8) & 0xFF; // writeAddress high byte
buf[1] = writeAddress & 0xFF; // writeAddress low byte
buf[2] = data & 0xFF; // data
/* write the data */
if (write(file, buf, sizeof(buf)) != sizeof(buf))
{
close(file);
fprintf(stderr,"write error\n");
emit i2cError();
return;
}
close(file);
fprintf(stderr,"write ok\n");
emit i2cWriteOk();
}
void I2cif::i2cRead(const uint8_t &slaveAddr, const uint16_t &startAddress, const uint16_t &nMemAddressRead, uint16_t *data)
{
int file;
char buf[2];
const char* devNameChar = "/dev/i2c-1";
fprintf(stderr, "reading from address %02x count %d\n", slaveAddr, nMemAddressRead);
if ((file = open (devNameChar, O_RDWR)) < 0)
{
fprintf(stderr,"open error %d, %s\n",errno, devNameChar);
emit i2cError();
return;
}
if (ioctl(file, I2C_SLAVE, slaveAddr) < 0)
{
close(file);
fprintf(stderr,"ioctl error\n");
emit i2cError();
return;
}
/* Read data */
for (int i = 0; i < nMemAddressRead; i++)
{
/* Write start address */
buf[0] = ((startAddress + i) >> 8) & 0xFF; // startAddress high byte
buf[1] = (startAddress + i) & 0xFF; // startAddress low byte
if (write(file, buf, sizeof(buf)) != sizeof(buf))
{
close(file);
fprintf(stderr,"write error\n");
emit i2cError();
return;
}
if (read(file, buf, sizeof(buf)) != sizeof(buf))
{
close(file);
fprintf(stderr,"read error\n");
emit i2cError();
return;
}
data[i] = ((uint16_t)buf[0] << 8) | buf[1]; // Combine high and low bytes into a 16-bit data
}
close(file);
fprintf(stderr, "read ");
for (int i = 0; i < nMemAddressRead; i++)
{
fprintf(stderr, "%04x ", data[i]);
}
fprintf(stderr, "\n");
emit i2cReadResultChanged();
}
void I2cif::i2cWrite(QString devName, unsigned char address, QString data)
{
int file;
@ -169,20 +274,42 @@ void I2cif::i2cWrite(QString devName, unsigned char address, QString data)
void I2cif::i2cRead(QString devName, unsigned char address, int count)
{
int file;
char buf[200];
const int CHUNK_SIZE = 200;
char buf[CHUNK_SIZE];
Conv conv;
int bytesRead = 0;
const int MAX_ATTEMPTS = 3;
int attempt = 0;
m_readResult = "";
//emit i2cReadResultChanged();
QByteArray tmpBa = devName.toUtf8();
const char* devNameChar = tmpBa.constData();
fprintf(stderr, "reading from address %02x count %d\n", address, count);
if ((file = open (devNameChar, O_RDWR)) < 0)
do
{
fprintf(stderr,"open error\n");
if ((file = open (devNameChar, O_RDWR)) < 0)
{
perror("open");
if (errno == EBUSY)
{
fprintf(stderr, "i2c bus is busy!\n");
usleep(50000); // wait for 50 ms
continue;
}else{
fprintf(stderr, "got error: %d\n", errno);
}
emit i2cError();
return;
}
break;
} while (++attempt < MAX_ATTEMPTS);
if (attempt == MAX_ATTEMPTS)
{
fprintf(stderr, "Failed to open the device after %d attempts\n", attempt);
emit i2cError();
return;
}
@ -190,32 +317,41 @@ void I2cif::i2cRead(QString devName, unsigned char address, int count)
if (ioctl(file, I2C_SLAVE, address) < 0)
{
close(file);
fprintf(stderr,"ioctl error\n");
perror("ioctl");
emit i2cError();
return;
}
/* Read data */
if (read( file, buf, count ) != count)
while(bytesRead < count)
{
close(file);
fprintf(stderr,"read error\n");
emit i2cError();
return;
}
int chunk = count - bytesRead;
if(chunk > CHUNK_SIZE)
{
chunk = CHUNK_SIZE;
}
close(file);
/* Read data */
if (read( file, buf, chunk ) != chunk)
{
close(file);
perror("read");
emit i2cError();
return;
}
/* copy buf to m_readResult */
int i;
/* copy buf to m_readResult */
fprintf(stderr, "read ");
for (int i=0; i<chunk ; i++)
{
m_readResult = m_readResult + conv.toHex(buf[i],2) + " ";
fprintf(stderr, "%02x ", buf[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, "read ");
for (i=0; i<count ; i++)
{
m_readResult = m_readResult + conv.toHex(buf[i],2) + " ";
fprintf(stderr, "%02x ", buf[i]);
bytesRead += chunk;
}
fprintf(stderr, "\n");
close(file);
emit i2cReadResultChanged();
}

@ -2,6 +2,8 @@
#define I2CIF_H
#include <QObject>
#include <QStringList>
#include <array>
class I2cif : public QObject
{
@ -20,6 +22,8 @@ public:
Q_INVOKABLE void i2cProbe(QString devName);
Q_INVOKABLE void i2cWrite(QString devName, unsigned char address, QString data);
Q_INVOKABLE void i2cRead(QString devName, unsigned char address, int count);
Q_INVOKABLE void i2cWrite(const uint8_t &slaveAddr,const uint16_t &writeAddress,const uint16_t &data);
Q_INVOKABLE void i2cRead(const uint8_t &slaveAddr,const uint16_t &startAddress, const uint16_t &nMemAddressRead,uint16_t *data);
Q_INVOKABLE void i2cWriteThenRead(QString devName, unsigned char address, QString data, int count);
Q_INVOKABLE void tohVddSet(QString onOff);

@ -1,4 +1,8 @@
#ifdef QT_QML_DEBUG
#include "conv.h"
#include "i2cif.h"
#include "mlx90640_API.h"
#include <QtQuick>
#endif
@ -6,15 +10,9 @@
int main(int argc, char *argv[])
{
// SailfishApp::main() will display "qml/thermi2c.qml", if you need more
// control over initialization, you can use:
//
// - SailfishApp::application(int, char *[]) to get the QGuiApplication *
// - SailfishApp::createView() to get a new QQuickView * instance
// - SailfishApp::pathTo(QString) to get a QUrl to a resource file
// - SailfishApp::pathToMainQml() to get a QUrl to the main QML file
//
// To display the view, call "show()" (will show fullscreen on device).
qmlRegisterType<I2cif>("harbour.i2ctool.I2cif", 1, 0, "I2cif");
qmlRegisterType<Conv>("harbour.i2ctool.Conv", 1, 0, "Conv");
qmlRegisterType<MLX90640>("melexis.driver", 1, 0, "MLX90640");
return SailfishApp::main(argc, argv);
}

@ -15,8 +15,8 @@ TARGET = thermi2c
CONFIG += sailfishapp
SOURCES += src/thermi2c.cpp \
src/MLX90640_API.cpp \
src/MLX90640_I2C_Driver.cpp \
src/mlx90640_API.cpp \
src/mlx90640_I2C_Driver.cpp \
src/conv.cpp \
src/i2cdriversingleton.cpp \
src/i2cif.cpp
@ -44,8 +44,8 @@ CONFIG += sailfishapp_i18n
TRANSLATIONS += translations/thermi2c-de.ts
HEADERS += \
src/MLX90640_API.h \
src/MLX90640_I2C_Driver.h \
src/mlx90640_API.h \
src/mlx90640_I2C_Driver.h \
src/conv.h \
src/i2cdriversingleton.h \
src/i2cif.h

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.15.2, 2023-05-17T06:03:32. -->
<!-- Written by QtCreator 4.15.2, 2023-05-17T11:50:01. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@ -275,7 +275,7 @@
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
@ -303,7 +303,11 @@
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmBuildStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmValidationStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</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>
@ -340,83 +344,6 @@
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
<value type="QString">-e</value>
<value type="QString">cpu-cycles</value>
<value type="QString">--call-graph</value>
<value type="QString">dwarf,4096</value>
<value type="QString">-F</value>
<value type="QString">250</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="QString" key="Analyzer.Valgrind.Callgrind.Arguments"></value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="QString" key="Analyzer.Valgrind.Memcheck.Arguments"></value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindArguments"></value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="bool" key="MerRunConfiguration.DebugBypassOpenSslArmCapEnabled">true</value>
<value type="QString" key="MerRunConfiguration.QmlLiveBenchWorkspace">C:/Users/Onyxa/Documents/thermi2c</value>
<value type="bool" key="MerRunConfiguration.QmlLiveEnabled">false</value>
<value type="int" key="MerRunConfiguration.QmlLiveIpcPort">-1</value>
<value type="int" key="MerRunConfiguration.QmlLiveOptions">3</value>
<value type="QString" key="MerRunConfiguration.QmlLiveTargetWorkspace"></value>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
@ -486,16 +413,16 @@
<value type="QString" key="MerRunConfiguration.QmlLiveTargetWorkspace"></value>
<value type="int" key="PE.EnvironmentAspect.Base">1</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Custom Executable2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerCustomRunConfiguration:</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">thermi2c</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRunConfiguration:C:/Users/Onyxa/Documents/thermi2c/thermi2c.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/Users/Onyxa/Documents/thermi2c/thermi2c.pro</value>
<value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>

@ -8,21 +8,6 @@
<translation>Mein Cover</translation>
</message>
</context>
<context>
<name>FirstPage</name>
<message>
<source>Show Page 2</source>
<translation>Zur Seite 2</translation>
</message>
<message>
<source>UI Template</source>
<translation>UI-Vorlage</translation>
</message>
<message>
<source>Hello Sailors</source>
<translation>Hallo Matrosen</translation>
</message>
</context>
<context>
<name>SecondPage</name>
<message>

@ -8,21 +8,6 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FirstPage</name>
<message>
<source>Show Page 2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>UI Template</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Hello Sailors</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SecondPage</name>
<message>

Loading…
Cancel
Save