master
Yorick GEOFFRE 2 years ago
parent cf1d4d2f17
commit 351d6cdd50

@ -1,43 +1,61 @@
import QtQuick 2.0 import QtQuick 2.0
import Sailfish.Silica 1.0 import Sailfish.Silica 1.0
import harbour.i2ctool.I2cif 1.0
import melexis.driver 1.0
Page { Page {
id: page id: probePage
property string deviceName: "/dev/i2c-1"
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All 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 id: resultLabel
SilicaFlickable { text: "0"
anchors.fill: parent }
// 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"))
} }
} }
// Tell SilicaFlickable the height of its content. I2cif
contentHeight: column.height {
id: i2cif
// Place our content in a Column. The PageHeader is always placed at the top onI2cProbingChanged:
// of the page, followed by our content. {
Column { var results = i2cif.i2cProbingStatus;
id: column for (var i=0 ; i<i2cif.i2cProbingStatus.length ; i++)
{
var res = results[i]
if(res === "ok"){
resultLabel.text = i;
break;
}
}
width: page.width probeBTN.text = "probe done";
spacing: Theme.paddingLarge thermal.fuzzyInit();
PageHeader {
title: qsTr("UI Template")
} }
Label {
x: Theme.horizontalPageMargin
text: qsTr("Hello Sailors")
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeExtraLarge
} }
MLX90640{
id: thermal
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. * limitations under the License.
* *
*/ */
#ifndef _MLX90640_API_H_ #ifndef _mlx90640_API_H_
#define _MLX90640_API_H_ #define _mlx90640_API_H_
#define MLX90640_NO_ERROR 0 #include <QObject>
#define MLX90640_I2C_NACK_ERROR 1 #include <QStringList>
#define MLX90640_I2C_WRITE_ERROR 2 #include <QVector>
#define MLX90640_BROKEN_PIXELS_NUM_ERROR 3 #include <array>
#define MLX90640_OUTLIER_PIXELS_NUM_ERROR 4
#define MLX90640_BAD_PIXELS_NUM_ERROR 5 #define mlx90640_DEV_ADDR 0x33
#define MLX90640_ADJACENT_BAD_PIXELS_ERROR 6
#define MLX90640_EEPROM_DATA_ERROR 7 #define mlx90640_NO_ERROR 0
#define MLX90640_FRAME_DATA_ERROR 8 #define mlx90640_I2C_NACK_ERROR 1
#define MLX90640_MEAS_TRIGGER_ERROR 9 #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 BIT_MASK(x) (1UL << (x))
#define REG_MASK(sbit,nbits) ~((~(~0UL << (nbits))) << (sbit)) #define REG_MASK(sbit,nbits) ~((~(~0UL << (nbits))) << (sbit))
#define MLX90640_EEPROM_START_ADDRESS 0x2400 #define mlx90640_EEPROM_START_ADDRESS 0x2400
#define MLX90640_EEPROM_DUMP_NUM 832 #define mlx90640_EEPROM_DUMP_NUM 832
#define MLX90640_PIXEL_DATA_START_ADDRESS 0x0400 #define mlx90640_PIXEL_DATA_START_ADDRESS 0x0400
#define MLX90640_PIXEL_NUM 768 #define mlx90640_PIXEL_NUM 768
#define MLX90640_LINE_NUM 24 #define mlx90640_LINE_NUM 24
#define MLX90640_COLUMN_NUM 32 #define mlx90640_COLUMN_NUM 32
#define MLX90640_LINE_SIZE 32 #define mlx90640_LINE_SIZE 32
#define MLX90640_COLUMN_SIZE 24 #define mlx90640_COLUMN_SIZE 24
#define MLX90640_AUX_DATA_START_ADDRESS 0x0700 #define mlx90640_AUX_DATA_START_ADDRESS 0x0700
#define MLX90640_AUX_NUM 64 #define mlx90640_AUX_NUM 64
#define MLX90640_STATUS_REG 0x8000 #define mlx90640_STATUS_REG 0x8000
#define MLX90640_INIT_STATUS_VALUE 0x0030 #define mlx90640_INIT_STATUS_VALUE 0x0030
#define MLX90640_STAT_FRAME_MASK BIT_MASK(0) #define mlx90640_STAT_FRAME_MASK BIT_MASK(0)
#define MLX90640_GET_FRAME(reg_value) (reg_value & MLX90640_STAT_FRAME_MASK) #define mlx90640_GET_FRAME(reg_value) (reg_value & mlx90640_STAT_FRAME_MASK)
#define MLX90640_STAT_DATA_READY_MASK BIT_MASK(3) #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_GET_DATA_READY(reg_value) (reg_value & mlx90640_STAT_DATA_READY_MASK)
#define MLX90640_CTRL_REG 0x800D #define mlx90640_CTRL_REG 0x800D
#define MLX90640_CTRL_TRIG_READY_MASK BIT_MASK(15) #define mlx90640_CTRL_TRIG_READY_MASK BIT_MASK(15)
#define MLX90640_CTRL_REFRESH_SHIFT 7 #define mlx90640_CTRL_REFRESH_SHIFT 7
#define MLX90640_CTRL_REFRESH_MASK REG_MASK(MLX90640_CTRL_REFRESH_SHIFT,3) #define mlx90640_CTRL_REFRESH_MASK REG_MASK(mlx90640_CTRL_REFRESH_SHIFT,3)
#define MLX90640_CTRL_RESOLUTION_SHIFT 10 #define mlx90640_CTRL_RESOLUTION_SHIFT 10
#define MLX90640_CTRL_RESOLUTION_MASK REG_MASK(MLX90640_CTRL_RESOLUTION_SHIFT,2) #define mlx90640_CTRL_RESOLUTION_MASK REG_MASK(mlx90640_CTRL_RESOLUTION_SHIFT,2)
#define MLX90640_CTRL_MEAS_MODE_SHIFT 12 #define mlx90640_CTRL_MEAS_MODE_SHIFT 12
#define MLX90640_CTRL_MEAS_MODE_MASK BIT_MASK(12) #define mlx90640_CTRL_MEAS_MODE_MASK BIT_MASK(12)
#define MLX90640_MS_BYTE_SHIFT 8 #define mlx90640_MS_BYTE_SHIFT 8
#define MLX90640_MS_BYTE_MASK 0xFF00 #define mlx90640_MS_BYTE_MASK 0xFF00
#define MLX90640_LS_BYTE_MASK 0x00FF #define mlx90640_LS_BYTE_MASK 0x00FF
#define MLX90640_MS_BYTE(reg16) ((reg16 & MLX90640_MS_BYTE_MASK) >> MLX90640_MS_BYTE_SHIFT) #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_LS_BYTE(reg16) (reg16 & mlx90640_LS_BYTE_MASK)
#define MLX90640_MSBITS_6_MASK 0xFC00 #define mlx90640_MSBITS_6_MASK 0xFC00
#define MLX90640_LSBITS_10_MASK 0x03FF #define mlx90640_LSBITS_10_MASK 0x03FF
#define MLX90640_NIBBLE1_MASK 0x000F #define mlx90640_NIBBLE1_MASK 0x000F
#define MLX90640_NIBBLE2_MASK 0x00F0 #define mlx90640_NIBBLE2_MASK 0x00F0
#define MLX90640_NIBBLE3_MASK 0x0F00 #define mlx90640_NIBBLE3_MASK 0x0F00
#define MLX90640_NIBBLE4_MASK 0xF000 #define mlx90640_NIBBLE4_MASK 0xF000
#define MLX90640_NIBBLE1(reg16) ((reg16 & MLX90640_NIBBLE1_MASK)) #define mlx90640_NIBBLE1(reg16) ((reg16 & mlx90640_NIBBLE1_MASK))
#define MLX90640_NIBBLE2(reg16) ((reg16 & MLX90640_NIBBLE2_MASK) >> 4) #define mlx90640_NIBBLE2(reg16) ((reg16 & mlx90640_NIBBLE2_MASK) >> 4)
#define MLX90640_NIBBLE3(reg16) ((reg16 & MLX90640_NIBBLE3_MASK) >> 8) #define mlx90640_NIBBLE3(reg16) ((reg16 & mlx90640_NIBBLE3_MASK) >> 8)
#define MLX90640_NIBBLE4(reg16) ((reg16 & MLX90640_NIBBLE4_MASK) >> 12) #define mlx90640_NIBBLE4(reg16) ((reg16 & mlx90640_NIBBLE4_MASK) >> 12)
#define POW2(x) pow(2, (double)x) #define POW2(x) pow(2, (double)x)
@ -79,7 +86,12 @@
#include <stdint.h> #include <stdint.h>
typedef struct class MLX90640 : public QObject
{
Q_OBJECT
public:
typedef struct
{ {
int16_t kVdd; int16_t kVdd;
int16_t vdd25; int16_t vdd25;
@ -110,45 +122,62 @@ typedef struct
uint16_t outlierPixels[5]; uint16_t outlierPixels[5];
} paramsMLX90640; } paramsMLX90640;
class MLX90640{ int mlx90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData);
public: int mlx90640_SynchFrame(uint8_t slaveAddr);
int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData); int mlx90640_TriggerMeasurement(uint8_t slaveAddr);
int MLX90640_SynchFrame(uint8_t slaveAddr); Q_INVOKABLE int mlx90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData);
int MLX90640_TriggerMeasurement(uint8_t slaveAddr); int mlx90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData); Q_INVOKABLE float mlx90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params);
int MLX90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); Q_INVOKABLE float mlx90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params);
float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params); Q_INVOKABLE void mlx90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params);
float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params); void mlx90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result);
void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result); Q_INVOKABLE int mlx90640_SetResolution(uint8_t slaveAddr, uint8_t resolution);
void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result); int mlx90640_GetCurResolution(uint8_t slaveAddr);
int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution); Q_INVOKABLE int mlx90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate);
int MLX90640_GetCurResolution(uint8_t slaveAddr); int mlx90640_GetRefreshRate(uint8_t slaveAddr);
int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate); int mlx90640_GetSubPageNumber(uint16_t *frameData);
int MLX90640_GetRefreshRate(uint8_t slaveAddr); int mlx90640_GetCurMode(uint8_t slaveAddr);
int MLX90640_GetSubPageNumber(uint16_t *frameData); Q_INVOKABLE int mlx90640_SetInterleavedMode(uint8_t slaveAddr);
int MLX90640_GetCurMode(uint8_t slaveAddr); Q_INVOKABLE int mlx90640_SetChessMode(uint8_t slaveAddr);
int MLX90640_SetInterleavedMode(uint8_t slaveAddr); void mlx90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640 *params);
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: protected:
void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *MLX90640);
int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640); int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *MLX90640);
int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2); int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2);
float GetMedian(float *values, int n); float GetMedian(float *values, int n);
int IsPixelBad(uint16_t pixel,paramsMLX90640 *params); int IsPixelBad(uint16_t pixel,paramsMLX90640 *params);
int ValidateFrameData(uint16_t *frameData); int ValidateFrameData(uint16_t *frameData);
int ValidateAuxData(uint16_t *auxData); int ValidateAuxData(uint16_t *auxData);
signals:
void dataReady();
}; };
#endif #endif

