project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp: Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem. sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately. sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades. sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for fastboot. Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
175 lines
5.4 KiB
C
175 lines
5.4 KiB
C
/*
|
|
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include <stdint.h>
|
|
|
|
#include <rthw.h>
|
|
#include <rtthread.h>
|
|
#include <rtdevice.h>
|
|
|
|
#if defined(RT_USING_RPMSG_CMD)
|
|
|
|
#include "rpmsg_cmd.h"
|
|
|
|
static void *rpmsg_cmd_table_callback_find(uint32_t cmd, struct rpmsg_cmd_table_t *table, uint32_t size)
|
|
{
|
|
uint32_t i;
|
|
|
|
for (i = 0; i < size; i++)
|
|
{
|
|
if (table[i].cmd == cmd)
|
|
{
|
|
return (void *)(table[i].callback);
|
|
}
|
|
}
|
|
|
|
return RT_NULL;
|
|
}
|
|
|
|
rt_err_t rpmsg_cmd_send(struct rpmsg_cmd_data_t *p_rpmsg_data, uint32_t timeout)
|
|
{
|
|
int32_t ret;
|
|
|
|
RT_ASSERT(p_rpmsg_data);
|
|
RT_ASSERT(p_rpmsg_data->handle);
|
|
|
|
struct rpmsg_cmd_head_t *head = &p_rpmsg_data->head;
|
|
struct rpmsg_ept_handle_t *handle = p_rpmsg_data->handle;
|
|
|
|
#ifdef PRIMARY_CPU
|
|
ret = rpmsg_lite_send(handle->instance, handle->ept,
|
|
EPT_M2R_ADDR(handle->endpoint),
|
|
head, sizeof(struct rpmsg_cmd_head_t),
|
|
timeout);
|
|
#else
|
|
ret = rpmsg_lite_send(handle->instance, handle->ept,
|
|
EPT_R2M_ADDR(handle->endpoint),
|
|
head, sizeof(struct rpmsg_cmd_head_t),
|
|
timeout);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int32_t rpmsg_ept_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv)
|
|
{
|
|
struct rpmsg_cmd_data_t rpmsg_data;
|
|
struct rpmsg_cmd_head_t *head = &rpmsg_data.head;
|
|
struct rpmsg_ept_handle_t *handle = (struct rpmsg_ept_handle_t *)priv;
|
|
|
|
RT_ASSERT(payload_len == sizeof(struct rpmsg_cmd_head_t));
|
|
|
|
/* Get payload data */
|
|
rt_memcpy(head, payload, sizeof(struct rpmsg_cmd_data_t));
|
|
|
|
/* Copy priv & src to rpmsg_data */
|
|
rpmsg_data.handle = handle;
|
|
rpmsg_data.endpoint = src;
|
|
|
|
if (head->type == RPMSG_TYPE_DIRECT)
|
|
{
|
|
void (*callback)(void *param);
|
|
callback = rpmsg_cmd_table_callback_find(head->cmd, handle->cmd_table, handle->cmd_counter);
|
|
if (callback) {
|
|
callback(&rpmsg_data);
|
|
}
|
|
}
|
|
else if (head->type == RPMSG_TYPE_URGENT)
|
|
{
|
|
rt_mq_urgent(handle->mq, &rpmsg_data, sizeof(struct rpmsg_cmd_data_t));
|
|
}
|
|
else
|
|
{
|
|
rt_mq_send(handle->mq, &rpmsg_data, sizeof(struct rpmsg_cmd_data_t));
|
|
}
|
|
|
|
return RL_RELEASE;
|
|
}
|
|
|
|
static void rpmsg_cmd_ept_thread(void *arg)
|
|
{
|
|
struct rpmsg_ept_handle_t *handle = (struct rpmsg_ept_handle_t *)arg;
|
|
struct rpmsg_cmd_data_t rpmsg_data;
|
|
|
|
while (1)
|
|
{
|
|
if (rt_mq_recv(handle->mq, &rpmsg_data, sizeof(struct rpmsg_cmd_data_t), RT_WAITING_FOREVER) == RT_EOK)
|
|
{
|
|
struct rpmsg_cmd_head_t *head = &rpmsg_data.head;
|
|
void (*callback)(void *param);
|
|
callback = rpmsg_cmd_table_callback_find(head->cmd, handle->cmd_table, handle->cmd_counter);
|
|
if (callback) {
|
|
callback(&rpmsg_data);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void rpmsg_cmd_ept_init(struct rpmsg_ept_handle_t *handle,
|
|
uint32_t master_id, uint32_t remote_id, uint32_t endpoint,
|
|
struct rpmsg_cmd_table_t *cmd_table, uint32_t cmd_counter,
|
|
uint32_t stack_size, uint32_t priority)
|
|
{
|
|
char name[32];
|
|
RT_ASSERT(handle);
|
|
|
|
handle->master_id = master_id;
|
|
handle->remote_id = remote_id;
|
|
handle->endpoint = endpoint;
|
|
handle->cmd_table = cmd_table;
|
|
handle->cmd_counter = cmd_counter;
|
|
|
|
snprintf(name, sizeof(name), "rpmsg_cmd_%1d_%1d_%3d", handle->master_id, handle->remote_id, handle->endpoint);
|
|
|
|
#ifdef PRIMARY_CPU
|
|
handle->instance = rpmsg_master_get_instance(handle->master_id, handle->remote_id);
|
|
#else
|
|
handle->instance = rpmsg_remote_get_instance(handle->master_id, handle->remote_id);
|
|
#endif
|
|
RT_ASSERT(handle->instance);
|
|
|
|
handle->ept = rpmsg_lite_create_ept(handle->instance, handle->endpoint, rpmsg_ept_cb, handle);
|
|
RT_ASSERT(handle->ept);
|
|
|
|
handle->mq = rt_mq_create(name, sizeof(struct rpmsg_cmd_data_t), RPMSG_MQ_MAX, RT_IPC_FLAG_FIFO);
|
|
RT_ASSERT(handle->mq);
|
|
|
|
handle->thread = rt_thread_create(name, rpmsg_cmd_ept_thread, handle,
|
|
stack_size, priority, 10);
|
|
RT_ASSERT(handle->thread);
|
|
rt_thread_startup(handle->thread);
|
|
}
|
|
|
|
void rpmsg_cmd_ept_thread_init(struct rpmsg_ept_handle_t *handle,
|
|
uint32_t stack_size, uint32_t priority)
|
|
{
|
|
char name[32];
|
|
RT_ASSERT(handle);
|
|
RT_ASSERT(handle->master_id == MASTER_ID);
|
|
RT_ASSERT(handle->remote_id != MASTER_ID);
|
|
RT_ASSERT(handle->remote_id <= REMOTE_ID_3);
|
|
|
|
snprintf(name, sizeof(name), "rpmsg_cmd_%1d_%1d_%3d", handle->master_id, handle->remote_id, handle->endpoint);
|
|
|
|
#ifdef PRIMARY_CPU
|
|
handle->instance = rpmsg_master_get_instance(handle->master_id, handle->remote_id);
|
|
#else
|
|
handle->instance = rpmsg_remote_get_instance(handle->master_id, handle->remote_id);
|
|
#endif
|
|
RT_ASSERT(handle->instance);
|
|
|
|
handle->ept = rpmsg_lite_create_ept(handle->instance, handle->endpoint, rpmsg_ept_cb, handle);
|
|
RT_ASSERT(handle->ept);
|
|
|
|
handle->mq = rt_mq_create(name, sizeof(struct rpmsg_cmd_data_t), RPMSG_MQ_MAX, RT_IPC_FLAG_FIFO);
|
|
RT_ASSERT(handle->mq);
|
|
|
|
handle->thread = rt_thread_create(name, rpmsg_cmd_ept_thread, handle,
|
|
stack_size, priority, 10);
|
|
RT_ASSERT(handle->thread);
|
|
rt_thread_startup(handle->thread);
|
|
}
|
|
#endif // RT_USING_RPMSG_LITE
|