20250529 同步自原始工程:

优化 CMakeLists.txt,增加 lib-out 目录的包含;修改 app_config.c 中的 LED 灯带开关变量名;更新 app_config.h,增加新的灯效模式和方向控制;更新 SBDEMO.h 中的默认设备名称;在 msc_host.c 中添加 USB 设备连接类型的处理;在 usbport.c 中增加 USB 连接类型的状态管理;更新 Kconfig,增加 LED 灯带的最大图层数和竞速模式选项;新增 spbelib_interface.h 文件,定义无线调参功能接口;删除不再使用的 components/CMakeLists.txt 文件;更新 misc.h,添加读取 MCU 身份信息的 MD5 值的函数声明;修改 tim.h 中的 drv_pwm_init 函数参数;更新 kk.h,增加默认工作队列的创建宏;优化 sh.c 中的命令行插入字符串逻辑;更新 sdkconfig 默认配置文件,升级 ESP-IDF 版本和调整蓝牙默认发射功率。
This commit is contained in:
LokLiang
2025-05-29 18:05:20 +08:00
parent 499994b239
commit 176b2c49f6
17 changed files with 451 additions and 77 deletions

View File

@@ -6,6 +6,7 @@ list(APPEND incs "../components/system/source/shell")
list(APPEND incs "drivers/data_port/usb-host") list(APPEND incs "drivers/data_port/usb-host")
list(APPEND incs "drivers/data_port/ble_spp") list(APPEND incs "drivers/data_port/ble_spp")
list(APPEND incs "drivers/data_port/socket_inet") list(APPEND incs "drivers/data_port/socket_inet")
list(APPEND incs "lib-out")

View File

@@ -495,7 +495,7 @@ int app_cfg_set_fc_protocol_type(uint8_t type)
int app_cfg_set_led_strip_sw(uint8_t sw) int app_cfg_set_led_strip_sw(uint8_t sw)
{ {
s_cfg_app.strip_sw = !!sw; s_cfg_app.led_strip_ctrl_sw = !!sw;
app_cfg_do_save(100); app_cfg_do_save(100);
return 0; return 0;
} }

View File

@@ -104,7 +104,7 @@ typedef struct // 设备配置统一数据结构
bool strip_pwrup : 1; // 使用灯带上电效果 bool strip_pwrup : 1; // 使用灯带上电效果
bool strip_show_rf : 1; // 在灯带中用一个灯来显示射频数据接口状态的灯效图层 bool strip_show_rf : 1; // 在灯带中用一个灯来显示射频数据接口状态的灯效图层
bool strip_link_fc : 1; // 开启灯带联动飞控用于飞控状态监控MSP bool strip_link_fc : 1; // 开启灯带联动飞控用于飞控状态监控MSP
bool bat_led_startup : 1; // 开启电量灯效 char ws2812_bat_led_mode : 2; // 电量灯效, 0: 关闭, 1: 普通飞控, 2: 竞速飞控
uint32_t reserve : 21; // 预留占位(原来是24个uint32) uint32_t reserve : 21; // 预留占位(原来是24个uint32)
} capacity; } capacity;
@@ -114,7 +114,7 @@ typedef struct // 设备配置统一数据结构
uint8_t protocol_type; // @ref fc_comm_protocol_type_t uint8_t protocol_type; // @ref fc_comm_protocol_type_t
} fc; } fc;
uint8_t strip_sw; // 记录当前灯带的模拟开关状态0: 表示切换到由飞控控制, 1: 表示切换到由本固件控制 uint8_t led_strip_ctrl_sw; // 记录当前灯带的模拟开关状态0: 表示切换到由飞控控制, 1: 表示切换到由本固件控制
uint8_t armed2close_rf_sw; // 解锁后自动关闭射频功能的开关0: 关, 1: 开 uint8_t armed2close_rf_sw; // 解锁后自动关闭射频功能的开关0: 关, 1: 开
@@ -131,7 +131,9 @@ typedef struct // 设备配置统一数据结构
uint8_t temp_log_index : 5; // 温度日志最新索引 uint8_t temp_log_index : 5; // 温度日志最新索引
} temperature_log; } temperature_log;
uint32_t reserve[37]; // 预留占位,下次更改时保证参数总长度不变,如超过预留长度后则当作新数据处理,sizeof(cfg_app_t) = 484UL bool ws2812_bat_led_direction; // 0: 正向1: 反向(正反向是指灯珠的连接方式,正向是指从第一个灯珠开始,反向是指从最后一个灯珠开始)
uint32_t reserve[36]; // 预留占位,下次更改时保证参数总长度不变,如超过预留长度后则当作新数据处理,sizeof(cfg_app_t) = 484UL
uint32_t crc32; // 校验数据(可放于任何位置) uint32_t crc32; // 校验数据(可放于任何位置)
} cfg_app_t; } cfg_app_t;

View File

