diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index e0287b7..39fd631 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,12 @@ idf_component_register(SRCS "main.c" + "lipton/cci.cpp" +"lipton/i2c.cpp" + "lipton/lepton_system.cpp" + "lipton/lepton_utilities.cpp" + "lipton/vospi.cpp" + "lipton/cci.h" + "lipton/i2c.h" + "lipton/lepton_system.h" + "lipton/lepton_utilities.h" + "lipton/vospi.h" INCLUDE_DIRS ".") \ No newline at end of file diff --git a/main/lipton/cci.cpp b/main/lipton/cci.cpp index 9100263..85ced4d 100644 --- a/main/lipton/cci.cpp +++ b/main/lipton/cci.cpp @@ -25,7 +25,7 @@ #include "i2c.h" #include #include -#include + #define CCI_MAX_WAIT_TICKS 5000 @@ -64,7 +64,7 @@ static void cci_wait_busy_clear_check(char* cmd); */ void cci_set_reg(uint16_t cmd, int len, uint16_t* buf) { - char cmd_buf[11]; // sized for 'cmd 0xNNNN' + char cmd_buf[12]; // sized for 'cmd 0xNNNN' int ret = 1; cci_last_status_error = false; @@ -554,7 +554,7 @@ void cc_run_oem_reboot() cci_wait_busy_clear(); cci_write_register(CCI_REG_COMMAND, CCI_CMD_OEM_RUN_REBOOT); // Sleep to allow camera to reboot and run FFC - delay(6000); + vTaskDelay(pdMS_TO_TICKS(6000)); cci_wait_busy_clear_check("CCI_CMD_OEM_RUN_REBOOT"); } @@ -631,10 +631,10 @@ static int cci_write_register(uint16_t reg, uint16_t value) { // Write the register address and value uint8_t write_buf[4] = { - reg >> 8 & 0xff, - reg & 0xff, - value >> 8 & 0xff, - value & 0xff + uint8_t (reg >> 8 & 0xff), + uint8_t (reg & 0xff), + uint8_t (value >> 8 & 0xff), + uint8_t (value & 0xff) }; if (i2c_master_write_slave(CCI_ADDRESS, write_buf, sizeof(write_buf)) != ESP_OK) { printf("[CCI] Error: failed to write CCI register %02x with value %02x\n", reg, value); diff --git a/main/lipton/i2c.cpp b/main/lipton/i2c.cpp index d86969e..db66432 100644 --- a/main/lipton/i2c.cpp +++ b/main/lipton/i2c.cpp @@ -83,7 +83,7 @@ esp_err_t i2c_master_read_slave(uint8_t addr7, uint8_t *data_rd, size_t size) } i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL); i2c_master_stop(cmd); - esp_err_t ret = i2c_master_cmd_begin((i2c_port_t)I2C_MODE_MASTER, cmd, 1000 / portTICK_RATE_MS); + esp_err_t ret = i2c_master_cmd_begin((i2c_port_t)I2C_MODE_MASTER, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); return ret; } @@ -104,7 +104,7 @@ esp_err_t i2c_master_write_slave(uint8_t addr7, uint8_t *data_wr, size_t size) i2c_master_write_byte(cmd, (addr7 << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN); i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN); i2c_master_stop(cmd); - esp_err_t ret = i2c_master_cmd_begin((i2c_port_t)I2C_MODE_MASTER, cmd, 1000 / portTICK_RATE_MS); + esp_err_t ret = i2c_master_cmd_begin((i2c_port_t)I2C_MODE_MASTER, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); return ret; } diff --git a/main/lipton/lepton_system.cpp b/main/lipton/lepton_system.cpp index 04a1de0..d262b93 100644 --- a/main/lipton/lepton_system.cpp +++ b/main/lipton/lepton_system.cpp @@ -7,7 +7,6 @@ #include "i2c.h" #include "vospi.h" #include -#include // lepton image and telem buffer @@ -45,12 +44,12 @@ bool lepton_io_init() } // initialize GPIO pins - pinMode(LEP_VSYNC_PIN, INPUT); + gpio_set_direction(LEP_VSYNC_PIN, GPIO_MODE_INPUT); #ifdef LEP_RESET_PIN - pinMode(LEP_RESET_PIN, OUTPUT); - digitalWrite(LEP_RESET_PIN, LEP_RESET_ON); - delay(10); - digitalWrite(LEP_RESET_PIN, LEP_RESET_OFF); + gpio_set_direction(LEP_RESET_PIN, GPIO_MODE_OUTPUT); + gpio_set_level(LEP_RESET_PIN, LEP_RESET_ON); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level(LEP_RESET_PIN, LEP_RESET_OFF); #endif return true; diff --git a/main/lipton/lepton_system.h b/main/lipton/lepton_system.h index 0920608..3ba4648 100644 --- a/main/lipton/lepton_system.h +++ b/main/lipton/lepton_system.h @@ -1,4 +1,5 @@ #pragma once +#include "driver/i2c.h" // // Hardware Configuration @@ -13,13 +14,13 @@ // #define I2C_MASTER_SDA_PIN 21 // SDA 5 // #define I2C_MASTER_SCL_PIN 22 // SCL 8 -#define LEP_MISO_PIN 40 // SPI_MISO 12 -#define LEP_VSYNC_PIN 41 // GPIO3/VSYNC 15 -#define LEP_SCK_PIN 47 // SPI_CLK 18 -#define LEP_CSN_PIN 14 // SPI_CS 10 -#define LEP_RESET_PIN 20 // RESET_L 17 +#define LEP_MISO_PIN GPIO_NUM_40 // SPI_MISO 12 +#define LEP_VSYNC_PIN GPIO_NUM_41 // GPIO3/VSYNC 15 +#define LEP_SCK_PIN GPIO_NUM_47 // SPI_CLK 18 +#define LEP_CSN_PIN GPIO_NUM_14 // SPI_CS 10 +#define LEP_RESET_PIN GPIO_NUM_20 // RESET_L 17 -#define I2C_MASTER_SDA_PIN 4 // SDA 5 +#define I2C_MASTER_SDA_PIN GPIO_NUM_4 // SDA 5 #define I2C_MASTER_SCL_PIN 5 // SCL 8 // I2C diff --git a/main/lipton/lepton_utilities.cpp b/main/lipton/lepton_utilities.cpp index 237881f..de4ae34 100644 --- a/main/lipton/lepton_utilities.cpp +++ b/main/lipton/lepton_utilities.cpp @@ -31,7 +31,7 @@ #include "esp_system.h" #include "vospi.h" #include -#include + static bool lep_is_radiometric = false; @@ -57,7 +57,7 @@ bool lepton_init() // If this is successful, we assume further communication will be successful rsp = cci_run_ping(); if (rsp != 0) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } @@ -86,16 +86,16 @@ bool lepton_init() // Configure Radiometry for TLinear enabled, auto-resolution cci_set_radiometry_enable_state(CCI_RADIOMETRY_ENABLED); rsp = cci_get_radiometry_enable_state(); - printf("[LEP UTIL] Lepton Radiometry = %d\n", rsp); + printf("[LEP UTIL] Lepton Radiometry = %ld\n", rsp); if (rsp != CCI_RADIOMETRY_ENABLED) { // Make one more effort - delay(10); + vTaskDelay(pdMS_TO_TICKS(10)); printf("[LEP UTIL] Retry Set Lepton Radiometry\n"); cci_set_radiometry_enable_state(CCI_RADIOMETRY_ENABLED); rsp = cci_get_radiometry_enable_state(); - printf("[LEP UTIL] Lepton Radiometry = %d\n", rsp); + printf("[LEP UTIL] Lepton Radiometry = %ld\n", rsp); if (rsp != CCI_RADIOMETRY_ENABLED) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } } @@ -104,17 +104,17 @@ bool lepton_init() val = (lep_stP->agc_set_enabled) ? CCI_RADIOMETRY_TLINEAR_DISABLED : CCI_RADIOMETRY_TLINEAR_ENABLED; cci_set_radiometry_tlinear_enable_state((cci_radiometry_tlinear_enable_state_t)val); rsp = cci_get_radiometry_tlinear_enable_state(); - printf("[LEP UTIL] Lepton Radiometry TLinear = %d\n", rsp); + printf("[LEP UTIL] Lepton Radiometry TLinear = %ld\n", rsp); if (rsp != val) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } cci_set_radiometry_tlinear_auto_res(CCI_RADIOMETRY_AUTO_RES_ENABLED); rsp = cci_get_radiometry_tlinear_auto_res(); - printf("[LEP UTIL] Lepton Radiometry Auto Resolution = %d\n", rsp); + printf("[LEP UTIL] Lepton Radiometry Auto Resolution = %ld\n", rsp); if (rsp != CCI_RADIOMETRY_AUTO_RES_ENABLED) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } } @@ -122,9 +122,9 @@ bool lepton_init() // Enable AGC calcs for a smooth transition between modes cci_set_agc_calc_enable_state(CCI_AGC_ENABLED); rsp = cci_get_agc_calc_enable_state(); - printf("[LEP UTIL] Lepton AGC Calcs = %d\n", rsp); + printf("[LEP UTIL] Lepton AGC Calcs = %ld\n", rsp); if (rsp != CCI_AGC_ENABLED) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } @@ -132,18 +132,18 @@ bool lepton_init() val = (lep_stP->agc_set_enabled) ? CCI_AGC_ENABLED : CCI_AGC_DISABLED; cci_set_agc_enable_state((cci_agc_enable_state_t)val); rsp = cci_get_agc_enable_state(); - printf("[LEP UTIL] Lepton AGC = %d\n", rsp); + printf("[LEP UTIL] Lepton AGC = %ld\n", rsp); if (rsp != val) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } // Enable telemetry cci_set_telemetry_enable_state(CCI_TELEMETRY_ENABLED); rsp = cci_get_telemetry_enable_state(); - printf("[LEP UTIL] Lepton Telemetry = %d\n", rsp); + printf("[LEP UTIL] Lepton Telemetry = %ld\n", rsp); if (rsp != CCI_TELEMETRY_ENABLED) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } vospi_include_telem(true); @@ -161,9 +161,9 @@ bool lepton_init() } cci_set_gain_mode((cc_gain_mode_t)val); rsp = cci_get_gain_mode(); - printf("[LEP UTIL] Lepton Gain Mode = %d\n", rsp); + printf("[LEP UTIL] Lepton Gain Mode = %ld\n", rsp); if (rsp != val) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } @@ -176,9 +176,9 @@ bool lepton_init() // Finally enable VSYNC on Lepton GPIO3 cci_set_gpio_mode(LEP_OEM_GPIO_MODE_VSYNC); rsp = cci_get_gpio_mode(); - printf("[LEP UTIL] Lepton GPIO Mode = %d\n", rsp); + printf("[LEP UTIL] Lepton GPIO Mode = %ld\n", rsp); if (rsp != LEP_OEM_GPIO_MODE_VSYNC) { - printf("[LEP UTIL] Error: Lepton communication failed (%d)\n", rsp); + printf("[LEP UTIL] Error: Lepton communication failed (%ld)\n", rsp); return false; } diff --git a/main/main.c b/main/main.c index 32c67bb..d4e7a3d 100644 --- a/main/main.c +++ b/main/main.c @@ -21,21 +21,62 @@ #define HREF_GPIO_NUM 7 #define PCLK_GPIO_NUM 13 +#define WIFI_IF WIFI_IF_AP + +#define MAX_PAYLOAD_SIZE 1400 + #include "esp_event.h" #include "esp_system.h" #include "esp_event.h" +#include "esp_timer.h" #include "esp_wifi.h" #include "esp_log.h" - +#include "esp_mac.h" #include "nvs_flash.h" #include "string.h" +#include "lipton/cci.h" +#include "lipton/vospi.h" +#include "lipton/lepton_system.h" +#include "lipton/lepton_utilities.h" + +// Number of consecutive VoSPI resynchronization attempts before attempting to reset +#define LEP_SYNC_FAIL_FAULT_LIMIT 10 + +// Reset fail delay before attempting a re-init (seconds) +#define LEP_RESET_FAIL_RETRY_SECS 5 + +// +// Code start +// +int vsync_count = 0; +int sync_fail_count = 0; +int reset_fail_count = 0; +int64_t vsyncDetectedUsec; + +esp_err_t tx_with_retry(wifi_interface_t iface, const void *buffer, int len, bool en_sys_seq) +{ + for (int i = 0; i < 160; i++) + { + esp_err_t err = esp_wifi_80211_tx(iface, buffer, len, en_sys_seq); + if (err == ESP_OK) + return ESP_OK; + if (err != ESP_ERR_NO_MEM) + return err; + // No delay, retry immediately + } + return ESP_ERR_NO_MEM; +} + static camera_config_t camera_config = { .pin_pwdn = PWDN_GPIO_NUM, .pin_reset = RESET_GPIO_NUM, .pin_xclk = XCLK_GPIO_NUM, - .pin_sccb_sda = SIOD_GPIO_NUM, - .pin_sccb_scl = SIOC_GPIO_NUM, + // .pin_sccb_sda = SIOD_GPIO_NUM, + // .pin_sccb_scl = SIOC_GPIO_NUM, + .pin_sccb_sda = -1, + .pin_sccb_scl = -1, + .sccb_i2c_port = I2C_MASTER_NUM, .pin_d7 = Y9_GPIO_NUM, .pin_d6 = Y8_GPIO_NUM, @@ -54,8 +95,8 @@ static camera_config_t camera_config = { .ledc_channel = LEDC_CHANNEL_0, .pixel_format = PIXFORMAT_JPEG, // YUV422,GRAYSCALE,RGB565,JPEG - //.frame_size = FRAMESIZE_UXGA, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.+ - .frame_size = FRAMESIZE_128X128, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates. + .frame_size = FRAMESIZE_UXGA, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.+ + //.frame_size = FRAMESIZE_128X128, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates. .jpeg_quality = 12, // 0-63, for OV series camera sensors, lower number means higher quality .fb_count = 1, // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode. @@ -66,6 +107,89 @@ static camera_config_t camera_config = { esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq); +uint16_t calculate_checksum(uint8_t *data, size_t len) +{ + uint16_t checksum = 0; + for (size_t i = 0; i < len; i++) + { + checksum ^= data[i]; // Simple XOR-based checksum + } + return checksum; +} + +void send_data_frame(uint8_t type, uint8_t *data, size_t len) +{ + uint8_t mac_addr[6]; + if (esp_wifi_get_mac(WIFI_IF_AP, mac_addr) != ESP_OK) + { + ESP_LOGE(TAG, "Failed to get MAC address"); + return; + } + + uint8_t header[] = { + 0x08, 0x02, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00}; + memcpy(&header[10], mac_addr, 6); + memcpy(&header[16], mac_addr, 6); + + size_t max_chunk_size = MAX_PAYLOAD_SIZE - (11 + 2); + size_t total_chunks = (len + max_chunk_size - 1) / max_chunk_size; + + for (uint16_t seq = 0; seq < total_chunks; seq++) + { + size_t offset = seq * max_chunk_size; + size_t chunk_size = (len - offset > max_chunk_size) ? max_chunk_size : (len - offset); + + uint8_t *raw_frame = malloc(11 + chunk_size + 2); + uint8_t *full_packet = malloc(sizeof(header) + 11 + chunk_size + 2); + if (!raw_frame || !full_packet) + { + ESP_LOGE(TAG, "Memory allocation failed!"); + free(raw_frame); + free(full_packet); + return; + } + + raw_frame[0] = type; + raw_frame[1] = seq >> 8; + raw_frame[2] = seq & 0xFF; + raw_frame[3] = total_chunks >> 8; + raw_frame[4] = total_chunks & 0xFF; + raw_frame[5] = 'P'; + raw_frame[6] = 'l'; + raw_frame[7] = 'e'; + raw_frame[8] = 'c'; + raw_frame[9] = 'y'; + raw_frame[10] = 'C'; + + memcpy(raw_frame + 11, data + offset, chunk_size); + uint16_t checksum = calculate_checksum(raw_frame, 11 + chunk_size); + raw_frame[11 + chunk_size] = checksum >> 8; + raw_frame[12 + chunk_size] = checksum & 0xFF; + + memcpy(full_packet, header, sizeof(header)); + memcpy(full_packet + sizeof(header), raw_frame, 11 + chunk_size + 2); + + esp_err_t ret = tx_with_retry(WIFI_IF, full_packet, sizeof(header) + 11 + chunk_size + 2, true); + + if (ret == ESP_OK) + { + ESP_LOGI(TAG, "Sent chunk %d/%d, size: %d bytes", seq + 1, total_chunks, chunk_size); + } + else + { + ESP_LOGE(TAG, "Failed to send chunk %d, %s", seq, esp_err_to_name(ret)); + } + + free(raw_frame); + free(full_packet); + vTaskDelay(50 / portTICK_PERIOD_MS); + } +} + esp_err_t camera_init() { // initialize the camera @@ -100,13 +224,6 @@ esp_err_t camera_capture() return ESP_FAIL; } - if (fb->len < 2 || fb->buf[0] != 0xFF || fb->buf[1] != 0xD8) { - ESP_LOGE(TAG, "Invalid JPEG data (no SOI marker)"); - esp_camera_fb_return(fb); - return ESP_FAIL; - } - - const size_t headerSize = sizeof(PreData); const size_t totalSize = fb->len + headerSize; uint8_t *dataOut = malloc(totalSize); @@ -130,31 +247,7 @@ esp_err_t camera_capture() memcpy(dataOut + headerSize, fb->buf, fb->len); // Now chunk and send - const size_t chunkSize = 1400; - size_t bytesSent = 0; - while (bytesSent < totalSize) - { - size_t bytesToSend = (totalSize - bytesSent) > chunkSize ? chunkSize : (totalSize - bytesSent); - - int retries = 3; - esp_err_t err; - do - { - err = esp_wifi_80211_tx(WIFI_IF_AP, dataOut + bytesSent, bytesToSend, true); - if (err != ESP_OK) - ESP_LOGW(TAG, "Retrying chunk send..."); - } while (err != ESP_OK && --retries > 0); - - if (err != ESP_OK) - { - ESP_LOGE(TAG, "Failed to send chunk after retries"); - free(dataOut); - esp_camera_fb_return(fb); - return ESP_FAIL; - } - - bytesSent += bytesToSend; - } + send_data_frame(0x10, dataOut, totalSize); free(dataOut); esp_camera_fb_return(fb); @@ -164,13 +257,111 @@ esp_err_t camera_capture() void app_main(void) { + nvs_flash_init(); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + + wifi_config_t ap_config = { + .ap = { + .ssid = "ESP32-Test", + .channel = 10, + .authmode = WIFI_AUTH_OPEN, + .max_connection = 1, + .ssid_hidden = 1, + .beacon_interval = 60000}}; + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); + + esp_log_level_set("wifi", ESP_LOG_DEBUG); + + uint8_t mac_addr[6]; + esp_read_mac(mac_addr, ESP_MAC_WIFI_SOFTAP); + ESP_LOGI(TAG, "ESP32 MAC: %02X:%02X:%02X:%02X:%02X:%02X", + mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + camera_init(); vTaskDelay(pdMS_TO_TICKS(300)); // Let the camera wake up fully while (1) { + + gpio_config_t usb_phy_conf = { + .pin_bit_mask = (1ULL << 19) | (1ULL << 20), + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&usb_phy_conf); + + printf("[MAIN] Start task\n"); + + LEP_CONFIG.agc_set_enabled = true; + LEP_CONFIG.emissivity = 100; + LEP_CONFIG.gain_mode = LEP_GAIN_AUTO; + + // initialize spi, i2c and gpio for lepton + if (!lepton_io_init()) + { + printf("[MAIN] Error: I/O init failed"); + while (1) + { + vTaskDelay(pdMS_TO_TICKS(100)); + } + } + + // allocate lepton buffers + if (!lepton_buffer_init()) + { + printf("[MAIN] Error: Memory init failed"); + while (1) + { + vTaskDelay(pdMS_TO_TICKS(100)); + } + } + + // wait for lepton to initialize + vTaskDelay(pdMS_TO_TICKS(1000));; + + // Attempt to initialize the VoSPI interface + if (vospi_init() != ESP_OK) + { + printf("[MAIN] Error: Lepton VoSPI initialization failed\n"); + while (1) + { + vTaskDelay(pdMS_TO_TICKS(100)); + } + } + + // initialize lepton + if (!lepton_init()) + { + printf("[MAIN] Error: Lepton CCI initialization failed\n"); + while (1) + { + vTaskDelay(pdMS_TO_TICKS(100)); + } + } + + // disable data from lepton + gpio_set_level(LEP_CSN_PIN, 1); + + printf("LEPTON INIT DONE"); + + int64_t start = esp_timer_get_time(); camera_capture(); - vTaskDelay(pdMS_TO_TICKS(50)); // 20 FPS = 1000/50ms + int64_t end = esp_timer_get_time(); + + int64_t duration = end - start; + + printf("%lf FPS, %lf SPF\n", 1 / (duration / 1000000.0), duration / 1000000.0); } } \ No newline at end of file diff --git a/managed_components/espressif__esp32-camera/README.md b/managed_components/espressif__esp32-camera/README.md index 092f893..0ed33dd 100644 --- a/managed_components/espressif__esp32-camera/README.md +++ b/managed_components/espressif__esp32-camera/README.md @@ -149,7 +149,7 @@ esp_err_t camera_init(){ //power up the camera if PWDN pin is defined if(CAM_PIN_PWDN != -1){ pinMode(CAM_PIN_PWDN, OUTPUT); - digitalWrite(CAM_PIN_PWDN, LOW); + gpio_set_level(CAM_PIN_PWDN, LOW); } //initialize the camera diff --git a/managed_components/espressif__esp32-camera/driver/sccb-ng.c b/managed_components/espressif__esp32-camera/driver/sccb-ng.c index 9272c37..6048e5c 100644 --- a/managed_components/espressif__esp32-camera/driver/sccb-ng.c +++ b/managed_components/espressif__esp32-camera/driver/sccb-ng.c @@ -28,8 +28,8 @@ static const char *TAG = "sccb-ng"; #include "driver/i2c_types.h" // support IDF 5.x -#ifndef portTICK_RATE_MS -#define portTICK_RATE_MS portTICK_PERIOD_MS +#ifndef portTICK_PERIOD_MS +#define portTICK_PERIOD_MS portTICK_PERIOD_MS #endif #define TIMEOUT_MS 1000 /*!< I2C timeout duration */ diff --git a/managed_components/espressif__esp32-camera/driver/sccb.c b/managed_components/espressif__esp32-camera/driver/sccb.c index 7007883..41d51cd 100644 --- a/managed_components/espressif__esp32-camera/driver/sccb.c +++ b/managed_components/espressif__esp32-camera/driver/sccb.c @@ -27,8 +27,8 @@ static const char* TAG = "sccb"; #include "driver/i2c.h" // support IDF 5.x -#ifndef portTICK_RATE_MS -#define portTICK_RATE_MS portTICK_PERIOD_MS +#ifndef portTICK_PERIOD_MS +#define portTICK_PERIOD_MS portTICK_PERIOD_MS #endif #define SCCB_FREQ CONFIG_SCCB_CLK_FREQ /*!< I2C master frequency*/ @@ -106,7 +106,7 @@ uint8_t SCCB_Probe(void) i2c_master_start(cmd); i2c_master_write_byte(cmd, ( slave_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); i2c_master_stop(cmd); - esp_err_t ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + esp_err_t ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if( ret == ESP_OK) { return slave_addr; @@ -124,7 +124,7 @@ uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg) i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) return -1; cmd = i2c_cmd_link_create(); @@ -132,7 +132,7 @@ uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg) i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN); i2c_master_read_byte(cmd, &data, NACK_VAL); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) { ESP_LOGE(TAG, "SCCB_Read Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret); @@ -149,7 +149,7 @@ int SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data) i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); i2c_master_write_byte(cmd, data, ACK_CHECK_EN); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) { ESP_LOGE(TAG, "SCCB_Write Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret); @@ -169,7 +169,7 @@ uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg) i2c_master_write_byte(cmd, reg_u8[0], ACK_CHECK_EN); i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) return -1; cmd = i2c_cmd_link_create(); @@ -177,7 +177,7 @@ uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg) i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN); i2c_master_read_byte(cmd, &data, NACK_VAL); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) { ESP_LOGE(TAG, "W [%04x]=%02x fail\n", reg, data); @@ -198,7 +198,7 @@ int SCCB_Write16(uint8_t slv_addr, uint16_t reg, uint8_t data) i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN); i2c_master_write_byte(cmd, data, ACK_CHECK_EN); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) { ESP_LOGE(TAG, "W [%04x]=%02x %d fail\n", reg, data, i++); @@ -219,7 +219,7 @@ uint16_t SCCB_Read_Addr16_Val16(uint8_t slv_addr, uint16_t reg) i2c_master_write_byte(cmd, reg_u8[0], ACK_CHECK_EN); i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) return -1; @@ -229,7 +229,7 @@ uint16_t SCCB_Read_Addr16_Val16(uint8_t slv_addr, uint16_t reg) i2c_master_read_byte(cmd, &data_u8[1], ACK_VAL); i2c_master_read_byte(cmd, &data_u8[0], NACK_VAL); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) { ESP_LOGE(TAG, "W [%04x]=%04x fail\n", reg, data); @@ -252,7 +252,7 @@ int SCCB_Write_Addr16_Val16(uint8_t slv_addr, uint16_t reg, uint16_t data) i2c_master_write_byte(cmd, data_u8[0], ACK_CHECK_EN); i2c_master_write_byte(cmd, data_u8[1], ACK_CHECK_EN); i2c_master_stop(cmd); - ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS); + ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) { ESP_LOGE(TAG, "W [%04x]=%04x fail\n", reg, data); diff --git a/managed_components/espressif__esp32-camera/examples/camera_example/main/take_picture.c b/managed_components/espressif__esp32-camera/examples/camera_example/main/take_picture.c index 1514740..4cb4eab 100644 --- a/managed_components/espressif__esp32-camera/examples/camera_example/main/take_picture.c +++ b/managed_components/espressif__esp32-camera/examples/camera_example/main/take_picture.c @@ -40,8 +40,8 @@ #include "freertos/task.h" // support IDF 5.x -#ifndef portTICK_RATE_MS -#define portTICK_RATE_MS portTICK_PERIOD_MS +#ifndef portTICK_PERIOD_MS +#define portTICK_PERIOD_MS portTICK_PERIOD_MS #endif #include "esp_camera.h" @@ -178,7 +178,7 @@ void app_main(void) ESP_LOGI(TAG, "Picture taken! Its size was: %zu bytes", pic->len); esp_camera_fb_return(pic); - vTaskDelay(5000 / portTICK_RATE_MS); + vTaskDelay(5000 / portTICK_PERIOD_MS); } #else ESP_LOGE(TAG, "Camera support is not available for this chip"); diff --git a/managed_components/espressif__esp32-camera/test/test_camera.c b/managed_components/espressif__esp32-camera/test/test_camera.c index 41a89b0..ee67a70 100644 --- a/managed_components/espressif__esp32-camera/test/test_camera.c +++ b/managed_components/espressif__esp32-camera/test/test_camera.c @@ -238,7 +238,7 @@ static void camera_performance_test(uint32_t xclk_freq, uint32_t pic_num) camera_sensor_info_t *info = esp_camera_sensor_get_info(&s->id); TEST_ASSERT_NOT_NULL(info); TEST_ESP_OK(esp_camera_deinit()); - vTaskDelay(500 / portTICK_RATE_MS); + vTaskDelay(500 / portTICK_PERIOD_MS); framesize_t max_size = info->max_size; pixformat_t all_format[] = {PIXFORMAT_JPEG, PIXFORMAT_RGB565, PIXFORMAT_YUV422, }; pixformat_t *format_s = &all_format[0]; @@ -257,10 +257,10 @@ static void camera_performance_test(uint32_t xclk_freq, uint32_t pic_num) for (size_t i = 0; i <= max_size; i++) { ESP_LOGI(TAG, "\n\n===> Testing format:%s resolution: %d x %d <===", get_cam_format_name(*format_s), resolution[i].width, resolution[i].height); ret = init_camera(xclk_freq, *format_s, i, 2, SIOD_GPIO_NUM, -1); - vTaskDelay(100 / portTICK_RATE_MS); + vTaskDelay(100 / portTICK_PERIOD_MS); if (ESP_OK != ret) { ESP_LOGW(TAG, "Testing init failed :-(, skip this item"); - vTaskDelay(500 / portTICK_RATE_MS); + vTaskDelay(500 / portTICK_PERIOD_MS); continue; } camera_test_fps(pic_num, &results[format_s - all_format].fps[i], &results[format_s - all_format].size[i]); @@ -293,7 +293,7 @@ TEST_CASE("Camera driver init, deinit test", "[camera]") TEST_CASE("Camera driver take RGB565 picture test", "[camera]") { TEST_ESP_OK(init_camera(10000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1)); - vTaskDelay(500 / portTICK_RATE_MS); + vTaskDelay(500 / portTICK_PERIOD_MS); ESP_LOGI(TAG, "Taking picture..."); camera_fb_t *pic = esp_camera_fb_get(); if (pic) { @@ -309,7 +309,7 @@ TEST_CASE("Camera driver take RGB565 picture test", "[camera]") TEST_CASE("Camera driver take YUV422 picture test", "[camera]") { TEST_ESP_OK(init_camera(10000000, PIXFORMAT_YUV422, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1)); - vTaskDelay(500 / portTICK_RATE_MS); + vTaskDelay(500 / portTICK_PERIOD_MS); ESP_LOGI(TAG, "Taking picture..."); camera_fb_t *pic = esp_camera_fb_get(); if (pic) { @@ -325,7 +325,7 @@ TEST_CASE("Camera driver take YUV422 picture test", "[camera]") TEST_CASE("Camera driver take JPEG picture test", "[camera]") { TEST_ESP_OK(init_camera(20000000, PIXFORMAT_JPEG, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1)); - vTaskDelay(500 / portTICK_RATE_MS); + vTaskDelay(500 / portTICK_PERIOD_MS); ESP_LOGI(TAG, "Taking picture..."); camera_fb_t *pic = esp_camera_fb_get(); if (pic) { @@ -529,7 +529,7 @@ TEST_CASE("Camera driver uses an i2c port initialized by other devices test", "[ { TEST_ESP_OK(i2c_master_init(I2C_MASTER_NUM)); TEST_ESP_OK(init_camera(20000000, PIXFORMAT_JPEG, FRAMESIZE_QVGA, 2, -1, I2C_MASTER_NUM)); - vTaskDelay(500 / portTICK_RATE_MS); + vTaskDelay(500 / portTICK_PERIOD_MS); TEST_ESP_OK(esp_camera_deinit()); TEST_ESP_OK(i2c_driver_delete(I2C_MASTER_NUM)); }