1. 新增sqlite文件、协议文档、调试截图、配置ini等各类辅助文件 2. 更新Keil开发包版本与工程配置,调整编译优化等级 3. 重构继电器控制逻辑、串口收发逻辑与线程优先级 4. 新增Modbus寄存器映射、校准结构体与Ymodem升级相关代码 5. 完善南北向协议解析、快充挡位配置与调试日志 6. 修复注释格式、数组越界与线程邮箱溢出问题 7. 新增屏幕控制、功率板调试与协议格式说明文档
875 lines
23 KiB
C
875 lines
23 KiB
C
/****************************************************************************
|
||
文件名称 : chrg_roll_nor.c
|
||
完成日期 :
|
||
当前版本号 : V1.0
|
||
主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。
|
||
版本历史 : 创建原始版本
|
||
说明 :
|
||
******************************************************************************/
|
||
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <rtthread.h>
|
||
|
||
#include "chrg_gpio.h"
|
||
#include "chrg_led.h"
|
||
#include "chrg_thread.h"
|
||
#include "chrg_sink.h"
|
||
#include "chrg_source.h"
|
||
#include "chrg_roll_nor.h"
|
||
#include "chrg_north.h"
|
||
#include "chrg_switch.h"
|
||
#include "chrg_utils.h"
|
||
#include "chrg_rel.h"
|
||
#include "chrg_wdt.h"
|
||
#define LOG_TAG "chrg.rollnor"
|
||
#include <rtdbg.h>
|
||
const rt_base_t sw_uart[TOTAL_NOR_CHS] = {
|
||
IDX_GPO_UART_SW1,
|
||
IDX_GPO_UART_SW2,
|
||
IDX_GPO_UART_SW3,
|
||
IDX_GPO_UART_SW4
|
||
};
|
||
|
||
struct chrg_rollnor_t chrgrollnor = {
|
||
.run = RUN_CONSOLE, // RUN_AUTO,
|
||
.ch = IDX_NOR_CH1,
|
||
// .Set_Role = ID_SINK,
|
||
// .group = 0,
|
||
};
|
||
/*****************************************************************
|
||
函数名称: sink_fill_pd_buf
|
||
函数描述: 根据快充协议类型填充PD指令的5字节数据缓冲区
|
||
输入参数:
|
||
pd_val: 快充协议类型(如0xC1/0xF8/0xFB等)
|
||
pd_volt: 电压值(mV,16位)
|
||
pd_curr: 电流值(mA,16位)
|
||
buf: 输出缓冲区
|
||
输出参数: buf: 填充后的5字节协议数据
|
||
返回说明: 0:成功 -1:参数错误
|
||
*****************************************************************/
|
||
int sink_fill_pd_buf(rt_uint8_t group,rt_uint8_t pd_val, rt_uint16_t pd_volt, rt_uint16_t pd_curr,rt_uint8_t *buf)
|
||
{
|
||
// 参数合法性校验
|
||
if (buf == RT_NULL) {
|
||
rt_kprintf("sink_fill_pd_buf: buf is a null pointer!\n");
|
||
return -1;
|
||
}
|
||
|
||
// 先清空缓冲区(默认全0)
|
||
rt_memset(buf, 0, 5);
|
||
|
||
// 按协议类型填充buf
|
||
switch(pd_val) {
|
||
// 标准/QC2.0/QC3.0/FCP(仅电压,第五位=电压)
|
||
case 0xFE: // 标准协议
|
||
case 0xF8: // QC2.0协议
|
||
case 0xF6: // QC3.0协议
|
||
case 0xF2: // FCP协议
|
||
buf[0] = pd_volt / 100; // 第5字节=电压(0.1V)
|
||
buf[1] = pd_curr / 100; // 第6字节=电流(0.1A)
|
||
#if PRO_TEST_DEBUG
|
||
rt_kprintf("type: %02X, Voltage(0.1V)=%d\n", pd_val, pd_volt/100);
|
||
rt_kprintf("type: %02x, Curr(0.1A)=%d\n",pd_curr,pd_curr/100);
|
||
#endif
|
||
break;
|
||
|
||
// PDO/PPS/PD3.1/UFCS/AVS(组号+电压+电流)
|
||
case 0xFC: // PPS手动/自动
|
||
case 0xE3: // AVS协议
|
||
buf[0] = group; // 第5字节=组号(默认0)
|
||
buf[1] = (pd_volt >> 8) & 0xFF; // 第6字节=电压高8位(mV)
|
||
buf[2] = pd_volt & 0xFF; // 第7字节=电压低8位(mV)
|
||
buf[3] = (pd_curr >> 8) & 0xFF; // 第8字节=电流高8位(mA)
|
||
buf[4] = pd_curr & 0xFF; // 第9字节=电流低8位(mA)
|
||
#if PRO_TEST_DEBUG
|
||
rt_kprintf("type: %02X, Group=0, Voltage=%d mV, Current=%d mA\n", pd_val, pd_volt, pd_curr);
|
||
#endif
|
||
break;
|
||
case 0xE0: // UFCS协议
|
||
case 0xE1: // PD3.1协议
|
||
case 0xFB: // PDO手动
|
||
|
||
buf[0] = 0x00; // 第5字节=组号(默认0)
|
||
buf[1] = (pd_volt >> 8) & 0xFF; // 第6字节=电压高8位(mV)
|
||
buf[2] = pd_volt & 0xFF; // 第7字节=电压低8位(mV)
|
||
buf[3] = (pd_curr >> 8) & 0xFF; // 第8字节=电流高8位(mA)
|
||
buf[4] = pd_curr & 0xFF; // 第9字节=电流低8位(mA)
|
||
#if PRO_TEST_DEBUG
|
||
rt_kprintf("type: %02X, Group=0, Voltage=%d mV, Current=%d mA\n", pd_val, pd_volt, pd_curr);
|
||
#endif
|
||
break;
|
||
|
||
// SCP/VIVO/传音(电压+电流)
|
||
case 0xF3: // SCP协议
|
||
case 0xFD: // VIVO协议
|
||
case 0xF7: // 传音/TFC协议
|
||
buf[0] = (pd_volt >> 8) & 0xFF; // 第6字节=电压高8位(mV)
|
||
buf[1] = pd_volt & 0xFF; // 第7字节=电压低8位(mV)
|
||
buf[2] = (pd_curr >> 8) & 0xFF; // 第8字节=电流高8位(mA)
|
||
buf[3] = pd_curr & 0xFF; // 第9字节=电流低8位(mA)
|
||
buf[4] = 0;
|
||
#if PRO_TEST_DEBUG
|
||
rt_kprintf("type: %02X, Voltage=%d mV, Current=%d mA\n", pd_val, pd_volt, pd_curr);
|
||
#endif
|
||
break;
|
||
|
||
// VOOC(无参数)
|
||
case 0xE2: // VOOC协议
|
||
#if PRO_TEST_DEBUG
|
||
rt_kprintf("type: VOOC(0xE2), No parameters\n");
|
||
#endif
|
||
break;
|
||
|
||
case 0xF9: // AFC协议
|
||
{
|
||
// 1. 电压转HEX
|
||
rt_uint8_t volt_hex = 0;
|
||
if (pd_volt >= 5000 && pd_volt <= 20000) { // 电压范围:5V(5000mV)~20V(20000mV)
|
||
rt_uint8_t volt_v = pd_volt / 1000; // 转成V(5000mV→5V)
|
||
volt_hex = volt_v - 5; // 5V对应0,20V对应15(0xF)
|
||
} else {
|
||
#if PRO_TEST_DEBUG
|
||
rt_kprintf("AFC VOLT ERROR VOLT=:%d mV Set 5000~20000\n", pd_volt);
|
||
#endif
|
||
return -1;
|
||
}
|
||
|
||
// 2. 电流转HEX
|
||
rt_uint8_t curr_hex = 0;
|
||
if (pd_curr >= 750 && pd_curr <= 3000) { // 电流范围:0.75A(750mA)~3.0A(3000mA)
|
||
rt_uint16_t curr_ma_step = (pd_curr - 750) / 150; // 步长150mA(0.75→1.5→...→3.0)
|
||
curr_hex = curr_ma_step; // 0.75A对应0,3.0A对应15(0xF)
|
||
rt_kprintf("curr_ma_step = %d",curr_ma_step);
|
||
} else {
|
||
#if PRO_TEST_DEBUG
|
||
rt_kprintf("AFC CURR ERROR%d mA SET 750~3000 \n", pd_curr);
|
||
#endif
|
||
return -1;
|
||
}
|
||
|
||
// 3. 合并电压Hex(高4位)和电流Hex(低4位)→ 填充第五字节
|
||
buf[0] = (volt_hex << 4) | curr_hex;
|
||
rt_kprintf("type: AFC(0xF9), Voltage=%d V, Current=%.2f A, volaue=0x%X\n",
|
||
pd_volt/1000, pd_curr/1000.0, buf[0]);
|
||
}
|
||
break;
|
||
// 未知类型
|
||
default:
|
||
// rt_kprintf("Unknown fast charge type: %02X, Parameters cleared\n", pd_val);
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
rt_uint16_t v1=0,v2=0;
|
||
|
||
|
||
//电源关闭
|
||
void chrg_nor_source_stop(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);
|
||
pSW->source.Stop_step_flag = 1;
|
||
break;
|
||
case 1: // 停止工作
|
||
chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_STOP);
|
||
pSW->source.Stop_step_flag = 2;
|
||
break;
|
||
case 2: // 关闭北向继电器
|
||
chrg_nor_sw_rel((eIDX_NOR_CH)idx,0);
|
||
pSW->source.Stop_step_flag = 3;
|
||
break;
|
||
case 3: // 状态2:已执行完停止操作,清空标志位
|
||
pSW->source.Set_CV_Flag = 0;
|
||
if(pSW->source.change_sink_Flag == 1){
|
||
pSW->source.change_sink_Flag = 0;
|
||
// chrg_com_sink_on(idx,pSW,enable);
|
||
}else{
|
||
*enable = 0;
|
||
}
|
||
break;
|
||
default:
|
||
pSW->source.Stop_step_flag = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*****************************************************************
|
||
函数名称: chrg_roll_nor_sw_uart
|
||
函数描述: 北向通道切换 sink/source 串口
|
||
输入参数: ch: 通道 id: sink/source
|
||
输出参数: -
|
||
返回说明: -
|
||
其它说明: -
|
||
*****************************************************************/
|
||
static void chrg_roll_nor_sw_uart (eIDX_NOR_CH ch, eIDX_ID id)
|
||
{
|
||
if (ch >= TOTAL_NOR_CHS) {
|
||
return ;
|
||
}
|
||
|
||
if (ID_SOURCE == id) {
|
||
rt_pin_write(chrgios[sw_uart[ch]].base, PIN_HIGH);
|
||
} else if (ID_SINK == id) {
|
||
rt_pin_write(chrgios[sw_uart[ch]].base, PIN_LOW);
|
||
}
|
||
|
||
}
|
||
|
||
//设置负载协议
|
||
void chrg_roll_nor_sink_pro_set(struct chrg_switch_t *pSW)
|
||
{
|
||
rt_uint8_t buf[6] = {0};
|
||
sink_fill_pd_buf(pSW->sink.Pro_Group,pSW->sink.protocol,pSW->sink.pro_loadv,pSW->sink.pro_loadc,buf);
|
||
sink_set_pd(pSW->sink.protocol,buf);
|
||
#if DEBUG_NORTH
|
||
rt_kprintf("set_pro\r\n");
|
||
#endif
|
||
}
|
||
|
||
//设置电源协议
|
||
void chrg_roll_nor_source_pro_set(struct chrg_switch_t *pSW){
|
||
if(pSW->source.Set_Pro_Flag == 1){
|
||
pSW->source.Set_Pro_Flag = 0;
|
||
if(pSW->source.LCD_Set_Pro_Flag==1){
|
||
source_set_pd(pSW->source.protocol,0,0,pSW->source.vc.set_voltage,0,pSW->source.vc.set_current);
|
||
}
|
||
else if(pSW->source.LCD_Set_Pro_Flag==2){
|
||
source_set_pd_com(pSW->source.protocol,pSW->source.pro_gear_idx);
|
||
}
|
||
else if(pSW->source.LCD_Set_Pro_Flag==3){
|
||
source_set_pd_new_com(pSW->source.protocol,pSW);
|
||
}
|
||
}else {
|
||
pSW->sub = IDX_GET_SOURCE_VC;
|
||
}
|
||
}
|
||
static int chrg_roll_nor_parse (struct chrg_rollnor_t *pROLL, rt_uint8_t *data)
|
||
{
|
||
if ((RT_NULL == pROLL)||(RT_NULL == data)) {
|
||
return -1;
|
||
}
|
||
chrg_north_switch(IDX_NOR_CH1);
|
||
// 读取北向全局结构体中当前通道的Source/Sink参数
|
||
struct chrg_switch_t *pSW = &chrgnorth.sw[pROLL->ch];
|
||
if (1 == pROLL->type) {
|
||
switch (pROLL->sub) {
|
||
case IDX_GET_SOURCE_VC: {
|
||
|
||
}
|
||
break;
|
||
|
||
case IDX_GET_SOURCE_PD: {
|
||
|
||
}
|
||
break;
|
||
|
||
case IDX_SET_SOURCE_PD: {
|
||
|
||
}
|
||
break;
|
||
|
||
case IDX_SET_SOURCE_CCLVL: {
|
||
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return -1;
|
||
break;
|
||
}
|
||
|
||
} else if (0 == pROLL->type) {
|
||
chrg_roll_nor_sw_uart(IDX_NOR_CH1,ID_SINK);
|
||
switch (pROLL->sub) {
|
||
case IDX_GET_SINK_VC: {
|
||
sink_get_vc(pSW->sink.pro_loadv,pSW->sink.pro_loadc);
|
||
}
|
||
break;
|
||
|
||
case IDX_GET_SINK_PD: {
|
||
|
||
}
|
||
break;
|
||
|
||
case IDX_SET_SINK_PD: {
|
||
|
||
}
|
||
break;
|
||
|
||
case IDX_SET_SINK_CCLINE: {
|
||
|
||
}
|
||
break;
|
||
|
||
case IDX_SET_SINK_CCLVL: {
|
||
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return -1;
|
||
}
|
||
} else {
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
static int chrg_roll_nor_cmd (struct chrg_rollnor_t *pROLL)
|
||
{
|
||
if (RT_NULL == pROLL) {
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
void chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW,rt_uint8_t *enable)
|
||
{
|
||
if(pSW->id==ID_SOURCE){ //电源
|
||
chrg_roll_nor_sw_uart((eIDX_NOR_CH)ch, ID_SOURCE);
|
||
switch(pSW->sub){
|
||
case IDX_SET_SOURCE_ID: //角色
|
||
chrg_set_eload_source(ch,pSW);
|
||
if(pSW->continue_flag)
|
||
pSW->sub = IDX_SET_SOURCE_CC_SET;
|
||
// rt_kprintf("set_start\r\n");
|
||
break;
|
||
case IDX_SET_SOURCE_CC_SET:
|
||
source_set_cc_choose(pSW->source.cc_set);
|
||
pSW->sub = IDX_SET_SOURCE_CV;
|
||
break;
|
||
case IDX_SET_SOURCE_CV: //恒压恒流
|
||
pSW->sub = IDX_SER_SOURCE_VOLT;
|
||
break;
|
||
case IDX_SER_SOURCE_VOLT://电压
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_VOLTAGE_OUT+1, 0);
|
||
pSW->sub = IDX_SER_SOURCE_CURR;
|
||
break;
|
||
case IDX_SER_SOURCE_CURR://电流
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_CURRENT_OUT+1, pSW->source.protective_curr);
|
||
pSW->sub = IDX_SET_SOURCE_WORK;
|
||
break;
|
||
case IDX_SET_SOURCE_WORK:
|
||
chrg_sou_work(ch,pSW);
|
||
break;
|
||
case IDX_SET_SOURCE_PD:
|
||
chrg_roll_nor_source_pro_set(pSW);
|
||
pSW->source.On_Flag = 1;
|
||
break;
|
||
case IDX_GET_SOURCE_VC:
|
||
source_get_vc(pSW->source.vc.set_voltage, pSW->source.vc.set_current);
|
||
break;
|
||
case IDX_SET_SOURCE_CCLVL:
|
||
source_set_cc_lvl(pSW->source.vol_lvl);
|
||
break;
|
||
case IDX_SET_SOURCE_STOP_STATE:
|
||
chrg_nor_source_stop(pSW,ch,enable);
|
||
break;
|
||
default:
|
||
|
||
break;
|
||
}
|
||
}else{
|
||
chrg_roll_nor_sw_uart((eIDX_NOR_CH)ch, ID_SINK);
|
||
switch(pSW->sub){
|
||
case IDX_GET_SINK_VC: //查询
|
||
sink_get_vc(pSW->sink.pro_loadv,pSW->sink.pro_loadc);
|
||
break;
|
||
case IDX_SET_SINK_CCLINE: //CC线选择
|
||
sink_set_cc_line(pSW->sink.cc_set);
|
||
pSW->sub = IDX_SET_SINK_PD;
|
||
break;
|
||
case IDX_SET_SINK_CCLVL: //CC电平
|
||
sink_set_cc_lvl(pSW->sink.cc_lvl);
|
||
break;
|
||
case IDX_SET_SINK_PD:
|
||
chrg_roll_nor_sink_pro_set(pSW);
|
||
pSW->sub = IDX_GET_SINK_VC;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*****************************************************************
|
||
函数名称: chrg_roll_nor_thread_entry
|
||
函数描述: 北向通道轮巡请求数据线程体
|
||
输入参数: *data: 本线程信息
|
||
输出参数: -
|
||
返回说明: -
|
||
其它说明: -
|
||
*****************************************************************/
|
||
void chrg_roll_nor_thread_entry (void *data)
|
||
{
|
||
struct chrg_thread_t *pTHR = (struct chrg_thread_t *)data;
|
||
|
||
if (RT_NULL == pTHR) {
|
||
return ;
|
||
}
|
||
|
||
rt_uint8_t index = 0, idx = 0, i = 0;
|
||
rt_uint8_t run = 0, crc = 0;
|
||
rt_err_t ret = RT_EOK;
|
||
struct chrg_rollnor_t *pROLL = &chrgrollnor;
|
||
struct chrg_thread_t *pTN = &chrgthr[IDX_THR_NORTH];
|
||
struct chrg_north_t *pNOR = &chrgnorth;
|
||
struct chrg_switch_t *pSW = RT_NULL;
|
||
struct mb_msg_t *pMB_R = RT_NULL;
|
||
for (i = 0; i < TOTAL_NOR_CHS; i++) {
|
||
chrg_roll_nor_sw_uart((eIDX_NOR_CH)i, ID_SINK);
|
||
}
|
||
while (1) {
|
||
chrg_wdt_feed();
|
||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||
run = pROLL->run;
|
||
rt_mutex_release(pTHR->mutex);
|
||
switch (run) {
|
||
case RUN_AUTO: {
|
||
idx = index%TOTAL_NOR_CHS;
|
||
if (0 == pNOR->enable[idx]) {
|
||
index++;
|
||
rt_thread_mdelay(2);
|
||
continue;
|
||
} else {
|
||
chrg_led_flashing(IDX_LED2, TIMES_ONE, PULSE_TIME*2, PULSE_TIME*2);
|
||
chrg_north_switch((eIDX_NOR_CH)idx);
|
||
chrgnorth.idx = idx;
|
||
pROLL->idx = idx;
|
||
pSW = &pNOR->sw[idx];
|
||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||
if(pNOR->north_mode == 0){
|
||
chrg_roll_nor_set(pROLL->idx,pSW,&pNOR->enable[idx]);
|
||
}
|
||
if(pNOR->north_mode == 1){
|
||
chrg_roll_trim_set(pROLL->idx,pNOR);
|
||
}
|
||
rt_mutex_release(pTHR->mutex);
|
||
}
|
||
index++;
|
||
}
|
||
break;
|
||
|
||
case RUN_LCD: {
|
||
chrg_roll_nor_cmd(pROLL);
|
||
}
|
||
break;
|
||
case RUN_CONSOLE: {
|
||
chrg_roll_nor_cmd(pROLL);
|
||
}
|
||
break;
|
||
case RUN_COM:
|
||
// {
|
||
// chrg_roll_nor_cmd(pROLL);
|
||
// }
|
||
break;
|
||
case RUN_NONE:
|
||
default:
|
||
rt_thread_mdelay(5);
|
||
continue;
|
||
break;
|
||
}
|
||
|
||
ret = rt_mb_recv(pTN->mb, (rt_uint32_t *)&pMB_R, 200); // 超时 200ms
|
||
if ((RT_EOK == ret)&&(RT_NULL != pMB_R)) { // 存在返回数据
|
||
crc = calc_crc8(pMB_R->payload, pMB_R->length-1);
|
||
if (crc == pMB_R->payload[pMB_R->length-1]) { // 数据正确
|
||
if (RUN_AUTO != run) { // 恢复自动轮巡
|
||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||
pROLL->run = RUN_AUTO;
|
||
rt_mutex_release(pTHR->mutex);
|
||
} else {
|
||
chrg_roll_nor_parse(pROLL, pMB_R->payload);
|
||
}
|
||
} else {
|
||
LOG_E("crc failed.");
|
||
}
|
||
|
||
if (RT_NULL != pMB_R->payload) {
|
||
rt_free(pMB_R->payload);
|
||
pMB_R->payload = RT_NULL;
|
||
}
|
||
|
||
if (RT_NULL != pMB_R) {
|
||
rt_free(pMB_R);
|
||
pMB_R = RT_NULL;
|
||
}
|
||
|
||
rt_thread_mdelay(20); // 间隔 200ms
|
||
} else {
|
||
if (RUN_AUTO != run) { // 非自动轮巡
|
||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||
//todo
|
||
pROLL->run = RUN_AUTO; // 切换会自动轮巡
|
||
rt_mutex_release(pTHR->mutex);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
#if 1
|
||
|
||
|
||
static int sink (int argc, char **argv)
|
||
{
|
||
int ret = 0;
|
||
if (argc < 4) {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|ccline|cclvl <data>\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
|
||
int gset = 0;
|
||
struct chrg_rollnor_t *pROLL = &chrgrollnor;
|
||
|
||
if (strcmp(argv[1], "get") == 0) {
|
||
gset = 0;
|
||
} else if (strcmp(argv[1], "set") == 0) {
|
||
gset = 1;
|
||
} else {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|ccline|cclvl <data>\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
|
||
rt_uint8_t ch = (rt_uint8_t)atoi(argv[2]);
|
||
if ((ch < 0)||(ch >= TOTAL_NOR_CHS)) {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|ccline|cclvl <data>\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
|
||
if (strcmp(argv[3], "vc") == 0) {
|
||
if (0 == gset) {
|
||
pROLL->sub = IDX_SET_SINK_WORK_STATE;
|
||
} else {
|
||
ret = -1;
|
||
rt_kprintf("sink vc can't set.\r\n");
|
||
return -1;
|
||
}
|
||
} else if (strcmp(argv[3], "pd") == 0) {
|
||
if (0 == gset) {
|
||
pROLL->sub = IDX_GET_SINK_PD;
|
||
} else {
|
||
//长度
|
||
if (argc != 5) {
|
||
rt_kprintf("help : %s set 0-3 ccline 0-3.\r\n", argv[0]);
|
||
return -1;
|
||
// sink_set_pd
|
||
} else { // sink set 0 pd 0
|
||
int type = atoi(argv[4]);
|
||
pROLL->pd = (rt_uint8_t)type;
|
||
pROLL->sub = IDX_SET_SINK_PD;
|
||
}
|
||
}
|
||
} else if (strcmp(argv[3], "ccline") == 0) {
|
||
if (1 == gset) {
|
||
if (argc != 5) {
|
||
rt_kprintf("help : %s set 0-3 ccline 0-3.\r\n", argv[0]);
|
||
return -1;
|
||
} else { // sink set 0 ccline 0-3
|
||
int line = atoi(argv[4]);
|
||
if ((line >= 0)&&(line <= 3)) {
|
||
pROLL->sub = IDX_SET_SINK_CCLINE;
|
||
pROLL->cc_line = (rt_uint8_t)line;
|
||
} else {
|
||
rt_kprintf("help : %s set 0-3 ccline 0-3.\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
}
|
||
} else {
|
||
ret = -1;
|
||
rt_kprintf("sink cc line can't get.\r\n");
|
||
}
|
||
} else if (strcmp(argv[3], "cclvl") == 0) {
|
||
if (1 == gset) {
|
||
if (argc != 5) {
|
||
rt_kprintf("help : %s set 0-3 cclvl 0-3.\r\n", argv[0]);
|
||
return -1;
|
||
} else { // sink set 0 cclvl 0-3
|
||
int line = atoi(argv[4]);
|
||
if ((line >= 0)&&(line <= 3)) {
|
||
pROLL->sub = IDX_SET_SINK_CCLVL;
|
||
pROLL->cc_line = (rt_uint8_t)line;
|
||
} else {
|
||
rt_kprintf("help : %s set 0-3 cclvl 0-3.\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
}
|
||
} else {
|
||
ret = -1;
|
||
rt_kprintf("sink cc level can't get.\r\n");
|
||
}
|
||
} else {
|
||
ret = -1;
|
||
}
|
||
|
||
if (0 == ret) {
|
||
pROLL->ch = ch;
|
||
pROLL->type = 0; // sink
|
||
pROLL->run = RUN_CONSOLE;
|
||
} else {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|ccline|cclvl\r\n", argv[0]);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
MSH_CMD_EXPORT(sink, north sink test);
|
||
|
||
static int source (int argc, char **argv)
|
||
{
|
||
int ret = 0;
|
||
if (argc < 4) {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|cclvl <data>\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
|
||
int gset = 0;
|
||
struct chrg_rollnor_t *pROLL = &chrgrollnor;
|
||
|
||
if (strcmp(argv[1], "get") == 0) {
|
||
gset = 0;
|
||
} else if (strcmp(argv[1], "set") == 0) {
|
||
gset = 1;
|
||
} else {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|cclvl <data>\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
|
||
rt_uint8_t ch = (rt_uint8_t)atoi(argv[2]);
|
||
if ((ch < 0)||(ch >= TOTAL_NOR_CHS)) {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|cclvl <data>\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
|
||
if (strcmp(argv[3], "vc") == 0) {
|
||
if (0 == gset) {
|
||
pROLL->sub = IDX_GET_SOURCE_VC;
|
||
} else {
|
||
ret = -1;
|
||
rt_kprintf("sink vc can't set.\r\n");
|
||
return -1;
|
||
}
|
||
} else if (strcmp(argv[3], "pd") == 0) {
|
||
if (0 == gset) {
|
||
pROLL->sub = IDX_GET_SOURCE_PD;
|
||
} else {
|
||
if (argc != 5) {
|
||
//if (argc != 5) {
|
||
rt_kprintf("help : %s set 0-3 pd 0-.\r\n", argv[0]);
|
||
return -1;
|
||
// sink_set_pd
|
||
} else { // sink set 0 pd 0
|
||
int type = atoi(argv[4]);
|
||
//协议
|
||
pROLL->pd = (rt_uint8_t)type;
|
||
//子命令
|
||
pROLL->sub = IDX_SET_SOURCE_PD;
|
||
}
|
||
}
|
||
} else if (strcmp(argv[3], "cclvl") == 0) {
|
||
if (1 == gset) {
|
||
if (argc != 5) {
|
||
rt_kprintf("help : %s set 0-3 cclvl 0-3.\r\n", argv[0]);
|
||
return -1;
|
||
} else { // sink set 0 cclvl 0-3
|
||
int line = atoi(argv[4]);
|
||
if ((line >= 0)&&(line <= 3)) {
|
||
pROLL->sub = IDX_SET_SOURCE_CCLVL;
|
||
pROLL->cc_line = (rt_uint8_t)line;
|
||
} else {
|
||
rt_kprintf("help : %s set 0-3 cclvl 0-3.\r\n", argv[0]);
|
||
return -1;
|
||
}
|
||
}
|
||
} else {
|
||
ret = -1;
|
||
rt_kprintf("sink cc level can't get.\r\n");
|
||
}
|
||
} else {
|
||
ret = -1;
|
||
}
|
||
|
||
if (0 == ret) {
|
||
pROLL->ch = ch;
|
||
pROLL->type = 1; // source
|
||
pROLL->run = RUN_CONSOLE;
|
||
} else {
|
||
rt_kprintf("help : %s get|set [0-3] vc|pd|cclvl\r\n", argv[0]);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
MSH_CMD_EXPORT(source, north source test);
|
||
|
||
#endif
|
||
|
||
//校准CRC计算
|
||
rt_uint16_t chrg_trim_crc(rt_uint8_t ch, struct chrg_north_t *pNOR)
|
||
{
|
||
struct chrg_trim *pTrim = &pNOR->trim[ch];
|
||
rt_uint8_t buf[22];
|
||
int idx = 0;
|
||
|
||
buf[idx++] = (pTrim->trim_volt_k_H >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_volt_k_H & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_volt_k_L >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_volt_k_L & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_volt_b >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_volt_b & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_curr_k_H >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_curr_k_H & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_curr_k_L >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_curr_k_L & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_curr_b >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_curr_b & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_source_curr_k_H >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_source_curr_k_H & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_source_curr_k_L >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_source_curr_k_L & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_source_curr_b >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_source_curr_b & 0xFF;
|
||
|
||
buf[idx++] = (pTrim->trim_zero >> 8) & 0xFF;
|
||
buf[idx++] = pTrim->trim_zero & 0xFF;
|
||
|
||
return mb_crc16(buf, 20);
|
||
}
|
||
//电源校准设置
|
||
void chrg_trim_set_volt(rt_uint8_t ch,struct chrg_north_t *pNOR){
|
||
struct chrg_trim *pTRIM = &pNOR->trim[ch];
|
||
switch(pTRIM->trim_step){
|
||
case 0:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Volt_CAL_K_H, pTRIM->trim_volt_k_H);
|
||
break;
|
||
case 1:
|
||
break;
|
||
case 2:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Volt_CAL_K_L, pTRIM->trim_volt_k_L);
|
||
break;
|
||
case 3:
|
||
break;
|
||
case 4:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Volt_CAL_B, pTRIM->trim_volt_b);
|
||
break;
|
||
pNOR->north_mode = 0;
|
||
break;
|
||
}
|
||
pTRIM->trim_step++;
|
||
}
|
||
//电流校准设置
|
||
void chrg_trim_set_curr(rt_uint8_t ch,struct chrg_north_t *pNOR){
|
||
struct chrg_trim *pTRIM = &pNOR->trim[ch];
|
||
switch(pTRIM->trim_step){
|
||
case 0:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Current_CAL_K_H, pTRIM->trim_curr_k_H);
|
||
break;
|
||
case 1:
|
||
break;
|
||
case 2:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Current_CAL_K_L, pTRIM->trim_curr_k_L);
|
||
break;
|
||
case 3:
|
||
break;
|
||
case 4:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Current_CAL_B, pTRIM->trim_curr_b);
|
||
pNOR->north_mode = 0;
|
||
break;
|
||
}
|
||
pTRIM->trim_step++;
|
||
}
|
||
//电源校准设置
|
||
void chrg_trim_set_source_curr(rt_uint8_t ch,struct chrg_north_t *pNOR){
|
||
struct chrg_trim *pTRIM = &pNOR->trim[ch];
|
||
rt_uint16_t crc = 0;
|
||
switch(pTRIM->trim_step){
|
||
case 0:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_SourceCurrent_CAL_K_H, pTRIM->trim_source_curr_k_H);
|
||
break;
|
||
case 1:
|
||
break;
|
||
case 2:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_SourceCurrent_CAL_K_L, pTRIM->trim_source_curr_k_L);
|
||
break;
|
||
case 3:
|
||
break;
|
||
case 4:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_SourceCurrent_CAL_B, pTRIM->trim_source_curr_b);
|
||
break;
|
||
case 5:
|
||
break;
|
||
case 6:
|
||
crc = chrg_trim_crc(ch, pNOR);
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Trim_CRC_CAL, crc);
|
||
rt_kprintf("crc=%04X\n",crc);
|
||
break;
|
||
case 7:
|
||
break;
|
||
case 8:
|
||
if(pTRIM->trim_enable_flag == 0){
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteEnable_ADD,ModbusRTU_CAL_WriteValue);
|
||
}else{
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteRecovery,ModbusRTU_CAL_WriteRecovery_Value);
|
||
}
|
||
pNOR->north_mode = 0;
|
||
break;
|
||
}
|
||
pTRIM->trim_step++;
|
||
}
|
||
//校准飘零设置
|
||
void chrg_trim_set_zero(rt_uint8_t ch,struct chrg_north_t *pNOR){
|
||
struct chrg_trim *pTRIM = &pNOR->trim[ch];
|
||
rt_uint16_t crc = 0;
|
||
switch(pTRIM->trim_step){
|
||
case 0:
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Trim_Zero_CAL, pTRIM->trim_zero);
|
||
break;
|
||
case 1:
|
||
break;
|
||
case 2:
|
||
crc = chrg_trim_crc(ch, pNOR);
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Trim_CRC_CAL, crc);
|
||
break;
|
||
case 3:
|
||
break;
|
||
case 4:
|
||
if(pTRIM->trim_enable_flag == 0){
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteEnable_ADD,ModbusRTU_CAL_WriteValue);
|
||
}else{
|
||
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteRecovery,ModbusRTU_CAL_WriteRecovery_Value);
|
||
}
|
||
pNOR->north_mode = 0;
|
||
break;
|
||
}
|
||
pTRIM->trim_step++;
|
||
}
|
||
//校准设置
|
||
void chrg_roll_trim_set(rt_uint8_t ch, struct chrg_north_t *pNOR){
|
||
struct chrg_trim *pTRIM = &pNOR->trim[ch];
|
||
switch(pTRIM->trim_mode){
|
||
case MODE_VOLT_CAL:
|
||
chrg_trim_set_volt(ch, pNOR);
|
||
break;
|
||
case MODE_CURR_CAL:
|
||
chrg_trim_set_curr(ch, pNOR);
|
||
break;
|
||
case MODE_SOURCE_CURR_CAL:
|
||
chrg_trim_set_source_curr(ch, pNOR);
|
||
break;
|
||
case MODE_ZERO_CAL:
|
||
chrg_trim_set_zero(ch, pNOR);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|