first commit

This commit is contained in:
David R.
2025-09-05 18:58:05 +02:00
parent fc13e0779b
commit ed05c83ac6
3678 changed files with 832193 additions and 0 deletions
@@ -0,0 +1,2 @@
idf_component_register(SRCS "app_camera.c" "test.c" "app_enthernet.c"
INCLUDE_DIRS "." "include")
@@ -0,0 +1,176 @@
menu "Example EthToAP Configuration"
config EXAMPLE_WIFI_SSID
string "Wi-Fi SSID"
default "eth2ap"
help
Set the SSID of Wi-Fi ap interface.
config EXAMPLE_WIFI_PASSWORD
string "Wi-Fi Password"
default "12345678"
help
Set the password of Wi-Fi ap interface.
config EXAMPLE_WIFI_CHANNEL
int "WiFi channel"
range 1 13
default 1
help
Set the channel of Wi-Fi ap.
config EXAMPLE_MAX_STA_CONN
int "Maximum STA connections"
default 4
help
Maximum number of the station that allowed to connect to current Wi-Fi hotspot.
endmenu
menu "Example CAM Configuration"
config EXAMPLE_ENABLE_MIPI_CSI_CAM_SENSOR
bool "Enable MIPI CSI Camera Sensor"
default y
depends on ESP_VIDEO_ENABLE_MIPI_CSI_VIDEO_DEVICE
if EXAMPLE_ENABLE_MIPI_CSI_CAM_SENSOR
config EXAMPLE_MIPI_CSI_SCCB_I2C_PORT
int "MIPI CSI SCCB I2C Port Number"
default 0
range 0 1
config EXAMPLE_MIPI_CSI_SCCB_I2C_SCL_PIN
int "MIPI CSI SCCB I2C SCL Pin"
default 8
range -1 56
config EXAMPLE_MIPI_CSI_SCCB_I2C_SDA_PIN
int "MIPI CSI SCCB I2C SDA Pin"
default 7
range -1 56
config EXAMPLE_MIPI_CSI_SCCB_I2C_FREQ
int "MIPI CSI SCCB I2C Frequency"
default 100000
range 100000 400000
help
Increasing this value can reduce the initialization time of the camera sensor.
Please refer to the relevant instructions of the camera sensor to adjust the value.
config EXAMPLE_MIPI_CSI_CAM_SENSOR_RESET_PIN
int "MIPI CSI Camera Sensor Reset Pin"
default -1
range -1 56
config EXAMPLE_MIPI_CSI_CAM_SENSOR_PWDN_PIN
int "MIPI CSI Camera Sensor Power Down Pin"
default -1
range -1 56
endif
config EXAMPLE_ENABLE_DVP_CAM_SENSOR
bool "Enable DVP Camera Sensor"
default n
depends on ESP_VIDEO_ENABLE_DVP_VIDEO_DEVICE
if EXAMPLE_ENABLE_DVP_CAM_SENSOR
config EXAMPLE_DVP_SCCB_I2C_PORT
int "DVP SCCB I2C Port Number"
default 1
range 0 1
config EXAMPLE_DVP_SCCB_I2C_SCL_PIN
int "DVP SCCB I2C SCL Pin"
default 33
range -1 56
config EXAMPLE_DVP_SCCB_I2C_SDA_PIN
int "DVP SCCB I2C SDA Pin"
default 32
range -1 56
config EXAMPLE_DVP_SCCB_I2C_FREQ
int "DVP SCCB I2C Frequency"
default 100000
range 100000 400000
help
Increasing this value can reduce the initialization time of the camera sensor.
Please refer to the relevant instructions of the camera sensor to adjust the value.
config EXAMPLE_DVP_CAM_SENSOR_RESET_PIN
int "DVP Camera Sensor Reset Pin"
default -1
range -1 56
config EXAMPLE_DVP_CAM_SENSOR_PWDN_PIN
int "DVP Camera Sensor Power Down Pin"
default -1
range -1 56
config EXAMPLE_DVP_XCLK_FREQ
int "DVP XCLK Frequency"
default 20000000
config EXAMPLE_DVP_XCLK_PIN
int "DVP XCLK Pin"
range 0 56
default 20
config EXAMPLE_DVP_PCLK_PIN
int "DVP PCLK Pin"
range 0 56
default 21
config EXAMPLE_DVP_VSYNC_PIN
int "DVP VSYNC Pin"
range 0 56
default 23
config EXAMPLE_DVP_DE_PIN
int "DVP DE Pin"
range 0 56
default 22
config EXAMPLE_DVP_D0_PIN
int "DVP D0 Pin"
range 0 56
default 53
config EXAMPLE_DVP_D1_PIN
int "DVP D1 Pin"
range 0 56
default 54
config EXAMPLE_DVP_D2_PIN
int "DVP D2 Pin"
range 0 56
default 52
config EXAMPLE_DVP_D3_PIN
int "DVP D3 Pin"
range 0 56
default 1
config EXAMPLE_DVP_D4_PIN
int "DVP D4 Pin"
range 0 56
default 0
config EXAMPLE_DVP_D5_PIN
int "DVP D5 Pin"
range 0 56
default 45
config EXAMPLE_DVP_D6_PIN
int "DVP D6 Pin"
range 0 56
default 46
config EXAMPLE_DVP_D7_PIN
int "DVP D7 Pin"
range 0 56
default 47
endif
endmenu
@@ -0,0 +1,284 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: ESPRESSIF MIT
*/
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/errno.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "driver/i2c_master.h"
#include "linux/videodev2.h"
#include "esp_video_init.h"
#include "esp_video_ioctl.h"
#include "app_camera.h"
#define MEMORY_TYPE V4L2_MEMORY_MMAP
#define BUFFER_COUNT 2
#define CAPTURE_SECONDS 3
static i2c_master_bus_handle_t i2c_handle = NULL;
static const char *TAG = "example";
#if CONFIG_EXAMPLE_ENABLE_MIPI_CSI_CAM_SENSOR
static esp_video_init_csi_config_t csi_config[] = {
{
.sccb_config = {
.init_sccb = true,
.i2c_config = {
.port = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_PORT,
.scl_pin = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_SCL_PIN,
.sda_pin = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_SDA_PIN,
},
.freq = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_FREQ,
},
.reset_pin = CONFIG_EXAMPLE_MIPI_CSI_CAM_SENSOR_RESET_PIN,
.pwdn_pin = CONFIG_EXAMPLE_MIPI_CSI_CAM_SENSOR_PWDN_PIN,
},
};
#endif
#if CONFIG_EXAMPLE_ENABLE_DVP_CAM_SENSOR
static const esp_video_init_dvp_config_t dvp_config[] = {
{
.sccb_config = {
.init_sccb = true,
.i2c_config = {
.port = CONFIG_EXAMPLE_DVP_SCCB_I2C_PORT,
.scl_pin = CONFIG_EXAMPLE_DVP_SCCB_I2C_SCL_PIN,
.sda_pin = CONFIG_EXAMPLE_DVP_SCCB_I2C_SDA_PIN,
},
.freq = CONFIG_EXAMPLE_DVP_SCCB_I2C_FREQ,
},
.reset_pin = CONFIG_EXAMPLE_DVP_CAM_SENSOR_RESET_PIN,
.pwdn_pin = CONFIG_EXAMPLE_DVP_CAM_SENSOR_PWDN_PIN,
.dvp_pin = {
.data_width = CAM_CTLR_DATA_WIDTH_8,
.data_io = {
CONFIG_EXAMPLE_DVP_D0_PIN, CONFIG_EXAMPLE_DVP_D1_PIN, CONFIG_EXAMPLE_DVP_D2_PIN, CONFIG_EXAMPLE_DVP_D3_PIN,
CONFIG_EXAMPLE_DVP_D4_PIN, CONFIG_EXAMPLE_DVP_D5_PIN, CONFIG_EXAMPLE_DVP_D6_PIN, CONFIG_EXAMPLE_DVP_D7_PIN,
},
.vsync_io = CONFIG_EXAMPLE_DVP_VSYNC_PIN,
.de_io = CONFIG_EXAMPLE_DVP_DE_PIN,
.pclk_io = CONFIG_EXAMPLE_DVP_PCLK_PIN,
.xclk_io = CONFIG_EXAMPLE_DVP_XCLK_PIN,
},
.xclk_freq = CONFIG_EXAMPLE_DVP_XCLK_FREQ,
},
};
#endif
static esp_err_t camera_capture_stream(void)
{
int fd;
esp_err_t ret;
int fmt_index = 0;
uint32_t frame_size;
uint32_t frame_count;
struct v4l2_buffer buf;
uint8_t *buffer[BUFFER_COUNT];
struct v4l2_format init_format;
struct v4l2_requestbuffers req;
struct v4l2_capability capability;
const int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fd = open("/dev/video0", O_RDONLY);
if (fd < 0) {
ESP_LOGE(TAG, "failed to open device");
return ESP_FAIL;
}
if (ioctl(fd, VIDIOC_QUERYCAP, &capability)) {
ESP_LOGE(TAG, "failed to get capability");
ret = ESP_FAIL;
goto exit_0;
}
ESP_LOGI(TAG, "version: %d.%d.%d", (uint16_t)(capability.version >> 16),
(uint8_t)(capability.version >> 8),
(uint8_t)capability.version);
ESP_LOGI(TAG, "driver: %s", capability.driver);
ESP_LOGI(TAG, "card: %s", capability.card);
ESP_LOGI(TAG, "bus: %s", capability.bus_info);
ESP_LOGI(TAG, "capabilities:");
if (capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
ESP_LOGI(TAG, "\tVIDEO_CAPTURE");
}
if (capability.capabilities & V4L2_CAP_READWRITE) {
ESP_LOGI(TAG, "\tREADWRITE");
}
if (capability.capabilities & V4L2_CAP_ASYNCIO) {
ESP_LOGI(TAG, "\tASYNCIO");
}
if (capability.capabilities & V4L2_CAP_STREAMING) {
ESP_LOGI(TAG, "\tSTREAMING");
}
if (capability.capabilities & V4L2_CAP_META_OUTPUT) {
ESP_LOGI(TAG, "\tMETA_OUTPUT");
}
if (capability.capabilities & V4L2_CAP_DEVICE_CAPS) {
ESP_LOGI(TAG, "device capabilities:");
if (capability.device_caps & V4L2_CAP_VIDEO_CAPTURE) {
ESP_LOGI(TAG, "\tVIDEO_CAPTURE");
}
if (capability.device_caps & V4L2_CAP_READWRITE) {
ESP_LOGI(TAG, "\tREADWRITE");
}
if (capability.device_caps & V4L2_CAP_ASYNCIO) {
ESP_LOGI(TAG, "\tASYNCIO");
}
if (capability.device_caps & V4L2_CAP_STREAMING) {
ESP_LOGI(TAG, "\tSTREAMING");
}
if (capability.device_caps & V4L2_CAP_META_OUTPUT) {
ESP_LOGI(TAG, "\tMETA_OUTPUT");
}
}
/* Set custom register configuration */
if (ioctl(fd, VIDIOC_S_SENSOR_FMT, &custom_format_info) != 0) {
ret = ESP_FAIL;
goto exit_0;
}
memset(&init_format, 0, sizeof(struct v4l2_format));
init_format.type = type;
if (ioctl(fd, VIDIOC_G_FMT, &init_format) != 0) {
ESP_LOGE(TAG, "failed to get format");
ret = ESP_FAIL;
goto exit_0;
}
struct v4l2_fmtdesc fmtdesc = {
.index = fmt_index++,
.type = type,
};
ESP_LOGI(TAG, "Capture %s format frames for %d seconds:", (char *)fmtdesc.description, CAPTURE_SECONDS);
memset(&req, 0, sizeof(req));
req.count = BUFFER_COUNT;
req.type = type;
req.memory = MEMORY_TYPE;
if (ioctl(fd, VIDIOC_REQBUFS, &req) != 0) {
ESP_LOGE(TAG, "failed to require buffer");
ret = ESP_FAIL;
goto exit_0;
}
for (int i = 0; i < BUFFER_COUNT; i++) {
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = type;
buf.memory = MEMORY_TYPE;
buf.index = i;
if (ioctl(fd, VIDIOC_QUERYBUF, &buf) != 0) {
ESP_LOGE(TAG, "failed to query buffer");
ret = ESP_FAIL;
goto exit_0;
}
buffer[i] = (uint8_t *)mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, buf.m.offset);
if (!buffer[i]) {
ESP_LOGE(TAG, "failed to map buffer");
ret = ESP_FAIL;
goto exit_0;
}
if (ioctl(fd, VIDIOC_QBUF, &buf) != 0) {
ESP_LOGE(TAG, "failed to queue video frame");
ret = ESP_FAIL;
goto exit_0;
}
}
if (ioctl(fd, VIDIOC_STREAMON, &type) != 0) {
ESP_LOGE(TAG, "failed to start stream");
ret = ESP_FAIL;
goto exit_0;
}
frame_count = 0;
frame_size = 0;
int64_t start_time_us = esp_timer_get_time();
while (esp_timer_get_time() - start_time_us < (CAPTURE_SECONDS * 1000 * 1000)) {
memset(&buf, 0, sizeof(buf));
buf.type = type;
buf.memory = MEMORY_TYPE;
if (ioctl(fd, VIDIOC_DQBUF, &buf) != 0) {
ESP_LOGE(TAG, "failed to receive video frame");
ret = ESP_FAIL;
goto exit_0;
}
frame_size += buf.bytesused;
if (ioctl(fd, VIDIOC_QBUF, &buf) != 0) {
ESP_LOGE(TAG, "failed to queue video frame");
ret = ESP_FAIL;
goto exit_0;
}
frame_count++;
}
if (ioctl(fd, VIDIOC_STREAMOFF, &type) != 0) {
ESP_LOGE(TAG, "failed to stop stream");
ret = ESP_FAIL;
goto exit_0;
}
ESP_LOGI(TAG, "\twidth: %" PRIu32, init_format.fmt.pix.width);
ESP_LOGI(TAG, "\theight: %" PRIu32, init_format.fmt.pix.height);
ESP_LOGI(TAG, "\tsize: %" PRIu32, frame_size / frame_count);
ESP_LOGI(TAG, "\tFPS: %" PRIu32, frame_count / CAPTURE_SECONDS);
// bsp_display_lock(0);
// lv_label_ins_text(label,LV_LABEL_POS_LAST,"Camera initial #00ff00 Success#\n");
// bsp_display_unlock();
ret = ESP_OK;
exit_0:
close(fd);
return ret;
}
void app_camera(void)
{
esp_err_t ret = ESP_OK;
i2c_master_get_bus_handle(1, &i2c_handle);
csi_config[0].sccb_config.init_sccb = false;
csi_config[0].sccb_config.i2c_handle = i2c_handle;
static const esp_video_init_config_t cam_config = {
.csi = csi_config,
};
ret = esp_video_init(&cam_config);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Camera init failed with error 0x%x", ret);
// bsp_display_lock(0);
// lv_label_ins_text(label,LV_LABEL_POS_LAST,"Camera initial #ff0000 Failed#\n");
// bsp_display_unlock();
return;
}
ret = camera_capture_stream();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Camera capture stream failed with error 0x%x", ret);
return;
}
}
@@ -0,0 +1,307 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* eth2ap (Ethernet to Wi-Fi AP packet forwarding) Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_eth_driver.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "esp_private/wifi.h"
#include "ethernet_init.h"
#include "app_enthernet.h"
static void wifi_scan_init(void);
static const char *TAG = "eth2ap_example";
static esp_eth_handle_t s_eth_handle = NULL;
static QueueHandle_t flow_control_queue = NULL;
static EventGroupHandle_t Btn_event_group = NULL;
static bool s_sta_is_connected = false;
static bool s_ethernet_is_connected = false;
static uint8_t s_eth_mac[6];
static bool enthernet_connect = false;
static bool wifi_connect = false;
#define FLOW_CONTROL_QUEUE_TIMEOUT_MS (100)
#define FLOW_CONTROL_QUEUE_LENGTH (40)
#define FLOW_CONTROL_WIFI_SEND_TIMEOUT_MS (100)
typedef struct {
void *packet;
uint16_t length;
} flow_control_msg_t;
typedef enum{
ETHERNET_CONNECTED = BIT(0),
ETHERNET_START = BIT(1),
}event_id_t;
// Forward packets from Wi-Fi to Ethernet
static esp_err_t pkt_wifi2eth(void *buffer, uint16_t len, void *eb)
{
if (s_ethernet_is_connected) {
if (esp_eth_transmit(s_eth_handle, buffer, len) != ESP_OK) {
ESP_LOGE(TAG, "Ethernet send packet failed");
}
}
esp_wifi_internal_free_rx_buffer(eb);
return ESP_OK;
}
// Forward packets from Ethernet to Wi-Fi
// Note that, Ethernet works faster than Wi-Fi on ESP32,
// so we need to add an extra queue to balance their speed difference.
static esp_err_t pkt_eth2wifi(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t len, void *priv)
{
esp_err_t ret = ESP_OK;
flow_control_msg_t msg = {
.packet = buffer,
.length = len
};
if (xQueueSend(flow_control_queue, &msg, pdMS_TO_TICKS(FLOW_CONTROL_QUEUE_TIMEOUT_MS)) != pdTRUE) {
ESP_LOGE(TAG, "send flow control message failed or timeout");
free(buffer);
ret = ESP_FAIL;
}
return ret;
}
// This task will fetch the packet from the queue, and then send out through Wi-Fi.
// Wi-Fi handles packets slower than Ethernet, we might add some delay between each transmitting.
static void eth2wifi_flow_control_task(void *args)
{
flow_control_msg_t msg;
int res = 0;
uint32_t timeout = 0;
while (1) {
if (xQueueReceive(flow_control_queue, &msg, pdMS_TO_TICKS(FLOW_CONTROL_QUEUE_TIMEOUT_MS)) == pdTRUE) {
timeout = 0;
if (s_sta_is_connected && msg.length) {
do {
vTaskDelay(pdMS_TO_TICKS(timeout));
timeout += 2;
res = esp_wifi_internal_tx(WIFI_IF_AP, msg.packet, msg.length);
} while (res && timeout < FLOW_CONTROL_WIFI_SEND_TIMEOUT_MS);
if (res != ESP_OK) {
ESP_LOGE(TAG, "WiFi send packet failed: %d", res);
}
}
free(msg.packet);
}
}
vTaskDelete(NULL);
}
// Event handler for Ethernet
static void eth_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
ESP_LOGI(TAG, "Ethernet Link Up");
s_ethernet_is_connected = true;
xEventGroupSetBits(Btn_event_group,ETHERNET_CONNECTED);
// esp_eth_ioctl(s_eth_handle, ETH_CMD_G_MAC_ADDR, s_eth_mac);
// esp_wifi_set_mac(WIFI_IF_AP, s_eth_mac);
// ESP_ERROR_CHECK(esp_wifi_start());
bsp_display_lock(0);
lv_label_ins_text(label,LV_LABEL_POS_LAST,"Enthernet initial success\n");
// lv_label_ins_text(label,LV_LABEL_POS_LAST,"WIFI initial success\n");
bsp_display_unlock();
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
s_ethernet_is_connected = false;
// ESP_ERROR_CHECK(esp_wifi_stop());
break;
case ETHERNET_EVENT_START:
ESP_LOGI(TAG, "Ethernet Started");
break;
case ETHERNET_EVENT_STOP:
ESP_LOGI(TAG, "Ethernet Stopped");
break;
default:
break;
}
}
// Event handler for Wi-Fi
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
static uint8_t s_con_cnt = 0;
switch (event_id) {
case WIFI_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "Wi-Fi AP got a station connected");
if (!s_con_cnt) {
s_sta_is_connected = true;
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, pkt_wifi2eth);
}
s_con_cnt++;
break;
case WIFI_EVENT_AP_STADISCONNECTED:
ESP_LOGI(TAG, "Wi-Fi AP got a station disconnected");
s_con_cnt--;
if (!s_con_cnt) {
s_sta_is_connected = false;
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
}
break;
default:
break;
}
}
static void initialize_ethernet(void)
{
uint8_t eth_port_cnt = 0;
esp_eth_handle_t *eth_handles;
ESP_ERROR_CHECK(example_eth_init(&eth_handles, &eth_port_cnt));
if (eth_port_cnt > 1) {
ESP_LOGW(TAG, "multiple Ethernet devices detected, the first initialized is to be used!");
}
s_eth_handle = eth_handles[0];
free(eth_handles);
ESP_ERROR_CHECK(esp_eth_update_input_path(s_eth_handle, pkt_eth2wifi, NULL));
bool eth_promiscuous = true;
ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_PROMISCUOUS, &eth_promiscuous));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler, NULL));
ESP_ERROR_CHECK(esp_eth_start(s_eth_handle));
EventBits_t uxBits;
uxBits = xEventGroupWaitBits(Btn_event_group,ETHERNET_CONNECTED,pdFALSE,pdFALSE,pdMS_TO_TICKS(5000));
if(!uxBits)
{
bsp_display_lock(0);
lv_label_ins_text(label,LV_LABEL_POS_LAST,"Enthernet initial #ff0000 Failed#\n");
// lv_label_ins_text(label,LV_LABEL_POS_LAST,"WIFI initial success\n");
bsp_display_unlock();
}
// vTaskDelay(pdMS_TO_TICKS(CONFIG_EXAMPLE_ETH_DEINIT_AFTER_S * 1000));
// ESP_LOGI(TAG, "stop and deinitialize Ethernet network...");
// // Stop Ethernet driver state machine and destroy netif
// for (int i = 0; i < eth_port_cnt; i++) {
// ESP_ERROR_CHECK(esp_eth_stop(eth_handles[i]));
// ESP_ERROR_CHECK(esp_eth_del_netif_glue(eth_netif_glues[i]));
// esp_netif_destroy(eth_netifs[i]);
// }
// esp_netif_deinit();
// ESP_ERROR_CHECK(example_eth_deinit(eth_handles, eth_port_cnt));
// ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
}
static void initialize_wifi(void)
{
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL));
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));
wifi_config_t wifi_config = {
.ap = {
.ssid = CONFIG_EXAMPLE_WIFI_SSID,
.ssid_len = strlen(CONFIG_EXAMPLE_WIFI_SSID),
.password = CONFIG_EXAMPLE_WIFI_PASSWORD,
.max_connection = CONFIG_EXAMPLE_MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA_WPA2_PSK,
.channel = CONFIG_EXAMPLE_WIFI_CHANNEL // default: channel 1
},
};
if (strlen(CONFIG_EXAMPLE_WIFI_PASSWORD) == 0) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
esp_wifi_get_mac(WIFI_IF_AP,s_eth_mac);
esp_wifi_set_mac(WIFI_IF_AP, s_eth_mac);
ESP_ERROR_CHECK(esp_wifi_start());
wifi_scan_init();
}
static void wifi_scan_init(void)
{
uint16_t ap_number;
uint16_t ap_num=25;
esp_err_t ret;
ret = esp_wifi_scan_start(NULL,true);
ESP_LOGI(TAG,"wifi scan = 0x%x",ret);
esp_wifi_scan_get_ap_num(&ap_number);
ESP_LOGI(TAG,"ap_number = %d",ap_number);
// ap_num = 10;
wifi_ap_record_t ap_info;
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_record(&ap_info));
// vTaskDelay(pdMS_TO_TICKS(1000));
ESP_LOGI(TAG,"ret_wiff= 0x%x",ret);
if(ret == ESP_OK)
{
ESP_LOGI(TAG,"ssid = %s,riss = %d db",ap_info.ssid,ap_info.rssi);
vTaskDelay(pdMS_TO_TICKS(1));
bsp_display_lock(0);
// lv_label_ins_text(label,LV_LABEL_POS_LAST,"Enthernet initial success\n");
lv_label_ins_text(label,LV_LABEL_POS_LAST,"WIFI initial #00ff00 Success#\n");
bsp_display_unlock();
}
else
{
bsp_display_lock(0);
// lv_label_ins_text(label,LV_LABEL_POS_LAST,"Enthernet initial success\n");
lv_label_ins_text(label,LV_LABEL_POS_LAST,"WIFI initial #ff0000 Failed#\n");
bsp_display_unlock();
}
}
static esp_err_t initialize_flow_control(void)
{
flow_control_queue = xQueueCreate(FLOW_CONTROL_QUEUE_LENGTH, sizeof(flow_control_msg_t));
if (!flow_control_queue) {
ESP_LOGE(TAG, "create flow control queue failed");
return ESP_FAIL;
}
BaseType_t ret = xTaskCreate(eth2wifi_flow_control_task, "flow_ctl", 2048, NULL, (tskIDLE_PRIORITY + 2), NULL);
if (ret != pdTRUE) {
ESP_LOGE(TAG, "create flow control task failed");
return ESP_FAIL;
}
return ESP_OK;
}
void test_enthernet_init(void)
{
Btn_event_group = xEventGroupCreate();
xEventGroupClearBits(Btn_event_group,ETHERNET_CONNECTED);
xEventGroupClearBits(Btn_event_group,ETHERNET_START);
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(initialize_flow_control());
initialize_wifi();
initialize_ethernet();
}
@@ -0,0 +1,26 @@
## IDF Component Manager Manifest File
dependencies:
## Required IDF version
idf:
version: '>=4.1.0'
# # Put list of dependencies here
# # For components maintained by Espressif:
# component: "~1.0.0"
# # For 3rd party components:
# username/component: ">=1.0.0,<2.0.0"
# username2/component2:
# version: "~1.0.0"
# # For transient dependencies `public` flag can be set.
# # `public` flag doesn't have an effect dependencies of the `main` component.
# # All dependencies of `main` are public by default.
# public: true
espressif/esp_video: ^0.9.1
esp_lcd_touch_gsl3680:
path: ../components/esp_lcd_touch_gsl3680
lvgl/lvgl: ^8.4.0
espressif/esp_hosted: '*'
espressif/esp_wifi_remote: '*'
espressif/esp_ipa: ^0.3.0
@@ -0,0 +1,165 @@
#ifndef __APP_CAMERA_H
#define __APP_CAMERA_H
#include <stdint.h>
#include "esp_cam_sensor_types.h"
#include "ov5647_types.h"
#include "bsp/esp-bsp.h"
#include "lvgl.h"
extern lv_obj_t *label;
void app_camera(void);
#define OV5647_IDI_CLOCK_RATE_800x800_50FPS (100000000ULL)
#define OV5647_8BIT_MODE (0x18)
#define OV5647_REG_END 0xffff
static const ov5647_reginfo_t ov5647_raw8_800x800_50fps[] = {
{0x3034, OV5647_8BIT_MODE}, // set RAW format
{0x3035, 0x41}, // system clk div
{0x3036, ((OV5647_IDI_CLOCK_RATE_800x800_50FPS * 8 * 4) / 25000000)},
{0x303c, 0x11},
{0x3106, 0xf5},
{0x3821, 0x03},
{0x3820, 0x41},
{0x3827, 0xec},
{0x370c, 0x0f},
{0x3612, 0x59},
{0x3618, 0x00},
{0x5000, 0xff},
{0x583e, 0xf0}, // LSC max gain
{0x583f, 0x20}, // LSC min gain
{0x5002, 0x41},
{0x5003, 0x08},
{0x5a00, 0x08},
{0x3000, 0x00},
{0x3001, 0x00},
{0x3002, 0x00},
{0x3016, 0x08},
{0x3017, 0xe0},
{0x3018, 0x44},
{0x301c, 0xf8},
{0x301d, 0xf0},
{0x3a18, 0x00},
{0x3a19, 0xf8},
{0x3c01, 0x80},
{0x3c00, 0x40},
{0x3b07, 0x0c},
//HTS line exposure time in # of pixels
{0x380c, (1896 >> 8) & 0x1F},
{0x380d, 1896 & 0xFF},
//VTS frame exposure time in # lines
{0x380e, (984 >> 8) & 0xFF},
{0x380f, 984 & 0xFF},
{0x3814, 0x31},
{0x3815, 0x31},
{0x3708, 0x64},
{0x3709, 0x52},
//[3:0]=0 X address start high byte
{0x3800, (500 >> 8) & 0x0F},
//[7:0]=0 X address start low byte
{0x3801, 500 & 0xFF},
//[2:0]=0 Y address start high byte
{0x3802, (0 >> 8) & 0x07},
//[7:0]=0 Y address start low byte
{0x3803, 0 & 0xFF},
//[3:0] X address end high byte
{0x3804, ((2624 - 1) >> 8) & 0x0F},
//[7:0] X address end low byte
{0x3805, (2624 - 1) & 0xFF},
//[2:0] Y address end high byte
{0x3806, ((1954 - 1) >> 8) & 0x07},
//[7:0] Y address end low byte
{0x3807, (1954 - 1) & 0xFF},
//[3:0] Output horizontal width high byte
{0x3808, (800 >> 8) & 0x0F},
//[7:0] Output horizontal width low byte
{0x3809, 800 & 0xFF},
//[2:0] Output vertical height high byte
{0x380a, (800 >> 8) & 0x7F},
//[7:0] Output vertical height low byte
{0x380b, 800 & 0xFF},
//[3:0]=0 timing hoffset high byte
{0x3810, (8 >> 8) & 0x0F},
//[7:0]=0 timing hoffset low byte
{0x3811, 8 & 0xFF},
//[2:0]=0 timing voffset high byte
{0x3812, (0 >> 8) & 0x07},
//[7:0]=0 timing voffset low byte
{0x3813, 0 & 0xFF},
{0x3630, 0x2e},
{0x3632, 0xe2},
{0x3633, 0x23},
{0x3634, 0x44},
{0x3636, 0x06},
{0x3620, 0x64},
{0x3621, 0xe0},
{0x3600, 0x37},
{0x3704, 0xa0},
{0x3703, 0x5a},
{0x3715, 0x78},
{0x3717, 0x01},
{0x3731, 0x02},
{0x370b, 0x60},
{0x3705, 0x1a},
{0x3f05, 0x02},
{0x3f06, 0x10},
{0x3f01, 0x0a},
{0x3a08, 0x01},
{0x3a09, 0x27},
{0x3a0a, 0x00},
{0x3a0b, 0xf6},
{0x3a0d, 0x04},
{0x3a0e, 0x03},
{0x3a0f, 0x58},
{0x3a10, 0x50},
{0x3a1b, 0x58},
{0x3a1e, 0x50},
{0x3a11, 0x60},
{0x3a1f, 0x28},
{0x4001, 0x02},
{0x4004, 0x02},
{0x4000, 0x09},
{0x4837, (1000000000 / OV5647_IDI_CLOCK_RATE_800x800_50FPS) * 2},
{0x4050, 0x6e},
{0x4051, 0x8f},
{OV5647_REG_END, 0x00},
};
static const esp_cam_sensor_isp_info_t custom_isp_info = {
.isp_v1_info = {
.version = SENSOR_ISP_INFO_VERSION_DEFAULT,
.pclk = 81666700,
.vts = 1896,
.hts = 984,
.bayer_type = ESP_CAM_SENSOR_BAYER_GBRG,
}
};
static const esp_cam_sensor_format_t custom_format_info = {
.name = "MIPI_2lane_24Minput_RAW8_800x800_50fps",
.format = ESP_CAM_SENSOR_PIXFORMAT_RAW8,
.port = ESP_CAM_SENSOR_MIPI_CSI,
.xclk = 24000000,
.width = 800,
.height = 800,
.regs = ov5647_raw8_800x800_50fps,
.regs_size = ARRAY_SIZE(ov5647_raw8_800x800_50fps),
.fps = 50,
.isp_info = &custom_isp_info,
.mipi_info = {
.mipi_clk = 400000000,
.lane_num = 2,
.line_sync_en = false,
},
.reserved = NULL,
};
#endif
@@ -0,0 +1,21 @@
#ifndef _ENTHERNET_H
#define _ENTHERNET_H
#include "esp_err.h"
#include "lvgl.h"
#include "bsp/esp-bsp.h"
#ifdef __cplusplus
extern "c" {
#endif
extern lv_obj_t *label;
void test_enthernet_init(void);
void get_enthernet_Result(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,283 @@
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_check.h"
#include "esp_system.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#include "app_enthernet.h"
#include "lvgl.h"
#include "bsp/esp-bsp.h"
#include "bsp/display.h"
#include "bsp_board_extra.h"
#include "bsp/esp-bsp.h"
#include "app_camera.h"
#define EXAMPLE_RECV_BUF_SIZE (2400)
#define ECHO_TEST_TXD (GPIO_NUM_26)
#define ECHO_TEST_RXD (GPIO_NUM_27)
// RTS for RS485 Half-Duplex Mode manages DE/~RE
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
// CTS is not used in RS485 Half-Duplex Mode
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)
#define BUF_SIZE (127)
#define BAUD_RATE (115200)
#define PACKET_READ_TICS (100 / portTICK_PERIOD_MS)
#define ECHO_TASK_STACK_SIZE (3072)
#define ECHO_TASK_PRIO (10)
#define ECHO_UART_PORT (1)
#define ECHO_READ_TOUT (3)
const int uart_num = ECHO_UART_PORT;
static const char err_reason[][30] = {"input param is invalid",
"operation timeout"
};
static const char *TAG = "MAIN";
static lv_obj_t *obj = NULL;
lv_obj_t *label = NULL;
static lv_obj_t *btn = NULL;
static bool RS485_test_bool = false;
static void i2s_echo(void *args)
{
uint8_t *mic_data = malloc(EXAMPLE_RECV_BUF_SIZE);
if (!mic_data) {
ESP_LOGE(TAG, "[echo] No memory for read data buffer");
abort();
}
esp_err_t ret = ESP_OK;
size_t bytes_read = 0;
size_t bytes_write = 0;
ESP_LOGI(TAG, "[echo] Echo start");
while (1) {
// ESP_LOGI(TAG,"i2s read");
memset(mic_data, 0, EXAMPLE_RECV_BUF_SIZE);
/* Read sample data from mic */
ret = bsp_extra_i2s_read(mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 1000);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[echo] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
abort();
}
/* Write sample data to earphone */
ret = bsp_extra_i2s_write(mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 1000);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[echo] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
abort();
}
if (bytes_read != bytes_write) {
ESP_LOGW(TAG, "[echo] %d bytes read but only %d bytes are written", bytes_read, bytes_write);
}
}
vTaskDelete(NULL);
}
static void echo_send(const int port, const char* str, uint8_t length)
{
// ESP_LOGI(TAG,"data = %s",str);
if (uart_write_bytes(port, str, length) != length) {
ESP_LOGE(TAG, "Send data critical failure.");
// add your code to handle sending failure here
abort();
}
}
static void RS485_test_callback(lv_event_t *e)
{
// echo_send(uart_num, "\r\n", 2);
char prefix[] = "RS485 TEST";
echo_send(uart_num,prefix,sizeof(prefix));
ESP_ERROR_CHECK(uart_wait_tx_done(uart_num, 10));
}
static void echo_task(void *arg)
{
uart_config_t uart_config = {
.baud_rate = BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 122,
.source_clk = UART_SCLK_DEFAULT,
};
// // Set UART log level
// esp_log_level_set(TAG, ESP_LOG_INFO);
ESP_LOGI(TAG, "Start RS485 application test and configure UART.");
// Install UART driver (we don't need an event queue here)
// In this example we don't even use a buffer for sending data.
ESP_ERROR_CHECK(uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0));
// Configure UART parameters
ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
ESP_LOGI(TAG, "UART set pins, mode and install driver.");
// Set UART pins as per KConfig settings
ESP_ERROR_CHECK(uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));
// Set RS485 half duplex mode
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX));
// Set read timeout of UART TOUT feature
ESP_ERROR_CHECK(uart_set_rx_timeout(uart_num, ECHO_READ_TOUT));
// Allocate buffers for UART
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
ESP_LOGI(TAG, "UART start receive loop.\r");
// echo_send(uart_num, "Start RS485 UART test.\r\n", 24);
while (1) {
//Read data from UART
int len = uart_read_bytes(uart_num, data, BUF_SIZE, PACKET_READ_TICS);
//Write data back to UART
if (len > 0) {
// echo_send(uart_num, "\r\n", 2);
// char prefix[] = "RS485 Received: [";
// echo_send(uart_num, prefix, (sizeof(prefix) - 1));
ESP_LOGI(TAG, "Received %u bytes:", len);
printf("[ ");
for (int i = 0; i < len; i++) {
printf("0x%.2x ", data[i]);
// echo_send(uart_num, (const char*)&data[i], 1);
// Add a Newline character if you get a return character from paste (Paste tests multibyte receipt/buffer)
// if (data[i] == '\r') {
// echo_send(uart_num, "\n", 1);
// }
}
printf("] \n");
// echo_send(uart_num, "]\r\n", 3);
char *re = strstr((char *)data,"RS485 TEST");
if(re == NULL)
{
ESP_LOGI(TAG,"NOT send data");
}
else
{
if(!RS485_test_bool)
{
RS485_test_bool = true;
lvgl_port_lock(-1);
lv_label_ins_text(label,LV_LABEL_POS_LAST,"RS485 initial #00ff00 Success#\n");
lvgl_port_unlock();
// break;
}
}
}
// } else {
// // Echo a "." to show we are alive while we wait for input
// echo_send(uart_num, ".", 1);
// ESP_ERROR_CHECK(uart_wait_tx_done(uart_num, 10));
// }
}
vTaskDelete(NULL);
}
void app_main(void)
{
esp_err_t ret_bsp = ESP_OK;
// bsp_i2c_init();
bsp_display_cfg_t cfg = {
.lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG(),
.buffer_size = BSP_LCD_H_RES * BSP_LCD_V_RES,
.double_buffer = BSP_LCD_DRAW_BUFF_DOUBLE,
.flags = {
.buff_dma = false,
.buff_spiram = true,
.sw_rotate = true,
}
};
bsp_display_start_with_config(&cfg);
bsp_display_backlight_on();
bsp_display_lock(0);
obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj,800,1280);
btn = lv_btn_create(obj);
lv_obj_align(btn,LV_ALIGN_TOP_MID,50,50);
lv_obj_set_size(btn,200,100);
lv_obj_t *label_btn = lv_label_create(btn);
lv_obj_center(label_btn);
lv_label_set_text(label_btn,"RS485 Test");
lv_obj_add_event_cb(btn,RS485_test_callback,LV_EVENT_CLICKED,NULL);
label = lv_label_create(obj);
lv_label_set_recolor(label,true);
lv_obj_set_style_text_font(label,&lv_font_montserrat_28,0);
lv_label_set_text(label,"LCD initial #00ff00 Success#\n");
lv_label_ins_text(label,LV_LABEL_POS_LAST,"TP initial #00ff00 Success#\n");
bsp_display_unlock();
esp_err_t ret;
ret = bsp_sdcard_mount();
if(ret == ESP_OK)
{
bsp_display_lock(0);
lv_label_ins_text(label,LV_LABEL_POS_LAST,"SDCard initial #00ff00 Success#\n");
bsp_display_unlock();
}
else
{
bsp_display_lock(0);
lv_label_ins_text(label,LV_LABEL_POS_LAST,"SDCard initial #ff0000 Failed#\n");
bsp_display_unlock();
}
test_enthernet_init();
ret_bsp = bsp_extra_codec_init();
bsp_extra_codec_volume_set(50, NULL);
if(ret_bsp == ESP_OK)
{
bsp_display_lock(0);
lv_label_ins_text(label,LV_LABEL_POS_LAST,"ES8311 initial #00ff00 success#\n");
bsp_display_unlock();
// bsp_extra_codec_volume_set(50,NULL);
}
else
{
bsp_display_lock(0);
lv_label_ins_text(label,LV_LABEL_POS_LAST,"ES8311 initial #ff0000 failed#\n");
bsp_display_unlock();
}
// bsp_audio_init();
// bsp_extra_codec_mute_set(true);
// bsp_extra_codec_volume_set(50,NULL);
//
app_camera();
xTaskCreate(i2s_echo, "i2s_echo", 8192, NULL, 4, NULL);
xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, 3, NULL);
}