Files
2025-12-03 11:12:34 +08:00

401 lines
10 KiB
C

#include "asm/cpu.h"
#include "asm/power_interface.h"
#include "system/includes.h"
#include "os/os_api.h"
#include "power/p11_cbuf.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".p11_cbuf.data.bss")
#pragma data_seg(".p11_cbuf.data")
#pragma const_seg(".p11_cbuf.text.const")
#pragma code_seg(".p11_cbuf.text")
#endif
static spinlock_t cbuf_lock;
#define p11_cbuf_spin_lock() spin_lock(&cbuf_lock)
#define p11_cbuf_spin_unlock() spin_unlock(&cbuf_lock)
#define CBUF_ENTER_CRITICAL() \
do{ \
p11_cbuf_spin_lock(); \
ipc_spin_lock(IPC_SPIN_LOCK_EVENT_CBUF);\
}while(0)
#define CBUF_EXIT_CRITICAL() \
do{ \
ipc_spin_unlock(IPC_SPIN_LOCK_EVENT_CBUF);\
p11_cbuf_spin_unlock(); \
}while(0)
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief cbuffer 通道开关
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] index 通道索引
* @param [in] enable 通道开关
*/
/* ----------------------------------------------------------------------------*/
void p11cbuf_mult_entry_enable(p11_cbuffer_t *cbuffer, int index, int enable)
{
if (!cbuffer) {
return;
}
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
if ((!cbuffer->child_count) || index >= cbuffer->child_count) {
return;
}
if (!cbuffer->child) {
return;
}
cbuffer_child_t *child;
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
CBUF_ENTER_CRITICAL();
if (!enable) { //关操作时候需要释放空间
child[index].en = !!enable;
child[index].offset = 0;
u32 min_offset = (u32) - 1;
for (int i = 0; i < cbuffer->child_count; i++) {
if (child[i].en && child[i].offset < min_offset) {
min_offset = child[i].offset;
}
}
for (int i = 0; i < cbuffer->child_count; i++) {
if (child[i].en) {
child[i].offset -= min_offset;
}
}
if (min_offset > cbuffer->data_len) {
min_offset = cbuffer->data_len;
}
cbuffer->tmp_len = cbuffer->data_len -= min_offset;
cbuffer->read_ptr += min_offset;
if ((u32)cbuffer->read_ptr >= (u32)cbuffer->end) {
cbuffer->read_ptr = (u8 *)cbuffer->begin + ((u32)cbuffer->read_ptr - (u32)cbuffer->end);
}
} else {
child[index].en = !!enable;
child[index].offset = 0;
}
CBUF_EXIT_CRITICAL();
}
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 获取存储数据的字节长度
*
* @param [in] cbuffer cbuffer 句柄
*
* @return 存储数据的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 p11_cbuf_get_data_len(p11_cbuffer_t *cbuffer)
{
if (!cbuffer) {
return 0;
}
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
return cbuffer->data_len;
}
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 获取存储数据的字节长度
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] index 当前通道的索引
* @return 存储数据的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 p11_cbuf_mult_read_get_data_len(p11_cbuffer_t *cbuffer, int index)
{
u32 len;
if (!cbuffer) {
return 0;
}
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
if (index >= cbuffer->child_count) {
return 0;
}
CBUF_ENTER_CRITICAL();
cbuffer_child_t *child;
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
if (child[index].en) {
len = cbuffer->data_len - child[index].offset;
} else {
len = 0;
}
CBUF_EXIT_CRITICAL();
return len;
}
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:memcpy管理+cbuf_read_alloc系列管理函数
* @brief 预分配待读取数据的空间,并把读取到的数据存入buf数组
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] index 当前通道的索引
* @param [out] buf 存储读取的数据的目标buf数组
* @param [in] len 要读取的数据的字节长度
*
* @return
*/
/* ----------------------------------------------------------------------------*/
u32 p11_cbuf_mult_read_alloc_len(p11_cbuffer_t *cbuffer, int index, void *buf, u32 len)
{
u32 r_len = len;
u32 copy_len;
u8 *read_ptr;
if (!cbuffer) {
return 0;
}
if (buf == NULL) {
printf("ERROR :%s %d buff is NULL!!!\n", __func__, __LINE__);
return 0;
}
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
if ((!cbuffer->child_count) || index >= cbuffer->child_count) {
return 0;
}
if (!cbuffer->child) {
return 0;
}
CBUF_ENTER_CRITICAL();
cbuffer_child_t *child;
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
if (!child[index].en) {
CBUF_EXIT_CRITICAL();
return 0;
}
read_ptr = cbuffer->read_ptr + child[index].offset;
if ((u32) read_ptr >= (u32)cbuffer->end) {
read_ptr = (u8 *)cbuffer->begin + ((u32)read_ptr - (u32)cbuffer->end);
}
if (cbuffer->data_len - child[index].offset < len) {
memset(buf, 0, len);
CBUF_EXIT_CRITICAL();
return 0;
}
copy_len = (u32)cbuffer->end - (u32)read_ptr;
if (copy_len > len) {
copy_len = len;
}
len -= copy_len;
memcpy(buf, read_ptr + P11_RAM_BASE, copy_len);
if (len == 0) {
/* cbuffer->read_ptr += copy_len; */
} else {
memcpy((u8 *)buf + copy_len, cbuffer->begin + P11_RAM_BASE, len);
}
CBUF_EXIT_CRITICAL();
return r_len;
}
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:memcpy管理+cbuf_read_alloc系列管理函数
* @brief 更新cbuf管理handle的读指针位置和数据长度
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] index 当前通道的索引
* @param [in] len 要更新的数据的字节长度
*/
/* ----------------------------------------------------------------------------*/
void p11_cbuf_mult_read_alloc_len_updata(p11_cbuffer_t *cbuffer, int index, u32 len)
{
if (!cbuffer) {
return ;
}
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
if ((!cbuffer->child_count) || index >= cbuffer->child_count) {
return ;
}
if (!cbuffer->child) {
return ;
}
CBUF_ENTER_CRITICAL();
cbuffer_child_t *child;
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
if (!child[index].en) {
CBUF_EXIT_CRITICAL();
return;
}
if (len + child[index].offset > cbuffer->data_len) {
len = cbuffer->data_len - child[index].offset;
}
child[index].offset += len;
u32 min_offset = (u32) - 1;
for (int i = 0; i < cbuffer->child_count; i++) {
if (child[i].en && child[i].offset < min_offset) {
min_offset = child[i].offset;
}
}
for (int i = 0; i < cbuffer->child_count; i++) {
if (child[i].en) {
child[i].offset -= min_offset;
}
}
if (min_offset > cbuffer->data_len) {
ASSERT(0);
/* min_offset = cbuffer->data_len; */
}
cbuffer->tmp_len = cbuffer->data_len -= min_offset;
cbuffer->read_ptr += min_offset;
if ((u32)cbuffer->read_ptr >= (u32)cbuffer->end) {
cbuffer->read_ptr = (u8 *)cbuffer->begin + ((u32)cbuffer->read_ptr - (u32)cbuffer->end);
}
CBUF_EXIT_CRITICAL();
}
#define P11_CBUF_TEST 0
#include "p11_app_msg.h"
#if P11_CBUF_TEST
static p11_cbuffer_t *cbuffer;
static void master_read_p11(void *p)
{
static int index_1;
static int index_2;
static int index_3;
u8 test[50];
int len = p11_cbuf_mult_read_alloc_len(cbuffer, 0, test, 10);
if (len) {
p11_cbuf_mult_read_alloc_len_updata(cbuffer, 0, len);
printf("index 0 read len %d ,left %d,total %d\n", len, p11_cbuf_mult_read_get_data_len(cbuffer, 0), p11_cbuf_get_data_len(cbuffer));
put_buf(test, len);
index_1 += len;
if (index_1 == 50) {
p11cbuf_mult_entry_enable(cbuffer, 1, 0);
printf("stop index 1\n");
}
if (index_1 == 100) {
p11cbuf_mult_entry_enable(cbuffer, 1, 1);
printf("open index 1\n");
}
}
printf("%s %d %x\n", __func__, __LINE__, (int)cbuffer);
len = p11_cbuf_mult_read_alloc_len(cbuffer, 1, test, 25);
if (len) {
p11_cbuf_mult_read_alloc_len_updata(cbuffer, 1, len);
printf("index 1 read len %d ,left %d,total %d\n", len, p11_cbuf_mult_read_get_data_len(cbuffer, 1), p11_cbuf_get_data_len(cbuffer));
put_buf(test, len);
}
len = p11_cbuf_mult_read_alloc_len(cbuffer, 2, test, 5);
if (len) {
p11_cbuf_mult_read_alloc_len_updata(cbuffer, 2, len);
printf("index 2 read len %d ,left %d,total %d\n", len, p11_cbuf_mult_read_get_data_len(cbuffer, 2), p11_cbuf_get_data_len(cbuffer));
put_buf(test, len);
}
task_post_msg2p11(NULL, 1, MSG_P11_SYS_KICK);
}
static void test_handler(void *priv, u8 *buf, u32 len)
{
if (buf == NULL) {
printf("ERROR :%s %d buff is NULL!!!\n", __func__, __LINE__);
return;
}
int msg[16];
printf("msg: %d, len: %d\n", msg[0], len);
ASSERT(len < sizeof(msg));
memcpy(msg, buf, len);
switch (msg[0]) {
case MSG_P11_SYS_RAM_INIT:
printf("MSG_P11_SYS_RAM_INIT %x\n", msg[1]);
cbuffer = (p11_cbuffer_t *)msg[1];
sys_timer_add(NULL, master_read_p11, 1000);
break;
}
}
REGISTER_P2M_MSG_HANDLER(NULL, MSG_APP, test_handler);
#endif