summaryrefslogtreecommitdiff
path: root/src/camera
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2025-11-07 23:10:25 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2025-11-07 23:10:25 +0100
commitc38edfbd30aae121ebdaaac8e8e25f8784da318d (patch)
treeb67604615c6feac45e503da9a28473c7ed7f8316 /src/camera
parenta9af2d69c0a4d46dc98b6e0adaf13a7f23a24bce (diff)
speedup; add some i2c commands
Diffstat (limited to 'src/camera')
-rw-r--r--src/camera/veye_i2c.cpp106
-rw-r--r--src/camera/veye_i2c.h12
-rw-r--r--src/camera/veyeimx287m.cpp13
-rw-r--r--src/camera/veyeimx287m.h4
-rw-r--r--src/camera/veyeimx287m_types.h135
5 files changed, 266 insertions, 4 deletions
diff --git a/src/camera/veye_i2c.cpp b/src/camera/veye_i2c.cpp
new file mode 100644
index 0000000..9d04d9b
--- /dev/null
+++ b/src/camera/veye_i2c.cpp
@@ -0,0 +1,106 @@
+#include "veye_i2c.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <iostream>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include "veyeimx287m_types.h"
+
+bool veye::imx287m::i2cRead(int fd, uint8_t i2c_addr, uint16_t reg, uint32_t &value)
+{
+ int err;
+ int i = 0;
+ uint8_t buf[2] = {reg >> 8, reg & 0xff};
+ uint8_t bufout[4] = {0};
+ struct i2c_msg msgs[2] = {
+ {.addr = i2c_addr,
+ .flags = 0,
+ .len = 2,
+ // .buf = (uint8_t *) (&reg),
+ .buf = buf},
+ {
+ .addr = i2c_addr,
+ .flags = I2C_M_RD,
+ .len = 4,
+ .buf = bufout,
+ },
+ };
+
+ struct i2c_rdwr_ioctl_data msgset;
+ msgset.msgs = msgs;
+ msgset.nmsgs = 2;
+
+ err = ioctl(fd, I2C_RDWR, &msgset);
+ //printf("Read i2c addr %02X\n", i2c_addr);
+ if (err != msgset.nmsgs) {
+ std::cerr << "Read i2c err " << err << std::endl;
+ return false;
+ }
+
+ value = ntohl(*(uint32_t *) bufout);
+ // fprintf(stderr, "addr %04x : value %08x \n", reg + i, value);
+
+ return true;
+}
+
+bool veye::imx287m::test(uint32_t value)
+{
+ const std::string i2cDevName{"/dev/i2c-10"};
+ constexpr uint32_t i2cDevAddr{0x3b};
+ int fd = open(i2cDevName.c_str(), O_RDWR);
+
+ if (!fd) {
+ std::cerr << "cannot open i2c device " << i2cDevName << ", error: " << strerror(errno)
+ << std::endl;
+ return false;
+ }
+
+ if (ioctl(fd, I2C_SLAVE_FORCE, i2cDevAddr) < 0) {
+ std::cerr << "cannot set i2c slave. dev: " << i2cDevName << ", addr: " << i2cDevAddr
+ << ", error: " << strerror(errno) << std::endl;
+
+ return false;
+ }
+
+ uint32_t expTime{0};
+ // if (!i2cRead(fd, i2cDevAddr, (uint16_t) veye::imx287m::Register::ME_Time, expTime)) {
+ // return false;
+ // }
+
+ // std::cout << "exp time is: " << expTime << std::endl;
+ std::cout << "set exp time to " << value;
+
+ if (!i2cWrite(fd, (uint16_t) veye::imx287m::Register::ME_Time, value)) {
+ return false;
+ }
+
+ if (!i2cRead(fd, i2cDevAddr, (uint16_t) veye::imx287m::Register::ME_Time, expTime)) {
+ return false;
+ }
+ std::cout << "\texp time is: " << expTime << std::endl;
+
+ return true;
+}
+
+bool veye::imx287m::i2cWrite(int fd, uint16_t reg, const uint32_t value)
+{
+ uint8_t msg[] = {reg >> 8, reg & 0xff, value >> 24, value >> 16, value >> 8, value >> 0};
+ int len = sizeof(msg) / sizeof(msg[0]);
+
+ if (write(fd, msg, len) != len) {
+ std::cerr << "cannot write value. reg: " << reg << ", error: " << strerror(errno)
+ << std::endl;
+ return false;
+ }
+
+ // TODO: find a best way to get up-to-date values
+ usleep(100);
+
+ return true;
+}
diff --git a/src/camera/veye_i2c.h b/src/camera/veye_i2c.h
new file mode 100644
index 0000000..1638976
--- /dev/null
+++ b/src/camera/veye_i2c.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <cstdint>
+
+namespace veye {
+namespace imx287m {
+bool i2cRead(int fd, uint8_t i2c_addr, uint16_t reg, uint32_t &value);
+bool i2cWrite(int fd, uint16_t reg, const uint32_t value);
+
+bool test(uint32_t value);
+} // namespace imx287m
+} // namespace veye
diff --git a/src/camera/veyeimx287m.cpp b/src/camera/veyeimx287m.cpp
index dee3c6a..c7e519a 100644
--- a/src/camera/veyeimx287m.cpp
+++ b/src/camera/veyeimx287m.cpp
@@ -15,6 +15,7 @@
#include <QElapsedTimer>
#include "constants.h"
+#include "imagealgos.h"
#include "pixels.h"
// #include "rotaryencoder.h"
@@ -141,7 +142,7 @@ bool VeyeIMX287m::init()
bool VeyeIMX287m::setExposureTimeUs(int valueUs)
{
- return true;
+ //return true;
std::cout << __func__ << ": " << valueUs << std::endl << std::flush;
/*
@@ -378,7 +379,15 @@ void VeyeIMX287m::calcFrameLoop(std::stop_token stopToken)
}
image.rotate();
- image.pixels();
+ // const auto pixels = image.pixels();
+ const auto pixels = image.sharedPixels();
+#pragma push_macro("emit")
+#undef emit
+ // std::cout << "emit pixels" << std::endl;
+ newPixels.emit(pixels);
+#pragma pop_macro("emit")
+ // const auto lines = pixelsToLines(*pixels);
+ // continue;
// setCamParam(V4L2_CID_EXPOSURE, 18);
}
diff --git a/src/camera/veyeimx287m.h b/src/camera/veyeimx287m.h
index 9986e59..37da5b0 100644
--- a/src/camera/veyeimx287m.h
+++ b/src/camera/veyeimx287m.h
@@ -42,8 +42,8 @@ public:
// Image &getImage();
public:
- libcamera::Signal<std::shared_ptr<Pixels>> newPixels;
- libcamera::Signal<std::shared_ptr<Image>> newImage;
+ // libcamera::Signal<std::shared_ptr<Pixels>> newPixels;
+ // libcamera::Signal<std::shared_ptr<Image>> newImage;
private:
bool setCamParam(unsigned int v4l2controlId, int value);
diff --git a/src/camera/veyeimx287m_types.h b/src/camera/veyeimx287m_types.h
new file mode 100644
index 0000000..640a0e1
--- /dev/null
+++ b/src/camera/veyeimx287m_types.h
@@ -0,0 +1,135 @@
+#pragma once
+
+#include <QObject>
+
+namespace veye {
+namespace imx287m {
+
+enum class Register {
+ ImageAcqu = 0x0400,
+ ImageFeature = 0x0800,
+ ImageSigProc = 0x0c00,
+ IOCtrl = 0x1000,
+ FPGACmd = 0x1400,
+ FPGABlock = 0x1800,
+
+ Manufacturer_Name = 0x0000,
+ Model_Name = 0x0004,
+ Sensor_Name = 0x0008,
+ Product_Info = 0x000C,
+ Device_Version = 0x0010,
+ System_reset = 0x0014,
+ Param_save_to_flash = 0x0018,
+ System_reboot = 0x001C,
+ Time_stamp = 0x0020,
+ Error_code = 0x0024,
+ Format_Cap = 0x0028,
+ TriggerMode_Cap = 0x0030,
+ LaneNum_Cap = 0x0034,
+ Temp_K = 0x0058,
+
+ Image_Acquisition = 0x400,
+ Trigger_Mode = 0x404,
+ Trigger_Source = 0x408,
+ Trigger_Num = 0x40C,
+ Trigger_Inerval = 0x410,
+ Trigger_Software = 0x414,
+ Trigger_Count = 0x418,
+ I2C_Addr = 0x41C,
+ I2C_Port_Sel = 0x420,
+
+ User_overlay_enable = 0x428,
+ User_overlay_zone0 = 0x42C,
+ User_overlay_zone1 = 0x430,
+ User_overlay_zone2 = 0x434,
+ User_overlay_zone3 = 0x438,
+ User_define_zone0 = 0x43C,
+ User_define_zone1 = 0x440,
+ User_define_zone2 = 0x444,
+ User_define_zone3 = 0x448,
+ Nondiscontinuous_mode = 0x44C,
+ Sensor_Reg_Addr = 0x0450,
+ Sensor_Reg_Val = 0x454,
+ Slave_mode = 0x460,
+ Sensor_Frame_Count = 0x464,
+ Out_Frame_Count = 0x468,
+ Trigger_Cycle_Min = 0x46C,
+ Trigger_Cycle_Max = 0x470,
+
+ Test_Image_Selector = 0x800,
+ Pixel_Format = 0x804,
+ Sensor_Width = 0x808,
+ Sensor_Height = 0x80C,
+ MaxFrame_Rate = 0x810,
+ Framerate = 0x814,
+ ROI_Width = 0x818,
+ ROI_Height = 0x81C,
+ ROI_Offset_X = 0x820,
+ ROI_Offset_Y = 0x824,
+ Image_Direction = 0x828,
+ Data_shift = 0x82C,
+ Black_Level = 0x830,
+ BLC_Mode = 0x834,
+ ReadOut_Mode = 0x838,
+ Lane_Num = 0x83C,
+ MIPI_DataRate = 0x840,
+ MIN_ROI_Width = 0x844,
+ MIN_ROI_Height = 0x848,
+ FrameRate_Ex = 0x850,
+ OSD_Mode = 0x854,
+
+ ISP_module_ctrl = 0xC00,
+ Exposure_Mode = 0xC04,
+ Target_Brightness = 0xC08,
+ Exposure_Time_Source = 0xC0C,
+ ME_Time = 0xC10,
+ AE_MAX_Time = 0xC14,
+ Exp_Time = 0xC18,
+ Gain_Mode = 0xC1C,
+ Manual_Gain = 0xC20,
+ AG_Max_Gain = 0xC24,
+ Cur_Gain = 0xC28,
+ AAROIOffsetX = 0xC2C,
+ AAROIOffsetY = 0xC30,
+ AAROIWidth = 0xC34,
+ AAROIHeight = 0xC38,
+ WB_Mode = 0xC3C,
+ MWB_Rgain = 0xC40,
+ MWB_Bgain = 0xC44,
+ AWBROIOffsetX = 0xC48,
+ AWBROIOffsetY = 0xC4C,
+ AWBROIWidth = 0xC50,
+ AWBROIHeight = 0xC54,
+ AWB_Rgain = 0xC58,
+ AWB_Bgain = 0xC5C,
+ Gamma = 0xC60,
+ DPC_Start = 0xC64,
+ DPC_Status = 0xC68,
+ DPC_Count = 0xC6C,
+ AAROI_enable = 0xC80,
+ Max_Exp_time = 0xC8C,
+ Min_Exp_time = 0xC90,
+
+ Trigger_Delay = 0x1000,
+ Trigger_Activation = 0x1004,
+ Trigger_Filter_Enable = 0x1008,
+ Trigger_Filter_Width = 0x100C,
+ Trigger_Exp_Delay = 0x1010,
+ GPIOS_Status = 0x1014,
+
+ GPIO1_OutSelect = 0x1020,
+ GPIO1_Useroutput = 0x1024,
+ GPIO1_Reverse = 0x1028,
+
+ GPIO2_OutSelect = 0x1030,
+ GPIO2_Useroutput = 0x1034,
+ GPIO2_Reverse = 0x1038
+};
+
+class Params : public QObject
+{
+ // Q_OBJECT
+};
+
+} // namespace imx287m
+} // namespace veye