@@ -1,7 +1,7 @@
#if (CONFIG_PRODUCT_ID_SBDEMO) #if (CONFIG_PRODUCT_ID_SBDEMO)
#define _DEFAULT_DEVICE_NAME_BLE "demo V1" #define _DEFAULT_DEVICE_NAME_BLE "SpeedyBee DEMO-BLE"
#define _DEFAULT_DEVICE_NAME_WIFI "demo V1-WIFI" #define _DEFAULT_DEVICE_NAME_WIFI "SpeedyBee DEMO-WIFI"
#define _DEFAULT_DRONE_DATA "MODE1_1.0" #define _DEFAULT_DRONE_DATA "MODE1_1.0"
static cfg_app_t const s_cfg_app_default = { static cfg_app_t const s_cfg_app_default = {
@@ -46,13 +46,24 @@ static cfg_app_t const s_cfg_app_default = {
/* 功能模块开关 */ /* 功能模块开关 */
.capacity = { .capacity = {
.pwrup_light = 0, // 短亮黄灯表示启动(方便观察是否有重启) .pwrup_light = 1, // 短亮黄灯表示启动(方便观察是否有重启)
.ble = 1, // 使用 BLE .ble = 1, // 使用 BLE
.ap = 0, // 使用 WIFI AP 模式 .ap = 1, // 使用 WIFI AP 模式
.sta = 0, // 使用 WIFI STA 模式 .sta = 1, // 使用 WIFI STA 模式
.strip_pwrup = 0, // 使用灯带上电效果
.strip_show_rf = 0, // 在灯带中用一个灯来显示射频数据接口状态的灯效图层
.strip_link_fc = 0, // 开启灯带联动飞控
.ws2812_bat_led_mode = 1, // 电量灯效, 0: 关闭, 1: 普通飞控, 2: 竞速飞控
}, },
.armed2close_rf_sw = 1, // 解锁后自动关闭射频功能的开关0:关, 1:开 .ws2812_bat_led_direction = 0, // 0: 正向1: 反向(正反向是指灯珠的连接方式,正向是指从第一个灯珠开始,反向是指从最后一个灯珠开始)
.temperature_log = {
.temp_log_on = 0, // 温度日志开关
.temp_log_index = 0, // 温度日志最新索引
},
.armed2close_rf_sw = 0, // 解锁后自动关闭射频功能的开关0:关, 1:开
.product_id = PRODUCT_ID, // 产品 ID .product_id = PRODUCT_ID, // 产品 ID
.gyro_heat_value = 0, // 陀螺仪加热值,单位温度,0为关闭,最大值为80℃
}; };
#endif #endif

View File

@@ -288,6 +288,7 @@ volatile static int s_out_buffered_data_len = 0;
(setup_pkt_ptr)->wLength = 255; \ (setup_pkt_ptr)->wLength = 255; \
}) })
#ifndef USB_SETUP_PACKET_INIT_GET_STATUS
#define USB_SETUP_PACKET_INIT_GET_STATUS(setup_pkt_ptr) ({ \ #define USB_SETUP_PACKET_INIT_GET_STATUS(setup_pkt_ptr) ({ \
(setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \ (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \
(setup_pkt_ptr)->bRequest = STM32_DFU_REQUEST_GETSTATUS; \ (setup_pkt_ptr)->bRequest = STM32_DFU_REQUEST_GETSTATUS; \
@@ -295,6 +296,7 @@ volatile static int s_out_buffered_data_len = 0;
(setup_pkt_ptr)->wIndex = 0; \ (setup_pkt_ptr)->wIndex = 0; \
(setup_pkt_ptr)->wLength = 6; \ (setup_pkt_ptr)->wLength = 6; \
}) })
#endif
#define USB_SETUP_PACKET_INIT_CLEAR_STATUS(setup_pkt_ptr) ({ \ #define USB_SETUP_PACKET_INIT_CLEAR_STATUS(setup_pkt_ptr) ({ \
(setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \ (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \

View File

@@ -18,6 +18,8 @@
#include "errno.h" #include "errno.h"
#include "esp_vfs.h" #include "esp_vfs.h"
#include "spbelib_interface.h"
#include "config/hardware_define.h" #include "config/hardware_define.h"
// #include "usb/cdc_acm_host.h" // #include "usb/cdc_acm_host.h"
@@ -58,7 +60,7 @@ typedef struct
} __usb_data_t; } __usb_data_t;
static QueueHandle_t app_queue; static QueueHandle_t app_queue;
static SemaphoreHandle_t ready_to_uninstall_usb; // static SemaphoreHandle_t ready_to_uninstall_usb;
static msc_host_vfs_handle_t vfs_handle; static msc_host_vfs_handle_t vfs_handle;
static usbport_status_e g_usb_status = USBPORT_STATUS_NO_CONNECTION; static usbport_status_e g_usb_status = USBPORT_STATUS_NO_CONNECTION;
@@ -89,6 +91,7 @@ static SemaphoreHandle_t s_usb_write_mux = NULL;
static portMUX_TYPE s_out_ringbuf_mux = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE s_out_ringbuf_mux = portMUX_INITIALIZER_UNLOCKED;
volatile static int s_in_buffered_data_len = 0; volatile static int s_in_buffered_data_len = 0;
volatile static int s_out_buffered_data_len = 0; volatile static int s_out_buffered_data_len = 0;
volatile static usb_connect_type_t s_usb_connect_type = USB_CONNECTED_UNKNOWN;
//////////// End CDC 全局变量 //////////// //////////// End CDC 全局变量 ////////////
@@ -100,27 +103,41 @@ static uint16_t g_msc_file_count = 0;
//////////// End MSC 全局变量 //////////// //////////// End MSC 全局变量 ////////////
static TaskHandle_t s_usb_task_handle, s_device_task_handle; //, workthread_handle;
static void usb_device_event_cb(const msc_host_event_t *event, void *arg) static void usb_device_event_cb(const msc_host_event_t *event, void *arg)
{ {
switch (event->event) switch (event->event)
{ {
case MSC_DEVICE_CONNECTED: case MSC_DEVICE_CONNECTED:
s_usb_connect_type = USB_CONNECTED_MSC;
SYS_LOG_INF("MSC device connected"); SYS_LOG_INF("MSC device connected");
sblib_send_event(LIB_EVENT_USBH_MSC, 0, NULL);
break; break;
case MSC_DEVICE_DISCONNECTED: case MSC_DEVICE_DISCONNECTED:
s_usb_connect_type = USB_CONNECTED_UNKNOWN;
SYS_LOG_INF("MSC device disconnected"); SYS_LOG_INF("MSC device disconnected");
sblib_send_event(LIB_EVENT_USBH_UNKNOW_DEVICE, 0, NULL);
break; break;
case CDC_DEVICE_CONNECTED: case CDC_DEVICE_CONNECTED:
s_usb_connect_type = USB_CONNECTED_CDC;
SYS_LOG_INF("CDC device connected"); SYS_LOG_INF("CDC device connected");
sblib_send_event(LIB_EVENT_USBH_CDC, 0, NULL);
break; break;
case CDC_DEVICE_DISCONNECTED: case CDC_DEVICE_DISCONNECTED:
s_usb_connect_type = USB_CONNECTED_UNKNOWN;
SYS_LOG_INF("CDC device disconnected"); SYS_LOG_INF("CDC device disconnected");
sblib_send_event(LIB_EVENT_USBH_UNKNOW_DEVICE, 0, NULL);
break; break;
case DFU_DEVICE_CONNECTED: case DFU_DEVICE_CONNECTED:
s_usb_connect_type = USB_CONNECTED_DFU;
SYS_LOG_INF("DFU device connected"); SYS_LOG_INF("DFU device connected");
sblib_send_event(LIB_EVENT_USBH_DFU, 0, NULL);
break; break;
case DFU_DEVICE_DISCONNECTED: case DFU_DEVICE_DISCONNECTED:
s_usb_connect_type = USB_CONNECTED_UNKNOWN;
SYS_LOG_INF("DFU device disconnected"); SYS_LOG_INF("DFU device disconnected");
sblib_send_event(LIB_EVENT_USBH_UNKNOW_DEVICE, 0, NULL);
break; break;
} }
@@ -133,20 +150,26 @@ static void handle_usb_events(void *args)
while (1) while (1)
{ {
uint32_t event_flags; uint32_t event_flags;
SYS_LOG_INF("usb_host_lib_handle_events(portMAX_DELAY, &event_flags);");
usb_host_lib_handle_events(portMAX_DELAY, &event_flags); usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
// Release devices once all clients has deregistered // Release devices once all clients has deregistered
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS)
{ {
SYS_LOG_INF("usb_host_device_free_all();");
usb_host_device_free_all(); usb_host_device_free_all();
// SYS_LOG_INF("xSemaphoreGive(ready_to_uninstall_usb);");
// xSemaphoreGive(ready_to_uninstall_usb);
break;
} }
// Give ready_to_uninstall_usb semaphore to indicate that USB Host library // Give ready_to_uninstall_usb semaphore to indicate that USB Host library
// can be deinitialized, and terminate this task. // can be deinitialized, and terminate this task.
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) // if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
{ // {
xSemaphoreGive(ready_to_uninstall_usb); // SYS_LOG_INF("xSemaphoreGive(ready_to_uninstall_usb);");
// xSemaphoreGive(ready_to_uninstall_usb);
// }
} }
} s_usb_task_handle = NULL;
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@@ -308,6 +331,7 @@ static void handle_device_events(void *args)
msc_host_event_t app_event; msc_host_event_t app_event;
while (1) while (1)
{ {
SYS_LOG_INF("xQueueReceive(app_queue, &app_event, portMAX_DELAY);");
xQueueReceive(app_queue, &app_event, portMAX_DELAY); xQueueReceive(app_queue, &app_event, portMAX_DELAY);
switch (app_event.event) switch (app_event.event)
@@ -501,19 +525,22 @@ static int _usbhost_port_read(sb_data_port_t *port, void *buffer, uint32_t lengt
} }
} }
static bool s_is_started = false;
static int _usbhost_start(sb_data_port_t *port) static int _usbhost_start(sb_data_port_t *port)
{ {
s_is_started = true;
return 0; return 0;
} }
static int _usbhost_stop(sb_data_port_t *port) static int _usbhost_stop(sb_data_port_t *port)
{ {
s_is_started = false;
return 0; return 0;
} }
static bool _usbhost_is_started(sb_data_port_t *port) static bool _usbhost_is_started(sb_data_port_t *port)
{ {
return true; return s_is_started;
} }
static uint32_t _usbhost_get_rx_length(sb_data_port_t *port) static uint32_t _usbhost_get_rx_length(sb_data_port_t *port)
@@ -705,8 +732,11 @@ static sb_data_port_vtable_t const usbhost_port_vtable = {
//////////// STM32固件升级相关的函数结束 ////////////// //////////// STM32固件升级相关的函数结束 //////////////
// static TaskHandle_t s_usb_task_handle, s_device_task_handle; //, workthread_handle;
int usbport_init(void) int usbport_init(void)
{ {
SYS_LOG_INF("usbport_init");
if (s_port.vtable) if (s_port.vtable)
{ {
SYS_LOG_WRN("repeated initialize"); SYS_LOG_WRN("repeated initialize");
@@ -716,26 +746,33 @@ int usbport_init(void)
s_port.vtable = &usbhost_port_vtable; s_port.vtable = &usbhost_port_vtable;
s_port.data = &s_usb_data; s_port.data = &s_usb_data;
TaskHandle_t usb_task_handle, device_task_handle; //, workthread_handle;
memset(&s_usb_data, 0, sizeof(__usb_data_t)); memset(&s_usb_data, 0, sizeof(__usb_data_t));
os_pipe_create(&s_usb_data.pipe_obj, 1024 * 2); os_pipe_create(&s_usb_data.pipe_obj, 1024 * 2);
ready_to_uninstall_usb = xSemaphoreCreateBinary(); // if (ready_to_uninstall_usb == NULL)
// {
// ready_to_uninstall_usb = xSemaphoreCreateBinary();
// }
app_queue = xQueueCreate(3, sizeof(msc_host_event_t)); app_queue = xQueueCreate(3, sizeof(msc_host_event_t));
assert(app_queue); assert(app_queue);
static usb_host_config_t const host_config = { static usb_host_config_t const host_config = {
// .skip_phy_setup = false, .skip_phy_setup = false,
.intr_flags = ESP_INTR_FLAG_LEVEL1, .intr_flags = ESP_INTR_FLAG_LEVEL1,
}; };
ESP_ERROR_CHECK(usb_host_install(&host_config)); ESP_ERROR_CHECK(usb_host_install(&host_config));
xTaskCreatePinnedToCore(handle_usb_events, "usb_events", 4096, NULL, SBTASK_PRIORITY_USB_HOST, &usb_task_handle, SBTASK_CORE_INDEX_USB_HOST); if (s_usb_task_handle == NULL)
assert(usb_task_handle); {
xTaskCreatePinnedToCore(handle_device_events, "device_events", 4096, NULL, SBTASK_PRIORITY_USB_DEVICE, &device_task_handle, SBTASK_CORE_INDEX_USB_DEVICE); xTaskCreatePinnedToCore(handle_usb_events, "usb_events", 4096, NULL, SBTASK_PRIORITY_USB_HOST, &s_usb_task_handle, SBTASK_CORE_INDEX_USB_HOST);
assert(device_task_handle); assert(s_usb_task_handle);
}
if (s_device_task_handle == NULL)
{
xTaskCreatePinnedToCore(handle_device_events, "device_events", 4096, NULL, SBTASK_PRIORITY_USB_DEVICE, &s_device_task_handle, SBTASK_CORE_INDEX_USB_DEVICE);
assert(s_device_task_handle);
}
const msc_host_driver_config_t msc_config = { const msc_host_driver_config_t msc_config = {
.create_backround_task = true, .create_backround_task = true,
@@ -748,6 +785,70 @@ int usbport_init(void)
return 0; return 0;
} }
void usbport_deinit(void)
{
SYS_LOG_INF("usbport_deinit");
if (s_port.vtable == NULL)
{
SYS_LOG_WRN("usb host not initialized");
return;
}
if (g_connected_usb_device)
{
if (vfs_handle)
{
msc_host_vfs_unregister(vfs_handle);
vfs_handle = NULL;
}
msc_host_uninstall_device(g_connected_usb_device);
g_connected_usb_device = NULL;
}
if (g_cdc_dev)
{
cdc_host_close(g_cdc_dev);
g_cdc_dev = NULL;
}
ESP_ERROR_CHECK(msc_host_uninstall());
vTaskDelay(pdMS_TO_TICKS(100));
// if (s_device_task_handle)
// {
// vTaskDelete(s_device_task_handle);
// s_device_task_handle = NULL;
// }
// if (s_usb_task_handle)
// {
// vTaskDelete(s_usb_task_handle);
// s_usb_task_handle = NULL;
// }
ESP_ERROR_CHECK(usb_host_uninstall());
if (app_queue)
{
vQueueDelete(app_queue);
app_queue = NULL;
}
// if (ready_to_uninstall_usb)
// {
// vSemaphoreDelete(ready_to_uninstall_usb);
// ready_to_uninstall_usb = NULL;
// }
if (os_pipe_is_valid(&s_usb_data.pipe_obj))
{
os_pipe_delete(&s_usb_data.pipe_obj);
}
s_port.vtable = NULL;
}
sb_data_port_t *usbport_bind(os_work_t *rx_resume_work) sb_data_port_t *usbport_bind(os_work_t *rx_resume_work)
{ {
if (s_port.data == NULL) if (s_port.data == NULL)
@@ -764,6 +865,21 @@ sb_data_port_t *usbport_bind(os_work_t *rx_resume_work)
return &s_port; return &s_port;
} }
void usbport_unbind(sb_data_port_t *port)
{
if (port == NULL)
{
SYS_LOG_WRN("usb host not initialized");
return;
}
__usb_data_t *usb_data = port->data;
os_pipe_unregist(&usb_data->pipe_obj);
usb_data->rx_resume_work = NULL;
}
usbport_status_e usbport_get_state(void) usbport_status_e usbport_get_state(void)
{ {
return g_usb_status; return g_usb_status;
@@ -785,3 +901,8 @@ msc_file_info *msc_get_cached_file_list(uint16_t *out_file_count)
} }
return g_msc_file_lists; return g_msc_file_lists;
} }
usb_connect_type_t usbport_get_usb_type(void)
{
return s_usb_connect_type;
}

View File

@@ -62,7 +62,10 @@ typedef struct
#pragma pack(pop) #pragma pack(pop)
int usbport_init(void); int usbport_init(void);
void usbport_deinit(void);
sb_data_port_t *usbport_bind(os_work_t *rx_resume_work); sb_data_port_t *usbport_bind(os_work_t *rx_resume_work);
void usbport_unbind(sb_data_port_t *port);
usbport_status_e usbport_get_state(void); usbport_status_e usbport_get_state(void);
// 读取flash layout信息 // 读取flash layout信息
@@ -111,3 +114,12 @@ void _usbh_pre_disconnect_deivce(void);
msc_file_info *msc_get_file_list(uint16_t *out_file_count, const excluding_file_item_t *excluding_files, uint8_t excluding_file_count); msc_file_info *msc_get_file_list(uint16_t *out_file_count, const excluding_file_item_t *excluding_files, uint8_t excluding_file_count);
msc_file_info *msc_get_cached_file_list(uint16_t *out_file_count); msc_file_info *msc_get_cached_file_list(uint16_t *out_file_count);
typedef enum
{
USB_CONNECTED_CDC = 0,
USB_CONNECTED_DFU = 1,
USB_CONNECTED_MSC = 2,
USB_CONNECTED_UNKNOWN = 3,
} usb_connect_type_t;
usb_connect_type_t usbport_get_usb_type(void);

View File

@@ -2,7 +2,13 @@ config LED_STRIP_MAX_LEDS
depends on CAP_LED_STRIP depends on CAP_LED_STRIP
int "最大灯珠数" int "最大灯珠数"
range 1 164 range 1 164
default 88 default 164
config LED_STRIP_MIN_LEDS
depends on CAP_LED_STRIP
int "最小灯珠数"
range 1 64
default 64
config LED_STRIP_DEFAULT_LEDS config LED_STRIP_DEFAULT_LEDS
depends on CAP_LED_STRIP depends on CAP_LED_STRIP
@@ -10,4 +16,22 @@ config LED_STRIP_DEFAULT_LEDS
range 1 LED_STRIP_MAX_LEDS range 1 LED_STRIP_MAX_LEDS
default LED_STRIP_MAX_LEDS default LED_STRIP_MAX_LEDS
config LED_STRIP_MAX_LAYER
depends on CAP_LED_STRIP
int "最大图层数"
range 1 8
default 2
menuconfig LED_STRIP_RACING_MODE
depends on CAP_LED_STRIP
bool "编译竞速模式"
default n
help
竞速飞塔项目新增的选项,通过收藏列表中的默认主题快速来实现仅一个简单的效果
config LED_STRIP_DEFAULT_FAVORITE_ID
depends on LED_STRIP_RACING_MODE
int "选择默认主题。对应代码中 led_ctrl_playmode_t 的枚举值"
range 1 14
default 18

View File

@@ -0,0 +1,194 @@
/**
* @file spbelib_interface.h
* @author LokLiang
* @brief 无线调参功能接口
* @version 0.1
* @date 2025-03-14
*
* @copyright Copyright (c) 2025
*
*/
#pragma once
#include "sys_types.h"
typedef enum
{
SBLIB_INIT_WIRE_TUNE = 0, // 初始化为无线调参功能
SBLIB_INIT_ADAPTER, // 初始化为 小黄砖4 功能
} sblib_init_t;
/**
* @brief 初始化功能库。
*/
void sblib_init(sblib_init_t init_type);
/*************************************************************************************************/
/**** 事件操作部分 ********************************************************************************/
/*************************************************************************************************/
/**
* @brief 注册事件回调函数。
* 当有关于小黄砖功能的事件发生或接收到数据时,调用回调函数。
* 由 lib_notify_event() 和 sblib_notify_datastream() 函数调用。
*/
typedef void (*lib_notify_cb)(void);
typedef enum __packed // 小黄砖功能控制命令
{
LIB_CONTROL_FCPORT_OFF, // 关闭飞控数据接口
LIB_CONTROL_FCPORT_UART, // 使用 UART 连接飞控
LIB_CONTROL_FCPORT_OTG, // 使用 OTG 连接飞控
LIB_CONTROL_RF_OFF, // 关闭射频连接
LIB_CONTROL_RF_BLE, // 打开 BLE
LIB_CONTROL_RF_AP, // 打开 WIFI(AP)
LIB_CONTROL_RF_STA, // 打开 WIFI(STA)
} lib_control_t;
typedef enum __packed // 小黄砖通知的事件类型
{
LIB_EVENT_NONE = 0,
LIB_EVENT_FC_PORT_OFF, // 飞控数据接口关闭。参数:无
LIB_EVENT_FC_PORT_UART, // 飞控数据接口为串口。参数:无
LIB_EVENT_FC_PORT_OTG, // 飞控数据接口为 USBH。参数
LIB_EVENT_USBH_NO_START, // USBH 接口未启动。参数:无
LIB_EVENT_USBH_CDC, // USBH 接口已连接 CDC 设备。参数:无
LIB_EVENT_USBH_DFU, // USBH 接口已连接 DFU 设备。参数:无
LIB_EVENT_USBH_MSC, // USBH 接口已连接 MSC 设备。参数:无
LIB_EVENT_USBH_UNKNOW_DEVICE, // USBH 接口已连接未知设备。参数:无
LIB_EVENT_RF_OFF, // 无线连接已关闭。参数:无
LIB_EVENT_RF_CHANGE_MODE, // 提示模式切换已就绪。参数:无
LIB_EVENT_RF_BLE_IDLE, // 蓝牙模式未连接。参数:无
LIB_EVENT_RF_BLE_CONNECTED, // 蓝牙模式已连接。参数:无
LIB_EVENT_RF_AP_IDLE, // WIFI AP 模式未连接。参数:无
LIB_EVENT_RF_AP_CONNECTED, // WIFI AP 模式已连接。参数:无
LIB_EVENT_RF_STA_IDLE, // WIFI STA 模式未连接。参数:无
LIB_EVENT_RF_STA_CONNECTED, // WIFI STA 模式已连接。参数:已连接设备的 MAC 地址
LIB_EVENT_BLE_NAME_SET, // BLE 名称已设置。参数:无
LIB_EVENT_BLE_PASSWD_SET, // BLE 密码已设置。参数:无
LIB_EVENT_WIFI_AP_SSID_SET, // WIFI AP SSID 已设置。参数:无
LIB_EVENT_WIFI_AP_PASSWD_SET, // WIFI AP 密码已设置。参数:无
LIB_EVENT_WIFI_STA_SSID_SET, // WIFI STA SSID 已设置。参数:无
LIB_EVENT_WIFI_STA_PASSWD_SET, // WIFI STA 密码已设置。参数:无
LIB_EVENT_MAX
} lib_event_type_t;
typedef struct // 小黄砖通知的事件数据
{
lib_event_type_t type; // 事件类型
uint8_t len; // data[] 有效数据长度
uint8_t data[6]; // 事件数据
} lib_event_t;
/**
* @brief 执行对小黄砖功能的控制。
*
* @param control 控制命令
* @retval 0 表示成功; -1 表示失败。
*/
int sblib_control(lib_control_t control);
/**
* @brief 注册事件回调函数。
* 当有关于小黄砖的新事件发生时,将调用指定的回调函数以通知上层应用。
* 内部可缓存的记录数为 32 个。
* 使用 sblib_get_event() 可读取这些记录,读取后会清除记录。
*
* @param cb 指定的回调函数。建议在回调函数中执行发送信号的操作。
*/
void sblib_regist_notify_event(lib_notify_cb cb);
/**
* @brief 获取小黄砖的事件。线程和中断可用。
*
* @return lib_event_t
*/
lib_event_t sblib_get_event(void);
/**
* @brief 发送通知。
* 通知信息保存到内部队列中,长度为 32。
* 每次发送通知时,由 sblib_regist_notify_event() 注册的回调函数会被调用。
* @param type 事件类型
* @param len 事件数据长度。范围 0..6。如果取值大于最大值时,事件数据被截断。
* @param data 事件数据
*/
void sblib_send_event(lib_event_type_t type, uint8_t len, const uint8_t data[]);
/*************************************************************************************************/
/**** 通过无线接口与 APP 通讯部分 ******************************************************************/
/*************************************************************************************************/
/**
* @brief 当无线接口接收到 APP 数据时的回调函数。
* @param port 收到的端口号,这个号码与注册时的 port 一致。
* @param cmd 收到的命令代号,这个号码与注册时的 cmd 一致。
* @param payload 收到的数据指针,指向数据的内存地址。
* @param size 收到的数据长度。
*/
typedef void (*cmd_func_cb)(uint8_t port, uint8_t cmd, const void *payload, uint16_t size);
typedef enum
{
SBLIB_CMD_PORT_DEBUG = 0, // 保留的端口,用于 debug 等
SBLIB_CMD_PORT_ADAPTER, // 无线调参扩展命令集
SBLIB_CMD_PORT_FINDTAG, // 寻机命令集
SBLIB_CMD_PORT_JOYSTICK, // 遥控器命令集
SBLIB_CMD_PORT_ELRS, // 接收机命令集
} sblib_cmd_port_t;
typedef struct // 注册命令的结构体
{
uint8_t cmd; // 命令代号
cmd_func_cb cb; // 命令处理函数
} sblib_cmd_t;
typedef enum // 返回的发送状态
{
SBLIB_SEND_STATUS_OK = 0, // 当前等发送数据已缓存到待发送区中,数据将会被发送
SBLIB_SEND_STATUS_NO_SPACE, // 当前没有缓存空间,数据不会被处理
SBLIB_SEND_STATUS_NO_CONNECT, // 当前没有连接,数据不会被处理
} sblib_cmd_send_status_t;
/**
* @brief 注册一个通过无线接口接收 APP 数据的外部命令集。
* 当收到 APP 发出的命令和数据时,会调 cmd_struct 中对应的 port 和 cmd 的函数。
* 回调过程中允许调用 sblib_send_event() 向 APP 发送数据。
* 注意:回调函数附带的参数不会被缓存,并且必须尽快处理,如果需要缓存需要自行处理。
*
* @param port 端口号。一个端口号对应一个应用的命令集合标识,具体序号由收发双方的应用层协商,一旦确定后,不能更改。收发双向都使用同一个端口号。
* @param cmd_struct 指向一个命令集合的结构体数组。这个命令集合与参数 port 绑定。当收到 APP 发出的命令时,会调 cmd_struct 中对应的 port 和 cmd 的函数。
* @param struct_size 命令集结构体大小。使用 sizeof() 计算。
* @retval 0 成功
* @retval -1 失败:内置预设的命令集已满,无法注册新的命令集。
*/
int sblib_register_cmd(sblib_cmd_port_t port, const sblib_cmd_t *cmd_struct, uint32_t struct_size);
/**
* @brief 通过无线接口发送数据到 APP。
* 发送的数据会被缓存到待发送区中,当收到 APP 的回应时缓存会被自动清除,通过 sblib_get_cmd_sned_buf() 函数可以获取当前未被成功发送的数据包的数量。
*
* @param port 端口号。一个端口号对应一个应用的命令集合标识,具体序号由收发双方的应用层协商,一旦确定后,不能更改。收发双向都使用同一个端口号。
* @param cmd 命令代号。命令代号由收发双方的应用层协商,一旦确定后,不能更改。
* @param data 数据指针。指向要发送的数据的内存地址。指向的内存地址的数据会被复制到缓存区中,发送结束后会被自动释放。
* @param length 数据长度。长度任意,建议最大为 1460 字节
* @return
* SBLIB_SEND_STATUS_OK 当前等发送数据已缓存到待发送区中,数据将会被发送
* SBLIB_SEND_STATUS_NO_SPACE 当前没有缓存空间,数据不会被处理
* SBLIB_SEND_STATUS_NO_CONNECT 当前没有连接,数据不会被处理
*/
sblib_cmd_send_status_t sblib_cmd_send(sblib_cmd_port_t port, uint8_t cmd, const void *data, uint16_t length);
/**
* @brief 获取当前已缓存但未发送成功的数据包的数量。
*
* @return uint32_t 未发送完成的数据包的数量
*/
uint32_t sblib_get_cmd_sned_buf(void);

View File

@@ -1,11 +0,0 @@
list(APPEND incs "system/include")
list(APPEND srcs "system/source/k_kit/k_kit.c")
list(APPEND srcs "system/source/shell/sh_vt100.c")
list(APPEND srcs "system/source/shell/sh_vset.c")
list(APPEND srcs "system/source/shell/sh.c")
idf_component_register(
INCLUDE_DIRS ${incs}
SRCS ${srcs}
)

View File

@@ -0,0 +1,11 @@
list(APPEND incs "include")
list(APPEND srcs "source/k_kit/k_kit.c")
list(APPEND srcs "source/shell/sh_vt100.c")
list(APPEND srcs "source/shell/sh_vset.c")
list(APPEND srcs "source/shell/sh.c")
idf_component_register(
INCLUDE_DIRS ${incs}
SRCS ${srcs}
)

View File

@@ -21,6 +21,15 @@ void drv_misc_busy_wait(unsigned us);
*/ */
unsigned *drv_misc_bitband(void *mem); unsigned *drv_misc_bitband(void *mem);
/**
* @brief 读取 MCU 身份信息的 MD5 值
*
* @param out[out] 输出
* @retval 0 成功
* @retval -1 失败
*/
int drv_misc_read_id_md5(unsigned char out[16]);
/** /**
* @brief 设置中断向量地址 * @brief 设置中断向量地址
* *

View File

@@ -51,7 +51,7 @@ void drv_pwm_pin_configure(hal_id_t id, uint8_t pin);
void drv_pwm_enable(hal_id_t id); void drv_pwm_enable(hal_id_t id);
void drv_pwm_disable(hal_id_t id); void drv_pwm_disable(hal_id_t id);
void drv_pwm_init(hal_id_t id, unsigned period_ns, unsigned reload_enable); void drv_pwm_init(hal_id_t id, unsigned channel_mask, unsigned period_ns, unsigned reload_enable);
void drv_pwm_deinit(hal_id_t id); void drv_pwm_deinit(hal_id_t id);
int drv_pwm_irq_callback_enable(hal_id_t id, tim_isr_cb_fn cb); int drv_pwm_irq_callback_enable(hal_id_t id, tim_isr_cb_fn cb);

View File

@@ -41,6 +41,7 @@ typedef k_pipe_t kk_pipe_t;
#define kk_work_q_is_valid() k_work_q_is_valid(WORK_Q_HDL) // 获取工作队列是否有效 #define kk_work_q_is_valid() k_work_q_is_valid(WORK_Q_HDL) // 获取工作队列是否有效
#define kk_work_create(work_handle, work_route, arg, priority) k_work_create(work_handle, #work_route, work_route, arg, priority) // 创建由工作队列管理的任务 #define kk_work_create(work_handle, work_route, arg, priority) k_work_create(work_handle, #work_route, work_route, arg, priority) // 创建由工作队列管理的任务
#define kk_work_create_default(work_handle, work_route, arg, priority, delay) k_work_create_default(work_handle, #work_route, work_route, arg, priority, delay) // 创建由工作队列管理的任务,使用默认的工作队列
#define kk_work_delete(work_handle) k_work_delete(work_handle) // 删除由工作队列管理的任务 #define kk_work_delete(work_handle) k_work_delete(work_handle) // 删除由工作队列管理的任务
#define kk_work_submit(work_q_handle, work_handle, delay) k_work_submit(work_q_handle, work_handle, delay) // 多少时间后唤醒任务 #define kk_work_submit(work_q_handle, work_handle, delay) k_work_submit(work_q_handle, work_handle, delay) // 多少时间后唤醒任务

View File

@@ -469,17 +469,15 @@ static void _find_and_run_key(sh_t *sh_hdl, char c)
*/ */
static void _insert_str(sh_t *sh_hdl, const char *str) static void _insert_str(sh_t *sh_hdl, const char *str)
{ {
int remain = _SH_ARRAY_COUNT(sh_hdl->cmd_line) - (sh_hdl->cmd_buf - sh_hdl->cmd_line) - sh_hdl->cmd_stored - 1; // -1: 保留 '\0'
int len = strlen(str); int len = strlen(str);
if (len)
{
int remain = _SH_ARRAY_COUNT(sh_hdl->cmd_line) - (sh_hdl->cmd_buf - sh_hdl->cmd_line) - sh_hdl->cmd_stored - 1;
if (len > remain) if (len > remain)
{ {
len = remain; len = remain;
} }
_apply_history(sh_hdl); if (len)
if (sh_hdl->cmd_stored < remain)
{ {
_apply_history(sh_hdl);
if (sh_hdl->port.insert_str) /* 设置终端插入一个字符 */ if (sh_hdl->port.insert_str) /* 设置终端插入一个字符 */
{ {
sh_hdl->port.insert_str(sh_hdl, str); sh_hdl->port.insert_str(sh_hdl, str);
@@ -507,7 +505,6 @@ static void _insert_str(sh_t *sh_hdl, const char *str)
sh_refresh_line(sh_hdl); sh_refresh_line(sh_hdl);
} }
} }
}
} }
/** /**
@@ -525,7 +522,7 @@ static char *_parse_input(int *argc, const char *argv[], char *dest, const char
char *ret = dest; char *ret = dest;
bool end = false; bool end = false;
*argc = 0; *argc = 0;
while (end == false && *argc < CONFIG_SH_MAX_PARAM) while (*src != '\0' && end == false && *argc < CONFIG_SH_MAX_PARAM)
{ {
int len = 0; int len = 0;
@@ -2763,6 +2760,7 @@ void sh_ctrl_print_cmd_line(sh_t *sh_hdl)
sh_echo(sh_hdl, line); sh_echo(sh_hdl, line);
sh_hdl->cmd_input = strlen(line); sh_hdl->cmd_input = strlen(line);
sh_hdl->cmd_stored = sh_hdl->cmd_input;
sh_hdl->sync_cursor = sh_hdl->cmd_input; sh_hdl->sync_cursor = sh_hdl->cmd_input;
_update_cursor(sh_hdl); _update_cursor(sh_hdl);
} }

View File

@@ -1,5 +1,5 @@
# This file was generated using idf.py save-defconfig. It can be edited manually. # This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) 5.2.1 Project Minimal Configuration # Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration
# #
CONFIG_IDF_TARGET="esp32s3" CONFIG_IDF_TARGET="esp32s3"
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
@@ -8,11 +8,10 @@ CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_BOARD_NAME_DEVKIT_ESP32S3=y CONFIG_BOARD_NAME_DEVKIT_ESP32S3=y
CONFIG_BUILD_WIFI=y CONFIG_BUILD_WIFI=y
CONFIG_BT_ENABLED=y CONFIG_BT_ENABLED=y
CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1=y
CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR=y CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR=y
CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR=y CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR=y
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P21=y CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P20=y
CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 CONFIG_ESP_IPC_TASK_STACK_SIZE=1536

View File

@@ -12,7 +12,7 @@ CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1=y
CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR=y CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR=y
CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR=y CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR=y
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P21=y CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P20=y
CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 CONFIG_ESP_IPC_TASK_STACK_SIZE=1536