@ -1,38 +1,40 @@
#include "MLX90640_I2C_Driver.h" #include "mlx90640_I2C_Driver.h"
#include "i2cdriversingleton.h" #include "i2cdriversingleton.h"
#include <QString> #include <QString>
#define DEFAULT_I2C_DEV QString("/dev/i2c-1/") #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()->tohVddSet(QString("on"));
i2cDriverSingleton::getinstance()->i2cProbe(DEFAULT_I2C_DEV); 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 /// \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 /// \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){ int mlx90640_I2CRead(uint8_t slaveAddr,uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data){
i2cDriverSingleton::getinstance()->i2cRead(DEFAULT_I2C_DEV,nMemAddressRead,nMemAddressRead); 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. * limitations under the License.
* *
*/ */
#ifndef _MLX90640_I2C_Driver_H_ #ifndef _mlx90640_I2C_Driver_H_
#define _MLX90640_I2C_Driver_H_ #define _mlx90640_I2C_Driver_H_
#include <stdint.h> #include <stdint.h>
#include "MLX90640_API.h" #include "mlx90640_API.h"
extern void MLX90640_I2CInit(void); extern void mlx90640_I2CInit(void);
extern int MLX90640_I2CGeneralReset(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 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); extern void mlx90640_I2CFreqSet(int freq);
#endif #endif

