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:
@@ -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/ble_spp")
|
||||
list(APPEND incs "drivers/data_port/socket_inet")
|
||||
list(APPEND incs "lib-out")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -495,7 +495,7 @@ int app_cfg_set_fc_protocol_type(uint8_t type)
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -101,10 +101,10 @@ typedef struct // 设备配置统一数据结构
|
||||
bool ap : 1; // 使用 WIFI AP 模式
|
||||
bool sta : 1; // 使用 WIFI STA 模式
|
||||
|
||||
bool strip_pwrup : 1; // 使用灯带上电效果
|
||||
bool strip_show_rf : 1; // 在灯带中用一个灯来显示射频数据接口状态的灯效图层
|
||||
bool strip_link_fc : 1; // 开启灯带联动飞控:用于飞控状态监控(MSP)
|
||||
bool bat_led_startup : 1; // 开启电量灯效
|
||||
bool strip_pwrup : 1; // 使用灯带上电效果
|
||||
bool strip_show_rf : 1; // 在灯带中用一个灯来显示射频数据接口状态的灯效图层
|
||||
bool strip_link_fc : 1; // 开启灯带联动飞控:用于飞控状态监控(MSP)
|
||||
char ws2812_bat_led_mode : 2; // 电量灯效, 0: 关闭, 1: 普通飞控, 2: 竞速飞控
|
||||
|
||||
uint32_t reserve : 21; // 预留占位(原来是24个uint32)
|
||||
} capacity;
|
||||
@@ -114,7 +114,7 @@ typedef struct // 设备配置统一数据结构
|
||||
uint8_t protocol_type; // @ref fc_comm_protocol_type_t
|
||||
} fc;
|
||||
|
||||
uint8_t strip_sw; // 记录当前灯带的模拟开关状态,0: 表示切换到由飞控控制, 1: 表示切换到由本固件控制
|
||||
uint8_t led_strip_ctrl_sw; // 记录当前灯带的模拟开关状态,0: 表示切换到由飞控控制, 1: 表示切换到由本固件控制
|
||||
|
||||
uint8_t armed2close_rf_sw; // 解锁后自动关闭射频功能的开关,0: 关, 1: 开
|
||||
|
||||
@@ -131,7 +131,9 @@ typedef struct // 设备配置统一数据结构
|
||||
uint8_t temp_log_index : 5; // 温度日志最新索引
|
||||
} 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; // 校验数据(可放于任何位置)
|
||||
} cfg_app_t;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#if (CONFIG_PRODUCT_ID_SBDEMO)
|
||||
|
||||
#define _DEFAULT_DEVICE_NAME_BLE "demo V1"
|
||||
#define _DEFAULT_DEVICE_NAME_WIFI "demo V1-WIFI"
|
||||
#define _DEFAULT_DEVICE_NAME_BLE "SpeedyBee DEMO-BLE"
|
||||
#define _DEFAULT_DEVICE_NAME_WIFI "SpeedyBee DEMO-WIFI"
|
||||
#define _DEFAULT_DRONE_DATA "MODE1_1.0"
|
||||
|
||||
static cfg_app_t const s_cfg_app_default = {
|
||||
@@ -46,13 +46,24 @@ static cfg_app_t const s_cfg_app_default = {
|
||||
|
||||
/* 功能模块开关 */
|
||||
.capacity = {
|
||||
.pwrup_light = 0, // 短亮黄灯表示启动(方便观察是否有重启)
|
||||
.pwrup_light = 1, // 短亮黄灯表示启动(方便观察是否有重启)
|
||||
.ble = 1, // 使用 BLE
|
||||
.ap = 0, // 使用 WIFI AP 模式
|
||||
.sta = 0, // 使用 WIFI STA 模式
|
||||
.ap = 1, // 使用 WIFI AP 模式
|
||||
.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
|
||||
.gyro_heat_value = 0, // 陀螺仪加热值,单位温度,0为关闭,最大值为80℃
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -288,13 +288,15 @@ volatile static int s_out_buffered_data_len = 0;
|
||||
(setup_pkt_ptr)->wLength = 255; \
|
||||
})
|
||||
|
||||
#ifndef USB_SETUP_PACKET_INIT_GET_STATUS
|
||||
#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)->bRequest = STM32_DFU_REQUEST_GETSTATUS; \
|
||||
(setup_pkt_ptr)->bRequest = STM32_DFU_REQUEST_GETSTATUS; \
|
||||
(setup_pkt_ptr)->wValue = 0; \
|
||||
(setup_pkt_ptr)->wIndex = 0; \
|
||||
(setup_pkt_ptr)->wLength = 6; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#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; \
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "errno.h"
|
||||
#include "esp_vfs.h"
|
||||
|
||||
#include "spbelib_interface.h"
|
||||
|
||||
#include "config/hardware_define.h"
|
||||
// #include "usb/cdc_acm_host.h"
|
||||
|
||||
@@ -58,7 +60,7 @@ typedef struct
|
||||
} __usb_data_t;
|
||||
|
||||
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 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;
|
||||
volatile static int s_in_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 全局变量 ////////////
|
||||
|
||||
@@ -100,27 +103,41 @@ static uint16_t g_msc_file_count = 0;
|
||||
|
||||
//////////// 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)
|
||||
{
|
||||
switch (event->event)
|
||||
{
|
||||
case MSC_DEVICE_CONNECTED:
|
||||
s_usb_connect_type = USB_CONNECTED_MSC;
|
||||
SYS_LOG_INF("MSC device connected");
|
||||
sblib_send_event(LIB_EVENT_USBH_MSC, 0, NULL);
|
||||
break;
|
||||
case MSC_DEVICE_DISCONNECTED:
|
||||
s_usb_connect_type = USB_CONNECTED_UNKNOWN;
|
||||
SYS_LOG_INF("MSC device disconnected");
|
||||
sblib_send_event(LIB_EVENT_USBH_UNKNOW_DEVICE, 0, NULL);
|
||||
break;
|
||||
case CDC_DEVICE_CONNECTED:
|
||||
s_usb_connect_type = USB_CONNECTED_CDC;
|
||||
SYS_LOG_INF("CDC device connected");
|
||||
sblib_send_event(LIB_EVENT_USBH_CDC, 0, NULL);
|
||||
break;
|
||||
case CDC_DEVICE_DISCONNECTED:
|
||||
s_usb_connect_type = USB_CONNECTED_UNKNOWN;
|
||||
SYS_LOG_INF("CDC device disconnected");
|
||||
sblib_send_event(LIB_EVENT_USBH_UNKNOW_DEVICE, 0, NULL);
|
||||
break;
|
||||
case DFU_DEVICE_CONNECTED:
|
||||
s_usb_connect_type = USB_CONNECTED_DFU;
|
||||
SYS_LOG_INF("DFU device connected");
|
||||
sblib_send_event(LIB_EVENT_USBH_DFU, 0, NULL);
|
||||
break;
|
||||
case DFU_DEVICE_DISCONNECTED:
|
||||
s_usb_connect_type = USB_CONNECTED_UNKNOWN;
|
||||
SYS_LOG_INF("DFU device disconnected");
|
||||
sblib_send_event(LIB_EVENT_USBH_UNKNOW_DEVICE, 0, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -133,20 +150,26 @@ static void handle_usb_events(void *args)
|
||||
while (1)
|
||||
{
|
||||
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);
|
||||
// Release devices once all clients has deregistered
|
||||
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS)
|
||||
{
|
||||
SYS_LOG_INF("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
|
||||
// can be deinitialized, and terminate this task.
|
||||
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
|
||||
{
|
||||
xSemaphoreGive(ready_to_uninstall_usb);
|
||||
}
|
||||
// if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
|
||||
// {
|
||||
// SYS_LOG_INF("xSemaphoreGive(ready_to_uninstall_usb);");
|
||||
// xSemaphoreGive(ready_to_uninstall_usb);
|
||||
// }
|
||||
}
|
||||
|
||||
s_usb_task_handle = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
@@ -308,6 +331,7 @@ static void handle_device_events(void *args)
|
||||
msc_host_event_t app_event;
|
||||
while (1)
|
||||
{
|
||||
SYS_LOG_INF("xQueueReceive(app_queue, &app_event, portMAX_DELAY);");
|
||||
xQueueReceive(app_queue, &app_event, portMAX_DELAY);
|
||||
|
||||
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)
|
||||
{
|
||||
s_is_started = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _usbhost_stop(sb_data_port_t *port)
|
||||
{
|
||||
s_is_started = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -705,8 +732,11 @@ static sb_data_port_vtable_t const usbhost_port_vtable = {
|
||||
|
||||
//////////// STM32固件升级相关的函数结束 //////////////
|
||||
|
||||
// static TaskHandle_t s_usb_task_handle, s_device_task_handle; //, workthread_handle;
|
||||
|
||||
int usbport_init(void)
|
||||
{
|
||||
SYS_LOG_INF("usbport_init");
|
||||
if (s_port.vtable)
|
||||
{
|
||||
SYS_LOG_WRN("repeated initialize");
|
||||
@@ -716,26 +746,33 @@ int usbport_init(void)
|
||||
s_port.vtable = &usbhost_port_vtable;
|
||||
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));
|
||||
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));
|
||||
assert(app_queue);
|
||||
|
||||
static usb_host_config_t const host_config = {
|
||||
// .skip_phy_setup = false,
|
||||
.skip_phy_setup = false,
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
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);
|
||||
assert(usb_task_handle);
|
||||
xTaskCreatePinnedToCore(handle_device_events, "device_events", 4096, NULL, SBTASK_PRIORITY_USB_DEVICE, &device_task_handle, SBTASK_CORE_INDEX_USB_DEVICE);
|
||||
assert(device_task_handle);
|
||||
if (s_usb_task_handle == NULL)
|
||||
{
|
||||
xTaskCreatePinnedToCore(handle_usb_events, "usb_events", 4096, NULL, SBTASK_PRIORITY_USB_HOST, &s_usb_task_handle, SBTASK_CORE_INDEX_USB_HOST);
|
||||
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 = {
|
||||
.create_backround_task = true,
|
||||
@@ -748,6 +785,70 @@ int usbport_init(void)
|
||||
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)
|
||||
{
|
||||
if (s_port.data == NULL)
|
||||
@@ -764,6 +865,21 @@ sb_data_port_t *usbport_bind(os_work_t *rx_resume_work)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
usb_connect_type_t usbport_get_usb_type(void)
|
||||
{
|
||||
return s_usb_connect_type;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,10 @@ typedef struct
|
||||
#pragma pack(pop)
|
||||
|
||||
int usbport_init(void);
|
||||
void usbport_deinit(void);
|
||||
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);
|
||||
|
||||
// 读取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_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);
|
||||
|
||||
@@ -2,7 +2,13 @@ config LED_STRIP_MAX_LEDS
|
||||
depends on CAP_LED_STRIP
|
||||
int "最大灯珠数"
|
||||
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
|
||||
depends on CAP_LED_STRIP
|
||||
@@ -10,4 +16,22 @@ config LED_STRIP_DEFAULT_LEDS
|
||||
range 1 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
|
||||
|
||||
|
||||
194
app/lib-out/spbelib_interface.h
Normal file
194
app/lib-out/spbelib_interface.h
Normal 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);
|
||||
@@ -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}
|
||||
)
|
||||
11
components/system/CMakeLists.txt
Normal file
11
components/system/CMakeLists.txt
Normal 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}
|
||||
)
|
||||
@@ -21,6 +21,15 @@ void drv_misc_busy_wait(unsigned us);
|
||||
*/
|
||||
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 设置中断向量地址
|
||||
*
|
||||
|
||||
@@ -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_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);
|
||||
|
||||
int drv_pwm_irq_callback_enable(hal_id_t id, tim_isr_cb_fn cb);
|
||||
|
||||
@@ -40,9 +40,10 @@ typedef k_pipe_t kk_pipe_t;
|
||||
#define kk_work_q_delete() k_work_q_delete(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_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_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_submit(work_q_handle, work_handle, delay) k_work_submit(work_q_handle, work_handle, delay) // 多少时间后唤醒任务
|
||||
|
||||
#define kk_work_is_valid(work_handle) k_work_is_valid(work_handle) // 获取任务对象是否有效
|
||||
#define kk_work_is_pending(work_handle) k_work_is_pending(work_handle) // 获取任务是否在就绪或延时的状态
|
||||
|
||||
@@ -469,43 +469,40 @@ static void _find_and_run_key(sh_t *sh_hdl, char c)
|
||||
*/
|
||||
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);
|
||||
if (len > remain)
|
||||
{
|
||||
len = remain;
|
||||
}
|
||||
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)
|
||||
{
|
||||
len = remain;
|
||||
}
|
||||
_apply_history(sh_hdl);
|
||||
if (sh_hdl->cmd_stored < remain)
|
||||
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);
|
||||
}
|
||||
|
||||
for (int i = sh_hdl->cmd_stored - 1 + len; i > sh_hdl->cmd_input; i--) /* 使光标之后的数据往后移动 len 个字节 */
|
||||
{
|
||||
sh_hdl->cmd_buf[i] = sh_hdl->cmd_buf[i - len];
|
||||
}
|
||||
for (int i = sh_hdl->cmd_stored - 1 + len; i > sh_hdl->cmd_input; i--) /* 使光标之后的数据往后移动 len 个字节 */
|
||||
{
|
||||
sh_hdl->cmd_buf[i] = sh_hdl->cmd_buf[i - len];
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sh_hdl->cmd_buf[sh_hdl->cmd_input + i] = str[i];
|
||||
}
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sh_hdl->cmd_buf[sh_hdl->cmd_input + i] = str[i];
|
||||
}
|
||||
|
||||
sh_hdl->cmd_input += len;
|
||||
sh_hdl->cmd_stored += len;
|
||||
sh_hdl->sync_cursor += len;
|
||||
sh_hdl->cmd_input += len;
|
||||
sh_hdl->cmd_stored += len;
|
||||
sh_hdl->sync_cursor += len;
|
||||
|
||||
sh_hdl->cmd_buf[sh_hdl->cmd_stored] = '\0';
|
||||
sh_hdl->cmd_buf[sh_hdl->cmd_stored] = '\0';
|
||||
|
||||
/* 启用刷新命令行模式 */
|
||||
if (sh_hdl->port.clear_line)
|
||||
{
|
||||
sh_refresh_line(sh_hdl);
|
||||
}
|
||||
/* 启用刷新命令行模式 */
|
||||
if (sh_hdl->port.clear_line)
|
||||
{
|
||||
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;
|
||||
bool end = false;
|
||||
*argc = 0;
|
||||
while (end == false && *argc < CONFIG_SH_MAX_PARAM)
|
||||
while (*src != '\0' && end == false && *argc < CONFIG_SH_MAX_PARAM)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
@@ -2763,6 +2760,7 @@ void sh_ctrl_print_cmd_line(sh_t *sh_hdl)
|
||||
sh_echo(sh_hdl, line);
|
||||
|
||||
sh_hdl->cmd_input = strlen(line);
|
||||
sh_hdl->cmd_stored = sh_hdl->cmd_input;
|
||||
sh_hdl->sync_cursor = sh_hdl->cmd_input;
|
||||
_update_cursor(sh_hdl);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 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_BOOTLOADER_LOG_LEVEL_WARN=y
|
||||
@@ -8,11 +8,10 @@ CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_BOARD_NAME_DEVKIT_ESP32S3=y
|
||||
CONFIG_BUILD_WIFI=y
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1=y
|
||||
CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR=y
|
||||
CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR=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_SLEEP_POWER_DOWN_FLASH=y
|
||||
CONFIG_ESP_IPC_TASK_STACK_SIZE=1536
|
||||
|
||||
@@ -12,7 +12,7 @@ CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1=y
|
||||
CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR=y
|
||||
CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR=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_SLEEP_POWER_DOWN_FLASH=y
|
||||
CONFIG_ESP_IPC_TASK_STACK_SIZE=1536
|
||||
|
||||
Reference in New Issue
Block a user