some more progress, but still can't see devices

This commit is contained in:
2025-04-15 22:42:50 +02:00
parent cd8aca36a2
commit 8e72fa7475
7 changed files with 169 additions and 89 deletions

23
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,23 @@
{
"files.associations": {
"**/debian/*.install": "plain",
"charconv": "cpp",
"chrono": "cpp",
"optional": "cpp",
"format": "cpp",
"ratio": "cpp",
"system_error": "cpp",
"array": "cpp",
"functional": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"__bit_reference": "cpp",
"__node_handle": "cpp",
"deque": "cpp",
"limits": "cpp",
"locale": "cpp",
"vector": "cpp",
"algorithm": "cpp"
}
}

View File

@@ -48,7 +48,6 @@
// #define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM // #define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM
#include "camera_pins.h" #include "camera_pins.h"
// //
// LEP Task constants // LEP Task constants
// //
@@ -69,7 +68,6 @@ int64_t vsyncDetectedUsec;
WiFiServer lipSrv(8078); WiFiServer lipSrv(8078);
// =========================== // ===========================
// Enter your WiFi credentials // Enter your WiFi credentials
// =========================== // ===========================
@@ -79,7 +77,8 @@ const char *password = "plechovka";
void startCameraServer(); void startCameraServer();
void setupLedFlash(int pin); void setupLedFlash(int pin);
void setup() { void setup()
{
gpio_config_t usb_phy_conf = { gpio_config_t usb_phy_conf = {
.pin_bit_mask = (1ULL << 19) | (1ULL << 20), .pin_bit_mask = (1ULL << 19) | (1ULL << 20),
.mode = GPIO_MODE_OUTPUT, .mode = GPIO_MODE_OUTPUT,
@@ -175,17 +174,23 @@ gpio_config(&usb_phy_conf);
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer. // for larger pre-allocated frame buffer.
if (config.pixel_format == PIXFORMAT_JPEG) { if (config.pixel_format == PIXFORMAT_JPEG)
if (psramFound()) { {
if (psramFound())
{
config.jpeg_quality = 10; config.jpeg_quality = 10;
config.fb_count = 2; config.fb_count = 2;
config.grab_mode = CAMERA_GRAB_LATEST; config.grab_mode = CAMERA_GRAB_LATEST;
} else { }
else
{
// Limit the frame size when PSRAM is not available // Limit the frame size when PSRAM is not available
config.frame_size = FRAMESIZE_SVGA; config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM; config.fb_location = CAMERA_FB_IN_DRAM;
} }
} else { }
else
{
// Best option for face detection/recognition // Best option for face detection/recognition
config.frame_size = FRAMESIZE_240X240; config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S3
@@ -200,20 +205,23 @@ gpio_config(&usb_phy_conf);
// camera init // camera init
esp_err_t err = esp_camera_init(&config); esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) { if (err != ESP_OK)
{
printf("Camera init failed with error 0x%x", err); printf("Camera init failed with error 0x%x", err);
return; return;
} }
sensor_t *s = esp_camera_sensor_get(); sensor_t *s = esp_camera_sensor_get();
// initial sensors are flipped vertically and colors are a bit saturated // initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) { if (s->id.PID == OV3660_PID)
{
s->set_vflip(s, 1); // flip it back s->set_vflip(s, 1); // flip it back
s->set_brightness(s, 1); // up the brightness just a bit s->set_brightness(s, 1); // up the brightness just a bit
s->set_saturation(s, -2); // lower the saturation s->set_saturation(s, -2); // lower the saturation
} }
// drop down frame size for higher initial frame rate // drop down frame size for higher initial frame rate
if (config.pixel_format == PIXFORMAT_JPEG) { if (config.pixel_format == PIXFORMAT_JPEG)
{
s->set_framesize(s, FRAMESIZE_QVGA); s->set_framesize(s, FRAMESIZE_QVGA);
} }
@@ -235,7 +243,8 @@ gpio_config(&usb_phy_conf);
WiFi.setSleep(false); WiFi.setSleep(false);
printf("WiFi connecting\n"); printf("WiFi connecting\n");
while (WiFi.status() != WL_CONNECTED) { while (WiFi.status() != WL_CONNECTED)
{
delay(500); delay(500);
printf("."); printf(".");
} }
@@ -250,7 +259,6 @@ gpio_config(&usb_phy_conf);
printf("' to connect\n"); printf("' to connect\n");
} }
uint8_t *take_picture() uint8_t *take_picture()
{ {
digitalWrite(LEP_CSN_PIN, 0); digitalWrite(LEP_CSN_PIN, 0);

View File

@@ -645,7 +645,7 @@ static int cci_write_burst(uint16_t start, uint16_t word_len, uint16_t *buf)
int i; int i;
size_t bufSize = sizeof(*buf) * (1 + word_len); size_t bufSize = sizeof(*buf) * (1 + word_len);
buffer = malloc(bufSize); unsigned char *buffer = (unsigned char *)malloc(bufSize);
// Create the i2c transaction buffer // Create the i2c transaction buffer
buffer[0] = start >> 8; buffer[0] = start >> 8;
@@ -656,15 +656,16 @@ static int cci_write_burst(uint16_t start, uint16_t word_len, uint16_t *buf)
buffer[i * 2 + 1] = *buf++ & 0xFF; buffer[i * 2 + 1] = *buf++ & 0xFF;
} }
esp_err_t ret = i2c_master_transmit(LEPTON_DEV_HANDLE, buffer, sizeof(buffer), I2C_TIMEOUT_MS_VALUE); esp_err_t ret = i2c_master_transmit(LEPTON_DEV_HANDLE, buffer, bufSize, I2C_TIMEOUT_MS_VALUE);
free(buffer);
if (ret == ESP_OK) if (ret == ESP_OK)
{ {
ESP_LOGV(TAG_CCI, "Burst write to register 0x%04X successful (Value: 0x%04X)", reg_addr, value); ESP_LOGV(TAG_CCI, "Burst write to register 0x%04X successful", start);
return 1; return 1;
} }
else else
{ {
ESP_LOGE(TAG_CCI, "Burst write to register 0x%04X failed: %s", reg_addr, esp_err_to_name(ret)); ESP_LOGE(TAG_CCI, "Burst write to register 0x%04X failed: %s", start, esp_err_to_name(ret));
return -1; return -1;
} }
} }
@@ -684,11 +685,12 @@ uint16_t cci_read_register(uint16_t reg_addr)
{ {
uint8_t buffer[2]; uint8_t buffer[2];
esp_err_t ret = i2c_master_transmit_receive(LEPTON_DEV_HANDLE, &reg_addr, sizeof(reg_addr), buffer, sizeof(buffer), I2C_TIMEOUT_MS_VALUE); esp_err_t ret = i2c_master_transmit_receive(LEPTON_DEV_HANDLE, (uint8_t *)&reg_addr, sizeof(reg_addr), buffer, sizeof(buffer), I2C_TIMEOUT_MS_VALUE);
if (ret == ESP_OK) if (ret == ESP_OK)
{ {
ESP_LOGV(TAG_CCI, "Read from register 0x%04X successful (Value: 0x%04X)", reg_addr, *value); uint16_t value = (((uint16_t)(buffer[0] & 0xFF)) << 8) | (buffer[1] & 0xFF);
return (((uint16_t)(buffer[0] & 0xFF)) << 8) | (buffer[1] & 0xFF); ESP_LOGV(TAG_CCI, "Read from register 0x%04X successful (Value: 0x%04X)", reg_addr, value);
return value;
} }
else else
{ {
@@ -713,24 +715,30 @@ int cci_read_burst(uint16_t start, uint16_t word_len, uint16_t *buf)
return -1; return -1;
} }
size_t bufSize = word_len * sizeof(*buf); size_t bufSize = word_len * sizeof(*buf);
buffer = malloc(bufSize); unsigned char *buffer = (unsigned char *)malloc(bufSize);
esp_err_t ret = i2c_master_transmit_receive(LEPTON_DEV_HANDLE, &reg_addr, sizeof(reg_addr), buffer, bufSize, I2C_TIMEOUT_MS_VALUE); esp_err_t ret = i2c_master_transmit_receive(LEPTON_DEV_HANDLE, (uint8_t *)&start, sizeof(start), buffer, bufSize, I2C_TIMEOUT_MS_VALUE);
if (ret == ESP_OK) if (ret == ESP_OK)
{ {
ESP_LOGV(TAG_CCI, "Read from register 0x%04X successful (Value: 0x%04X)", reg_addr, *value); ESP_LOGV(TAG_CCI, "Read from register 0x%04X successful", start);
for (int i = 0; i < word_len; i++) for (int i = 0; i < word_len; i++)
{ // CHECK IF THIS IS NEEDED { // CHECK IF THIS IS NEEDED
*buf++ = buffer[i * 2] << 8 | buffer[i * 2 + 1]; *buf++ = buffer[i * 2] << 8 | buffer[i * 2 + 1];
} }
free(buffer);
return 1; return 1;
} }
else else
{ {
ESP_LOGE(TAG_CCI, "Read from register 0x%04X failed: %s", reg_addr, esp_err_to_name(ret)); ESP_LOGE(TAG_CCI, "Read from register 0x%04X failed: %s", start, esp_err_to_name(ret));
return -1; return -1;
} }
} }
/**
* Wait for busy to be clear in the status register
* Returns the 16-bit STATUS
* Returns 0x00010000 if there is a communication failure
*/
/** /**
* Wait for busy to be clear in the status register * Wait for busy to be clear in the status register
* Returns the 16-bit STATUS * Returns the 16-bit STATUS
@@ -739,12 +747,13 @@ int cci_read_burst(uint16_t start, uint16_t word_len, uint16_t *buf)
static uint32_t cci_wait_busy_clear() static uint32_t cci_wait_busy_clear()
{ {
bool err = false; bool err = false;
uint8_t buf[2] = {0x00, 0x07}; uint8_t tx_buf[2]; // Register address to read from
uint8_t rx_buf[2]; // Value buffer
int t = 0; // maximum tick count uint16_t reg_addr = 0x0002; // STATUS register
int t = 0;
// Wait for booted, not busy while (!err)
while (((buf[1] & 0x07) != 0x06) && !err)
{ {
if (t++ >= CCI_MAX_WAIT_TICKS) if (t++ >= CCI_MAX_WAIT_TICKS)
{ {
@@ -752,32 +761,33 @@ static uint32_t cci_wait_busy_clear()
break; break;
} }
// Write STATUS register address // Prepare register address in big-endian
buf[0] = 0x00; tx_buf[0] = (reg_addr >> 8) & 0xFF;
buf[1] = 0x02; tx_buf[1] = reg_addr & 0xFF;
esp_err_t ret = i2c_master_transmit_receive(LEPTON_DEV_HANDLE, &reg_addr, sizeof(reg_addr), buf, sizeof(buf), I2C_TIMEOUT_MS_VALUE); esp_err_t ret = i2c_master_transmit_receive(LEPTON_DEV_HANDLE, tx_buf, sizeof(tx_buf), rx_buf, sizeof(rx_buf), I2C_TIMEOUT_MS_VALUE);
if (ret == ESP_OK) if (ret != ESP_OK)
{
ESP_LOGV(TAG_CCI, "Read from register 0x%04X successful (Value: 0x%04X)", reg_addr, *value);
}
else
{
ESP_LOGE(TAG_CCI, "Read from register 0x%04X failed: %s", reg_addr, esp_err_to_name(ret));
return -1;
}
}
if (err)
{ {
ESP_LOGE(TAG_CCI, "Failed to read STATUS register: %s", esp_err_to_name(ret));
return 0x00010000; return 0x00010000;
} }
else
uint16_t status = ((uint16_t)rx_buf[0] << 8) | rx_buf[1];
ESP_LOGV(TAG_CCI, "STATUS register read: 0x%04X", status);
// Check bits [2:0] == 0b110 (0x06)
if ((rx_buf[1] & 0x07) == 0x06)
{ {
return (buf[0] << 8) | buf[1]; return status;
} }
} }
// Timed out
return 0x00010000;
}
/** /**
* Wait for busy to be clear in the status register and check the result * Wait for busy to be clear in the status register and check the result
* printing an error if detected * printing an error if detected

View File

@@ -29,6 +29,9 @@
// #include "freertos/FreeRTOS.h" // #include "freertos/FreeRTOS.h"
// #include "freertos/semphr.h" // #include "freertos/semphr.h"
i2c_master_bus_handle_t i2c0_bus_hdl; // migrate to newer
i2c_master_dev_handle_t LEPTON_DEV_HANDLE;
// //
// I2C API // I2C API
// //
@@ -36,20 +39,55 @@
/** /**
* i2c master initialization * i2c master initialization
*/ */
esp_err_t i2c_master_bus_detect_devices(i2c_master_bus_handle_t handle)
{
const uint16_t probe_timeout_ms = 50; // timeout in milliseconds
uint8_t address;
bool found_any = false;
printf("Scanning I2C bus...\n");
for (int i = 0; i < 128; i++)
{
fflush(stdout);
address = i;
esp_err_t ret = i2c_master_probe(handle, address, probe_timeout_ms);
if (ret == ESP_OK)
{
printf("Found device at 0x%02X\n", address);
found_any = true;
}
}
if (!found_any)
{
printf("No I2C devices found.\n");
}
return ESP_OK;
}
esp_err_t i2c_master_init(gpio_num_t scl_pin, gpio_num_t sda_pin) esp_err_t i2c_master_init(gpio_num_t scl_pin, gpio_num_t sda_pin)
{ {
i2c_master_bus_config_t i2c0_bus_cfg = { i2c_master_bus_config_t i2c0_bus_cfg = {
.i2c_port = I2C_MASTER_NUM, .i2c_port = I2C_MASTER_NUM,
.sda_io_num = sda_pin, .sda_io_num = sda_pin,
.scl_io_num = scl_pin, .scl_io_num = scl_pin,
.clk_source = I2C_CLK_SRC_DEFAULT, .clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7, .glitch_ignore_cnt = 7,
.flags = {
.enable_internal_pullup = true,
.allow_pd = false,
}
}; };
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c0_bus_cfg, &i2c0_bus_hdl)); ESP_ERROR_CHECK(i2c_new_master_bus(&i2c0_bus_cfg, &i2c0_bus_hdl));
i2c_master_bus_detect_devices(i2c0_bus_hdl);
i2c_device_config_t LEPTON_DEV_CFG = { i2c_device_config_t LEPTON_DEV_CFG = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7, .dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = CCI_ADDRESS, .device_address = CCI_ADDRESS,

View File

@@ -22,7 +22,9 @@
* along with tCam. If not, see <https://www.gnu.org/licenses/>. * along with tCam. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
#pragma once
#ifndef TCAM_I2C
#define TCAM_I2C
#include <stdint.h> #include <stdint.h>
#include "esp_system.h" #include "esp_system.h"
@@ -41,10 +43,11 @@
#define ACK_VAL (i2c_ack_type_t)0x0 #define ACK_VAL (i2c_ack_type_t)0x0
#define NACK_VAL (i2c_ack_type_t)0x1 #define NACK_VAL (i2c_ack_type_t)0x1
i2c_master_bus_handle_t i2c0_bus_hdl; //migrate to newer extern i2c_master_bus_handle_t i2c0_bus_hdl; //migrate to newer
i2c_master_dev_handle_t LEPTON_DEV_HANDLE; extern i2c_master_dev_handle_t LEPTON_DEV_HANDLE;
// //
// I2C API // I2C API
// //
esp_err_t i2c_master_init(gpio_num_t scl_pin, gpio_num_t sda_pin); esp_err_t i2c_master_init(gpio_num_t scl_pin, gpio_num_t sda_pin);
#endif

View File

@@ -12,7 +12,6 @@
// lepton image and telem buffer // lepton image and telem buffer
lep_buffer_t rsp_lep_buffer; lep_buffer_t rsp_lep_buffer;
/** /**
* Initialize the ESP32 GPIO and internal peripherals * Initialize the ESP32 GPIO and internal peripherals
*/ */
@@ -29,7 +28,6 @@ bool lepton_io_init()
printf("[LEP SYS] Error: I2C Master initialization failed\n"); printf("[LEP SYS] Error: I2C Master initialization failed\n");
return false; return false;
} }
// Attempt to initialize the SPI Master used by the lep_task // Attempt to initialize the SPI Master used by the lep_task
memset(&spi_buscfg, 0, sizeof(spi_bus_config_t)); memset(&spi_buscfg, 0, sizeof(spi_bus_config_t));
spi_buscfg.miso_io_num=LEP_MISO_PIN; spi_buscfg.miso_io_num=LEP_MISO_PIN;

View File

@@ -19,10 +19,10 @@
#define LEP_CSN_PIN 14 // SPI_CS 10 #define LEP_CSN_PIN 14 // SPI_CS 10
#define LEP_RESET_PIN 20 // RESET_L 17 #define LEP_RESET_PIN 20 // RESET_L 17
#define I2C_TIMEOUT_MS_VALUE 20 #define I2C_TIMEOUT_MS_VALUE 2000
#define I2C_MASTER_SDA_PIN GPIO_NUM_4 // SDA 5 #define I2C_MASTER_SDA_PIN GPIO_NUM_4 // SDA
#define I2C_MASTER_SCL_PIN GPIO_NUM_5 // SCL 8 #define I2C_MASTER_SCL_PIN GPIO_NUM_5 // SCL
#define CCI_ADDRESS 0x2A #define CCI_ADDRESS 0x2A
// I2C // I2C