@ -1,6 +1,6 @@
#include "i2cdriversingleton.h" #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() I2cif* i2cDriverSingleton::getinstance()
{ {
@ -13,5 +13,6 @@ I2cif* i2cDriverSingleton::getinstance()
void i2cDriverSingleton::cleanup(){ void i2cDriverSingleton::cleanup(){
if(instance != nullptr){ if(instance != nullptr){
instance->tohVddSet(QString("off")); instance->tohVddSet(QString("off"));
delete instance;
} }
} }

@ -1,5 +1,3 @@
#include "i2cif.h"
#include "i2cif.h" #include "i2cif.h"
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-dev.h> #include <linux/i2c-dev.h>
@ -15,6 +13,8 @@
#include <sailfishapp.h> #include <sailfishapp.h>
#include "conv.h" #include "conv.h"
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#define DEFAULT_I2C_DEV QString("/dev/i2c-1/")
I2cif::I2cif(QObject *parent) : I2cif::I2cif(QObject *parent) :
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) void I2cif::i2cWrite(QString devName, unsigned char address, QString data)
{ {
int file; 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) void I2cif::i2cRead(QString devName, unsigned char address, int count)
{ {
int file; int file;
char buf[200]; const int CHUNK_SIZE = 200;
char buf[CHUNK_SIZE];
Conv conv; Conv conv;
int bytesRead = 0;
const int MAX_ATTEMPTS = 3;
int attempt = 0;
m_readResult = ""; m_readResult = "";
//emit i2cReadResultChanged();
QByteArray tmpBa = devName.toUtf8(); QByteArray tmpBa = devName.toUtf8();
const char* devNameChar = tmpBa.constData(); const char* devNameChar = tmpBa.constData();
fprintf(stderr, "reading from address %02x count %d\n", address, count); fprintf(stderr, "reading from address %02x count %d\n", address, count);
do
{
if ((file = open (devNameChar, O_RDWR)) < 0) if ((file = open (devNameChar, O_RDWR)) < 0)
{ {
fprintf(stderr,"open error\n"); 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(); emit i2cError();
return; return;
} }
@ -190,33 +317,42 @@ void I2cif::i2cRead(QString devName, unsigned char address, int count)
if (ioctl(file, I2C_SLAVE, address) < 0) if (ioctl(file, I2C_SLAVE, address) < 0)
{ {
close(file); close(file);
fprintf(stderr,"ioctl error\n"); perror("ioctl");
emit i2cError(); emit i2cError();
return; return;
} }
while(bytesRead < count)
{
int chunk = count - bytesRead;
if(chunk > CHUNK_SIZE)
{
chunk = CHUNK_SIZE;
}
/* Read data */ /* Read data */
if (read( file, buf, count ) != count) if (read( file, buf, chunk ) != chunk)
{ {
close(file); close(file);
fprintf(stderr,"read error\n"); perror("read");
emit i2cError(); emit i2cError();
return; return;
} }
close(file);
/* copy buf to m_readResult */ /* copy buf to m_readResult */
int i;
fprintf(stderr, "read "); fprintf(stderr, "read ");
for (i=0; i<count ; i++) for (int i=0; i<chunk ; i++)
{ {
m_readResult = m_readResult + conv.toHex(buf[i],2) + " "; m_readResult = m_readResult + conv.toHex(buf[i],2) + " ";
fprintf(stderr, "%02x ", buf[i]); fprintf(stderr, "%02x ", buf[i]);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
bytesRead += chunk;
}
close(file);
emit i2cReadResultChanged(); emit i2cReadResultChanged();
} }
/* /*

@ -2,6 +2,8 @@
#define I2CIF_H #define I2CIF_H
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <array>
class I2cif : public QObject class I2cif : public QObject
{ {
@ -20,6 +22,8 @@ public:
Q_INVOKABLE void i2cProbe(QString devName); Q_INVOKABLE void i2cProbe(QString devName);
Q_INVOKABLE void i2cWrite(QString devName, unsigned char address, QString data); 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 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 i2cWriteThenRead(QString devName, unsigned char address, QString data, int count);
Q_INVOKABLE void tohVddSet(QString onOff); Q_INVOKABLE void tohVddSet(QString onOff);

@ -1,4 +1,8 @@
#ifdef QT_QML_DEBUG #ifdef QT_QML_DEBUG
#include "conv.h"
#include "i2cif.h"
#include "mlx90640_API.h"
#include <QtQuick> #include <QtQuick>
#endif #endif
@ -6,15 +10,9 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// SailfishApp::main() will display "qml/thermi2c.qml", if you need more qmlRegisterType<I2cif>("harbour.i2ctool.I2cif", 1, 0, "I2cif");
// control over initialization, you can use: qmlRegisterType<Conv>("harbour.i2ctool.Conv", 1, 0, "Conv");
// qmlRegisterType<MLX90640>("melexis.driver", 1, 0, "MLX90640");
// - 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).
return SailfishApp::main(argc, argv); return SailfishApp::main(argc, argv);
} }

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

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!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> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -275,7 +275,7 @@
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.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> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
@ -303,7 +303,11 @@
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmBuildStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmBuildStep</value>
</valuemap> </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.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
@ -340,83 +344,6 @@
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">3</value> <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> <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> <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events"> <valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value> <value type="QString">cpu-cycles</value>
@ -486,16 +413,16 @@
<value type="QString" key="MerRunConfiguration.QmlLiveTargetWorkspace"></value> <value type="QString" key="MerRunConfiguration.QmlLiveTargetWorkspace"></value>
<value type="int" key="PE.EnvironmentAspect.Base">1</value> <value type="int" key="PE.EnvironmentAspect.Base">1</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Custom Executable2</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">thermi2c</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerCustomRunConfiguration:</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"></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="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value> <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap> </valuemap>
</data> </data>
<data> <data>

@ -8,21 +8,6 @@
<translation>Mein Cover</translation> <translation>Mein Cover</translation>
</message> </message>
</context> </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> <context>
<name>SecondPage</name> <name>SecondPage</name>
<message> <message>

@ -8,21 +8,6 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </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> <context>
<name>SecondPage</name> <name>SecondPage</name>
<message> <message>

Loading…
Cancel
Save