Files
chrg/apps/chrg/applications/thread/chrg_north.c
T
wrh 25b378775d chore: 关闭部分调试打印并更新充电负载配置
1.  修改apps/chrg/applications/thread/chrg_north.c,注释掉调试日志打印,同时将DEBUG_NORTH宏默认值改为0关闭该调试开关
2.  修改rt-thread/components/fal/src/fal_rtt.c,注释掉flash读写对比的调试打印
3.  更新apps/chrg/applications/utils/chrg_sink.c的负载控制逻辑,新增短路测试保持时间配置,调整寄存器下发数组长度和初始化参数
2026-07-21 15:48:16 +08:00

752 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/****************************************************************************
文件名称 : chrg_north.c
完成日期 :
当前版本号 : V1.0
主要功能 : 实现北向通信交互,包括接收命令解析,发送请求命令,切换通路。以独立线程处理。
版本历史 : 创建原始版本
说明 :
******************************************************************************/
#include <string.h>
#include <stdlib.h>
#include <rtthread.h>
#include "chrg_eload.h"
#include "chrg_gpio.h"
#include "chrg_thread.h"
#include "chrg_north_pkg.h"
#include "chrg_north.h"
#include "chrg_roll_nor.h"
#include "chrg_switch.h"
#include "chrg_utils.h"
#include "ulog.h"
#include "chrg_rel.h"
//#define LOG_TAG "chrg.nor"
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
rt_uint16_t volt;
uint16_t chrg_compare(rt_int16_t a, rt_int16_t b)
{
if(a>b) return a - b;
else return b - a;
}
/*****************************************************************
函数名称: chrg_source_stop
功能描述: 南向功率源停止流程控制函数(分步执行停止操作)
函数描述: 通过状态机分步执行南向功率停止流程:停止功率输出 -> 关闭北向继电器 -> 清空控制标志并禁用使能
输入参数:
frame_data :原始数据帧指针,用于提取当前电压值
pSW :北向通道控制结构体指针
idx :通道编号(功率通道/北向通道索引)
enable :北向通道使能,停止后关掉使能
返回说明: 无返回值
*****************************************************************/
void chrg_source_stop(rt_uint8_t *frame_data,struct chrg_switch_t *pSW,rt_uint8_t idx,rt_uint8_t *enable){
switch(pSW->source.Stop_step_flag){
case 0: // 停止工作
chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_STOP);
rt_thread_mdelay(50);
rt_uint16_t volt_mv_Now = (frame_data[4] << 8) | frame_data[5];
volt = volt_mv_Now;
if(volt_mv_Now < 1000){
pSW->source.Stop_step_flag = 1;
}
break;
case 1: // 关闭北向继电器
chrg_nor_sw_rel((eIDX_NOR_CH)idx,0);
rt_thread_mdelay(50);
pSW->source.Stop_step_flag = 2;
break;
case 2: // 状态2:已执行完停止操作,清空标志位
pSW->source.Set_CV_Flag = 0;
*enable = 0;
break;
default:
break;
}
}
/*****************************************************************
函数名称: chrg_source_standard_output
功能描述: 南向功率源标准输出控制函数
函数描述: 根据CV标志位,分别设置电源输出电压或输出电流,实现标准模式下的恒压/恒流输出
输入参数:
idx :功率通道编号
pSW :北向通道控制结构体指针,包含电压/电流设定值、CV控制标志等参数
输出参数:
pSW :更新CV控制标志位
返回说明: 无返回值
*****************************************************************/
void chrg_source_standard_output(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
if(pSW->source.Set_CV_Flag) {
chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_VOLTAGE_OUT+1, pSW->source.max_vol);
#if DEBUG_NORTH
rt_kprintf("Volt_Set%d\r\n",pSW->source.vc.set_voltage);
#endif
pSW->source.Set_CV_Flag = 1;
pSW->change_flag = 0;
}
// if(pSW->source.Set_CV_Flag==0){
// chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_CURRENT_OUT+1, pSW->source.max_vol);
//#if DEBUG_NORTH
// rt_kprintf("Curr_set%d\r\n",Curr_mA);
//#endif
// pSW->source.Set_CV_Flag = 0;
// }
}
//电源快充
void chrg_source_fast_output(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
struct chrg_rollsou_t *pROLL = &chrgrollsou;
rt_uint16_t volt_mv = (frame_data[8] << 8) | frame_data[9];
rt_uint16_t Curr_mA = (frame_data[10] << 8) | frame_data[11];
rt_uint16_t volt_mv_Now = (frame_data[4] << 8) | frame_data[5];
rt_uint16_t Curr_mA_Now = (frame_data[6] << 8) | frame_data[7];
rt_uint16_t volt_compare = chrg_compare(volt_mv, volt_mv_Now);
rt_uint16_t Curr_compare = chrg_compare(Curr_mA, Curr_mA_Now);
static rt_uint8_t number = 0;
#if LCD_OPEN
// rt_kprintf("volt_mv=%d,volt_mv_Now=%d,compare=%d\r\n",volt_mv,volt_mv_Now,volt_compare);
if(volt_compare<5000){ //比较设定值与实际值差距,小于2V认为达成设定,允许屏幕开始变换
number++;
number = number%10;
if(number == 9)
{
pSW->change_flag = 0;
}
}else { //没有达成设定,屏幕不允许变换
pSW->change_flag = 0x01;
}
#endif
// if(volt_mv_Now==0){
// chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_START);
// }
// else{
if (pSW->source.Set_CV_Flag == 0){
{
chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_VOLTAGE_OUT+1, volt_mv);
}
pSW->source.Set_CV_Flag = 1;
#if DEBUG_NORTH
rt_kprintf("Volt_Set%d\r\n",volt_mv);
#endif
}
else if(pSW->source.Set_CV_Flag==1){
chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_START);
pSW->source.Set_CV_Flag = 0;
}else{
pSW->source.Set_CV_Flag=0;
}
}
//电源设置
void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
//执行输出调整
if (pSW->source.On_Flag == 1) {
if(pSW->source.protocol==0x00){//标准下输出设定值
chrg_source_standard_output(idx, pSW);
}
else{ //快充部分按协商结果输出
chrg_source_fast_output(frame_data, idx, pSW, pNOR);
// rt_kprintf("set_end\r\n");
}
}else if(pSW->source.On_Flag == 0){
//chrg_source_stop(frame_data,pSW,idx,&pNOR->enable[idx]);
pSW->sub = IDX_SET_SOURCE_STOP_STATE;
}
}
////解析负载返回数据
//void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
// struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
//{
// rt_uint16_t volt_mv = ((frame_data[4] << 8) | frame_data[5])*10;
// static uint8_t volt_low[TOTAL_SOU_CHS] = {0};
// static uint8_t no_curr[TOTAL_SOU_CHS] = {0};
// pSW->VZ = ((frame_data[14] << 8) | frame_data[15]);
// pSW->VF = ((frame_data[16] << 8) | frame_data[17]);
//#if DEBUG_NORTH
// LOG_D("Sink[%d] real volt: %d mV", idx, volt_mv);
//#endif
//
// if(pSW->sink.On_work == 1) {
// if(pSW->sink.test.test_mode == 0){
// if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
// volt_low[idx]++;
// //if(volt_low[idx]>=5) pSW->sink.work_mode = SINK_WORK_LOW; // 复位工作状态机
// }
// else{ // 电压稳定时执行工作状态机(继电器/工作模式切换)
// volt_low[idx] = 0;
// pSW->change_flag = 0;
// if((pSW->sink.pro_loadv - volt_mv) <= 2000){
// pSW->sink.work_mode = SINK_WORK_RUNING;
// if(pSW->Now_current<=200){
// if(no_curr[idx]++>=5){
// pSW->sink.work_mode = SINK_WORK_WAIT;
// no_curr[idx] = 0;
// }
// }
// else no_curr[idx] = 0;
// }
// }
// }
// }
// else{
// volt_low[idx] = 0;
//// pSW->sink.work_mode = SINK_WORK_STOP;
// }
// chrg_sink_work(idx,pSW);
//}
//解析负载返回数据
void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
rt_uint16_t volt_mv = ((frame_data[4] << 8) | frame_data[5]) * 10;
static rt_uint8_t volt_low[TOTAL_SOU_CHS] = {0};
static rt_uint8_t no_curr[TOTAL_SOU_CHS] = {0};
static rt_uint8_t volt_set_ok[TOTAL_SOU_CHS] = {0};
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return;
}
pSW->VZ = ((frame_data[14] << 8) | frame_data[15]);
pSW->VF = ((frame_data[16] << 8) | frame_data[17]);
#if DEBUG_NORTH
// LOG_D("Sink[%d] real volt: %d mV", idx, volt_mv);
#endif
if(pSW->sink.On_work == 1 && pSW->sink.test.test_mode == 0) {
if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
// volt_low[idx]++;
/* Treat low voltage as a fault only after voltage was once valid. */
if (volt_set_ok[idx] == 1) {
if (++volt_low[idx] >= 3) {
volt_set_ok[idx] = 0;
no_curr[idx] = 0;
pSW->sink.work_mode = SINK_WORK_LOW;
}
}
// if(volt_low[idx]>=5) pSW->sink.work_on_step = SINK_WORK_LOW; // 复位工作状态机
}
else{ // 电压稳定时执行工作状态机(继电器/工作模式切换)
volt_low[idx] = 0;
volt_set_ok[idx] = 1;
pSW->change_flag = 0;
/* Avoid unsigned underflow when actual voltage is above target. */
if ((rt_uint32_t)volt_mv + 2000 >= pSW->sink.pro_loadv) {
pSW->sink.work_mode = SINK_WORK_RUNING;
/* Voltage is normal but current is still zero: retry from WAIT. */
if (pSW->Now_current <= 200) {
if (++no_curr[idx] >= 3) {
pSW->sink.work_mode = SINK_WORK_WAIT;
no_curr[idx] = 0;
}
}
else {
no_curr[idx] = 0;
}
} else {
no_curr[idx] = 0;
}
}
}
else{
volt_low[idx] = 0;
no_curr[idx] = 0;
volt_set_ok[idx] = 0;
// pSW->sink.work_on_step = SINK_WORK_STOP; // 复位工作状态机
}
chrg_sink_work(idx,pSW);
}
/*****************************************************************
函数名称: chrg_north_handle_Seting_Volt
功能描述: 处理设置电压/电流命令,解析命令数据并执行相应操作
****************************************************/
rt_uint8_t change_number = 0;
static void chrg_north_handle_Seting_Volt(rt_uint8_t *frame_data, rt_uint16_t frame_len)
{
// 提取电压/电流值
struct chrg_north_t *pNOR = &chrgnorth;
rt_uint16_t idx = pNOR->idx;
struct chrg_switch_t *pSW = &chrgnorth.sw[idx];
static uint8_t number = 0;
//电源部分
if(pSW->id==ID_SOURCE){
chrg_source_setting(frame_data,(eIDX_SOU_CH)idx, pSW, pNOR);
}
else{
chrg_sink_parse(frame_data,(eIDX_SOU_CH)idx, pSW, pNOR);
}
}
struct chrg_north_t chrgnorth = {
.devname = DEV_NAME_NORTH, // 设备名
.tty = RT_NULL, // 串口句柄初始为空
.enable = {1, 0, 0, 0}, // 4个通道使能初始关闭
.free_flag = 1,
// 通道1IDX_NOR_CH1)初始化
.sw[IDX_NOR_CH1] = {
.CV_mode = 2,
.change_flag = 0,
.show_step = 0,
.sub = IDX_GET_SINK_VC,
.id = ID_SINK, // 初始为负载模式
.source = { // 电源侧参数初始化
.On_Flag = 0, // 启动标志初始关闭
.Set_CV_Flag = 1, // 启停控制初始置1
.Set_Pro_Flag = 1 // 电压/电流切换初始置1
}, // 关键:补充逗号分隔source和sink
.sink = {
.protocol = 0xFE,
.work_mode= SINK_WORK_WAIT,
.test.test_mode_old = 0,
}
},
// 通道2IDX_NOR_CH2)初始化
.sw[IDX_NOR_CH2] = {
.show_step = 0,
.id = ID_SINK,
.CV_mode = 2,
.change_flag = 0,
.source = {
.On_Flag = 0,
.Set_CV_Flag = 1,
.Set_Pro_Flag = 1
},
.sink = {
.protocol = 0xFE,
.work_mode= SINK_WORK_WAIT,
.test.test_mode_old = 0,
}
},
// 通道3IDX_NOR_CH3)初始化
.sw[IDX_NOR_CH3] = {
.show_step = 0,
.CV_mode = 2,
.id = ID_SINK,
.change_flag = 0,
.source = {
.On_Flag = 0,
.Set_CV_Flag = 1,
.Set_Pro_Flag = 1
},
.sink = {
.protocol = 0xFE,
.work_mode= SINK_WORK_WAIT,
.test.test_mode_old = 0,
}
},
// 通道4IDX_NOR_CH4)初始化
.sw[IDX_NOR_CH4] = {
.show_step = 0,
.CV_mode = 2,
.id = ID_SINK,
.change_flag = 0,
.source = {
.On_Flag = 0,
.Set_CV_Flag = 1,
.Set_Pro_Flag = 1
},
.sink = {
.protocol = 0xFE,
.work_mode= SINK_WORK_WAIT,
.test.test_mode_old = 0,
}
}
};
/*****************************************************************
函数名称: chrg_north_switch
函数描述: 北向通道选择
输入参数: ch: 北向通道
输出参数: -
返回说明: <0: 错误
其它说明: -
*****************************************************************/
int chrg_north_switch (eIDX_NOR_CH ch)
{
if (ch >= TOTAL_NOR_CHS) {
return -1;
}
return chrg_switch_ch(chrgios[IDX_GPO_NOR_SW_A].base,
chrgios[IDX_GPO_NOR_SW_B].base, (eIDX_CH)ch);
}
/*****************************************************************
函数名称: chrg_north_send
函数描述: 北向通道数据发送
输入参数: *data: 数据 length: 数据长度
输出参数: -
返回说明: <0: 错误 >0:发送数据长度
其它说明: -
*****************************************************************/
int chrg_north_send (rt_uint8_t *data, rt_size_t length)
{
rt_ssize_t ret = -1;
struct chrg_tty_t *pTTY = chrgnorth.tty;
if (RT_NULL != pTTY) {
#if DEBUG_NORTH //是否打印
LOG_HEX("sendN", 32, data, length);
#endif
ret = chrg_tty_send(pTTY, data, length);
}
return ret;
}
/*****************************************************************
函数名称: chrg_north_frame_head
函数描述: 北向通道数据帧头提取
输入参数: *rb: 缓冲区 *head: 帧头 id:编号
输出参数: -
返回说明: <0: 错误 >0:帧长度
其它说明: 提取3字节帧头
*****************************************************************/
static int chrg_north_frame_head (struct rt_ringbuffer *rb, rt_uint8_t *head, eIDX_ID id)
{
int i = 0;
rt_uint8_t data = 0, stage = 0;
rt_size_t ret = 0;
rt_size_t len_rb = 0; // ring数据长度
rt_uint8_t len_frame = 0; // 帧长度
if (RT_NULL == rb) {
rt_kprintf("len_rb=NULL%d\r\n",len_rb);
return -1;
}
len_rb = rt_ringbuffer_data_len(rb);
if (len_rb < LEN_FRAME_HEAD) {
return 0;
}
for (i = 0; i < len_rb - 2; i++) { // 找头三个字节 [帧长, 0x00, id]
ret = rt_ringbuffer_getchar(rb, &data);
if (0 == ret) {
continue;
}
switch (stage) {
case 0:
head[0] = data;
len_frame = data;
if (data < MIN_FRAME_LENGTH) { // 长度不符
stage = 0;
continue;
}
stage = 1;
break;
case 1:
head[1] = data;
if (0x00 != data) {
stage = 0;
} else {
stage = 2;
}
break;
case 2:
head[2] = data;
if ((rt_uint8_t)id != data) {
stage = 0;
} else {
// if (id == ID_SINK) {
// rt_uint8_t ext1, ext2;
// // 主动读取并丢弃2字节扩展字段
// rt_ringbuffer_getchar(rb, &ext1);
// rt_ringbuffer_getchar(rb, &ext2);
// rt_kprintf("Sink:%02X %02X\r\n", ext1, ext2);
// }
return len_frame;
}
break;
default:
break;
}
}
return -1;
}
/*****************************************************************
函数名称: chrg_north_pickup_frame
函数描述: 北向通道数据帧提取
输入参数: *rb: 缓冲区 *pFrame: 数据帧 idx:通道
输出参数: -
返回说明: <0: 错误 >0:帧长度
其它说明: -
*****************************************************************/
int a_number;
#define NORTH_FRAME_TIMEOUT_MS 100
static void chrg_north_frame_reset(struct pickup_info_t *pFrame, rt_bool_t release)
{
if (RT_NULL == pFrame) {
return;
}
if (release && (RT_NULL != pFrame->pMB)) {
if (RT_NULL != pFrame->pMB->payload) {
rt_free(pFrame->pMB->payload);
}
rt_free(pFrame->pMB);
}
pFrame->last_tick = 0;
pFrame->length = 0;
pFrame->findhead = 0;
pFrame->len_msg = 0;
pFrame->pMB = RT_NULL;
}
static int chrg_north_frame_append(struct rt_ringbuffer *rb,
struct pickup_info_t *pFrame)
{
rt_size_t remaining;
rt_size_t copied;
if ((RT_NULL == rb)||(RT_NULL == pFrame)||(RT_NULL == pFrame->pMB)||
(RT_NULL == pFrame->pMB->payload)||(pFrame->len_msg <= 0)||
(pFrame->length > (rt_size_t)pFrame->len_msg)) {
return -1;
}
remaining = (rt_size_t)pFrame->len_msg - pFrame->length;
if (0 == remaining) {
return 1;
}
copied = rt_ringbuffer_data_len(rb);
if (copied > remaining) {
copied = remaining;
}
if (copied > 0) {
copied = rt_ringbuffer_get(rb,
&pFrame->pMB->payload[pFrame->length], copied);
pFrame->length += copied;
pFrame->last_tick = rt_tick_get();
}
return (pFrame->length == (rt_size_t)pFrame->len_msg) ? 1 : 0;
}
static void chrg_north_frame_dispatch(struct pickup_info_t *pFrame)
{
struct mb_msg_t *pMB = pFrame->pMB;
if (pMB->length == 21) {
chrg_north_handle_Seting_Volt(pMB->payload, pMB->length);
}
chrg_north_frame_reset(pFrame, RT_FALSE);
chrg_thread_mb_send(IDX_THR_NORTH, pMB);
}
static int chrg_north_pickup_frame (struct rt_ringbuffer *rb,
struct pickup_info_t *pFrame, eIDX_NOR_CH idx)
{
int cnt = 0;
int status = 0;
rt_size_t len_rb = 0;
if ((RT_NULL == rb)||(RT_NULL == pFrame)) {
return -1;
}
struct chrg_switch_t *pSW = &chrgnorth.sw[idx];
//rt_kprintf("north_idx=%d\r\n",idx);
do {
if (0 == pFrame->findhead) {
//pFrame->len_msg = chrg_north_frame_head(pSW->id,rb, pFrame->head, pSW->id);
pFrame->len_msg = chrg_north_frame_head(rb, pFrame->head, pSW->id);
// rt_kprintf("msg=:%d",pFrame->len_msg);
if (pFrame->len_msg > 0) {
if ((pFrame->len_msg < LEN_FRAME_HEAD)||
(pFrame->len_msg >= SIZE_BUF_TTY)) {
LOG_E("invalid msg length: %d", pFrame->len_msg);
chrg_north_frame_reset(pFrame, RT_TRUE);
return -3;
}
pFrame->pMB = (struct mb_msg_t *)rt_malloc(sizeof(struct mb_msg_t));
if (RT_NULL == pFrame->pMB) {
LOG_E("malloc mb failed.");
chrg_north_frame_reset(pFrame, RT_FALSE);
return -2;
}
pFrame->pMB->length = pFrame->len_msg;
pFrame->pMB->payload = RT_NULL;
pFrame->pMB->payload = (rt_uint8_t *)rt_malloc(pFrame->len_msg);
if (RT_NULL == pFrame->pMB->payload) {
LOG_E("malloc buf failed.");
chrg_north_frame_reset(pFrame, RT_TRUE);
return -4;
}
rt_memcpy(pFrame->pMB->payload, pFrame->head, LEN_FRAME_HEAD);
pFrame->length = LEN_FRAME_HEAD;
pFrame->findhead = 1;
pFrame->last_tick = rt_tick_get();
status = chrg_north_frame_append(rb, pFrame);
if (status > 0) {
chrg_north_frame_dispatch(pFrame);
cnt++;
} else if (status < 0) {
chrg_north_frame_reset(pFrame, RT_TRUE);
return -5;
} else {
break;
}
}
} else {
status = chrg_north_frame_append(rb, pFrame);
if (status > 0) {
chrg_north_frame_dispatch(pFrame);
cnt++;
} else if (status < 0) {
chrg_north_frame_reset(pFrame, RT_TRUE);
return -5;
} else {
break;
}
}
len_rb = rt_ringbuffer_data_len(rb);
} while (len_rb >= LEN_FRAME_HEAD);
return cnt;
}
/*****************************************************************
函数名称: chrg_north_thread_entry
函数描述: 北向通道数据接收线程体
输入参数: *data: 本线程信息
输出参数: -
返回说明: -
其它说明: -
*****************************************************************/
void chrg_north_thread_entry (void *data)
{
struct chrg_thread_t *pTHR = (struct chrg_thread_t *)data;
if (RT_NULL == pTHR) {
return ;
}
int len = 0;
rt_size_t put_len = 0;
struct chrg_tty_t *pTTY = RT_NULL;
struct chrg_north_t *pNOR = &chrgnorth;
//北向协议板线程体通道初始化为CH1,
chrg_north_switch(IDX_NOR_CH1);
pTTY = chrg_tty_create(pNOR->devname, 230400, 0, -1, 1);
if (RT_NULL == pTTY) {
LOG_E("tty can't create.");
return ;
}
chrg_tty_set_recv_tmo(pTTY, 10);
if (chrg_tty_connect(pTTY) != RT_EOK) {
chrg_tty_destory(pTTY);
return ;
}
pNOR->tty = pTTY;
pNOR->rb = rt_ringbuffer_create(SIZE_BUF_TTY*2);
if (RT_NULL == pNOR->rb) {
LOG_E("create rb '%s' failed.", pNOR->devname);
return ;
}
while (1) {
if (pNOR->frame.findhead &&
((rt_tick_t)(rt_tick_get() - pNOR->frame.last_tick) >=
rt_tick_from_millisecond(NORTH_FRAME_TIMEOUT_MS))) {
chrg_north_frame_reset(&pNOR->frame, RT_TRUE);
LOG_W("partial frame timeout");
}
rt_memset(pNOR->rx_buf, 0, sizeof(pNOR->rx_buf));
len = chrg_tty_recv(pTTY, pNOR->rx_buf, sizeof(pNOR->rx_buf));
if (len <= 0) {
rt_thread_mdelay(1);
continue;
}
put_len = rt_ringbuffer_put(pNOR->rb, pNOR->rx_buf, len);
if (put_len != (rt_size_t)len) {
LOG_E("north ringbuffer overflow: recv=%d put=%d", len, put_len);
rt_ringbuffer_reset(pNOR->rb);
chrg_north_frame_reset(&pNOR->frame, RT_TRUE);
continue;
}
#if DEBUG_NORTH
LOG_HEX("recvN", 32, pNOR->rx_buf, len);
#endif
chrg_north_pickup_frame(pNOR->rb, &pNOR->frame, pNOR->idx);
}
}
#if 1
static int north_ch(rt_uint8_t argc, char **argv)
{
int ret = 0;
if (2 != argc) {
rt_kprintf("help : %s [0-3]\r\n", argv[0]);
return -1;
}
ret = chrg_north_switch((eIDX_NOR_CH)atoi(argv[1]));
return ret;
}
MSH_CMD_EXPORT(north_ch, north channel select);
static int north_diag(int argc, char **argv)
{
rt_uint8_t i;
struct chrg_north_t *pNOR = &chrgnorth;
struct chrg_rollnor_t *pROLL = &chrgrollnor;
rt_kprintf("roll: run=%d idx=%d ch=%d type=%d sub=%d\r\n",
pROLL->run, pROLL->idx, pROLL->ch, pROLL->type, pROLL->sub);
rt_kprintf("rx: rb_len=%d findhead=%d frame_len=%d received=%d\r\n",
pNOR->rb ? rt_ringbuffer_data_len(pNOR->rb) : 0,
pNOR->frame.findhead, pNOR->frame.len_msg, pNOR->frame.length);
for (i = 0; i < TOTAL_NOR_CHS; i++) {
rt_kprintf("ch%d: enable=%d id=%d sub=%d\r\n", i,
pNOR->enable[i], pNOR->sw[i].id, pNOR->sw[i].sub);
}
return 0;
}
MSH_CMD_EXPORT(north_diag, show north polling and frame state);
#endif