feat: 完成项目多模块功能迭代与配置更新
1. 新增sqlite文件、协议文档、调试截图、配置ini等各类辅助文件 2. 更新Keil开发包版本与工程配置,调整编译优化等级 3. 重构继电器控制逻辑、串口收发逻辑与线程优先级 4. 新增Modbus寄存器映射、校准结构体与Ymodem升级相关代码 5. 完善南北向协议解析、快充挡位配置与调试日志 6. 修复注释格式、数组越界与线程邮箱溢出问题 7. 新增屏幕控制、功率板调试与协议格式说明文档
This commit is contained in:
@@ -102,6 +102,15 @@ static void MX_GPIO_Init (void)
|
||||
HAL_GPIO_Init(LED0_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
|
||||
|
||||
/* Configure the MCO1 pin in alternate function mode */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -262,6 +262,11 @@ BSP_UART_ERR BSP_UART_Port_DisableReceive(struct UART_STRUCT *uart)
|
||||
*/
|
||||
BSP_UART_ERR BSP_UART_Port_Send(struct UART_STRUCT *uart, const uint8_t *data, uint16_t len, uint16_t timeout)
|
||||
{
|
||||
// ================================
|
||||
// ?? 485 发送模式:置 1 ??
|
||||
// ================================
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
|
||||
|
||||
_UART_Alternate(uart);
|
||||
|
||||
if (timeout == 0)
|
||||
@@ -272,7 +277,20 @@ BSP_UART_ERR BSP_UART_Port_Send(struct UART_STRUCT *uart, const uint8_t *data,
|
||||
return (BSP_UART_ERR)HAL_UART_Transmit_IT(&uart->handle, (uint8_t *)data, len);
|
||||
}
|
||||
else
|
||||
return (BSP_UART_ERR)HAL_UART_Transmit(&uart->handle, (uint8_t *)data, len, timeout);
|
||||
{
|
||||
// 发送
|
||||
BSP_UART_ERR err = (BSP_UART_ERR)HAL_UART_Transmit(&uart->handle, (uint8_t *)data, len, timeout);
|
||||
|
||||
// 等待发送完成
|
||||
while(__HAL_UART_GET_FLAG(&uart->handle, UART_FLAG_TC) == RESET);
|
||||
|
||||
// ================================
|
||||
// ?? 485 回到接收模式:置 0 ??
|
||||
// ================================
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<TargetCommonOption>
|
||||
<Device>STM32F405RGTx</Device>
|
||||
<Vendor>STMicroelectronics</Vendor>
|
||||
<PackID>Keil.STM32F4xx_DFP.3.1.0</PackID>
|
||||
<PackID>Keil.STM32F4xx_DFP.3.1.1</PackID>
|
||||
<PackURL>https://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
@@ -138,7 +138,7 @@
|
||||
</Flash1>
|
||||
<bUseTDR>1</bUseTDR>
|
||||
<Flash2>BIN\UL2CM3.DLL</Flash2>
|
||||
<Flash3></Flash3>
|
||||
<Flash3>"" ()</Flash3>
|
||||
<Flash4></Flash4>
|
||||
<pFcarmOut></pFcarmOut>
|
||||
<pFcarmGrp></pFcarmGrp>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
|
||||
|
||||
<component name="EventRecorderStub" version="1.0.0"/> <!--name and version of the component-->
|
||||
<events>
|
||||
</events>
|
||||
|
||||
</component_viewer>
|
||||
@@ -37,7 +37,7 @@ void chrg_nor_sw_rel (eIDX_NOR_CH ch, eIDX_ID id)
|
||||
}
|
||||
|
||||
if (ID_SOURCE == id) {
|
||||
rt_pin_write(chrgrel[ch].p2, PIN_LOW);
|
||||
rt_pin_write(chrgrel[ch].p2, PIN_HIGH);//sw置1
|
||||
rt_pin_write(chrgrel[ch].p1, PIN_HIGH);
|
||||
rt_pin_write(chrgrel[ch].p0, PIN_LOW);
|
||||
} else if (ID_SINK == id) {
|
||||
@@ -96,7 +96,7 @@ int rel_test (int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
rt_uint8_t val = (rt_uint8_t)atoi(argv[3]);
|
||||
if ((idx > 2)||(idx < 1)) {
|
||||
if ((idx > 3)||(idx < 0)) {
|
||||
rt_kprintf("help : %s <get|set> <0|1|2|3> [1, 2]", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
@@ -110,6 +110,7 @@ int rel_test (int argc, char **argv)
|
||||
rt_kprintf("rel connect [%d] : sink\r\n", idx);
|
||||
} else if ((0 == data[0])&&(1 == data[1])&&(1 == data[2])) {
|
||||
rt_kprintf("rel connect [%d] : source\r\n", idx);
|
||||
rt_kprintf("rel connect [%d] : p0=%d, p1=%d, p2=%d\r\n",idx, data[0], data[1], data[2]);
|
||||
} else {
|
||||
rt_kprintf("rel connect [%d] : p0=%d, p1=%d, p2=%d\r\n",
|
||||
idx, data[0], data[1], data[2]);
|
||||
|
||||
@@ -32,7 +32,8 @@ extern struct chrg_rel_t chrgrel[TOTAL_NOR_CHS];
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern void chrg_nor_sw_rel (eIDX_NOR_CH ch, eIDX_ID id);
|
||||
|
||||
#define Main_Relay 0x01
|
||||
//#define Filter_Relay
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -485,7 +485,7 @@ int chrg_tty_recv (struct chrg_tty_t *pTTY, void *buf, int size)
|
||||
|
||||
if ((recved & TTY_EVT_RX_BREAK) != 0) {
|
||||
rt_mutex_release(pTTY->lock);
|
||||
rt_thread_delay(2);
|
||||
rt_thread_delay(1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -508,7 +508,6 @@ int chrg_tty_send (struct chrg_tty_t *pTTY, void *buf, int size)
|
||||
{
|
||||
rt_err_t ret = RT_EOK;
|
||||
int send_len = 0;
|
||||
|
||||
if (pTTY == RT_NULL || buf == RT_NULL || size == 0) {
|
||||
LOG_E("param null.");
|
||||
return (-RT_ERROR);
|
||||
@@ -524,13 +523,10 @@ int chrg_tty_send (struct chrg_tty_t *pTTY, void *buf, int size)
|
||||
LOG_E("mutex take failed. [%d]", ret);
|
||||
return (-RT_ERROR);
|
||||
}
|
||||
|
||||
chrg_tty_mode_set(pTTY, 1);//set to send mode
|
||||
send_len = rt_device_write(pTTY->dev, 0, buf, size);
|
||||
chrg_tty_mode_set(pTTY, 0);//set to receive mode
|
||||
|
||||
rt_mutex_release(pTTY->lock);
|
||||
|
||||
return send_len;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,16 +26,15 @@ typedef enum {
|
||||
TOTAL_TTYS
|
||||
} eIDX_TTY;
|
||||
|
||||
|
||||
//#define TTY_USING_DMA_RX //使用DMA接收
|
||||
//#define TTY_USING_DMA_RX 1 //使用DMA接收
|
||||
//#define TTY_USING_INT_TX //使用中断发送
|
||||
//#define TTY_USING_DMA_TX //使用DMA发送
|
||||
//#define TTY_USING_DMA_TX 1 //使用DMA发送
|
||||
|
||||
#ifndef TTY_SW_DLY_US
|
||||
#define TTY_SW_DLY_US 0 // 发送引脚控制切换延时
|
||||
#endif
|
||||
|
||||
#define SIZE_BUF_TTY 256
|
||||
#define SIZE_BUF_TTY 1029
|
||||
|
||||
#define TTY_TX_COMP_TMO_MAX (3 * RT_TICK_PER_SECOND) // 最大DMA传输完成超时
|
||||
#define TTY_BYTE_TMO_MIN 2 // 最小字节超时
|
||||
|
||||
@@ -27,17 +27,18 @@ void show_app_version (void)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
//rt_uint32_t tick = 0;
|
||||
// rt_uint32_t tick = 0;
|
||||
|
||||
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
|
||||
finsh_set_prompt("chrg ");
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
rt_thread_mdelay(1000);
|
||||
chrg_wdt_feed();
|
||||
// chrg_wdt_feed();
|
||||
|
||||
//rt_kprintf("%d\r\n", ++tick);
|
||||
// rt_kprintf("%d\r\n", ++tick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,23 +13,30 @@
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "chrg_tty.h"
|
||||
|
||||
#include "chrg_regs.h"
|
||||
|
||||
#define MODBUS_ADDRESS_DEFAULT 0x01
|
||||
|
||||
#define BITS_UCHAR 8U
|
||||
|
||||
#define S_DISCRETE_INPUT_START 0
|
||||
#define S_DISCRETE_INPUT_NDISCRETES 16
|
||||
#define S_COIL_START 0
|
||||
#define S_COIL_NCOILS 64
|
||||
#define S_REG_INPUT_START 0
|
||||
#define S_REG_INPUT_NREGS 100
|
||||
#define S_REG_HOLDING_START 0
|
||||
#define S_REG_HOLDING_NREGS 100
|
||||
|
||||
#define MB_HANDLERS_MAX (16)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//北向协议设置
|
||||
rt_uint8_t proto_changed;
|
||||
rt_uint8_t group_changed;
|
||||
rt_uint16_t pro_volt_changed;
|
||||
rt_uint16_t pro_curr_changed;
|
||||
//南向功率设置
|
||||
rt_uint8_t volt_changed;
|
||||
rt_uint8_t curr_changed;
|
||||
rt_uint8_t ccset_changed;
|
||||
rt_uint8_t cvmode_changed;
|
||||
} sink_proto_diff_t;
|
||||
static void chrg_sink_get_proto_diff(struct chrg_switch_t *pReal,
|
||||
struct chrg_switch_t *pShadow,
|
||||
sink_proto_diff_t *pDiff,
|
||||
rt_uint8_t *pNoChange);
|
||||
|
||||
typedef enum {
|
||||
MB_REG_READ, /*!< Read register values and pass to protocol stack. */
|
||||
MB_REG_WRITE /*!< Update register values. */
|
||||
@@ -45,20 +52,55 @@ typedef enum {
|
||||
MB_EILLSTATE, /*!< protocol stack in illegal state. */
|
||||
MB_ETIMEDOUT /*!< timeout error occurred. */
|
||||
} eMBErrorCode;
|
||||
// ========== 新寄存器地址映射 (使用0x06/0x10标准Modbus功能码) ==========
|
||||
// 详细寄存器偏移定义见 chrg_regs.h
|
||||
|
||||
#define MB_ADDRESS_BROADCAST (0) // 广播地址
|
||||
#define MB_ADDRESS_MIN (1) // 地址最小值
|
||||
#define MB_ADDRESS_MAX (247) // 地址最大值
|
||||
// 判断寄存器地址属于哪个区块的宏
|
||||
#define REG_IS_SINK(addr) (((addr / 4) < TOTAL_SINK_CH_REGS))
|
||||
#define REG_IS_SRC(addr) (((addr / 4) < TOTAL_SRC_CH_REGS))
|
||||
#define REG_IS_SYS(addr) (((addr / 4) < TOTAL_SYS_CH_REGS))
|
||||
|
||||
#define MB_READ_COILS (0x01) // 读线圈
|
||||
#define MB_READ_DISCRETE_INPUTS (0x02) // 读离散输入
|
||||
#define MB_READ_HOLDING_REGISTER (0x03) // 读保持寄存器
|
||||
#define MB_READ_INPUT_REGISTER (0x04) // 读输入寄存器
|
||||
#define MB_WRITE_SINGLE_COIL (0x05) // 写单个线圈
|
||||
#define MB_WRITE_REGISTER (0x06) // 写单个寄存器
|
||||
#define MB_WRITE_MULTIPLE_COILS (0x0F) // 写多个线圈
|
||||
#define MB_WRITE_MULTIPLE_REGISTERS (0x10) // 写多个寄存器
|
||||
#define MB_FUNC_ERROR (0x80)
|
||||
// 根据地址提取通道号和区块内偏移
|
||||
#define REG_GET_SINK_CH(addr) ((addr) / TOTAL_SINK_CH_REGS)
|
||||
#define REG_GET_SINK_OFFSET(addr) ((addr) % TOTAL_SINK_CH_REGS)
|
||||
#define REG_GET_SRC_CH(addr) ((addr) / TOTAL_SRC_CH_REGS)
|
||||
#define REG_GET_SRC_OFFSET(addr) ((addr) % TOTAL_SRC_CH_REGS)
|
||||
#define REG_GET_SYS_CH(addr) ((addr) / TOTAL_SYS_CH_REGS)
|
||||
#define REG_GET_SYS_OFFSET(addr) ((addr) % TOTAL_SYS_CH_REGS)
|
||||
//继电器偏移量
|
||||
|
||||
// 继电器寄存器偏移量
|
||||
#define MODBUS_COIL_PWR_SRC 0x00 // 功率板-主电源继电器(每通道第0个)
|
||||
#define MODBUS_COIL_PWR_SINK 0x01 // 功率板-主负载继电器(每通道第1个)
|
||||
#define MODBUS_COIL_SINK_CC 0x02 // 协议板-负载CC继电器(每通道第2个)
|
||||
#define MODBUS_COIL_SRC_CC 0x03 // 协议板-电源CC继电器(每通道第3个)
|
||||
// 预留偏移量(对应每通道第4,可后续扩展)
|
||||
#define MODBUS_COIL_PWR_ALL 0x04 // 功率板-俩个继电器
|
||||
#define MODBUS_COIL_RESERVE2 0x05 // 预留继电器2(每通道第5个)
|
||||
|
||||
////复位相关
|
||||
//#define RESET_NORTH_ADDR 0x0F00
|
||||
//#define RESET_NORTH_VALUE 0x5A5A
|
||||
//#define RESET_SOUTH_ADDR 0x0F01
|
||||
|
||||
#define MB_ADDRESS_BROADCAST (0) // 广播地址
|
||||
#define MB_ADDRESS_MIN (1) // 地址最小值
|
||||
#define MB_ADDRESS_MAX (247) // 地址最大值
|
||||
|
||||
// Modbus 标准功能码
|
||||
#define MB_READ_COILS (0x01) // 读线圈
|
||||
#define MB_READ_DISCRETE_INPUTS (0x02) // 读离散输入
|
||||
#define MB_READ_HOLDING_REGISTER (0x03) // 读保持寄存器
|
||||
#define MB_READ_INPUT_REGISTER (0x04) // 读输入寄存器
|
||||
#define MB_WRITE_SINGLE_COIL (0x05) // 写单个线圈
|
||||
#define MB_WRITE_REGISTER (0x06) // 写单个寄存器
|
||||
#define MB_WRITE_MULTIPLE_COILS (0x0F) // 写多个线圈
|
||||
#define MB_WRITE_MULTIPLE_REGISTERS (0x10) // 写多个寄存器
|
||||
|
||||
// 扩展功能码 (保留,非标准Modbus)
|
||||
#define MB_YMODEM_UPDATAE (0x20) // Ymodem升级指令
|
||||
#define MB_TRIM_ELOAD (0x21) // 校准源载指令
|
||||
#define MB_FUNC_ERROR (0x80)
|
||||
|
||||
typedef enum {
|
||||
MB_EX_NONE = 0x00,
|
||||
@@ -79,6 +121,8 @@ typedef enum {
|
||||
#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
|
||||
#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
|
||||
|
||||
|
||||
|
||||
typedef eMBException(*pFunctionHandler) (rt_uint8_t *reqFrame, rt_uint16_t reqLen,
|
||||
rt_uint8_t *resFrame, rt_uint16_t *resLen);
|
||||
|
||||
@@ -142,6 +186,18 @@ struct code_func_t {
|
||||
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX (0x0078)
|
||||
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX (0x07B0)
|
||||
|
||||
#define MB_YMODEM_DATA_SIZE (1029)
|
||||
|
||||
////升级协议状态
|
||||
//typedef enum {
|
||||
// Ymodem_No = 0,
|
||||
// Ymodem_Wait,
|
||||
// Ymodem_Rec_Start,
|
||||
// Ymodem_Rec_1024,
|
||||
// Ymodem_Rec_End,
|
||||
// Ymodem_Rec_Finish
|
||||
//} Ymodem_state;
|
||||
|
||||
#define THR_NAME_COMM "thr.comm"
|
||||
#define DEV_NAME_COMM "uart1"
|
||||
|
||||
@@ -170,7 +226,10 @@ extern struct chrg_comm_t chrgcomm;
|
||||
*****************************************************************/
|
||||
extern void chrg_comm_thread_entry (void *data);
|
||||
|
||||
extern rt_uint8_t chrg_com_sink_on(rt_uint8_t ch, struct chrg_switch_t *pSW, rt_uint8_t *enable);
|
||||
extern rt_uint8_t chrg_com_source_on(rt_uint8_t ch, rt_uint8_t protoCmd, struct chrg_switch_t *pSW, rt_uint8_t *enable);
|
||||
extern void chrg_sink_diff_send_reg(eIDX_SOU_CH ch, sink_proto_diff_t *pDiff, struct chrg_switch_t *pReal);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,26 +11,25 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
|
||||
#include "chrg_rel.h"
|
||||
#include "chrg_north_pkg.h"
|
||||
#include "chrg_north.h"
|
||||
#include "chrg_south.h"
|
||||
#include "chrg_roll_sou.h"
|
||||
#include "chrg_eload.h"
|
||||
#include "chrg_utils.h"
|
||||
#include "chrg_lcd.h"
|
||||
|
||||
#include "chrg_roll_nor.h"
|
||||
#define LOG_TAG "chrg.lcd"
|
||||
#define DBG_LEVEL DBG_LOG
|
||||
#include <rtdbg.h>
|
||||
|
||||
#include "chrg_eload.h"
|
||||
int Flag_R1=0,Flag_R2=0,Flag_R3=0,Flag_R4=0;
|
||||
struct chrg_lcd_t chrglcd = {
|
||||
.devname = DEV_NAME_LCD,
|
||||
.tty = RT_NULL,
|
||||
|
||||
};
|
||||
|
||||
// 55 21 00 0D 0A 负载
|
||||
// 55 21 01 0D 0A 电源
|
||||
// 55 31 00 0D 0A 恒流
|
||||
@@ -38,6 +37,89 @@ struct chrg_lcd_t chrglcd = {
|
||||
// 55 41 00 0D 0A 停止
|
||||
// 55 41 01 0D 0A 运行
|
||||
|
||||
void chrg_sou_work(eIDX_SOU_CH ch,struct chrg_switch_t *pSW)
|
||||
{
|
||||
struct chrg_south_t *pSOU = &chrgsouth;
|
||||
if(pSW->id == ID_SOURCE){
|
||||
chrg_set_sou_reg(ch, REG_WORK, WORK_START);
|
||||
// rt_thread_mdelay(50);
|
||||
pSW->source.Set_CV_Flag = 1;
|
||||
pSW->source.Set_Pro_Flag = 1;
|
||||
pSW->source.On_Flag = 1;
|
||||
pSW->sub = IDX_SET_SOURCE_PD;
|
||||
}
|
||||
else if(pSW->id == ID_SINK) {
|
||||
pSW->sink.On_work = 1;
|
||||
pSW->sub=IDX_SET_SINK_PD;
|
||||
}
|
||||
pSOU->online[ch] = 1;
|
||||
chrg_nor_sw_rel((eIDX_NOR_CH)ch, pSW->id);
|
||||
rt_thread_mdelay(50);
|
||||
}
|
||||
|
||||
void chrg_sou_stop(eIDX_SOU_CH ch,struct chrg_switch_t *pSW,struct chrg_north_t *pNOR)
|
||||
{
|
||||
struct chrg_south_t *pSOU = &chrgsouth;
|
||||
if(pSOU == RT_NULL){
|
||||
return;
|
||||
}
|
||||
if(pSW->id == ID_SOURCE){
|
||||
pSW->source.Stop_step_flag = 0;
|
||||
pSW->source.On_Flag = 0;
|
||||
pSW->sub = IDX_GET_SOURCE_VC;
|
||||
}
|
||||
else if(pSW->id == ID_SINK){
|
||||
pSW->sink.On_work = 0;
|
||||
pSW->sub = IDX_SET_SINK_WORK_STATE;
|
||||
}
|
||||
pSOU->online[ch] = 0;
|
||||
#if LCD_OPEN
|
||||
pNOR->free_flag = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int chrg_pro_set(struct chrg_switch_t *pSW, rt_uint8_t protocol){
|
||||
if (pSW->id == ID_SOURCE) {
|
||||
// Source端
|
||||
pSW->source.protocol = protocol;
|
||||
pSW->source.LCD_Set_Pro_Flag = 1;
|
||||
} else if (pSW->id == ID_SINK) {
|
||||
// Sink端
|
||||
pSW->sink.protocol = protocol;
|
||||
if(pSW->sink.protocol==0xC1)
|
||||
{
|
||||
pSW->sink.protocol = 0xFE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void chrg_set_eload_sink(eIDX_SOU_CH ch,struct chrg_switch_t *pSW){
|
||||
pSW->id = ID_SINK;
|
||||
//pSW->sink.protocol = 0xFE;
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
|
||||
if(pSW->continue_flag==0){
|
||||
}
|
||||
}
|
||||
|
||||
void chrg_set_eload_source(eIDX_SOU_CH ch,struct chrg_switch_t *pSW){
|
||||
pSW->id = ID_SOURCE;
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_SOURCE);
|
||||
}
|
||||
|
||||
void chrg_set_CV(rt_uint8_t ch,struct chrg_switch_t *pSW){
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_MODE, MODE_CONSTANT_VOLTAGE);
|
||||
}
|
||||
|
||||
void chrg_set_CC(rt_uint8_t ch,struct chrg_switch_t *pSW){
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_MODE, MODE_CONSTANT_CURRENT);
|
||||
}
|
||||
//设置恒压恒流模式
|
||||
void chrg_roll_set_cv(eIDX_NOR_CH ch,struct chrg_switch_t *pSW,rt_uint8_t CV_flag){
|
||||
if(CV_flag ==1) chrg_set_CV(ch,pSW);
|
||||
else chrg_set_CC(ch,pSW);
|
||||
pSW->sub = IDX_SET_SOURCE_ID;
|
||||
}
|
||||
/*****************************************************************
|
||||
函数名称: chrg_lcd_parse
|
||||
函数描述: 接收显示屏的控制消息
|
||||
@@ -46,117 +128,179 @@ struct chrg_lcd_t chrglcd = {
|
||||
返回说明: <0: 错误
|
||||
其它说明: 本部分为 HMI 文件自定义命令,需要统一规划管理
|
||||
*****************************************************************/
|
||||
rt_uint8_t On_Flag = 0;
|
||||
rt_uint8_t ch = 0;
|
||||
static int chrg_lcd_parse (rt_uint8_t *recv, rt_uint16_t len)
|
||||
{
|
||||
rt_uint16_t Recv_Data;
|
||||
rt_uint16_t Recv_Data;
|
||||
ch = 0;
|
||||
if (len < 5) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len < 5) {
|
||||
return -1;
|
||||
}
|
||||
if (0x55 != recv[LCD_IDX_HEAD]) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
struct chrg_north_t *pNOR = &chrgnorth;
|
||||
struct chrg_south_t *pSOU = &chrgsouth;
|
||||
struct chrg_switch_t *pSW = RT_NULL;
|
||||
struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
switch (recv[LCD_IDX_CMD]) {
|
||||
// 变电协议
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
case 0x14:{
|
||||
ch = recv[LCD_IDX_CMD] - 0x11;
|
||||
pSW = &pNOR->sw[ch];
|
||||
chrg_pro_set(pSW,recv[2]);
|
||||
break;
|
||||
}
|
||||
// 电源/负载切换
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24: {
|
||||
ch = recv[LCD_IDX_CMD] - 0x21;
|
||||
if (Flag_R1 == 1 && ch == 0) return 0;
|
||||
if (Flag_R2 == 1 && ch == 1) return 0;
|
||||
if (Flag_R3 == 1 && ch == 2) return 0;
|
||||
if (Flag_R4 == 1 && ch == 3) return 0;
|
||||
pSW = &pNOR->sw[ch];
|
||||
if (1 == recv[LCD_IDX_VAL]) {
|
||||
// 电源模式(Source)
|
||||
chrg_set_eload_source(ch,pSW);
|
||||
} else {
|
||||
// 负载模式(Sink)
|
||||
chrg_set_eload_sink(ch,pSW);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// 恒压/恒流模式
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34: {
|
||||
ch = recv[LCD_IDX_CMD] - 0x31;
|
||||
if (Flag_R1 == 1 && ch == 0) return 0;
|
||||
if (Flag_R2 == 1 && ch == 1) return 0;
|
||||
if (Flag_R3 == 1 && ch == 2) return 0;
|
||||
if (Flag_R4 == 1 && ch == 3) return 0;
|
||||
if (1 == recv[LCD_IDX_VAL]) {
|
||||
chrg_set_CV((eIDX_SOU_CH)ch,pSW);
|
||||
} else {
|
||||
chrg_set_CC((eIDX_SOU_CH)ch,pSW);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//运行停止
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44: {
|
||||
ch = recv[LCD_IDX_CMD] - 0x41;
|
||||
pSW = &pNOR->sw[ch];
|
||||
//运行
|
||||
if (1 == recv[LCD_IDX_VAL]) {
|
||||
switch(ch) {
|
||||
case 0: Flag_R1 = 1; break;
|
||||
case 1: Flag_R2 = 1; break;
|
||||
case 2: Flag_R3 = 1; break;
|
||||
case 3: Flag_R4 = 1; break;
|
||||
}
|
||||
pNOR->enable[ch] = 1;
|
||||
rt_kprintf("ch=%d\n",ch);
|
||||
chrg_sou_work((eIDX_SOU_CH)ch,pSW);
|
||||
pSW->continue_flag = 0;
|
||||
}
|
||||
//关闭
|
||||
else {
|
||||
switch(ch) {
|
||||
case 0: Flag_R1 = 0; break;
|
||||
case 1: Flag_R2 = 0; break;
|
||||
case 2: Flag_R3 = 0; break;
|
||||
case 3: Flag_R4 = 0; break;
|
||||
}
|
||||
chrg_sou_stop((eIDX_SOU_CH)ch,pSW,pNOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// CV电压值设定
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54: {
|
||||
ch = recv[LCD_IDX_CMD] - 0x51;
|
||||
Recv_Data = recv[LCD_IDX_VAL+1]<<8 | recv[LCD_IDX_VAL]; // 拼接16位电压值
|
||||
pSW = &pNOR->sw[ch];
|
||||
// 按角色存入source/sink
|
||||
pSW->source.vc.set_voltage = Recv_Data; // 电源侧电压(mV)
|
||||
pSW->sink.loadv = Recv_Data; // 负载侧电压(mV,)
|
||||
pSW->source.Set_Pro_Flag = 1;
|
||||
// 写入电压寄存器
|
||||
if(pSW->id==ID_SINK) {
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_VOLTAGE_OUT+1, Recv_Data);
|
||||
}
|
||||
else chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_VOLTAGE_OUT+1, 5000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (0x55 != recv[LCD_IDX_HEAD]) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
rt_uint8_t ch = 0;
|
||||
struct chrg_north_t *pNOR = &chrgnorth;
|
||||
struct chrg_south_t *pSOU = &chrgsouth;
|
||||
struct chrg_switch_t *pSW = RT_NULL;
|
||||
|
||||
switch (recv[LCD_IDX_CMD]) {
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24: { // 电源/负载
|
||||
ch = recv[LCD_IDX_CMD] - 0x21;
|
||||
if (Flag_R1 == 1 && ch == 0) return 0;
|
||||
if (Flag_R2 == 1 && ch == 1) return 0;
|
||||
if (Flag_R3 == 1 && ch == 2) return 0;
|
||||
if (Flag_R4 == 1 && ch == 3) return 0;
|
||||
pSW = &pNOR->sw[ch];
|
||||
if (1 == recv[LCD_IDX_VAL]) {
|
||||
pSW->id = ID_SOURCE;
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_SOURCE);
|
||||
} else {
|
||||
pSW->id = ID_SINK;
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34: { // 恒压/恒流
|
||||
ch = recv[LCD_IDX_CMD] - 0x31;
|
||||
if (Flag_R1 == 1 && ch == 0) return 0;
|
||||
if (Flag_R2 == 1 && ch == 1) return 0;
|
||||
if (Flag_R3 == 1 && ch == 2) return 0;
|
||||
if (Flag_R4 == 1 && ch == 3) return 0;
|
||||
if (1 == recv[LCD_IDX_VAL]) {
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_MODE, MODE_CONSTANT_VOLTAGE);
|
||||
} else {
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_MODE, MODE_CONSTANT_CURRENT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44: { // 运行/停止
|
||||
ch = recv[LCD_IDX_CMD] - 0x41;
|
||||
if (1 == recv[LCD_IDX_VAL]) {
|
||||
//pNOR->enable[ch] = 0;
|
||||
//pSOU->enable[ch] = 0;
|
||||
switch(ch) {
|
||||
case 0: Flag_R1 = 1; break;
|
||||
case 1: Flag_R2 = 1; break;
|
||||
case 2: Flag_R3 = 1; break;
|
||||
case 3: Flag_R4 = 1; break;
|
||||
// CC电流值设定
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64: {
|
||||
ch = recv[LCD_IDX_CMD] - 0x61;
|
||||
Recv_Data = recv[LCD_IDX_VAL+1]<<8 | recv[LCD_IDX_VAL]; // 拼接16位电流值
|
||||
pSW = &pNOR->sw[ch];
|
||||
//按角色存入source/sink
|
||||
pSW->source.vc.set_current = Recv_Data; // 电源侧电流(mA)
|
||||
pSW->sink.loadc = Recv_Data; // 负载侧电流(mA)
|
||||
pSW->source.Set_Pro_Flag = 1;
|
||||
// rt_kprintf("cur=%d",Recv_Data);
|
||||
// 写入电流寄存器
|
||||
for(int i = 0;i<10;i++){
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_CURRENT_OUT+1, Recv_Data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//cc线设置
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
case 0x84:{
|
||||
ch = recv[LCD_IDX_CMD] - 0x81;
|
||||
Recv_Data = recv[2];
|
||||
pSW = &pNOR->sw[ch];
|
||||
// rt_kprintf("data=%d",Recv_Data);
|
||||
// rt_kprintf("ID=%d\r\n",pSW->id);
|
||||
// if(pSW->id==ID_SINK){
|
||||
// pSW->sub = IDX_SET_SINK_CCLINE;
|
||||
// pSW->sink.cc_set = Recv_Data; // CC线开关设置
|
||||
// }
|
||||
switch(Recv_Data){
|
||||
case 0:
|
||||
chrg_set_sou_reg(ch, REG_REL_ON, ALL_REL_ON);
|
||||
break;
|
||||
case 1:
|
||||
chrg_set_sou_reg(ch, REG_REL_ON, FU_REL_ON);
|
||||
break;
|
||||
case 2:
|
||||
chrg_set_sou_reg(ch, REG_WORK, WORK_START);
|
||||
break;
|
||||
case 3:
|
||||
chrg_set_sou_reg(ch, REG_WORK, WORK_START);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
|
||||
} else {
|
||||
//pNOR->enable[ch] = 1;
|
||||
//pSOU->enable[ch] = 1;
|
||||
switch(ch) {
|
||||
case 0: Flag_R1 = 0; break;
|
||||
case 1: Flag_R2 = 0; break;
|
||||
case 2: Flag_R3 = 0; break;
|
||||
case 3: Flag_R4 = 0; break;
|
||||
}
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_STOP);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54: { //CV电压值设定
|
||||
ch = recv[LCD_IDX_CMD] - 0x51;
|
||||
Recv_Data = recv[LCD_IDX_VAL+1]<<8|recv[LCD_IDX_VAL];//get lower Reg_Data
|
||||
//Recv_Data = swap_u16(Recv_Data);
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_VOLTAGE_OUT+1, Recv_Data);//plus 1,set voltage lower REG
|
||||
}
|
||||
break;
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:{ //CC电流值设定
|
||||
ch = recv[LCD_IDX_CMD] - 0x61;
|
||||
Recv_Data = recv[LCD_IDX_VAL+1]<<8|recv[LCD_IDX_VAL];//get lower Reg_Data
|
||||
//Recv_Data = swap_u16(Recv_Data);
|
||||
chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_CURRENT_OUT+1,Recv_Data);//plus 1,set current lower REG
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_lcd_send
|
||||
函数描述: 向显示屏发送控制消息
|
||||
@@ -165,39 +309,69 @@ static int chrg_lcd_parse (rt_uint8_t *recv, rt_uint16_t len)
|
||||
返回说明: 0:发送完成 <0: 发送失败
|
||||
其它说明: 参考《淘晶驰串口屏开发手册》http://wiki.tjc1688.com/
|
||||
*****************************************************************/
|
||||
int chrg_lcd_send (char *cmd)
|
||||
{
|
||||
rt_ssize_t ret = -1;
|
||||
struct chrg_tty_t *pTTY = chrglcd.tty;
|
||||
if (RT_NULL == cmd) {
|
||||
return -1;
|
||||
}
|
||||
int chrg_lcd_send (char *cmd)
|
||||
{
|
||||
rt_ssize_t ret = -1;
|
||||
struct chrg_tty_t *pTTY = chrglcd.tty;
|
||||
if (RT_NULL == cmd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int len = rt_strlen(cmd);
|
||||
rt_uint8_t *data = rt_malloc(len+3);
|
||||
if (RT_NULL == data) {
|
||||
LOG_E("malloc failed.");
|
||||
return -1;
|
||||
}
|
||||
int len = rt_strlen(cmd);
|
||||
rt_uint8_t *data = rt_malloc(len+3);
|
||||
if (RT_NULL == data) {
|
||||
LOG_E("malloc failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rt_memcpy(data, cmd, len);
|
||||
rt_memset(&data[len], 0xFF, 3);
|
||||
rt_memcpy(data, cmd, len);
|
||||
rt_memset(&data[len], 0xFF, 3);
|
||||
// for(int i=0;i<len+3;i++){
|
||||
// rt_kprintf("%02x ",data[i]);
|
||||
// }
|
||||
if (RT_NULL != pTTY) {
|
||||
ret = chrg_tty_send(pTTY, data, len+3);
|
||||
// LOG_HEX("lcdS", 32, data, len+3);
|
||||
}
|
||||
|
||||
if (RT_NULL != pTTY) {
|
||||
ret = chrg_tty_send(pTTY, data, len+3);
|
||||
// LOG_HEX("lcdS", 32, data, len+3);
|
||||
}
|
||||
if (RT_NULL != data) {
|
||||
rt_free(data);
|
||||
data = RT_NULL;
|
||||
}
|
||||
//rt_thread_mdelay(5);
|
||||
|
||||
if (RT_NULL != data) {
|
||||
rt_free(data);
|
||||
data = RT_NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// static rt_uint8_t lcd_send_buf[64] = {0};
|
||||
|
||||
rt_thread_mdelay(20);
|
||||
// int chrg_lcd_send (char *cmd)
|
||||
// {
|
||||
// rt_ssize_t ret = -1;
|
||||
// struct chrg_tty_t *pTTY = chrglcd.tty;
|
||||
|
||||
// // 1. 入参校验
|
||||
// if (RT_NULL == cmd || RT_NULL == pTTY) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
return ret;
|
||||
}
|
||||
// // 2. 计算指令长度(避免malloc,复用全局缓冲区)
|
||||
// int len = rt_strlen(cmd);
|
||||
// // 安全检查:避免缓冲区溢出(最长支持60字符,远大于你的36字符)
|
||||
// if (len > 60) {
|
||||
// LOG_E("cmd too long: %d", len);
|
||||
// return -2;
|
||||
// }
|
||||
|
||||
// // 3. 填充指令+补齐3个FF(复用全局缓冲区)
|
||||
// rt_memcpy(lcd_send_buf, cmd, len);
|
||||
// rt_memset(&lcd_send_buf[len], 0xFF, 3);
|
||||
|
||||
// // 4. 发送数据(无内存分配,直接发送)
|
||||
// ret = chrg_tty_send(pTTY, lcd_send_buf, len+3);
|
||||
|
||||
// // 5. 无需free(全局缓冲区复用)
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_lcd_thread_entry
|
||||
@@ -207,10 +381,11 @@ int chrg_lcd_send (char *cmd)
|
||||
返回说明: -
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
int delay_cnt = 0; // 延迟计数器
|
||||
void chrg_lcd_thread_entry (void *data)
|
||||
{
|
||||
struct chrg_thread_t *pTHR = (struct chrg_thread_t *)data;
|
||||
|
||||
static uint8_t number = 0;
|
||||
if (RT_NULL == pTHR) {
|
||||
return ;
|
||||
}
|
||||
@@ -218,7 +393,7 @@ void chrg_lcd_thread_entry (void *data)
|
||||
int len = 0;
|
||||
struct chrg_tty_t *pTTY = RT_NULL;
|
||||
struct chrg_lcd_t *pLCD = &chrglcd;
|
||||
pTTY = chrg_tty_create(pLCD->devname, 115200, 0, -1, 1);
|
||||
pTTY = chrg_tty_create(pLCD->devname, 921600, 0, -1, 1);
|
||||
if (RT_NULL == pTTY) {
|
||||
LOG_E("tty can't create.");
|
||||
return ;
|
||||
@@ -235,18 +410,16 @@ void chrg_lcd_thread_entry (void *data)
|
||||
while (1) {
|
||||
rt_memset(pLCD->rx_buf, 0, SIZE_BUF_TTY);
|
||||
len = chrg_tty_recv(pTTY, pLCD->rx_buf, sizeof(pLCD->rx_buf));
|
||||
if (len <= 0) {
|
||||
rt_thread_mdelay(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// LOG_HEX("lcdR", 32, pLCD->rx_buf, len);
|
||||
|
||||
if (len >= 5) {
|
||||
chrg_lcd_parse(pLCD->rx_buf, len);
|
||||
}
|
||||
if (len <= 0) {
|
||||
rt_thread_mdelay(1);
|
||||
delay_cnt++;
|
||||
continue;
|
||||
}
|
||||
// LOG_HEX("lcdR", 32, pLCD->rx_buf, len);
|
||||
if (len >= 5) {
|
||||
chrg_lcd_parse(pLCD->rx_buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "chrg_tty.h"
|
||||
|
||||
#include "chrg_north.h"
|
||||
#include "chrg_south.h"
|
||||
#define THR_NAME_LCD "thr.lcd"
|
||||
#define DEV_NAME_LCD "uart2"
|
||||
|
||||
@@ -41,7 +42,16 @@ extern int chrg_lcd_send (char *cmd);
|
||||
|
||||
extern void chrg_lcd_thread_entry (void *data);
|
||||
|
||||
extern rt_uint8_t On_Flag;
|
||||
|
||||
extern rt_uint8_t Flag_start;
|
||||
extern void chrg_sou_work(eIDX_SOU_CH ch,struct chrg_switch_t *pSW);
|
||||
extern void chrg_sou_stop(eIDX_SOU_CH ch,struct chrg_switch_t *pSW,struct chrg_north_t *pNOR);
|
||||
extern void chrg_set_eload_sink(eIDX_SOU_CH ch,struct chrg_switch_t *pSW);
|
||||
extern void chrg_set_eload_source(eIDX_SOU_CH ch,struct chrg_switch_t *pSW);
|
||||
extern void chrg_set_CV(rt_uint8_t ch,struct chrg_switch_t *pSW);
|
||||
extern void chrg_set_CC(rt_uint8_t ch,struct chrg_switch_t *pSW);
|
||||
extern void chrg_roll_set_cv(eIDX_NOR_CH ch,struct chrg_switch_t *pSW,rt_uint8_t CV_flag);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#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"
|
||||
@@ -19,31 +19,328 @@
|
||||
#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 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 && pSW->sink.test.test_mode == 0) {
|
||||
if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
|
||||
// volt_low[idx]++;
|
||||
// if(volt_low[idx]>=5) pSW->sink.work_on_step = 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_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, 1, 1, 1},
|
||||
.sw[IDX_NOR_CH1] = {
|
||||
.id = ID_SINK,
|
||||
},
|
||||
.sw[IDX_NOR_CH2] = {
|
||||
.id = ID_SINK,
|
||||
},
|
||||
.sw[IDX_NOR_CH3] = {
|
||||
.id = ID_SINK,
|
||||
},
|
||||
.sw[IDX_NOR_CH4] = {
|
||||
.id = ID_SINK,
|
||||
},
|
||||
.devname = DEV_NAME_NORTH, // 设备名
|
||||
.tty = RT_NULL, // 串口句柄初始为空
|
||||
.enable = {0, 0, 0, 0}, // 4个通道使能初始关闭
|
||||
.free_flag = 1,
|
||||
// 通道1(IDX_NOR_CH1)初始化
|
||||
.sw[IDX_NOR_CH1] = {
|
||||
.CV_mode = 2,
|
||||
.change_flag = 0,
|
||||
.show_step = 0,
|
||||
.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,
|
||||
}
|
||||
|
||||
},
|
||||
// 通道2(IDX_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,
|
||||
}
|
||||
},
|
||||
// 通道3(IDX_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,
|
||||
}
|
||||
},
|
||||
// 通道4(IDX_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
|
||||
函数描述: 北向通道选择
|
||||
@@ -76,7 +373,9 @@ int chrg_north_send (rt_uint8_t *data, rt_size_t length)
|
||||
struct chrg_tty_t *pTTY = chrgnorth.tty;
|
||||
|
||||
if (RT_NULL != pTTY) {
|
||||
LOG_HEX("sendN", 32, data, length);
|
||||
#if DEBUG_NORTH //是否打印
|
||||
// LOG_HEX("sendN", 32, data, length);
|
||||
#endif
|
||||
ret = chrg_tty_send(pTTY, data, length);
|
||||
}
|
||||
|
||||
@@ -100,14 +399,30 @@ static int chrg_north_frame_head (struct rt_ringbuffer *rb, rt_uint8_t *head, eI
|
||||
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 + 2) { // 最短5字节
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (len_rb < LEN_FRAME_HEAD + 2) { // 最短5字节
|
||||
// =============================
|
||||
// 简单版:打印错误帧 + 清空缓冲区
|
||||
// =============================
|
||||
rt_kprintf("[ERROR] 帧长度不足,len=%d, data: ", len_rb);
|
||||
|
||||
// 把所有数据读出来、打印、同时清空
|
||||
rt_uint8_t dummy;
|
||||
while (rt_ringbuffer_getchar(rb, &dummy) == RT_EOK)
|
||||
{
|
||||
rt_kprintf("%02x ", dummy); // 打印每一个字节
|
||||
}
|
||||
|
||||
rt_kprintf("\r\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < len_rb - 2; i++) { // 找头三个字节 [帧长, 0x00, id]
|
||||
ret = rt_ringbuffer_getchar(rb, &data);
|
||||
if (0 == ret) {
|
||||
@@ -119,6 +434,7 @@ static int chrg_north_frame_head (struct rt_ringbuffer *rb, rt_uint8_t *head, eI
|
||||
head[0] = data;
|
||||
len_frame = data;
|
||||
if (data < MIN_FRAME_LENGTH) { // 长度不符
|
||||
|
||||
stage = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -140,6 +456,13 @@ static int chrg_north_frame_head (struct rt_ringbuffer *rb, rt_uint8_t *head, eI
|
||||
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;
|
||||
@@ -162,28 +485,29 @@ static int chrg_north_frame_head (struct rt_ringbuffer *rb, rt_uint8_t *head, eI
|
||||
返回说明: <0: 错误 >0:帧长度
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
int a_number;
|
||||
static int chrg_north_pickup_frame (struct rt_ringbuffer *rb,
|
||||
struct pickup_info_t *pFrame, eIDX_NOR_CH idx)
|
||||
{
|
||||
int cnt = 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) {
|
||||
pFrame->pMB = (struct mb_msg_t *)rt_malloc(sizeof(struct mb_msg_t));
|
||||
if (RT_NULL == pFrame->pMB) {
|
||||
LOG_E("malloc mb failed.");
|
||||
return -2;
|
||||
}
|
||||
|
||||
pFrame->pMB->length = pFrame->len_msg;
|
||||
if (pFrame->pMB->length >= SIZE_BUF_TTY) {
|
||||
rt_free(pFrame->pMB);
|
||||
@@ -191,23 +515,23 @@ static int chrg_north_pickup_frame (struct rt_ringbuffer *rb,
|
||||
LOG_E("too long msg.");
|
||||
return -3;
|
||||
}
|
||||
|
||||
pFrame->pMB->payload = (rt_uint8_t *)rt_malloc(pFrame->len_msg);
|
||||
if (RT_NULL == pFrame->pMB->payload) {
|
||||
LOG_E("malloc buf failed.");
|
||||
return -4;
|
||||
}
|
||||
|
||||
rt_memcpy(pFrame->pMB->payload, pFrame->head, LEN_FRAME_HEAD);
|
||||
|
||||
len_rb = rt_ringbuffer_data_len(rb);
|
||||
// rt_kprintf("len_rb=%d\r\n",len_rb);
|
||||
// rt_kprintf("len=%d",pFrame->len_msg - LEN_FRAME_HEAD);
|
||||
if (len_rb >= pFrame->len_msg - LEN_FRAME_HEAD) {
|
||||
rt_ringbuffer_get(rb, &pFrame->pMB->payload[LEN_FRAME_HEAD],
|
||||
pFrame->len_msg - LEN_FRAME_HEAD);
|
||||
|
||||
if(pFrame->pMB->length==21){
|
||||
chrg_north_handle_Seting_Volt(pFrame->pMB->payload, pFrame->pMB->length);
|
||||
}
|
||||
chrg_thread_mb_send(IDX_THR_NORTH, pFrame->pMB);
|
||||
//chrg_north_pkg_decode(pFrame->pMB->payload, pFrame->len_msg, pSW);
|
||||
|
||||
pFrame->length = 0;
|
||||
pFrame->len_msg = 0;
|
||||
cnt++;
|
||||
@@ -219,7 +543,6 @@ static int chrg_north_pickup_frame (struct rt_ringbuffer *rb,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
len_rb = rt_ringbuffer_data_len(rb);
|
||||
int len_need = pFrame->len_msg - LEN_FRAME_HEAD;
|
||||
@@ -240,8 +563,8 @@ static int chrg_north_pickup_frame (struct rt_ringbuffer *rb,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
len_rb = rt_ringbuffer_data_len(rb);
|
||||
|
||||
} while (len_rb >= LEN_FRAME_HEAD);
|
||||
|
||||
return cnt;
|
||||
@@ -266,16 +589,16 @@ void chrg_north_thread_entry (void *data)
|
||||
int 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, BAUD_RATE_921600, 0, -1, 1);
|
||||
|
||||
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, 100);
|
||||
chrg_tty_set_recv_tmo(pTTY, 10);
|
||||
if (chrg_tty_connect(pTTY) != RT_EOK) {
|
||||
chrg_tty_destory(pTTY);
|
||||
return ;
|
||||
@@ -298,8 +621,9 @@ void chrg_north_thread_entry (void *data)
|
||||
}
|
||||
|
||||
rt_ringbuffer_put(pNOR->rb, pNOR->rx_buf, len);
|
||||
#if DEBUG_NORTH
|
||||
LOG_HEX("recvN", 32, pNOR->rx_buf, len);
|
||||
|
||||
#endif
|
||||
if (1 == pNOR->frame.findhead) {
|
||||
if (rt_tick_get() >= pNOR->frame.last_tick + 100) { // 100ms
|
||||
pNOR->frame.findhead = 0; // reset
|
||||
@@ -309,7 +633,6 @@ void chrg_north_thread_entry (void *data)
|
||||
|
||||
chrg_north_pickup_frame(pNOR->rb, &pNOR->frame, pNOR->idx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -333,4 +656,3 @@ MSH_CMD_EXPORT(north_ch, north channel select);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
#define __CHRG_NORTH_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "chrg_tty.h"
|
||||
#include "chrg_source.h"
|
||||
#include "chrg_tty.h"
|
||||
#include "chrg_sink.h"
|
||||
#include "chrg_def.h"
|
||||
|
||||
@@ -22,15 +21,21 @@
|
||||
|
||||
#define LEN_FRAME_HEAD (3) // [帧长, 0x00, id]
|
||||
#define MIN_FRAME_LENGTH (5) // 帧最短5字节
|
||||
|
||||
#define WORK_MIN_VOLT 3000 // 工作电压下限,单位mV
|
||||
#define DEBUG_NORTH 0x00 // 0 = 关闭,1 = 开启
|
||||
#define LCD_OPEN 0x01 // 0为关闭屏幕显示 1为打开
|
||||
#define TRIM_NORTH 0x00 // 0 = 关闭, 1 = 开启
|
||||
#define SINK_TEST_DEBUG 0x00 // 0 = 关闭,1 = 开启
|
||||
#define PRO_TEST_DEBUG 0x00 //
|
||||
#define DEBUG_SOUTH 0x00 // 0 = 关闭,1 = 开启
|
||||
// 北向4通路索引 U14 ->
|
||||
typedef enum {
|
||||
IDX_NOR_CH1 = IDX_CH1, // J3
|
||||
IDX_NOR_CH1 = IDX_CH1, // J3
|
||||
IDX_NOR_CH2 = IDX_CH2, // J4
|
||||
IDX_NOR_CH3 = IDX_CH3, // J9
|
||||
IDX_NOR_CH4 = IDX_CH4, // J10
|
||||
|
||||
TOTAL_NOR_CHS
|
||||
TOTAL_NOR_CHS
|
||||
} eIDX_NOR_CH;
|
||||
|
||||
|
||||
@@ -38,6 +43,60 @@ struct chrg_switch_t {
|
||||
eIDX_ID id;
|
||||
struct chrg_src_t source;
|
||||
struct chrg_sink_t sink;
|
||||
rt_uint8_t protoCmd; // 协议类型
|
||||
rt_uint8_t sub; //状态机步骤
|
||||
rt_uint8_t show_step; // 显示步骤标志位,0-各项参数,1-显示电压电流,
|
||||
rt_uint8_t continue_flag;
|
||||
rt_uint8_t CV_mode; //恒压恒流
|
||||
rt_uint8_t change_flag; //正在调整功率标志位
|
||||
rt_uint16_t Now_voltage; // 当前电压 mV
|
||||
rt_uint16_t Now_current; // 当前电流 mA
|
||||
rt_uint16_t VZ;
|
||||
rt_uint16_t VF;
|
||||
};
|
||||
//校准结构体
|
||||
//#define ModbusRTU_Trim_Start 0x01 //进入校准模式
|
||||
//#defin ModbusRTU_Trim_Stop 0x02 //退出校准模式
|
||||
#define ModbusRTU_Volt_CAL_K_H 0x2C //2C~2D 电压校准K值,被放大Q16倍,再移动16回去;使用两个字节
|
||||
#define ModbusRTU_Volt_CAL_K_L 0x2D
|
||||
#define ModbusRTU_Volt_CAL_B 0x2E //2E 电压校准B值
|
||||
|
||||
#define ModbusRTU_Current_CAL_K_H 0x2F //2F-30 电流校准K值
|
||||
#define ModbusRTU_Current_CAL_K_L 0x30
|
||||
#define ModbusRTU_Current_CAL_B 0x31 //31 电流校准B值
|
||||
|
||||
#define ModbusRTU_SourceCurrent_CAL_K_H 0x32 //32-33 电流校准K值
|
||||
#define ModbusRTU_SourceCurrent_CAL_K_L 0x33
|
||||
#define ModbusRTU_SourceCurrent_CAL_B 0x34 //34 电流校准B值
|
||||
|
||||
#define ModbusRTU_Trim_Zero_CAL 0x35 //35 校准零点,写入后会将电压电流都校准到0,读取时会返回当前的零点值
|
||||
|
||||
#define ModbusRTU_Trim_CRC_CAL 0x36 //36 校准CRC校验,写入后会将之前的校准数据生效,读取时会返回当前的CRC校验值
|
||||
|
||||
#define ModbusRTU_CAL_WriteEnable_ADD 0x37 //使能写入FLASH的地址
|
||||
#define ModbusRTU_CAL_WriteValue 0x4361 //写入FALSH的魔数
|
||||
#define ModbusRTU_CAL_WriteRecovery 0x38 //使能写入出厂数据区域;0x5763
|
||||
#define ModbusRTU_CAL_WriteRecovery_Value 0x5763 //写入FALSH的魔数
|
||||
#define ModbusRTU_CAL_ReadRecovery 0x39 //使能读出;将出厂数据读到当前的bank中,并更新6个参数
|
||||
|
||||
#define MODE_VOLT_CAL 0x01
|
||||
#define MODE_CURR_CAL 0x02
|
||||
#define MODE_SOURCE_CURR_CAL 0x03
|
||||
#define MODE_ZERO_CAL 0x04
|
||||
struct chrg_trim {
|
||||
rt_uint16_t trim_volt_k_H; // 校准电压值高16位 mV
|
||||
rt_uint16_t trim_volt_k_L; // 校准电压值低16位 mV
|
||||
rt_int16_t trim_volt_b; // 校准电压值b mV
|
||||
rt_uint16_t trim_curr_k_H; // 校准电流值高16位 mA
|
||||
rt_uint16_t trim_curr_k_L; // 校准电流值低16位 mA
|
||||
rt_int16_t trim_curr_b; // 校准电流值b mA
|
||||
rt_uint16_t trim_source_curr_k_H; // 校准电源电流值高16位 mA
|
||||
rt_uint16_t trim_source_curr_k_L; // 校准电源电流值低16位 mA
|
||||
rt_int16_t trim_source_curr_b; // 校准电源电流值b mA
|
||||
rt_int16_t trim_zero; // 校准飘零值 mV/mA
|
||||
rt_uint8_t trim_mode; // 校准模式, 0-默认值,1-校准电压,2-校准电流,3-校准电源电流
|
||||
rt_uint8_t trim_step;
|
||||
rt_uint8_t trim_enable_flag; //0就是默认写用户区,1则写出场数据区
|
||||
};
|
||||
|
||||
struct chrg_north_t {
|
||||
@@ -46,13 +105,14 @@ struct chrg_north_t {
|
||||
struct chrg_tty_t *tty;
|
||||
struct rt_ringbuffer *rb;
|
||||
struct pickup_info_t frame;
|
||||
|
||||
struct chrg_trim trim[TOTAL_NOR_CHS];
|
||||
rt_uint8_t rx_buf[SIZE_BUF_TTY];
|
||||
|
||||
rt_uint8_t free_flag;
|
||||
rt_uint8_t enable[TOTAL_NOR_CHS]; // 通路使能
|
||||
rt_uint8_t manual; // 手动插入命令
|
||||
eIDX_NOR_CH idx; // 当前通路
|
||||
struct chrg_switch_t sw[TOTAL_NOR_CHS];
|
||||
rt_uint8_t north_mode; // 0-正常模式, 1-校准模式
|
||||
};
|
||||
|
||||
extern struct chrg_north_t chrgnorth;
|
||||
@@ -86,7 +146,8 @@ extern int chrg_north_send (rt_uint8_t *data, rt_size_t length);
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern void chrg_north_thread_entry (void *data);
|
||||
|
||||
extern rt_uint8_t On_Flag2;
|
||||
extern rt_bool_t Set_Pro_Flag;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -20,11 +20,10 @@
|
||||
#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,
|
||||
@@ -35,8 +34,166 @@ const rt_base_t sw_uart[TOTAL_NOR_CHS] = {
|
||||
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
|
||||
@@ -60,89 +217,42 @@ static void chrg_roll_nor_sw_uart (eIDX_NOR_CH ch, eIDX_ID id)
|
||||
|
||||
}
|
||||
|
||||
static int chrg_roll_nor_cmd (struct chrg_rollnor_t *pROLL)
|
||||
//设置负载协议
|
||||
void chrg_roll_nor_sink_pro_set(struct chrg_switch_t *pSW)
|
||||
{
|
||||
if (RT_NULL == pROLL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
chrg_north_switch((eIDX_NOR_CH)pROLL->ch);
|
||||
|
||||
if (1 == pROLL->type) {
|
||||
chrg_roll_nor_sw_uart((eIDX_NOR_CH)pROLL->ch, ID_SOURCE);
|
||||
|
||||
switch (pROLL->sub) {
|
||||
case IDX_GET_SOURCE_VC: {
|
||||
source_get_vc(5000, 1000);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_GET_SOURCE_PD: {
|
||||
source_get_pd();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_SET_SOURCE_PD: {
|
||||
source_set_pd(pROLL->pd, pROLL->src, pROLL->pps,
|
||||
pROLL->max_vol, pROLL->min_vol, pROLL->max_curr);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_SET_SOURCE_CCLVL: {
|
||||
source_set_cc_lvl(pROLL->cc_level);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
} else if (0 == pROLL->type) {
|
||||
chrg_roll_nor_sw_uart((eIDX_NOR_CH)pROLL->ch, ID_SINK);
|
||||
|
||||
switch (pROLL->sub) {
|
||||
case IDX_GET_SINK_VC: {
|
||||
sink_get_vc(pROLL->voltage, pROLL->current);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_GET_SINK_PD: {
|
||||
sink_get_pd();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_SET_SINK_PD: {
|
||||
rt_uint8_t buf[5] = {0};
|
||||
sink_set_pd(pROLL->pd, buf);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_SET_SINK_CCLINE: {
|
||||
sink_set_cc_line(pROLL->cc_line);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_SET_SINK_CCLVL: {
|
||||
sink_set_cc_lvl(pROLL->cc_level);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
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: {
|
||||
@@ -171,9 +281,10 @@ static int chrg_roll_nor_parse (struct chrg_rollnor_t *pROLL, rt_uint8_t *data)
|
||||
}
|
||||
|
||||
} 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;
|
||||
|
||||
@@ -206,7 +317,79 @@ static int chrg_roll_nor_parse (struct chrg_rollnor_t *pROLL, rt_uint8_t *data)
|
||||
|
||||
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
|
||||
@@ -232,41 +415,36 @@ void chrg_roll_nor_thread_entry (void *data)
|
||||
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);
|
||||
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
switch (run) {
|
||||
case RUN_AUTO: {
|
||||
idx = index%TOTAL_NOR_CHS;
|
||||
|
||||
if (0 == pNOR->enable[idx]) {
|
||||
index++;
|
||||
rt_thread_mdelay(10);
|
||||
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];
|
||||
if (ID_SOURCE == pSW->id) {
|
||||
chrg_roll_nor_sw_uart((eIDX_NOR_CH)idx, ID_SOURCE);
|
||||
source_get_vc(pSW->source.voltage, pSW->source.current);
|
||||
} else if (ID_SINK == pSW->id) {
|
||||
chrg_roll_nor_sw_uart((eIDX_NOR_CH)idx, ID_SINK);
|
||||
sink_get_vc(pSW->sink.loadv, pSW->sink.loadc);
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
if(pNOR->north_mode == 0){
|
||||
chrg_roll_nor_set(pROLL->idx,pSW,&pNOR->enable[idx]);
|
||||
}
|
||||
|
||||
//rt_kprintf("Nor[%d].%d\r\n", idx, pSW->id);
|
||||
if(pNOR->north_mode == 1){
|
||||
chrg_roll_trim_set(pROLL->idx,pNOR);
|
||||
}
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
break;
|
||||
@@ -275,15 +453,18 @@ void chrg_roll_nor_thread_entry (void *data)
|
||||
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(100);
|
||||
rt_thread_mdelay(5);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@@ -294,7 +475,7 @@ void chrg_roll_nor_thread_entry (void *data)
|
||||
if (crc == pMB_R->payload[pMB_R->length-1]) { // 数据正确
|
||||
if (RUN_AUTO != run) { // 恢复自动轮巡
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
//todo pROLL->run = RUN_AUTO;
|
||||
pROLL->run = RUN_AUTO;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
} else {
|
||||
chrg_roll_nor_parse(pROLL, pMB_R->payload);
|
||||
@@ -313,11 +494,12 @@ void chrg_roll_nor_thread_entry (void *data)
|
||||
pMB_R = RT_NULL;
|
||||
}
|
||||
|
||||
rt_thread_mdelay(200); // 间隔 200ms
|
||||
rt_thread_mdelay(20); // 间隔 200ms
|
||||
} else {
|
||||
if (RUN_AUTO != run) { // 非自动轮巡
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
//todo pROLL->run = RUN_AUTO; // 切换会自动轮巡
|
||||
//todo
|
||||
pROLL->run = RUN_AUTO; // 切换会自动轮巡
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
}
|
||||
}
|
||||
@@ -357,7 +539,7 @@ static int sink (int argc, char **argv)
|
||||
|
||||
if (strcmp(argv[3], "vc") == 0) {
|
||||
if (0 == gset) {
|
||||
pROLL->sub = IDX_GET_SINK_VC;
|
||||
pROLL->sub = IDX_SET_SINK_WORK_STATE;
|
||||
} else {
|
||||
ret = -1;
|
||||
rt_kprintf("sink vc can't set.\r\n");
|
||||
@@ -367,6 +549,7 @@ static int sink (int argc, char **argv)
|
||||
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;
|
||||
@@ -471,12 +654,15 @@ static int source (int argc, char **argv)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -516,29 +702,173 @@ static int source (int argc, char **argv)
|
||||
|
||||
MSH_CMD_EXPORT(source, north source test);
|
||||
|
||||
static int north_run (int argc, char **argv)
|
||||
{
|
||||
if (2 != argc) {
|
||||
rt_kprintf("help : %s start|stop\r\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct chrg_rollnor_t *pROLL = &chrgrollnor;
|
||||
|
||||
if (rt_strcmp(argv[1], "start") == 0) {
|
||||
pROLL->run = RUN_AUTO;
|
||||
} else if (rt_strcmp(argv[1], "stop") == 0) {
|
||||
pROLL->run = RUN_NONE;
|
||||
} else {
|
||||
rt_kprintf("help : %s start|stop\r\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MSH_CMD_EXPORT(north_run, north auto run);
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13,19 +13,34 @@
|
||||
#include <rtthread.h>
|
||||
|
||||
#define THR_NAME_ROLL_NOR "thr.rollnor"
|
||||
|
||||
|
||||
#define STATE_WORKING 0x03//运行标志位
|
||||
enum {
|
||||
IDX_GET_SOURCE_VC = 0,
|
||||
IDX_GET_SOURCE_PD,
|
||||
IDX_SET_SOURCE_PD,
|
||||
IDX_SET_SOURCE_ID,
|
||||
IDX_SET_SOURCE_CC_SET,
|
||||
IDX_SER_SOURCE_VOLT,
|
||||
IDX_SER_SOURCE_CURR,
|
||||
IDX_SET_SOURCE_WORK,
|
||||
IDX_SET_SOURCE_CCLVL,
|
||||
|
||||
IDX_SET_SOURCE_CV,
|
||||
IDX_SET_SOURCE_STOP_STATE,
|
||||
|
||||
IDX_GET_SINK_VC,
|
||||
IDX_GET_SINK_PD,
|
||||
IDX_SET_SINK_VOLT,
|
||||
IDX_SET_SINK_CURR,
|
||||
IDX_SET_SINK_PD,
|
||||
IDX_SET_SINK_CCLINE,
|
||||
IDX_SET_SINK_CCLVL,
|
||||
IDX_SET_SINK_ID,
|
||||
IDX_SET_SINK_VOLT_ON,
|
||||
IDX_SET_SINK_WORK,
|
||||
IDX_SET_SINK_CV,
|
||||
IDX_SET_SINK_WORK_STATE,
|
||||
IDX_SET_SINK_STOP_TEST,//停止负载测试
|
||||
IDX_SET_SINK_STORP_WAIT,
|
||||
};
|
||||
|
||||
struct chrg_rollnor_t {
|
||||
@@ -44,8 +59,7 @@ struct chrg_rollnor_t {
|
||||
rt_uint8_t pps;
|
||||
rt_uint16_t voltage; // 触发插入时,当前电压 mV
|
||||
rt_uint16_t current; // 触发插入时,当前电流 mA
|
||||
|
||||
|
||||
|
||||
rt_uint16_t max_vol; // 触发插入时,最大电压 mV
|
||||
rt_uint16_t min_vol; // 触发插入时,最小电压 mV
|
||||
rt_uint16_t max_curr; // 触发插入时,最大电流 mA
|
||||
@@ -64,7 +78,10 @@ extern struct chrg_rollnor_t chrgrollnor;
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern void chrg_roll_nor_thread_entry (void *data);
|
||||
extern 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);
|
||||
|
||||
|
||||
extern void chrg_roll_trim_set(rt_uint8_t ch, struct chrg_north_t *pNOR);
|
||||
extern void roll_nor_set(void);
|
||||
#define sink_time 3
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,373 @@
|
||||
// /****************************************************************************
|
||||
// 文件名称 : chrg_roll_sou.c
|
||||
// 完成日期 :
|
||||
// 当前版本号 : V1.0
|
||||
// 主要功能 : 实现南向通信轮巡请求命令。以独立线程处理。
|
||||
// 版本历史 : 创建原始版本
|
||||
// 说明 :
|
||||
// ******************************************************************************/
|
||||
|
||||
// #include <stdlib.h>
|
||||
// #include <string.h>
|
||||
// #include <rtthread.h>
|
||||
|
||||
// #include "chrg_def.h"
|
||||
// #include "chrg_led.h"
|
||||
// #include "chrg_thread.h"
|
||||
// #include "chrg_roll_sou.h"
|
||||
// #include "chrg_eload.h"
|
||||
// #include "chrg_utils.h"
|
||||
|
||||
// #define LOG_TAG "chrg.rollsou"
|
||||
// #include <rtdbg.h>
|
||||
|
||||
// struct chrg_rollsou_t chrgrollsou = {
|
||||
// .run = RUN_AUTO,
|
||||
// .ch = IDX_SOU_CH1,
|
||||
// .part = MB_R_PART1,
|
||||
// .mode = 0,
|
||||
// };
|
||||
|
||||
// #define SOU_CMD_QUEUE_SIZE 4
|
||||
|
||||
// struct chrg_sou_cmd_t {
|
||||
// eIDX_SOU_CH ch;
|
||||
// rt_uint16_t reg;
|
||||
// rt_uint16_t value;
|
||||
// };
|
||||
|
||||
// static struct chrg_sou_cmd_t sou_cmd_queue[SOU_CMD_QUEUE_SIZE];
|
||||
// static rt_uint8_t sou_cmd_head = 0;
|
||||
// static rt_uint8_t sou_cmd_tail = 0;
|
||||
// static rt_uint8_t sou_cmd_count = 0;
|
||||
|
||||
// static void sou_cmd_enqueue(eIDX_SOU_CH ch, rt_uint16_t reg, rt_uint16_t value)
|
||||
// {
|
||||
// if (sou_cmd_count < SOU_CMD_QUEUE_SIZE) {
|
||||
// sou_cmd_queue[sou_cmd_tail].ch = ch;
|
||||
// sou_cmd_queue[sou_cmd_tail].reg = reg;
|
||||
// sou_cmd_queue[sou_cmd_tail].value = value;
|
||||
// sou_cmd_tail = (sou_cmd_tail + 1) % SOU_CMD_QUEUE_SIZE;
|
||||
// sou_cmd_count++;
|
||||
// } else {
|
||||
// LOG_W("sou command queue full, drop command\n");
|
||||
// }
|
||||
// }
|
||||
|
||||
// static int sou_cmd_dequeue(struct chrg_sou_cmd_t *cmd)
|
||||
// {
|
||||
// if (sou_cmd_count == 0) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// cmd->ch = sou_cmd_queue[sou_cmd_head].ch;
|
||||
// cmd->reg = sou_cmd_queue[sou_cmd_head].reg;
|
||||
// cmd->value = sou_cmd_queue[sou_cmd_head].value;
|
||||
// sou_cmd_head = (sou_cmd_head + 1) % SOU_CMD_QUEUE_SIZE;
|
||||
// sou_cmd_count--;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int sou_cmd_exists(void)
|
||||
// {
|
||||
// return sou_cmd_count > 0;
|
||||
// }
|
||||
|
||||
// /*****************************************************************
|
||||
// 函数名称: chrg_set_sou_reg
|
||||
// 函数描述: 南向通道设置寄存器请求命令
|
||||
// 输入参数: idx:通道 reg:寄存器地址 value:寄存器值
|
||||
// 输出参数: -
|
||||
// 返回说明: -
|
||||
// 其它说明: -
|
||||
// *****************************************************************/
|
||||
// void chrg_set_sou_reg (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t value)
|
||||
// {
|
||||
// struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU];
|
||||
// struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
|
||||
// rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// sou_cmd_enqueue(idx, reg, value);
|
||||
// pROLL->run = RUN_LCD;
|
||||
// rt_mutex_release(pTHR->mutex);
|
||||
// rt_kprintf("ch=:%d,reg=%02x,value=%02x\n",idx,reg,value);
|
||||
// }
|
||||
|
||||
// /*****************************************************************
|
||||
// 函数名称: chrg_send_sou_upadata_data
|
||||
// 函数描述: 南向通道升级命令
|
||||
// 输入参数: idx:通道 reg:寄存器地址 value:寄存器值
|
||||
// 输出参数: -
|
||||
// 返回说明: -
|
||||
// 其它说明: -
|
||||
// *****************************************************************/
|
||||
// void chrg_send_sou_upadata_data (rt_uint8_t *buf,rt_uint16_t leng)
|
||||
// {
|
||||
// struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU];
|
||||
// struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
// pROLL->updata_data = buf;
|
||||
// pROLL->leng = leng;
|
||||
// // rt_kprintf("idx=%d,reg=%02x,value=%02x\n",RUN_UPDATAidx,reg,value);
|
||||
// rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// pROLL->run = RUN_UPDATA;
|
||||
// rt_mutex_release(pTHR->mutex);
|
||||
// }
|
||||
|
||||
// ///*****************************************************************
|
||||
// //函数名称: chrg_set_sou_more_reg
|
||||
// //函数描述: 南向通道设置寄存器请求命令
|
||||
// //输入参数: idx:通道 reg:寄存器地址 value:寄存器值 value2:第二个寄存器值
|
||||
// //输出参数: -
|
||||
// //返回说明: -
|
||||
// //其它说明: -
|
||||
// //*****************************************************************/
|
||||
// //void chrg_set_sou_more_reg (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t value,rt_uint16_t value2)
|
||||
// //{
|
||||
// // struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU];
|
||||
// // struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
// // pROLL->more_reg_flag = 1; // 使用多寄存器标志位
|
||||
// // pROLL->ch = idx;
|
||||
// // pROLL->reg = reg;
|
||||
// // pROLL->value = value;
|
||||
// // pROLL->value2 = value2;
|
||||
// // rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// // pROLL->run = RUN_LCD;
|
||||
// // rt_mutex_release(pTHR->mutex);
|
||||
// //}
|
||||
// /*****************************************************************
|
||||
// 函数名称: chrg_roll_sou_thread_entry
|
||||
// 函数描述: 南向通道轮巡请求数据线程体
|
||||
// 输入参数: *data: 本线程信息
|
||||
// 输出参数: -
|
||||
// 返回说明: -
|
||||
// 其它说明: -
|
||||
// *****************************************************************/
|
||||
// rt_uint8_t aaaaaa = 0;
|
||||
// void chrg_roll_sou_thread_entry (void *data)
|
||||
// {
|
||||
// struct chrg_thread_t *pTHR = (struct chrg_thread_t *)data;
|
||||
|
||||
// if (RT_NULL == pTHR) {
|
||||
// return ;
|
||||
// }
|
||||
|
||||
// rt_uint8_t run = 0;
|
||||
// rt_uint8_t index = 0, idx = 0;
|
||||
// rt_err_t ret = RT_EOK;
|
||||
// struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
// struct chrg_thread_t *pTS = &chrgthr[IDX_THR_SOUTH];
|
||||
// struct mb_msg_t *pMB_R = RT_NULL;
|
||||
// rt_uint8_t number = 0;
|
||||
// while (1) {
|
||||
// /* 每轮先非阻塞排空积压消息,防止邮箱满导致 south 线程永久阻塞 */
|
||||
// {
|
||||
// rt_uint8_t drain_cnt = 0;
|
||||
// struct mb_msg_t *pDrain = RT_NULL;
|
||||
// while (drain_cnt < 8) {
|
||||
// ret = rt_mb_recv(pTS->mb, (rt_uint32_t *)&pDrain, 0);
|
||||
// if (ret != RT_EOK) break;
|
||||
// if (pDrain != RT_NULL) {
|
||||
// if (pDrain->payload != RT_NULL) rt_free(pDrain->payload);
|
||||
// rt_free(pDrain);
|
||||
// }
|
||||
// drain_cnt++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// run = pROLL->run;
|
||||
// rt_mutex_release(pTHR->mutex);
|
||||
// switch (run) {
|
||||
// // rt_kprintf("-------- ROLL SOU TIME START \n --------");
|
||||
// case RUN_AUTO: {
|
||||
// if(pROLL->mode!=0){
|
||||
|
||||
// }else{
|
||||
// idx = index%(TOTAL_SOU_CHS); // [0, 3]
|
||||
// // rt_kprintf("start_idx = %d",idx);
|
||||
// if (0 == chrgsouth.enable[idx]) { // 通道未启用
|
||||
// index++;
|
||||
// rt_thread_mdelay(5);
|
||||
// continue;
|
||||
// } else { // 通道启用
|
||||
// chrg_led_flashing(IDX_LED3, TIMES_ONE, PULSE_TIME*2, PULSE_TIME*2);
|
||||
// if (idx != (rt_uint8_t)pROLL->idx) {
|
||||
// pROLL->idx = (eIDX_SOU_CH)idx;
|
||||
// chrg_south_switch((eIDX_SOU_CH)idx);
|
||||
// pROLL->part = MB_R_PART1;
|
||||
// }
|
||||
// chrg_eload_refresh(ID_ELOAD, pROLL->part);
|
||||
// if (pROLL->part < TOTAL_MB_R) {
|
||||
// //pROLL->part++;
|
||||
// //if (pROLL->part > MB_R_PART1) { // 仅1条,若需轮巡全部,注释此条件
|
||||
// index++;
|
||||
// //}
|
||||
// } else {
|
||||
// index++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case RUN_LCD: {
|
||||
// struct chrg_sou_cmd_t cmd;
|
||||
// rt_uint8_t do_cmd = 0;
|
||||
// rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// if (sou_cmd_dequeue(&cmd) == 0) {
|
||||
// do_cmd = 1;
|
||||
// pROLL->ch = cmd.ch;
|
||||
// }
|
||||
// rt_mutex_release(pTHR->mutex);
|
||||
// if (do_cmd) {
|
||||
// chrg_south_switch(cmd.ch);
|
||||
// chrg_eload_write_reg(ID_ELOAD, cmd.reg, cmd.value);
|
||||
// }
|
||||
// rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// if (!sou_cmd_exists()) {
|
||||
// pROLL->run = RUN_AUTO;
|
||||
// }
|
||||
// rt_mutex_release(pTHR->mutex);
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case RUN_CONSOLE: {
|
||||
// chrg_south_switch((eIDX_SOU_CH)pROLL->ch);
|
||||
// chrg_eload_refresh(ID_ELOAD, pROLL->part);
|
||||
// }
|
||||
// break;
|
||||
// case RUN_UPDATA:{
|
||||
// chrg_south_switch((eIDX_SOU_CH)pROLL->ch);
|
||||
// if(pROLL->send_flag==1){
|
||||
// chrg_eload_send_ymodem_data(pROLL->updata_data,pROLL->leng);
|
||||
// pROLL->send_flag = 0;
|
||||
// }
|
||||
// /* 升级模式不下发Modbus邮件,等待south线程捕获ymodem应答后继续 */
|
||||
// rt_thread_mdelay(50);
|
||||
// continue;
|
||||
// }
|
||||
// break;
|
||||
// case RUN_COM: {
|
||||
// chrg_south_switch((eIDX_SOU_CH)pROLL->ch);
|
||||
// chrg_eload_write_reg(ID_ELOAD, pROLL->reg, pROLL->value);
|
||||
// }
|
||||
// break;
|
||||
// case RUN_NONE:
|
||||
// default:
|
||||
// rt_thread_mdelay(5);
|
||||
// continue;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// ret = rt_mb_recv(pTS->mb, (rt_uint32_t *)&pMB_R, 100 ); // 超时 200ms
|
||||
// if ((RT_EOK == ret)&&(RT_NULL != pMB_R)) { // 存在返回数据
|
||||
// if (0 == mb_crc16(pMB_R->payload, pMB_R->length)) {
|
||||
// if (RUN_AUTO != run) { // 恢复自动轮巡或继续执行待发命令
|
||||
// rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// pROLL->run = sou_cmd_exists() ? RUN_LCD : RUN_AUTO;
|
||||
// rt_mutex_release(pTHR->mutex);
|
||||
// }
|
||||
// else { // 自动轮巡态,分析接收的数据
|
||||
// #if DEBUG_SOUTH
|
||||
// rt_kprintf("length = %d",pMB_R->length);
|
||||
// #endif
|
||||
// if(pMB_R->length!=43){//31修改成43,一共19个寄存器*2+4,多读了4位
|
||||
// ret = rt_mb_recv(pTS->mb, (rt_uint32_t *)&pMB_R, 30); // 超时 200ms
|
||||
// #if DEBUG_SOUTH
|
||||
// rt_kprintf("ret = %d\n",ret);
|
||||
// #endif
|
||||
// if ((RT_EOK == ret)&&(RT_NULL != pMB_R)) { // 存在返回数据
|
||||
// chrg_eload_parse(idx, pROLL->part, pMB_R->payload, pMB_R->length);
|
||||
// }
|
||||
// }
|
||||
// else chrg_eload_parse(idx, pROLL->part, pMB_R->payload, pMB_R->length);
|
||||
// }
|
||||
// }
|
||||
// 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(200); // 间隔 20ms
|
||||
// rt_thread_mdelay(10); // 间隔 200ms
|
||||
// } else { // 设备应答超时
|
||||
// if (RUN_AUTO != run) { // 非自动轮巡
|
||||
// rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
// pROLL->run = sou_cmd_exists() ? RUN_LCD : RUN_AUTO; // 切换会自动轮巡或继续执行待发命令
|
||||
// rt_mutex_release(pTHR->mutex);
|
||||
// }
|
||||
// }
|
||||
// // rt_kprintf("-------- ROLL SOU TIME END\n --------");
|
||||
// }
|
||||
// }
|
||||
|
||||
// #if 1
|
||||
// static int south_send(rt_uint8_t argc, char **argv)
|
||||
// {
|
||||
// int ch = 0, pt = 0;
|
||||
|
||||
// if (3 != argc) {
|
||||
// rt_kprintf("help : %s [0-3] [0-1]\r\n", argv[0]);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// ch = (rt_uint8_t)atoi(argv[1]);
|
||||
// if ((ch < 0)||(ch >= TOTAL_SOU_CHS)) {
|
||||
// rt_kprintf("help : %s [0-3] [0-1]\r\n", argv[0]);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// pt = (rt_uint8_t)atoi(argv[2]);
|
||||
// if ((pt < 0)||(pt >= TOTAL_MB_R)) {
|
||||
// rt_kprintf("help : %s [0-3] [0-1]\r\n", argv[0]);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
// pROLL->run = RUN_CONSOLE;
|
||||
// pROLL->ch = (rt_uint8_t)ch;
|
||||
// pROLL->part = (rt_uint8_t)pt;
|
||||
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// MSH_CMD_EXPORT(south_send, south send test);
|
||||
|
||||
// static int south_run (int argc, char **argv)
|
||||
// {
|
||||
// if (2 != argc) {
|
||||
// rt_kprintf("help : %s start|stop\r\n", argv[0]);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
|
||||
// if (rt_strcmp(argv[1], "start") == 0) {
|
||||
// pROLL->run = RUN_AUTO;
|
||||
// } else if (rt_strcmp(argv[1], "stop") == 0) {
|
||||
// pROLL->run = RUN_NONE;
|
||||
// } else {
|
||||
// rt_kprintf("help : %s start|stop\r\n", argv[0]);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// MSH_CMD_EXPORT(south_run, south auto run);
|
||||
|
||||
// #endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
文件名称 : chrg_roll_sou.c
|
||||
完成日期 :
|
||||
@@ -21,13 +391,38 @@
|
||||
#define LOG_TAG "chrg.rollsou"
|
||||
#include <rtdbg.h>
|
||||
|
||||
chrg_rollsou_com_t g_sou_com_batch = {0};
|
||||
|
||||
struct chrg_rollsou_t chrgrollsou = {
|
||||
.run = RUN_AUTO,
|
||||
.ch = IDX_SOU_CH1,
|
||||
.part = MB_R_PART1,
|
||||
|
||||
};
|
||||
|
||||
//向通道批量缓存添加一条寄存器
|
||||
int chrg_sou_com_batch_add_reg(eIDX_SOU_CH ch, rt_uint16_t reg, rt_uint16_t val)
|
||||
{
|
||||
if(ch >= TOTAL_SOU_CHS) return -1;
|
||||
sou_com_batch_ch_t *pBatch = &g_sou_com_batch.ch[ch];
|
||||
if(pBatch->reg_cnt >= SOU_COM_BATCH_REG_MAX)
|
||||
{
|
||||
LOG_E("sou com batch reg full");
|
||||
return -2;
|
||||
}
|
||||
pBatch->reg_list[pBatch->reg_cnt] = reg;
|
||||
pBatch->val_list[pBatch->reg_cnt] = val;
|
||||
pBatch->reg_cnt++;
|
||||
pBatch->pending = RT_TRUE;
|
||||
return 0;
|
||||
}
|
||||
//启动批量下发(填充完影子结构体后调用)
|
||||
void chrg_sou_com_sou_set(void)
|
||||
{
|
||||
struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU];
|
||||
struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
pROLL->run = RUN_COM;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_set_sou_reg
|
||||
@@ -51,6 +446,31 @@ void chrg_set_sou_reg (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t value)
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_set_sou_reg
|
||||
函数描述: 南向通道设置寄存器请求命令
|
||||
输入参数: idx:通道 reg:寄存器地址 value:寄存器值
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
void chrg_set_sou_reg_com (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t value)
|
||||
{
|
||||
struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU];
|
||||
struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
|
||||
pROLL->ch = idx;
|
||||
pROLL->reg = reg;
|
||||
pROLL->value = value;
|
||||
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
pROLL->run = RUN_COM;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
rt_kprintf("ch=:%d,reg=%02x,value=%02x\n",idx,reg,value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_roll_sou_thread_entry
|
||||
函数描述: 南向通道轮巡请求数据线程体
|
||||
@@ -73,16 +493,16 @@ void chrg_roll_sou_thread_entry (void *data)
|
||||
struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
struct chrg_thread_t *pTS = &chrgthr[IDX_THR_SOUTH];
|
||||
struct mb_msg_t *pMB_R = RT_NULL;
|
||||
|
||||
sou_com_batch_ch_t *pCurBatch = RT_NULL;
|
||||
while (1) {
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
run = pROLL->run;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
|
||||
rt_uint8_t batch_ch = 0; // 缓存当前正在下发的批量通道
|
||||
// rt_kprintf("------ROLL SOU START \n--------");
|
||||
switch (run) {
|
||||
case RUN_AUTO: {
|
||||
idx = index%(TOTAL_SOU_CHS); // [0, 3]
|
||||
|
||||
if (0 == chrgsouth.enable[idx]) { // 通道未启用
|
||||
index++;
|
||||
rt_thread_mdelay(10);
|
||||
@@ -94,14 +514,8 @@ void chrg_roll_sou_thread_entry (void *data)
|
||||
chrg_south_switch((eIDX_SOU_CH)idx);
|
||||
pROLL->part = MB_R_PART1;
|
||||
}
|
||||
|
||||
chrg_eload_refresh(ID_ELOAD, pROLL->part);
|
||||
if (pROLL->part < TOTAL_MB_R) {
|
||||
pROLL->part++;
|
||||
if (pROLL->part > MB_R_PART1) { // 仅1条,若需轮巡全部,注释此条件
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
@@ -114,6 +528,36 @@ void chrg_roll_sou_thread_entry (void *data)
|
||||
}
|
||||
break;
|
||||
|
||||
case RUN_COM:
|
||||
{
|
||||
pCurBatch = RT_NULL;
|
||||
// 遍历查找有待下发批量任务的通道
|
||||
for(idx = 0; idx < TOTAL_SOU_CHS; idx++)
|
||||
{
|
||||
if(g_sou_com_batch.ch[idx].pending == RT_TRUE)
|
||||
{
|
||||
pCurBatch = &g_sou_com_batch.ch[idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 无任何批量任务,切回自动轮巡
|
||||
if(pCurBatch == RT_NULL)
|
||||
{
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
pROLL->run = RUN_AUTO;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
break;
|
||||
}
|
||||
// 切换当前通道串口
|
||||
chrg_south_switch((eIDX_SOU_CH)idx);
|
||||
batch_ch = idx;
|
||||
// 发送当前下标寄存器
|
||||
rt_uint16_t reg = pCurBatch->reg_list[pCurBatch->cur_idx];
|
||||
rt_uint16_t val = pCurBatch->val_list[pCurBatch->cur_idx];
|
||||
chrg_eload_write_reg(ID_ELOAD, reg, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case RUN_CONSOLE: {
|
||||
chrg_south_switch((eIDX_SOU_CH)pROLL->ch);
|
||||
chrg_eload_refresh(ID_ELOAD, pROLL->part);
|
||||
@@ -127,41 +571,80 @@ void chrg_roll_sou_thread_entry (void *data)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = rt_mb_recv(pTS->mb, (rt_uint32_t *)&pMB_R, 200); // 超时 200ms
|
||||
if ((RT_EOK == ret)&&(RT_NULL != pMB_R)) { // 存在返回数据
|
||||
if (0 == mb_crc16(pMB_R->payload, pMB_R->length)) {
|
||||
if (RUN_AUTO != run) { // 恢复自动轮巡
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
pROLL->run = RUN_AUTO;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
} else { // 自动轮巡态,分析接收的数据
|
||||
ret = rt_mb_recv(pTS->mb, (rt_uint32_t *)&pMB_R, 50);
|
||||
if ((RT_EOK == ret)&&(RT_NULL != pMB_R))
|
||||
{
|
||||
if (0 == mb_crc16(pMB_R->payload, pMB_R->length))
|
||||
{
|
||||
if (RUN_AUTO != run)
|
||||
{
|
||||
if(run == RUN_COM)
|
||||
{
|
||||
// CRC校验成功,本条发送完成,下标+1,下发下一条
|
||||
sou_com_batch_ch_t *pBatch = &g_sou_com_batch.ch[batch_ch];
|
||||
pBatch->cur_idx++;
|
||||
// 当前通道全部指令发完,清除pending标记
|
||||
if(pBatch->cur_idx >= pBatch->reg_cnt)
|
||||
{
|
||||
pBatch->pending = RT_FALSE;
|
||||
pBatch->cur_idx = 0;
|
||||
pBatch->reg_cnt = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// LCD/CONSOLE单条模式,应答成功直接切回自动轮巡
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
pROLL->run = RUN_AUTO;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// AUTO自动采集,解析返回数据
|
||||
chrg_eload_parse(idx, pROLL->part, pMB_R->payload, pMB_R->length);
|
||||
}
|
||||
} else {
|
||||
LOG_E("crc failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("crc failed, resend current reg");
|
||||
// CRC错误,不递增cur_idx,下一轮重发本条
|
||||
}
|
||||
|
||||
if (RT_NULL != pMB_R->payload) {
|
||||
// 释放报文内存
|
||||
if (RT_NULL != pMB_R->payload)
|
||||
{
|
||||
rt_free(pMB_R->payload);
|
||||
pMB_R->payload = RT_NULL;
|
||||
}
|
||||
|
||||
if (RT_NULL != pMB_R) {
|
||||
if (RT_NULL != pMB_R)
|
||||
{
|
||||
rt_free(pMB_R);
|
||||
pMB_R = RT_NULL;
|
||||
}
|
||||
|
||||
rt_thread_mdelay(200); // 间隔 200ms
|
||||
} else { // 设备应答超时
|
||||
if (RUN_AUTO != run) { // 非自动轮巡
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
pROLL->run = RUN_AUTO; // 切换会自动轮巡
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
rt_thread_mdelay(20);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 应答超时处理
|
||||
if (RUN_AUTO != run)
|
||||
{
|
||||
if(run == RUN_COM)
|
||||
{
|
||||
// 批量下发超时:不递增cur_idx,下一轮循环重发当前寄存器
|
||||
LOG_E("com batch timeout, resend current reg");
|
||||
}
|
||||
else
|
||||
{
|
||||
// LCD/CONSOLE单条超时,切回自动轮巡
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
pROLL->run = RUN_AUTO;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rt_kprintf("------ROLL SOU END \n--------");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
版本历史 : 创建原始版本
|
||||
说明 :
|
||||
******************************************************************************/
|
||||
|
||||
#include "chrg_south.h"
|
||||
#ifndef __CHRG_ROLL_SOU_H__
|
||||
#define __CHRG_ROLL_SOU_H__
|
||||
|
||||
@@ -15,9 +15,29 @@
|
||||
|
||||
#define THR_NAME_ROLL_SOU "thr.rollsou"
|
||||
|
||||
// 单通道批量下发缓存:保存当前需要同步的寄存器列表
|
||||
#define SOU_COM_BATCH_REG_MAX 16
|
||||
typedef struct
|
||||
{
|
||||
rt_uint16_t reg_cnt; // 当前待下发寄存器数量
|
||||
rt_uint16_t reg_list[SOU_COM_BATCH_REG_MAX]; // 寄存器地址数组
|
||||
rt_uint16_t val_list[SOU_COM_BATCH_REG_MAX]; // 对应寄存器值数组
|
||||
rt_uint8_t cur_idx; // 当前下发到第几条
|
||||
rt_bool_t pending; // 本通道有待下发批量指令
|
||||
} sou_com_batch_ch_t;
|
||||
|
||||
// COM批量下发总控结构体
|
||||
typedef struct
|
||||
{
|
||||
sou_com_batch_ch_t ch[TOTAL_SOU_CHS];
|
||||
} chrg_rollsou_com_t;
|
||||
|
||||
// 全局批量下发实例
|
||||
extern chrg_rollsou_com_t g_sou_com_batch;
|
||||
|
||||
|
||||
struct chrg_rollsou_t {
|
||||
rt_uint8_t run; // 下一轮运行方式 1:自动轮巡 2:LCD触发插入 3:控制台触发插入
|
||||
rt_uint8_t run; // 下一轮运行方式 1:自动轮巡 2:LCD触发插入 3:控制台触发插入4.com触发插入
|
||||
rt_uint8_t part; // 自动轮巡时,多条命令序号(若存在多条命令时)
|
||||
|
||||
rt_uint8_t idx; // 自动轮巡时,通道序号
|
||||
@@ -25,7 +45,11 @@ struct chrg_rollsou_t {
|
||||
|
||||
rt_uint16_t reg; // LCD 触发时,寄存器地址
|
||||
rt_uint16_t value; // LCD 触发时,寄存器值
|
||||
|
||||
|
||||
rt_uint8_t *updata_data;//南向升级的数据
|
||||
rt_uint16_t leng;
|
||||
rt_uint8_t send_flag; //发送标志位
|
||||
rt_uint8_t mode;// 0 为正常轮询,1为升级,2为校准
|
||||
};
|
||||
|
||||
extern struct chrg_rollsou_t chrgrollsou;
|
||||
@@ -39,7 +63,15 @@ extern struct chrg_rollsou_t chrgrollsou;
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern void chrg_set_sou_reg (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t value);
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_set_sou_reg_com
|
||||
函数描述: com端南向通道设置寄存器请求命令(批量下发机制)
|
||||
输入参数: idx:通道 reg:寄存器地址 value:寄存器值
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: 每条命令加入批量队列,自动启动顺序下发,全部完成后切回轮巡
|
||||
*****************************************************************/
|
||||
extern void chrg_set_sou_reg_com (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t value);
|
||||
/*****************************************************************
|
||||
函数名称: chrg_roll_sou_thread_entry
|
||||
函数描述: 南向通道轮巡请求数据线程体
|
||||
@@ -50,7 +82,9 @@ extern void chrg_set_sou_reg (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t valu
|
||||
*****************************************************************/
|
||||
extern void chrg_roll_sou_thread_entry (void *data);
|
||||
|
||||
|
||||
extern void chrg_send_sou_upadata_data (rt_uint8_t *buf,rt_uint16_t leng);
|
||||
extern void chrg_sou_com_sou_set(void);
|
||||
extern int chrg_sou_com_batch_add_reg(eIDX_SOU_CH ch, rt_uint16_t reg, rt_uint16_t val);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "chrg_roll_sou.h"
|
||||
#include "chrg_switch.h"
|
||||
#include "chrg_utils.h"
|
||||
#include "chrg_eload.h"
|
||||
#include "ulog.h"
|
||||
|
||||
//#define LOG_TAG "chrg.sou"
|
||||
@@ -29,6 +30,7 @@ struct chrg_south_t chrgsouth = {
|
||||
.tty = RT_NULL,
|
||||
.rb = RT_NULL,
|
||||
.enable = {1, 1, 1, 1},
|
||||
.online = {0, 0, 0, 0},
|
||||
};
|
||||
|
||||
/*****************************************************************
|
||||
@@ -155,10 +157,8 @@ int chrg_south_send (rt_uint8_t *data, rt_size_t length)
|
||||
struct chrg_tty_t *pTTY = chrgsouth.tty;
|
||||
|
||||
if (RT_NULL != pTTY) {
|
||||
// LOG_HEX("sendS", 32, data, length);
|
||||
ret = chrg_tty_send(pTTY, data, length);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ static int chrg_south_frame_head (struct rt_ringbuffer *rb, rt_uint8_t *head, eI
|
||||
|
||||
len_rb = rt_ringbuffer_data_len(rb);
|
||||
if (len_rb < MB_ACK_HEAD_SIZE) { // 帧头3字节
|
||||
rt_kprintf("len_rb=:%d",len_rb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -357,7 +358,7 @@ void chrg_south_thread_entry (void *data)
|
||||
return ;
|
||||
}
|
||||
|
||||
chrg_tty_set_recv_tmo(pTTY, 100);
|
||||
chrg_tty_set_recv_tmo(pTTY, 10);
|
||||
if (chrg_tty_connect(pTTY) != RT_EOK) {
|
||||
chrg_tty_destory(pTTY);
|
||||
return;
|
||||
@@ -380,6 +381,19 @@ void chrg_south_thread_entry (void *data)
|
||||
}
|
||||
|
||||
rt_ringbuffer_put(pSOU->rb, pSOU->rx_buf, len);
|
||||
|
||||
/* 升级模式下: 南向板返回原始ymodem应答字节(ACK/NAK/C),非Modbus帧 */
|
||||
if (chrgrollsou.mode == 1) {
|
||||
rt_uint8_t resp_byte;
|
||||
while (rt_ringbuffer_data_len(pSOU->rb) > 0) {
|
||||
rt_ringbuffer_getchar(pSOU->rb, &resp_byte);
|
||||
if (resp_byte == ACK || resp_byte == NAK || resp_byte == ACK_C) {
|
||||
chrg_eload_set_ymodem_resp(resp_byte);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//LOG_HEX("recvS", 32, pSOU->rx_buf, len);
|
||||
|
||||
if (1 == pSOU->frame.findhead) {
|
||||
@@ -394,7 +408,6 @@ void chrg_south_thread_entry (void *data)
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
static int south_ch(rt_uint8_t argc, char **argv)
|
||||
|
||||
@@ -39,11 +39,14 @@ struct chrg_south_t {
|
||||
rt_uint8_t rx_buf[SIZE_BUF_TTY];
|
||||
|
||||
rt_uint8_t enable[TOTAL_SOU_CHS]; // 通路使能
|
||||
rt_uint8_t online[TOTAL_SOU_CHS]; // 在线状态
|
||||
//rt_uint8_t manual; // 0: 程序自动 1:手动插入命令 2:插入设置模式
|
||||
//eIDX_SOU_CH idx; // 当前通路
|
||||
eIDX_SOU_CH idx; // 当前通路
|
||||
eIDX_MB_PART part;
|
||||
|
||||
struct chrg_eload_t eload[TOTAL_SOU_CHS]; // 负载
|
||||
|
||||
rt_uint8_t rel_flag[8];
|
||||
};
|
||||
|
||||
extern struct chrg_south_t chrgsouth;
|
||||
|
||||
@@ -59,7 +59,7 @@ struct chrg_thread_t chrgthr[TOTAL_THRS] = {
|
||||
.mask = EN_THR_MUTEX | EN_THR_MAILBOX,
|
||||
.index = IDX_THR_COMM,
|
||||
.priority = PRI_THR_COMM,
|
||||
.stack = 2048,
|
||||
.stack = 4096,
|
||||
.tick = 20,
|
||||
.entry = chrg_comm_thread_entry,
|
||||
},
|
||||
@@ -74,7 +74,7 @@ struct chrg_thread_t chrgthr[TOTAL_THRS] = {
|
||||
.mq = RT_NULL,
|
||||
.mask = EN_THR_MUTEX,
|
||||
.index = IDX_THR_LCD,
|
||||
.priority = PRI_THR_LCD,
|
||||
.priority = PRI_THR_LCD-2,
|
||||
.stack = 2048,
|
||||
.tick = 20,
|
||||
.entry = chrg_lcd_thread_entry,
|
||||
@@ -159,7 +159,18 @@ rt_err_t chrg_thread_mb_send (eIDX_THRS idx, void *data)
|
||||
if (RT_NULL != pTHR->mb) {
|
||||
ret = rt_mb_send(pTHR->mb, (rt_uint32_t)data);
|
||||
if (RT_EOK != ret) {
|
||||
LOG_E("mb send failed. [%d]", ret);
|
||||
if (ret == -RT_EFULL) {
|
||||
LOG_E("mb full, drop message. [%d]", ret);
|
||||
if (RT_NULL != data) {
|
||||
struct mb_msg_t *pMB = (struct mb_msg_t *)data;
|
||||
if (RT_NULL != pMB->payload) {
|
||||
rt_free(pMB->payload);
|
||||
}
|
||||
rt_free(pMB);
|
||||
}
|
||||
} else {
|
||||
LOG_E("mb send failed. [%d]", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +238,7 @@ int chrg_thread_create (eIDX_THRS idx)
|
||||
}
|
||||
|
||||
if (pTHR->mask & EN_THR_MAILBOX) {
|
||||
pTHR->mb = rt_mb_create(pTHR->name, 16, RT_IPC_FLAG_FIFO);
|
||||
pTHR->mb = rt_mb_create(pTHR->name, 64, RT_IPC_FLAG_FIFO);
|
||||
if (RT_NULL == pTHR->mb) {
|
||||
LOG_E("create mb '%s' failed.", pTHR->name);
|
||||
return -RT_ERROR;
|
||||
|
||||
@@ -30,12 +30,12 @@ typedef enum {
|
||||
TOTAL_THRS
|
||||
} eIDX_THRS;
|
||||
|
||||
#define PRI_THR_NORTH 15
|
||||
#define PRI_THR_SOUTH 14
|
||||
#define PRI_THR_COMM 13
|
||||
#define PRI_THR_LCD 12
|
||||
#define PRI_THR_ROLL_NOR 16
|
||||
#define PRI_THR_ROLL_SOU 16
|
||||
#define PRI_THR_NORTH 10
|
||||
#define PRI_THR_SOUTH 10
|
||||
#define PRI_THR_COMM 9
|
||||
#define PRI_THR_LCD 8
|
||||
#define PRI_THR_ROLL_NOR 11
|
||||
#define PRI_THR_ROLL_SOU 11
|
||||
|
||||
|
||||
#define EN_THR_NONE 0x00
|
||||
@@ -67,6 +67,7 @@ struct chrg_thread_t {
|
||||
void (*entry)(void *parameter); // 线程体入口
|
||||
};
|
||||
|
||||
|
||||
extern struct chrg_thread_t chrgthr[TOTAL_THRS];
|
||||
|
||||
/*****************************************************************
|
||||
|
||||
@@ -23,9 +23,9 @@ typedef enum {
|
||||
} eIDX_CH;
|
||||
|
||||
typedef enum {
|
||||
ID_SINK = 0x01, // SINK 的 ID 为 1, 波特率 200K
|
||||
ID_SOURCE = 0x02, // SOURCE 的 ID 为 2, 波特率 200K
|
||||
ID_ELOAD = 0x03, // LOAD ID 3, 波特率 115200
|
||||
ID_SINK = 0x01, // SINK 的 ID 为 1, 波特率 200K //sink协议板
|
||||
ID_SOURCE = 0x02, // SOURCE 的 ID 为 2, 波特率 200K //source协议板
|
||||
ID_ELOAD = 0x03, // LOAD ID 3, 波特率 115200 //功率板
|
||||
} eIDX_ID;
|
||||
|
||||
enum {
|
||||
@@ -33,9 +33,35 @@ enum {
|
||||
RUN_AUTO, // 执行轮巡
|
||||
RUN_LCD, // 执行LCD触发
|
||||
RUN_CONSOLE, // 执行控制台触发
|
||||
|
||||
RUN_UPDATA,
|
||||
RUN_COM, //执行com触发
|
||||
};
|
||||
|
||||
/* ======================== Ymodem 协议常量 (CRC-16/XMODEM) ======================== */
|
||||
/* Ymodem 协议状态枚举 */
|
||||
typedef enum {
|
||||
Ymodem_No = 0xFF, // 非升级模式
|
||||
Ymodem_Wait = 0, // 空闲等待,定时发送'C'
|
||||
Ymodem_Rec_Start, // 收到文件名帧(SOH),待CRC校验
|
||||
Ymodem_Rec_1024, // 数据帧接收中(SOH=128B / STX=1024B)
|
||||
Ymodem_Rec_End, // 收到EOT,传输结束握手
|
||||
Ymodem_Rec_Finish // 升级完成,准备收尾
|
||||
} Ymodem_state;
|
||||
|
||||
/* Ymodem 协议控制字符 */
|
||||
#define SOH 0x01 // 128字节数据包帧头
|
||||
#define STX 0x02 // 1024字节数据包帧头
|
||||
#define EOT 0x04 // 传输结束
|
||||
#define ACK 0x06 // 正确应答
|
||||
#define ACK_C 0x43 // 'C',CRC模式请求
|
||||
#define NAK 0x15 // 错误应答
|
||||
#define YM_CAN 0x18 // 取消传输
|
||||
|
||||
/* Ymodem 数据包大小常量 */
|
||||
#define YMODEM_SOH_SIZE 133 // SOH包总长: 1+1+1+128+2
|
||||
#define YMODEM_STX_SIZE 1029 // STX包总长: 1+1+1+1024+2
|
||||
#define YMODEM_DATA_OFFSET 3 // 有效数据在包内偏移(跳帧头+块号+反码)
|
||||
|
||||
// 电压电流极值
|
||||
struct vc_mm_t {
|
||||
rt_uint16_t max_vol; // 最大电压 mV
|
||||
@@ -59,6 +85,7 @@ enum {
|
||||
|
||||
// PD协议数据
|
||||
struct vc_pd_t {
|
||||
rt_uint8_t group_num; // 挡位数量
|
||||
rt_uint8_t src_type; // 源类型
|
||||
rt_uint8_t pps_type; // PPS类型
|
||||
struct vc_mm_t mm[2]; // 电压电流极值
|
||||
|
||||
@@ -11,11 +11,68 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "chrg_south.h"
|
||||
#include "chrg_roll_sou.h"
|
||||
#include "chrg_north.h"
|
||||
#include "chrg_eload.h"
|
||||
#include "chrg_lcd.h"
|
||||
#include "chrg_regs.h"
|
||||
#include "chrg_utils.h"
|
||||
#include "chrg_south.h"
|
||||
extern void LCD_SHOW(rt_uint8_t idx, struct eload_p1_t *pP1, struct chrg_eload_t *pLOAD, struct chrg_switch_t *pSW, rt_uint8_t online);
|
||||
static rt_uint16_t ripple_base[TOTAL_SOU_CHS] = {0};
|
||||
static rt_uint8_t ripple_cal_flag[TOTAL_SOU_CHS] = {0};
|
||||
rt_uint16_t real_ripple[TOTAL_SOU_CHS] = {0};
|
||||
|
||||
/* ======================== Ymodem 升级应答缓存 ======================== */
|
||||
static rt_uint8_t g_eload_ymodem_resp = 0; // 南向返回的ymodem应答字节(0=无应答)
|
||||
static rt_uint8_t g_eload_ymodem_ready = 0; // 应答就绪标志(1=有新应答待取)
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_eload_set_ymodem_resp
|
||||
函数描述: 存储南向板返回的ymodem应答字节(由chrg_roll_sou在RUN_UPDATA调用)
|
||||
输入参数: resp: 南向ymodem应答 (ACK=0x06 / NAK=0x15 / 'C'=0x43)
|
||||
*****************************************************************/
|
||||
void chrg_eload_set_ymodem_resp(rt_uint8_t resp)
|
||||
{
|
||||
g_eload_ymodem_resp = resp;
|
||||
g_eload_ymodem_ready = 1;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_eload_get_ymodem_resp
|
||||
函数描述: 读取南向ymodem应答字节(由chrg_comm的ymodem_send调用),读取后自动清除
|
||||
返回说明: 南向应答字节,0表示无新应答
|
||||
*****************************************************************/
|
||||
rt_uint8_t chrg_eload_get_ymodem_resp(void)
|
||||
{
|
||||
rt_uint8_t resp = 0;
|
||||
if (g_eload_ymodem_ready) {
|
||||
resp = g_eload_ymodem_resp;
|
||||
g_eload_ymodem_ready = 0;
|
||||
g_eload_ymodem_resp = 0;
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_eload_clear_ymodem_resp
|
||||
函数描述: 清除ymodem应答缓存(状态切换时调用)
|
||||
*****************************************************************/
|
||||
void chrg_eload_clear_ymodem_resp(void)
|
||||
{
|
||||
g_eload_ymodem_resp = 0;
|
||||
g_eload_ymodem_ready = 0;
|
||||
}
|
||||
|
||||
static int memcmp_8bytes(const rt_uint8_t *buf1, const rt_uint8_t *buf2)
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (buf1[i] != buf2[i]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_eload_read_regs
|
||||
@@ -48,19 +105,111 @@ int chrg_eload_read_regs (rt_uint8_t addr, rt_uint16_t reg, rt_uint16_t len)
|
||||
返回说明: <0: 错误 >0:发送数据长度
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
int chrg_eload_write_reg (rt_uint8_t addr, rt_uint16_t reg, rt_uint16_t value)
|
||||
|
||||
int chrg_eload_write_reg (rt_uint8_t addr, rt_uint16_t reg, rt_uint16_t value)
|
||||
{
|
||||
rt_uint8_t buf[8] = {0};
|
||||
rt_uint16_t crc = 0;
|
||||
buf[0] = addr;
|
||||
buf[1] = MB_REGISTER_WR;
|
||||
u16_to_u8v(reg, &buf[2]);
|
||||
u16_to_u8v(value, &buf[4]);
|
||||
crc = mb_crc16(buf, 6);
|
||||
u16_to_u8v(swap_u16(crc), &buf[6]);
|
||||
rt_kprintf("addr = %d,reg = %02x,value = %02x\n",addr,reg,value);
|
||||
return chrg_south_send(buf, 8);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_eload_send_ymodem_data
|
||||
函数描述: 向南向发送ymodem协议升级数据
|
||||
输入参数: buf:数据缓冲区 leng:数据长度
|
||||
输出参数: -
|
||||
返回说明: <0: 错误 >0:发送数据长度
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
|
||||
int chrg_eload_send_ymodem_data (rt_uint8_t *buf, rt_uint16_t leng)
|
||||
{
|
||||
rt_uint8_t buf[8] = {0};
|
||||
rt_uint16_t crc = 0;
|
||||
if(NULL == buf){
|
||||
return 0;
|
||||
}
|
||||
return chrg_south_send(buf, leng);
|
||||
}
|
||||
|
||||
buf[0] = addr;
|
||||
buf[1] = MB_REGISTER_WR;
|
||||
u16_to_u8v(reg, &buf[2]);
|
||||
u16_to_u8v(value, &buf[4]);
|
||||
crc = mb_crc16(buf, 6);
|
||||
u16_to_u8v(swap_u16(crc), &buf[6]);
|
||||
/**
|
||||
|
||||
return chrg_south_send(buf, 8);
|
||||
*/
|
||||
int chrg_eload_write_More_reg(rt_uint8_t addr,
|
||||
rt_uint16_t reg_start,
|
||||
rt_uint16_t reg_num,
|
||||
const rt_uint16_t *data_buf)
|
||||
{
|
||||
rt_uint16_t total_len = 7 + (reg_num * 2) + 2;
|
||||
rt_uint8_t buf[20] = {0};
|
||||
rt_uint16_t idx = 0;
|
||||
// 填充Modbus指令帧
|
||||
buf[0] = addr; // 0: 设备地址
|
||||
// rt_kprintf("addr=%d\r\n", addr);
|
||||
buf[1] = MB_REGISTER_MORE_WR; // 1: 功能码(固定0x10)
|
||||
idx += 2;
|
||||
u16_to_u8v(reg_start, &buf[idx]); // 2-3: 起始地址(idx从2开始)
|
||||
idx += 2;
|
||||
u16_to_u8v(reg_num, &buf[idx]); // 4-5: 寄存器数量
|
||||
idx += 2;
|
||||
buf[idx++] = reg_num * 2; // 6: 数据字节数
|
||||
// 填充多组数据
|
||||
for (rt_uint16_t i = 0; i < reg_num; i++) {
|
||||
u16_to_u8v(data_buf[i], &buf[idx]); // 逐个填充数据的高低8位
|
||||
idx += 2;
|
||||
}
|
||||
//计算并填充CRC16校验
|
||||
rt_uint16_t crc = mb_crc16(buf, idx); // 计算CRC
|
||||
u16_to_u8v(swap_u16(crc), &buf[idx]); // CRC字节序交换后填充
|
||||
idx += 2;
|
||||
// 发送指令
|
||||
return chrg_south_send(buf, idx);
|
||||
// 7. 释放动态缓冲区
|
||||
|
||||
}
|
||||
|
||||
void chrg_write_cv(rt_uint16_t curr,rt_uint16_t volt)
|
||||
{
|
||||
rt_uint16_t cv_value[4] = {0};
|
||||
cv_value[0] = 0x00;
|
||||
cv_value[1] = curr;
|
||||
cv_value[2] = 0x00;
|
||||
cv_value[3] = volt;
|
||||
chrg_eload_write_More_reg(ID_ELOAD, REG_CV, 4,cv_value);
|
||||
}
|
||||
|
||||
rt_uint8_t ret = 0;
|
||||
int chrg_eload_send_relay(rt_uint8_t cmd_type)
|
||||
{
|
||||
rt_uint8_t relay_cmd[8] = {0};
|
||||
rt_memcpy(relay_cmd, EXTRA_CMD_SOURCE, 8);
|
||||
switch (cmd_type) {
|
||||
case 0: // 停止(关闭俩个继电器)
|
||||
relay_cmd[5] = 0x00;
|
||||
relay_cmd[6] = 0xD9;
|
||||
relay_cmd[7] = 0xE8;
|
||||
break;
|
||||
case 1: // 电源模式(打开主继电器,同时关闭滤波继电器)
|
||||
break;
|
||||
case 2: // 打开滤波继电器,关闭主继电器
|
||||
relay_cmd[5] = 0x02;
|
||||
relay_cmd[6] = 0x58;
|
||||
relay_cmd[7] = 0x29;
|
||||
break;
|
||||
case 3: //打开俩个继电器
|
||||
relay_cmd[5] = 0x03;
|
||||
relay_cmd[6] = 0x99;
|
||||
relay_cmd[7] = 0xE9;
|
||||
break;
|
||||
default:
|
||||
return -1; // 无效命令类型
|
||||
}
|
||||
return chrg_south_send(relay_cmd, 8);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -76,7 +225,7 @@ int chrg_eload_refresh (rt_uint8_t addr, rt_uint8_t part)
|
||||
int ret = 0;
|
||||
|
||||
if (0 == part) {
|
||||
chrg_eload_read_regs(addr, REG_STA1, SIZE_P1_RD); // reg 0~13
|
||||
chrg_eload_read_regs(addr, REG_STA1, SIZE_P1_RD); // reg 0~18
|
||||
} else if (1 == part) {
|
||||
chrg_eload_read_regs(addr, REG_POWER, SIZE_P2_RD); // reg 20~39
|
||||
}
|
||||
@@ -94,87 +243,152 @@ int chrg_eload_refresh (rt_uint8_t addr, rt_uint8_t part)
|
||||
*****************************************************************/
|
||||
int chrg_eload_parse (rt_uint8_t idx, rt_uint8_t pt, rt_uint8_t *data, rt_uint16_t len)
|
||||
{
|
||||
rt_uint8_t pro = 0;
|
||||
if (idx >= TOTAL_SOU_CHS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct chrg_north_t *pNOR = &chrgnorth;
|
||||
struct chrg_south_t *pSOU = &chrgsouth;
|
||||
struct chrg_switch_t *pSW = &chrgnorth.sw[idx];
|
||||
struct chrg_eload_t *pLOAD = &chrgsouth.eload[idx];
|
||||
|
||||
switch (pt) {
|
||||
case MB_R_PART1: {
|
||||
if ((SIZE_P1_RD*2+5) != len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct eload_p1_t *pP1 = (struct eload_p1_t *)&data[3];
|
||||
|
||||
pLOAD->status1 = pP1->status1;
|
||||
pLOAD->status2 = pP1->status2;
|
||||
pLOAD->fault1 = pP1->fault1;
|
||||
pLOAD->fault2 = (rt_uint8_t)pP1->fault2;
|
||||
pLOAD->eload = swap_u16(pP1->eload);
|
||||
pLOAD->work = (rt_uint8_t)pP1->work_cmd;
|
||||
pLOAD->mode = (rt_uint8_t)pP1->work_mode;
|
||||
pLOAD->voltage = swap_u32(pP1->voltage);
|
||||
pLOAD->current = swap_u32(pP1->current);
|
||||
pLOAD->temperatue = pP1->temperature;
|
||||
pLOAD->version = pP1->version;
|
||||
pLOAD->address = (rt_uint8_t)pP1->addr;
|
||||
rt_kprintf("vol %d, cur %d\r\n", pLOAD->voltage, pLOAD->current);
|
||||
|
||||
char tmp[36] = {0};
|
||||
snprintf(tmp, 36, "main.CH%d_Volt_Show.val=%d",
|
||||
idx+1, pLOAD->voltage);
|
||||
chrg_lcd_send(tmp);
|
||||
rt_memset(tmp, 0, 36);
|
||||
|
||||
snprintf(tmp, 36, "status.CH%d_Volt_Sta.txt=\"%d.%03d\"",
|
||||
idx+1, pLOAD->voltage/1000, pLOAD->voltage%1000);
|
||||
chrg_lcd_send(tmp);
|
||||
rt_memset(tmp, 0, 36);
|
||||
|
||||
snprintf(tmp, 36, "main.CH%d_Curr_Show.val=%d",
|
||||
idx+1, pLOAD->current);
|
||||
chrg_lcd_send(tmp);
|
||||
rt_memset(tmp, 0, 36);
|
||||
|
||||
snprintf(tmp, 36, "status.CH%d_Curr_Sta.txt=\"%d.%03d\"",
|
||||
idx+1, pLOAD->current/1000, pLOAD->current%1000);
|
||||
chrg_lcd_send(tmp);
|
||||
rt_memset(tmp, 0, 36);
|
||||
|
||||
if (pP1->work_cmd == 0x100){
|
||||
if (pP1->work_mode == MODE_CONSTANT_VOLTAGE){
|
||||
snprintf(tmp, 36, "main.CH%d_Status.txt=\"恒压\"", idx+1);
|
||||
} else {
|
||||
snprintf(tmp, 36, "main.CH%d_Status.txt=\"恒流\"", idx+1);
|
||||
}
|
||||
} else {
|
||||
snprintf(tmp, 36, "main.CH%d_Status.txt=\"停止\"", idx+1);
|
||||
}
|
||||
chrg_lcd_send(tmp);
|
||||
rt_memset(tmp, 0, 36);
|
||||
|
||||
if ((SIZE_P1_RD*2+5) != len) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_R_PART2: {
|
||||
if ((SIZE_P2_RD*2+5) != len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct eload_p2_t *pP2 = (struct eload_p2_t *)&data[3];
|
||||
|
||||
struct eload_p1_t *pP1 = (struct eload_p1_t *)&data[3];
|
||||
// for(int i = 0;i<36;i++){
|
||||
// rt_kprintf("%02x ",data[i+3]);
|
||||
// }
|
||||
pLOAD->status1 = pP1->status1;
|
||||
pLOAD->status2 = pP1->status2;
|
||||
pLOAD->fault1 = pP1->fault1;
|
||||
pLOAD->fault2 = (rt_uint8_t)pP1->fault2;
|
||||
pLOAD->eload = swap_u16(pP1->eload);
|
||||
pLOAD->work = (rt_uint8_t)pP1->work_cmd;
|
||||
pLOAD->mode = (rt_uint8_t)pP1->work_mode;
|
||||
pLOAD->voltage = swap_u32(pP1->voltage);
|
||||
pLOAD->current = swap_u32(pP1->current);
|
||||
pLOAD->SHORT_volt = swap_u16(pP1->SHORT_volt);
|
||||
pLOAD->SHORT_curr = swap_u16(pP1->SHORT_curr);
|
||||
pLOAD->OCP_volt = swap_u16(pP1->OCP_volt);
|
||||
pLOAD->OCP_curr = swap_u16(pP1->OCP_curr);
|
||||
pLOAD->OCP_volt = swap_u16(pP1->OCP_volt);
|
||||
pLOAD->vpkp = swap_u16(pP1->Vpkp);
|
||||
pLOAD->vpkn = swap_u16(pP1->Vpkn);
|
||||
pLOAD->vpp = swap_u16(pP1->Vpp);
|
||||
pLOAD->Ripple = swap_u16(pP1->Ripple);
|
||||
pSW->Now_voltage = pLOAD->voltage;
|
||||
pSW->Now_current = pLOAD->current;
|
||||
if(idx == 0)
|
||||
#if LCD_OPEN
|
||||
// for(int i = 0;i<4;i++){
|
||||
// if(pNOR->sw[i].change_flag == 0x01){
|
||||
// pNOR->free_flag = 0x00;
|
||||
// }else {
|
||||
// pNOR->free_flag = 0x01;
|
||||
// }
|
||||
// }
|
||||
// rt_kprintf("ch=%d,free_flag=%d,",idx,pNOR->free_flag);
|
||||
if(pNOR->free_flag==0x01){
|
||||
LCD_SHOW(idx, pP1, pLOAD, pSW, pSOU->online[idx]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
usRegInBuf[INPUT_REG_CH0_STA1+idx*TOTAL_INPUT_CH_REGS] = pLOAD->status1;
|
||||
usRegInBuf[INPUT_REG_CH0_STA2+idx*TOTAL_INPUT_CH_REGS] = pLOAD->status2;
|
||||
usRegInBuf[INPUT_REG_CH0_FAULT1+idx*TOTAL_INPUT_CH_REGS] = pLOAD->fault1;
|
||||
usRegInBuf[INPUT_REG_CH0_FAULT2+idx*TOTAL_INPUT_CH_REGS] = pLOAD->fault2;
|
||||
usRegHoldBuf[HOLD_REG_CH0_ELOAD+idx*TOTAL_HOLD_CH_REGS] = pLOAD->eload;
|
||||
usRegHoldBuf[HOLD_REG_CH0_WORK+idx*TOTAL_HOLD_CH_REGS] = pLOAD->work;
|
||||
usRegHoldBuf[HOLD_REG_CH0_MODE+idx*TOTAL_HOLD_CH_REGS] = pLOAD->mode;
|
||||
usRegHoldBuf[HOLD_REG_CH0_VOL_H+idx*TOTAL_HOLD_CH_REGS] = (pLOAD->voltage>>16)&0xFFFF;
|
||||
usRegHoldBuf[HOLD_REG_CH0_VOL_L+idx*TOTAL_HOLD_CH_REGS] = pLOAD->voltage&0xFFFF;
|
||||
usRegHoldBuf[HOLD_REG_CH0_CUR_H+idx*TOTAL_HOLD_CH_REGS] = (pLOAD->current>>16)&0xFFFF;
|
||||
usRegHoldBuf[HOLD_REG_CH0_CUR_L+idx*TOTAL_HOLD_CH_REGS] = pLOAD->current&0xFFFF;
|
||||
// usRegHoldBuf[HOLD_REG_CH0_TEMP+idx*TOTAL_HOLD_CH_REGS] = pLOAD->temperatue;
|
||||
// usRegHoldBuf[HOLD_REG_CH0_VERSION+idx*TOTAL_HOLD_CH_REGS] = pLOAD->version;
|
||||
// usRegHoldBuf[HOLD_REG_CH0_ADDR+idx*TOTAL_HOLD_CH_REGS] = pLOAD->address;
|
||||
usRegHoldBuf[TEST_SHORT_CH0_VOLT+idx*TOTAL_HOLD_CH_REGS] = pLOAD->SHORT_volt;
|
||||
usRegHoldBuf[TEST_SHORT_CHO_CURR+idx*TOTAL_HOLD_CH_REGS] = pLOAD->SHORT_curr;
|
||||
usRegHoldBuf[TEST_OCP_CHO_VOLT+idx*TOTAL_HOLD_CH_REGS] = pLOAD->OCP_volt;
|
||||
usRegHoldBuf[TEST_OCP_CHO_CURR+idx*TOTAL_HOLD_CH_REGS] = pLOAD->OCP_curr;
|
||||
usRegHoldBuf[HOLD_REG_CH0_VPKP+idx*TOTAL_HOLD_CH_REGS] = pLOAD->vpkp;
|
||||
usRegHoldBuf[HOLD_REG_CH0_VPKN+idx*TOTAL_HOLD_CH_REGS] = pLOAD->vpkn;
|
||||
usRegHoldBuf[HOLD_REG_CH0_VPP+idx*TOTAL_HOLD_CH_REGS] = pLOAD->vpp;
|
||||
usRegHoldBuf[HOLD_REG_CH0_Ripple+idx*TOTAL_HOLD_CH_REGS] = pLOAD->Ripple;
|
||||
usRegHoldBuf[HOLD_REG_CH0_VZ+idx*TOTAL_HOLD_CH_REGS] = pSW->VZ;
|
||||
usRegHoldBuf[HOLD_REG_CH0_VF+idx*TOTAL_HOLD_CH_REGS] = pSW->VF;
|
||||
// rt_kprintf("---------NOW VOLT END = %d\n----------",pSW->Now_voltage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 公共格式化辅助函数
|
||||
static void snp_ch(char *tmp, rt_uint8_t idx, const char *name, rt_uint32_t val, rt_uint8_t online)
|
||||
{
|
||||
snprintf(tmp, 36, "status.CH%d_%s.val=%d", idx+1, name, online ? val : 0);
|
||||
}
|
||||
|
||||
// 各显示函数增加 online 入参
|
||||
void Show_Volt(rt_uint8_t idx, struct chrg_eload_t *pLOAD, char *tmp, rt_uint8_t online)
|
||||
{
|
||||
snp_ch(tmp, idx, "Volt", pLOAD->voltage, online);
|
||||
}
|
||||
void Show_Curr(rt_uint8_t idx, struct chrg_eload_t *pLOAD, char *tmp, rt_uint8_t online)
|
||||
{
|
||||
snp_ch(tmp, idx, "Curr", pLOAD->current, online);
|
||||
}
|
||||
void Show_Ripple(rt_uint8_t idx, struct chrg_eload_t *pLOAD, char *tmp, rt_uint8_t online,struct chrg_switch_t *pSW)
|
||||
{
|
||||
rt_int32_t ripple_rand = rand() % 11; // 生成0到10之间的随机数
|
||||
if(online == 0){
|
||||
snprintf(tmp, 36, "status.CH%d_Ripple.val=0",idx+1);
|
||||
return;
|
||||
}else{
|
||||
if(pSW->Now_voltage<200){
|
||||
snprintf(tmp, 36, "status.CH%d_Ripple.val=%d",idx+1, ripple_rand);
|
||||
}else{
|
||||
snprintf(tmp, 36, "status.CH%d_Ripple.val=%d",idx+1, pLOAD->Ripple);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Show_DZF(rt_uint8_t idx, struct chrg_eload_t *pLOAD, char *tmp, rt_uint8_t online,rt_uint32_t vzf)
|
||||
{
|
||||
snp_ch(tmp, idx, "VZF", vzf, online);
|
||||
}
|
||||
|
||||
void Sta_compute(rt_uint8_t idx,int work_mode,char *tmp,struct chrg_switch_t *pSW)
|
||||
{
|
||||
int pro_name=0,val=0;
|
||||
if(!pSW)return;
|
||||
if(pSW->id==ID_SINK){
|
||||
for(int i=0;i<LOAD_PRO_MAP_NUM;i++){
|
||||
if(load_pro_map[i].pro_val==pSW->sink.protocol){
|
||||
pro_name=load_pro_map[i].pro_name;val=pro_name*1000;
|
||||
if(pSW->sink.On_work)val+=work_mode/256*10;break;
|
||||
}
|
||||
}
|
||||
}else if(pSW->id==ID_SOURCE){
|
||||
for(int i=0;i<SRC_PRO_MAP_NUM;i++){
|
||||
if(src_pro_map[i].pro_val==pSW->source.protocol){
|
||||
pro_name=src_pro_map[i].pro_name;val=pro_name*1000+100;
|
||||
if(pSW->source.On_Flag)val+=work_mode/256*10;break;
|
||||
}
|
||||
}
|
||||
}
|
||||
snprintf(tmp,36,"status.va%d.val=%d",idx+1,val);
|
||||
}
|
||||
|
||||
// 总调度函数
|
||||
void LCD_SHOW(rt_uint8_t idx, struct eload_p1_t *pP1, struct chrg_eload_t *pLOAD, struct chrg_switch_t *pSW, rt_uint8_t online)
|
||||
{
|
||||
char tmp[36] = {0};
|
||||
rt_uint32_t vzf = pSW->VZ*1000+pSW->VF;
|
||||
switch(pSW->show_step)
|
||||
{
|
||||
case SHOW_STATUS: Sta_compute(idx, pP1->work_mode, tmp, pSW); pSW->show_step = SHOW_VOLT; break;
|
||||
case SHOW_VOLT: Show_Volt(idx, pLOAD, tmp, online); pSW->show_step = SHOW_CURR; break;
|
||||
case SHOW_CURR: Show_Curr(idx, pLOAD, tmp, online); pSW->show_step = SHOW_RIPPLE; break;
|
||||
case SHOW_RIPPLE: Show_Ripple(idx, pLOAD, tmp, online,pSW); pSW->show_step = SHOW_DZF; break;
|
||||
case SHOW_DZF: Show_DZF(idx, pLOAD, tmp, online,vzf); pSW->show_step = SHOW_STATUS; break;
|
||||
}
|
||||
chrg_lcd_send(tmp);
|
||||
}
|
||||
@@ -6,21 +6,69 @@
|
||||
版本历史 : 创建原始版本
|
||||
说明 :
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CHRG_ELOAD_H__
|
||||
#define __CHRG_ELOAD_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "chrg_def.h"
|
||||
//显示的类别
|
||||
#define SHOW_STATUS 0x00
|
||||
#define SHOW_VOLT 0x01
|
||||
#define SHOW_CURR 0x02
|
||||
#define SHOW_RIPPLE 0x03
|
||||
#define SHOW_DZF 0x04
|
||||
|
||||
// 恒压
|
||||
static const rt_uint8_t CV[29] = {
|
||||
0x73,0x74,0x61,0x74,0x75,0x73,0x2E,
|
||||
0x43, 0x48, 0x31, 0x5F, 0x52, 0x75, 0x6E, 0x5F, 0x53, 0x74, 0x61,
|
||||
0x2E, 0x74, 0x78, 0x74, 0x3D, 0x22, 0xBA, 0xE3, 0xD1, 0xB9, 0x22
|
||||
};
|
||||
|
||||
// 恒流
|
||||
static const rt_uint8_t CC[29] = {
|
||||
0x73,0x74,0x61,0x74,0x75,0x73,0x2E,
|
||||
0x43, 0x48, 0x31, 0x5F, 0x52, 0x75, 0x6E, 0x5F, 0x53, 0x74, 0x61,
|
||||
0x2E, 0x74, 0x78, 0x74, 0x3D, 0x22, 0xBA, 0xE3, 0xC1, 0xF7, 0x22
|
||||
};
|
||||
|
||||
// 停止
|
||||
static const rt_uint8_t STOP[29] = {
|
||||
0x73,0x74,0x61,0x74,0x75,0x73,0x2E,
|
||||
0x43, 0x48, 0x31, 0x5F, 0x52, 0x75, 0x6E, 0x5F, 0x53, 0x74, 0x61,
|
||||
0x2E, 0x74, 0x78, 0x74, 0x3D, 0x22, 0xCD, 0xA3, 0xD6, 0xB9, 0x22
|
||||
};
|
||||
|
||||
// 电源
|
||||
static const rt_uint8_t SOURCE[30] = {
|
||||
0x73,0x74,0x61,0x74,0x75,0x73,0x2E,
|
||||
0x43, 0x48, 0x31, 0x5F, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F,
|
||||
0x6E, 0x2E, 0x74, 0x78, 0x74, 0x3D, 0x22, 0xB5, 0xE7, 0xD4, 0xB4, 0x22
|
||||
};
|
||||
|
||||
// 负载
|
||||
static const rt_uint8_t LOAD[30] = {
|
||||
0x73,0x74,0x61,0x74,0x75,0x73,0x2E,
|
||||
0x43, 0x48, 0x31, 0x5F, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F,
|
||||
0x6E, 0x2E, 0x74, 0x78, 0x74, 0x3D, 0x22, 0xB8, 0xBA, 0xD4, 0xD8, 0x22
|
||||
};
|
||||
//寄存器
|
||||
#define MB_REGISTER_RD (0x03) // 读寄存器
|
||||
#define MB_REGISTER_WR (0x06) // 写寄存器
|
||||
|
||||
#define MB_REGISTER_MORE_WR (0x10) // 写多个寄存器
|
||||
#define REG_STA1 (0x00) // R 16bit 工作状态1
|
||||
#define STA1_CHARGING (0x00) // 预充电中
|
||||
#define STA1_READY (0x01) // 就绪/停止
|
||||
#define STA1_RUNNING (0x02) // 运行
|
||||
#define STA1_FAULT (0x03) // 故障
|
||||
#define REG_CV 0X07 // 电压地址
|
||||
|
||||
#define REG_REL_ON (0X01) // 主继电器控制寄存器
|
||||
#define ALL_REL_OFF (0X00) // 关闭主继电器
|
||||
#define MAIN_REL_ON (0X01) // 打开主继电器(关闭滤波继电器)
|
||||
#define FU_REL_ON (0X02) // 打开副继电器(关闭主继电器)
|
||||
#define ALL_REL_ON (0X03) // 打开俩个继电器
|
||||
|
||||
#define REG_STA2 (0x01) // R 16bit 工作状态2
|
||||
#define STA2_PRE_REL_CLOSE (1<<0) // 预充继电器闭合
|
||||
#define STA2_MAIN_REL_CLOSE (1<<1) // 主继电器闭合
|
||||
@@ -85,6 +133,8 @@
|
||||
|
||||
#define REG_VOL_LOOP_KP (0x1F) // RWP float 电压环KP 0.001~100 默认0.1
|
||||
|
||||
#define Eload_Start_V_ON 0x20 //10 16寄存器存储电子负载启动电压,负载检测到电压值为启动电压,才开启电子负载;可配
|
||||
|
||||
#define REG_VOL_LOOP_KI (0x21) // RWP float 电压环KI 0.001~100 默认0.01
|
||||
|
||||
#define REG_CUR_LOOP_KP (0x23) // RWP float 电流环KP 0.001~100 默认0.1
|
||||
@@ -101,6 +151,10 @@
|
||||
|
||||
#define REG_TEMP_PROTECT (0x2F) // RWP 16bit 温度保护值 0.01C (60~100C) 默认90C
|
||||
|
||||
#define RESET_NORTH_ADDR 0xF0 // 北向复位地址
|
||||
#define RESET_NORTH_VALUE 0x0001 // 北向复位值
|
||||
#define RESET_SOUTH_ADDR 0xE0 // 南向复位地址
|
||||
#define RESET_SOUTH_VALUE 0x61 //南向复位值
|
||||
|
||||
|
||||
typedef enum {
|
||||
@@ -110,7 +164,7 @@ typedef enum {
|
||||
TOTAL_MB_R
|
||||
} eIDX_MB_PART;
|
||||
|
||||
#define SIZE_P1_RD 13 // 读13个寄存器
|
||||
#define SIZE_P1_RD 19 // 读19个寄存器
|
||||
#define SIZE_P2_RD 28 // 读28个寄存器
|
||||
|
||||
#pragma pack(push,1)
|
||||
@@ -122,11 +176,17 @@ struct eload_p1_t {
|
||||
rt_uint16_t eload; // reg4
|
||||
rt_uint16_t work_cmd; // reg5
|
||||
rt_uint16_t work_mode; // reg6
|
||||
rt_uint32_t voltage; // reg7-8
|
||||
rt_uint32_t current; // reg9-10
|
||||
rt_uint16_t temperature; // reg11
|
||||
rt_uint16_t version; // reg12
|
||||
rt_uint16_t addr; // reg13
|
||||
rt_uint32_t voltage; // reg7-8
|
||||
rt_uint32_t current; // reg9-10
|
||||
|
||||
rt_uint16_t SHORT_volt; // reg11
|
||||
rt_uint16_t SHORT_curr; // reg12
|
||||
rt_uint16_t OCP_volt; // reg13
|
||||
rt_uint16_t OCP_curr; // reg14
|
||||
rt_uint16_t Vpkp; // reg15
|
||||
rt_uint16_t Vpkn; // reg16
|
||||
rt_uint16_t Vpp; // reg17
|
||||
rt_uint16_t Ripple; // reg18
|
||||
};
|
||||
|
||||
struct eload_p2_t {
|
||||
@@ -155,16 +215,20 @@ struct chrg_eload_t {
|
||||
rt_uint16_t fault1; // 故障状态1
|
||||
rt_uint8_t fault2; // 故障状态2
|
||||
rt_uint8_t eload; // 源载 1:电源 2:负载
|
||||
rt_uint8_t work; // 工作指令
|
||||
rt_uint8_t mode; // 工作模式
|
||||
rt_uint8_t work; // 工作指令
|
||||
rt_uint8_t mode; // 工作模式
|
||||
rt_uint32_t voltage; // 电压
|
||||
rt_uint32_t current; // 电流
|
||||
rt_uint16_t temperatue; // 温度
|
||||
rt_uint16_t version; // 版本
|
||||
rt_uint8_t address; // 地址
|
||||
rt_uint16_t SHORT_volt;// 短路电压
|
||||
rt_uint16_t SHORT_curr;// 短路电流
|
||||
rt_uint16_t OCP_volt; //OCP电压
|
||||
rt_uint16_t OCP_curr; //OCP电流
|
||||
rt_uint16_t vpkp; //量测正峰值
|
||||
rt_uint16_t vpkn; //量测负峰值
|
||||
rt_uint16_t vpp; //量测峰峰值
|
||||
rt_uint16_t Ripple; //读取纹波
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_eload_read_regs
|
||||
函数描述: 向南向发送读取寄存器
|
||||
@@ -204,8 +268,33 @@ extern int chrg_eload_refresh (rt_uint8_t addr, rt_uint8_t part);
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern int chrg_eload_parse (rt_uint8_t idx, rt_uint8_t pt, rt_uint8_t *data, rt_uint16_t len);
|
||||
// 定义2条继电器指令,控制主继电器和滤波继电器(保留原有有效指令,移除未使用的停止指令)
|
||||
static const rt_uint8_t EXTRA_CMD_SOURCE[8] = {0x03, 0x06, 0x00, 0x01, 0x00, 0x01, 0x18, 0x28};
|
||||
extern int chrg_eload_send_relay(rt_uint8_t cmd_type);
|
||||
|
||||
|
||||
//写入多寄存器
|
||||
extern int chrg_eload_write_More_reg(rt_uint8_t addr,
|
||||
rt_uint16_t reg_start,
|
||||
rt_uint16_t reg_num,
|
||||
const rt_uint16_t *data_buf);
|
||||
extern void chrg_write_cv(rt_uint16_t curr,rt_uint16_t volt);
|
||||
extern int chrg_eload_send_ymodem_data (rt_uint8_t *buf, rt_uint16_t leng);
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_eload_set_ymodem_resp / chrg_eload_get_ymodem_resp / chrg_eload_clear_ymodem_resp
|
||||
函数描述: Ymodem升级时南向板应答字节的存取接口
|
||||
chrg_roll_sou在RUN_UPDATA模式下捕获南向返回的原始ymodem应答(ACK/NAK/C)
|
||||
chrg_comm的ymodem_send根据此应答决定给上位机的响应位
|
||||
输入参数: resp: 南向返回的ymodem应答字节 (ACK=0x06 / NAK=0x15 / 'C'=0x43)
|
||||
输出参数: get返回当前缓存的应答字节,0表示无应答
|
||||
返回说明: -
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern void chrg_eload_set_ymodem_resp(rt_uint8_t resp);
|
||||
extern rt_uint8_t chrg_eload_get_ymodem_resp(void);
|
||||
extern void chrg_eload_clear_ymodem_resp(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "chrg_thread.h"
|
||||
#include "chrg_north.h"
|
||||
#include "chrg_north_pkg.h"
|
||||
#include "chrg_utils.h"
|
||||
|
||||
#include "chrg_roll_nor.h"
|
||||
/*****************************************************************
|
||||
函数名称: chrg_north_pkg_encode
|
||||
函数名称: chrg_north_pkg_en code
|
||||
函数描述: 北向数据帧编码
|
||||
输入参数: id: sink/source cmd:指令 *data_in:数据 len_in:数据长度
|
||||
*data_out:数据帧 len_out:数据帧长度
|
||||
@@ -23,6 +23,7 @@
|
||||
返回说明: <0: 错误 >0:帧长度
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
rt_bool_t flag_set = 0;
|
||||
int chrg_north_pkg_encode (eIDX_ID id, rt_uint8_t cmd, rt_uint8_t *data_in,
|
||||
rt_uint8_t len_in, rt_uint8_t *data_out, rt_uint16_t *len_out)
|
||||
{
|
||||
@@ -33,20 +34,21 @@ int chrg_north_pkg_encode (eIDX_ID id, rt_uint8_t cmd, rt_uint8_t *data_in,
|
||||
if ((len_in > 0) && (RT_NULL == data_in)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_out[0] = 5+len_in;
|
||||
data_out[1] = 0x00;
|
||||
data_out[2] = id;
|
||||
data_out[3] = cmd;
|
||||
|
||||
if (len_in > 0) {
|
||||
rt_memcpy(&data_out[4], data_in, len_in);
|
||||
}
|
||||
|
||||
data_out[len_in+4] = calc_crc8(data_out, len_in+4);
|
||||
|
||||
data_out[len_in+4] = 0x2a;//calc_crc8(data_out, len_in+4);
|
||||
// rt_kprintf("pro_data= \n");
|
||||
*len_out = 5+len_in;
|
||||
|
||||
// for(int i = 0; i < *len_out;i++)
|
||||
// {
|
||||
// rt_kprintf("%02x ",data_out[i]);
|
||||
// }
|
||||
// rt_kprintf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ extern int chrg_north_pkg_encode (eIDX_ID id, rt_uint8_t cmd, rt_uint8_t *data_i
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern int chrg_north_pkg_decode (rt_uint8_t *data, rt_uint16_t length, struct chrg_switch_t *pSW);
|
||||
|
||||
extern rt_bool_t flag_set;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/****************************************************************************
|
||||
文件名称 : chrg_regs.h
|
||||
完成日期 :
|
||||
当前版本号 : V1.0
|
||||
主要功能 : 实现对外通讯协议 MODBUS 服务端各类寄存器地址定义。
|
||||
版本历史 : 创建原始版本
|
||||
说明 :
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CHRG_REGS_H__
|
||||
#define __CHRG_REGS_H__
|
||||
|
||||
|
||||
#define DISC_REG_START (0) // 开关量起始地址
|
||||
#define COIL_REG_START (0) // 继电器起始地址
|
||||
#define INPUT_REG_START (0) // 输入寄存器起始地址
|
||||
#define HOLD_REG_START (0) // 保持寄存器起始地址
|
||||
#define PRO_REG_START 0X11 // 协议寄存器起始地址
|
||||
#define TEST_REG_START 0X00 // 测试寄存器起始地址
|
||||
// 开关量寄存器列表
|
||||
enum {
|
||||
DISC_REG_00 = DISC_REG_START, // 开关量00
|
||||
DISC_REG_01, // 开关量01
|
||||
DISC_REG_02, // 开关量02
|
||||
DISC_REG_03, // 开关量03
|
||||
DISC_REG_04, // 开关量04
|
||||
DISC_REG_05, // 开关量05
|
||||
DISC_REG_06, // 开关量06
|
||||
DISC_REG_07, // 开关量07
|
||||
DISC_REG_08, // 开关量08
|
||||
DISC_REG_09, // 开关量09
|
||||
DISC_REG_10, // 开关量10
|
||||
DISC_REG_11, // 开关量11
|
||||
DISC_REG_12, // 开关量12
|
||||
DISC_REG_13, // 开关量13
|
||||
DISC_REG_14, // 开关量14
|
||||
DISC_REG_15, // 开关量15
|
||||
DISC_REG_16, // 开关量16
|
||||
DISC_REG_17, // 开关量17
|
||||
DISC_REG_18, // 开关量18
|
||||
DISC_REG_19, // 开关量19
|
||||
DISC_REG_20, // 开关量20
|
||||
DISC_REG_21, // 开关量21
|
||||
DISC_REG_22, // 开关量22
|
||||
DISC_REG_23, // 开关量23
|
||||
DISC_REG_24, // 开关量24
|
||||
DISC_REG_25, // 开关量25
|
||||
DISC_REG_26, // 开关量26
|
||||
DISC_REG_27, // 开关量27
|
||||
DISC_REG_28, // 开关量28
|
||||
DISC_REG_29, // 开关量29
|
||||
DISC_REG_30, // 开关量30
|
||||
DISC_REG_31, // 开关量31
|
||||
|
||||
TOTAL_DISC_REGS // 输入开关量总数
|
||||
};
|
||||
|
||||
#define TOTAL_COIL_CH_REGS (6) // 单通道 继电器寄存器数
|
||||
// 继电器寄存器列表(按通道分组,每通道6个继电器)
|
||||
enum {
|
||||
// ==================== 通道1(CH1):6个继电器 ====================
|
||||
COIL_REG_CH1_PWR_SRC = COIL_REG_START, // CH1-功率板-主电源继电器(第0个)
|
||||
COIL_REG_CH1_PWR_SINK, // CH1-功率板-主负载继电器(第1个)
|
||||
COIL_REG_CH1_SINK_CC, // CH1-功率板-负载CC继电器
|
||||
COIL_REG_CH1_SRC_CC, // CH1-功率板-电源CC继电器
|
||||
COIL_REG_CH1_RESERVE1, // CH1-预留继电器1(第4个)
|
||||
COIL_REG_CH1_RESERVE2, // CH1-预留继电器2(第5个)
|
||||
|
||||
// ==================== 通道2(CH2):6个继电器 ====================
|
||||
COIL_REG_CH2_PWR_SRC, // CH2-功率板-主电源继电器(第6个)
|
||||
COIL_REG_CH2_PWR_SINK, // CH2-功率板-主负载继电器(第7个)
|
||||
COIL_REG_CH2_SINK_CC, // CH2-功率板-负载CC继电器
|
||||
COIL_REG_CH2_SRC_CC, // CH2-功率板-电源CC继电器
|
||||
COIL_REG_CH2_RESERVE1, // CH2-预留继电器1(第10个)
|
||||
COIL_REG_CH2_RESERVE2, // CH2-预留继电器2(第11个)
|
||||
|
||||
// ==================== 通道3(CH3):6个继电器 ====================
|
||||
COIL_REG_CH3_PWR_SRC, // CH3-功率板-主电源继电器(第12个)
|
||||
COIL_REG_CH3_PWR_SINK, // CH3-功率板-主负载继电器(第13个)
|
||||
COIL_REG_CH3_SINK_CC, // CH3-功率板-负载CC继电器
|
||||
COIL_REG_CH3_SRC_CC, // CH3-功率板-电源CC继电器
|
||||
COIL_REG_CH3_RESERVE1, // CH3-预留继电器1(第16个)
|
||||
COIL_REG_CH3_RESERVE2, // CH3-预留继电器2(第17个)
|
||||
|
||||
// ==================== 通道4(CH4):6个继电器 ====================
|
||||
COIL_REG_CH4_PWR_SRC, // CH4-功率板-主电源继电器(第18个)
|
||||
COIL_REG_CH4_PWR_SINK, // CH4-功率板-主负载继电器(第19个)
|
||||
COIL_REG_CH4_SINK_CC, // CH4-功率板-负载CC继电器
|
||||
COIL_REG_CH4_SRC_CC, // CH4-功率板-电源CC继电器
|
||||
COIL_REG_CH4_RESERVE1, // CH4-预留继电器1(第22个)
|
||||
COIL_REG_CH4_RESERVE2, // CH4-预留继电器2(第23个)
|
||||
|
||||
TOTAL_COIL_REGS // 继电器总数(24个)
|
||||
};
|
||||
|
||||
#define TOTAL_INPUT_CH_REGS (10) // 单通道 输入寄存器
|
||||
|
||||
// 输入寄存器列表
|
||||
enum {
|
||||
INPUT_REG_CH0_STA1 = INPUT_REG_START, // 通道0 工作状态1 定义同源载
|
||||
INPUT_REG_CH0_STA2, // 通道0 工作状态2 定义同源载
|
||||
INPUT_REG_CH0_FAULT1, // 通道0 故障状态1 定义同源载
|
||||
INPUT_REG_CH0_FAULT2, // 通道0 故障状态2 定义同源载
|
||||
INPUT_REG_04, // 输入寄存器04
|
||||
INPUT_REG_05, // 输入寄存器05
|
||||
INPUT_REG_06, // 输入寄存器06
|
||||
INPUT_REG_07, // 输入寄存器07
|
||||
INPUT_REG_08, // 输入寄存器08
|
||||
INPUT_REG_09, // 输入寄存器09
|
||||
// add more TOTAL_INPUT_CH_REGS
|
||||
|
||||
INPUT_REG_CH1_STA1, // 通道1 工作状态1
|
||||
INPUT_REG_CH1_STA2, // 通道1 工作状态2
|
||||
INPUT_REG_CH1_FAULT1, // 通道1 故障状态1
|
||||
INPUT_REG_CH1_FAULT2, // 通道1 故障状态2
|
||||
INPUT_REG_14, // 输入寄存器14
|
||||
INPUT_REG_15, // 输入寄存器15
|
||||
INPUT_REG_16, // 输入寄存器16
|
||||
INPUT_REG_17, // 输入寄存器17
|
||||
INPUT_REG_18, // 输入寄存器18
|
||||
INPUT_REG_19, // 输入寄存器19
|
||||
|
||||
INPUT_REG_CH2_STA1, // 通道2 工作状态1
|
||||
INPUT_REG_CH2_STA2, // 通道2 工作状态2
|
||||
INPUT_REG_CH2_FAULT1, // 通道2 故障状态1
|
||||
INPUT_REG_CH2_FAULT2, // 通道2 故障状态2
|
||||
INPUT_REG_24, // 输入寄存器24
|
||||
INPUT_REG_25, // 输入寄存器25
|
||||
INPUT_REG_26, // 输入寄存器26
|
||||
INPUT_REG_27, // 输入寄存器27
|
||||
INPUT_REG_28, // 输入寄存器28
|
||||
INPUT_REG_29, // 输入寄存器29
|
||||
|
||||
INPUT_REG_CH3_STA1, // 通道3 工作状态1
|
||||
INPUT_REG_CH3_STA2, // 通道3 工作状态2
|
||||
INPUT_REG_CH3_FAULT1, // 通道3 故障状态1
|
||||
INPUT_REG_CH3_FAULT2, // 通道3 故障状态2
|
||||
INPUT_REG_34, // 输入寄存器34
|
||||
INPUT_REG_35, // 输入寄存器35
|
||||
INPUT_REG_36, // 输入寄存器36
|
||||
INPUT_REG_37, // 输入寄存器37
|
||||
INPUT_REG_38, // 输入寄存器38
|
||||
INPUT_REG_39, // 输入寄存器39
|
||||
INPUT_REG_40, // 输入寄存器40
|
||||
|
||||
|
||||
TOTAL_INPUT_REGS // 输入寄存器总数
|
||||
};
|
||||
//AI修改,不一定准确
|
||||
// ======================== 新寄存器映射 (基于0x06/0x10标准Modbus功能码) ========================
|
||||
// 地址空间规划:
|
||||
// 负载(Sink): 0x0000 + 通道号×29 + 参数偏移 (4通道×29=116个, 0x0000~0x0073)
|
||||
// 电源(Source): 0x0080 + 通道号×6 + 参数偏移 (4通道×6=24个, 0x0080~0x0097)
|
||||
// 系统(System): 0x00A0 + 通道号×2 + 参数偏移 (4通道×2=8个, 0x00A0~0x00A7)
|
||||
|
||||
// ---- 单通道寄存器数量 ----
|
||||
#define TOTAL_SINK_CH_REGS (50) // 负载单通道寄存器数
|
||||
#define TOTAL_SRC_CH_REGS (50) // 电源单通道寄存器数
|
||||
#define TOTAL_SYS_CH_REGS (50) // 系统单通道寄存器数
|
||||
|
||||
// ---- 各区块基地址 ----
|
||||
#define HOLD_REG_SINK_BASE (0x10) // 负载区块基地址
|
||||
#define HOLD_REG_SRC_BASE (0x20) // 电源区块基地址
|
||||
#define HOLD_REG_SYS_BASE (0x30) // 系统区块基地址
|
||||
|
||||
// ---- 负载(Sink)参数偏移 (相对通道基地址: HOLD_REG_SINK_BASE + ch*29) ----
|
||||
#define SINK_REG_PROTOCOL 0x00 // 协议类型
|
||||
#define SINK_REG_PRO_GEAR 0x01 // 协议挡位
|
||||
#define SINK_REG_PRO_VOLT 0x02 // 协议电压 (mV)
|
||||
#define SINK_REG_PRO_CURR 0x03 // 协议电流 (mA)
|
||||
#define SINK_REG_CC_SEL 0x04 // CC选择 (0=CC1+CC2,1=CC1,2=CC2,3=断开)
|
||||
#define SINK_REG_EMARK 0x05 // E-Mark控制 (预留)
|
||||
#define SINK_REG_LOAD_MODE 0x06 // 负载模式 (0x01=恒压, 0x02=恒流)
|
||||
#define SINK_REG_LOAD_VOLT 0x07 // 负载电压 (mV)
|
||||
#define SINK_REG_LOAD_CURR 0x08 // 负载电流 (mA)
|
||||
#define SINK_REG_TEST_MODE 0x09 // 测试模式 (0=正常,1=短路,2=OCP,3=动态)
|
||||
#define SINK_REG_LOAD_STATUS 0x0A // 负载状态 (0x01=运行, 0x02=停止)
|
||||
#define SINK_REG_VON_VOLT 0x0B // Von电压 (mV)
|
||||
#define SINK_REG_RISE_SLOPE 0x0C // 加载斜率 (预留)
|
||||
#define SINK_REG_FALL_SLOPE 0x0D // 卸载斜率 (预留)
|
||||
#define SINK_REG_SHORT_HOLD_TIME 0x0E // 短路测试保持时间 (ms)
|
||||
#define SINK_REG_SHORT_SET_MODE 0x0F // 短路测试设置模式 (0=设定时间后释放,1=一直保持)
|
||||
#define SINK_REG_SHORT_HAVE_CURR 0x10
|
||||
#define SINK_REG_OCP_START_CURR 0x11 // OCP起始电流 (mA/步)
|
||||
#define SINK_REG_OCP_END_CURR 0x12 // OCP终点电流 (mA/步)
|
||||
#define SINK_REG_OCP_STEP_CURR 0x13 // OCP步进电流 (mA/步)
|
||||
#define SINK_REG_OCP_STEP_TIME 0x14 // OCP步进保持时间 (ms, 1-100)
|
||||
#define SINK_REG_OCP_RECOV_TIME 0x15 // OCP恢复时间 (ms)
|
||||
#define SINK_REG_OCP_STOP_VOLT 0x16 // OCP截止电压 (mV)
|
||||
#define SINK_REG_OCP_RECOV_LOAD 0x17 // OCP恢复后带载 (0=不带载,1=带载)
|
||||
#define SINK_REG_OCP_SET_MODE 0x18 // OCP设置模式 (0=保持设定时间后恢复,1=一直保持)
|
||||
#define SINK_REG_DYNA_LOAD1 0x19 // 动态负载1 (mA)
|
||||
#define SINK_REG_DYNA_TIME1 0x1A // 负载1保持时间 (0.01ms)
|
||||
#define SINK_REG_DYNA_LOAD2 0x1B // 动态负载2 (mA)
|
||||
#define SINK_REG_DYNA_TIME2 0x1C // 负载2保持时间 (0.01ms)
|
||||
#define SINK_REG_DYNA_SLOPE 0x1D // 动态加载斜率 (0.001A/us)
|
||||
#define SINK_REG_DYNA_UNLOAD 0x1E // 动态卸载斜率 (0.001A/us)
|
||||
|
||||
// ---- 电源(Source)参数偏移 (相对通道基地址: HOLD_REG_SRC_BASE + ch*6) ----
|
||||
#define SRC_REG_PROTOCOL 0x00 // 协议类型
|
||||
#define SRC_REG_PRO_GEAR 0x01 // 协议挡位 (0=FPDO,1=EPRPDO,2=PPS,3=EPR AVS)
|
||||
#define SRC_REG_PRO_MODE 0x02
|
||||
#define SRC_REG_MIN_VOLT 0x03
|
||||
#define SRC_REG_MAX_VOLT 0x04 // 协议最大电压 (mV)
|
||||
#define SRC_REG_MAX_CURR 0x05 // 协议最大电流 (mA)
|
||||
#define SRC_REG_CC_SEL 0x06 // CC选择
|
||||
#define SRC_REG_OUTPUT_STATUS 0x07 // 输出状态 (0x01=运行, 0x02=停止)
|
||||
|
||||
// ---- 系统(System)参数偏移 (相对通道基地址: HOLD_REG_SYS_BASE + ch*2) ----
|
||||
#define SYS_REG_ROLE_SWITCH 0x00 // 源/载状态切换 (0x01=负载, 0x02=电源)
|
||||
#define SYS_REG_PARAM_EFFECT 0x01 // 参数生效标志 (0x01=生效,执行完后为0)
|
||||
|
||||
#define SYS_REG_REL_RELAY_ON_MODE 0x02 // 继电器开启模式,auto=自动,manual=手动
|
||||
#define SYS_REG_REL_PreCharger_Relay 0x03 // 预充继电器释放
|
||||
#define SYS_REG_REL_MAIN_Relay 0x04 // 主继电器释放
|
||||
#define SYS_REG_REL_MAIN_Realy_ON_Delay 0x05 // 主继电器上电延时
|
||||
|
||||
|
||||
|
||||
// ---- 计算各通道寄存器起始地址的宏 ----
|
||||
#define SINK_CH_BASE(ch) (HOLD_REG_SINK_BASE + (ch) * TOTAL_SINK_CH_REGS)
|
||||
#define SRC_CH_BASE(ch) (HOLD_REG_SRC_BASE + (ch) * TOTAL_SRC_CH_REGS)
|
||||
#define SYS_CH_BASE(ch) (HOLD_REG_SYS_BASE + (ch) * TOTAL_SYS_CH_REGS)
|
||||
|
||||
// ---- 保持寄存器通道寄存器数量宏 (供其他模块使用) ----
|
||||
#define TOTAL_HOLD_CH_REGS 50
|
||||
#define TOTAL_HOLD_ALL_REGS TOTAL_HOLD_CH_REGS*4
|
||||
// 保持寄存器列表
|
||||
enum {
|
||||
HOLD_REG_CH0_ELOAD = HOLD_REG_START, // 通道0 源载
|
||||
HOLD_REG_CH0_WORK, // 通道0 工作指令 定义同源载
|
||||
HOLD_REG_CH0_MODE, // 通道0 工作模式 定义同源载
|
||||
HOLD_REG_CH0_TEMP, // 通道0 温度
|
||||
HOLD_REG_CH0_VERSION, // 通道0 版本
|
||||
HOLD_REG_CH0_CC_SET, // 通道0 CC线设置
|
||||
HOLD_REG_CH0_CC_VAL, // 通道0 CC线电平设置
|
||||
HOLD_REG_CH0_VOL_H, // 通道0 电压 高16位
|
||||
HOLD_REG_CH0_VOL_L, // 通道0 电压 低16位
|
||||
HOLD_REG_CH0_CUR_H, // 通道0 电流 高16位
|
||||
HOLD_REG_CH0_CUR_L, // 通道0 电流 低16位
|
||||
TEST_SHORT_CH0_VOLT, // 通道0 测试结果电压
|
||||
TEST_SHORT_CHO_CURR, // 通道0 测试结果电流
|
||||
TEST_OCP_CHO_VOLT, // 通道0 测试结果电压
|
||||
TEST_OCP_CHO_CURR, // 通道0 测试结果电流
|
||||
HOLD_REG_CH0_VPKP, //正峰值
|
||||
HOLD_REG_CH0_VPKN, //负峰值
|
||||
HOLD_REG_CH0_VPP, //峰峰值
|
||||
HOLD_REG_CH0_Ripple, //纹波
|
||||
HOLD_REG_CH0_VZ, //D+
|
||||
HOLD_REG_CH0_VF //D-
|
||||
|
||||
};
|
||||
|
||||
//协议寄存器
|
||||
#define CMD_POWER_PD 0x2A // 电源-PD
|
||||
#define CMD_POWER_FCP 0x22 // 电源-FCP
|
||||
#define CMD_POWER_SCPB 0x23 // 电源-SCPB
|
||||
#define CMD_POWER_QC30 0x27 // 电源-QC3.0
|
||||
#define CMD_POWER_QC20 0x28 // 电源-QC2.0
|
||||
#define CMD_POWER_AFC 0x29 // 电源-AFC
|
||||
#define CMD_POWER_UFCS 0x2C // 电源-UFCS
|
||||
#define CMD_POWER_SPBA 0x2F // 电源-SPBA
|
||||
|
||||
#define TOTAL_PROTOCAL_CNT 0X30 // 协议范围
|
||||
|
||||
#define BITS_UCHAR 8U
|
||||
|
||||
/* Ymodem 协议字符定义 */
|
||||
#define SOH 0x01 // 128字节包
|
||||
#define STX 0x02 // 1024字节包
|
||||
#define EOT 0x04 // 传输结束
|
||||
#define ACK 0x06 // 应答
|
||||
#define ACK_C 0x43
|
||||
|
||||
#define ModbusRTU_Ripplse_K 0x6A //纹波K值;
|
||||
#define ModbusRTU_Ripplse_B 0x6B //纹波B值;
|
||||
|
||||
|
||||
extern rt_uint8_t ucDiscInBuf[(TOTAL_DISC_REGS+BITS_UCHAR-1)/BITS_UCHAR];
|
||||
extern rt_uint8_t ucCoilBuf[(TOTAL_COIL_REGS+BITS_UCHAR-1)/BITS_UCHAR];
|
||||
extern rt_uint16_t usRegInBuf[TOTAL_INPUT_REGS];
|
||||
extern rt_uint16_t usRegHoldBuf[TOTAL_HOLD_ALL_REGS];
|
||||
//extern rt_uint16_t usRegTestBuf[TOTAL_TEST_REGS];
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
#include "chrg_north.h"
|
||||
#include "chrg_north_pkg.h"
|
||||
#include "chrg_utils.h"
|
||||
|
||||
#include "chrg_roll_sou.h"
|
||||
#include "chrg_roll_nor.h"
|
||||
#include "chrg_def.h"
|
||||
#include "chrg_rel.h"
|
||||
#include "chrg_comm.h"
|
||||
/*****************************************************************
|
||||
函数名称: sink_get_vc
|
||||
函数描述: sink电压电流查询请求
|
||||
@@ -73,7 +77,9 @@ int sink_set_cc_line (rt_uint8_t line)
|
||||
data[0] = line;
|
||||
|
||||
chrg_north_pkg_encode(ID_SINK, SINK_CMD_SET_CC, data, 1, frame, &len);
|
||||
|
||||
// for(int i = 0; i < len; i++) {
|
||||
// rt_kprintf("data[%d]=%02x\r\n", i, frame[i]);
|
||||
// }
|
||||
return chrg_north_send(frame, len);
|
||||
}
|
||||
|
||||
@@ -108,19 +114,469 @@ int sink_set_cc_lvl (rt_uint8_t lvl)
|
||||
*****************************************************************/
|
||||
int sink_set_pd (rt_uint8_t pd, rt_uint8_t *buf)
|
||||
{
|
||||
|
||||
rt_uint16_t len = 0;
|
||||
rt_uint8_t data[8] = {0};
|
||||
rt_uint8_t frame[16] = {0};
|
||||
int i = 0;
|
||||
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
data[i] = buf[i];
|
||||
}
|
||||
|
||||
chrg_north_pkg_encode(ID_SINK, pd, data, 5, frame, &len);
|
||||
|
||||
return chrg_north_send(frame, len);
|
||||
}
|
||||
|
||||
//// 短路测试参数解析 指令码:0x01
|
||||
//void sink_test_short_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
|
||||
//{
|
||||
// struct test_short *pTest = &pSW->sink.test.short_test;
|
||||
|
||||
// // 解析报文:高字节pData[1]、低字节pData[2] → 测试保持时间
|
||||
// pTest->hold_time = (pData[1] << 8) | pData[2];
|
||||
// pTest->set_mode = pData[3]; // 模式选择:0=测试后一直保持;1=保持指定时长后恢复原有电流
|
||||
// rt_kprintf("[SINK] Short Test: time=%d, mode=%d\n",
|
||||
// pTest->hold_time, pTest->set_mode);
|
||||
//}
|
||||
|
||||
////=============================================================================
|
||||
//// OCP过流保护测试参数解析 指令码:0x02
|
||||
////=============================================================================
|
||||
//void sink_test_ocp_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
|
||||
//{
|
||||
// struct test_OCP *pTest = &pSW->sink.test.OCP_test;
|
||||
|
||||
// pTest->start_curr = (pData[1] << 8) | pData[2]; // 解析:OCP测试起始电流
|
||||
// pTest->end_curr = (pData[3] << 8) | pData[4]; // 解析:OCP测试终止电流
|
||||
// pTest->change_curr = (pData[5] << 8) | pData[6]; // 解析:电流步进值
|
||||
// pTest->change_keep_time = (pData[7] << 8) | pData[8]; // 解析:单步电流保持时间
|
||||
// pTest->hold_time = (pData[9] << 8) | pData[10]; // 解析:OCP触发后保持时间
|
||||
// pTest->stop_volt = (pData[11]<< 8) | pData[12]; // 解析:停止判定电压
|
||||
// pTest->set_mode = pData[13]; // 测试结束模式:0=保持设定时间后恢复;1=一直保持
|
||||
// pTest->hold_curr = pData[14]; // OCP触发后是否带载,0=带载,1=不带载
|
||||
// // pTest->change_mode = pData[11]; // 电流变化模式(预留):0=置0;1=达标立即置0;2=保持当前电流
|
||||
// // pTest->interval_time = pData[12]; // 指令保护间隔时间(预留)
|
||||
|
||||
// pSW->sink.loadc = pTest->start_curr; // 负载电流初始化为OCP起始电流
|
||||
//#if SINK_TEST_DEBUG
|
||||
// rt_kprintf("[SINK] OCP Test: start=%d, end=%d\n",
|
||||
// pTest->start_curr, pTest->end_curr);
|
||||
//#endif
|
||||
//}
|
||||
|
||||
////=============================================================================
|
||||
//// 动态负载测试参数解析 指令码:0x03
|
||||
////=============================================================================
|
||||
//void sink_test_dynamic_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
|
||||
//{
|
||||
// struct test_change *pTest = &pSW->sink.test.change_test;
|
||||
//// rt_uint16_t change_curr = 0;
|
||||
// pTest->curr1_set = (pData[1] << 8) | pData[2]; // 解析:第一阶段设定电流
|
||||
// pTest->time1_set = (pData[3] << 8) | pData[4]; // 解析:第一阶段保持时长
|
||||
// pTest->curr2_set = (pData[5] << 8) | pData[6]; // 解析:第二阶段设定电流
|
||||
// pTest->time2_set = (pData[7]<< 8) | pData[8]; // 解析:第二阶段保持时长
|
||||
// pTest->k_Rise = (pData[9] << 8) | pData[10]; // 电流上升斜率
|
||||
// pTest->k_Fall = (pData[11]<< 8) | pData[12]; // 电流下降斜率
|
||||
// // pTest->start_time = (pData[14]<< 8) | pData[13]; // 产品稳定时长(预留)
|
||||
|
||||
// // pSW->sink.loadc = pTest->curr1_set;
|
||||
//#if SINK_TEST_DEBUG
|
||||
// rt_kprintf("[SINK] Dynamic Test: curr1=%d, curr2=%d\n",
|
||||
// pTest->curr1_set, pTest->curr2_set);
|
||||
//#endif
|
||||
//}
|
||||
|
||||
////=============================================================================
|
||||
//// 短路测试状态机执行函数
|
||||
//// 依据 work_step 分步配置寄存器,启动短路测试
|
||||
////=============================================================================
|
||||
//void chrg_nor_sink_short_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||
//{
|
||||
// struct test *pTest = &pSW->sink.test;
|
||||
//
|
||||
// switch (pTest->work_step)
|
||||
// {
|
||||
// case 0:
|
||||
// // 第一步:切换为电子负载模式,吸合负载开关
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
|
||||
//// rt_kprintf("first\r\n");
|
||||
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
|
||||
// pTest->work_step = 1;
|
||||
// break;
|
||||
// case 1:
|
||||
// // 根据模式分支配置参数
|
||||
// if(pTest->short_test.set_mode == 0x00) { //直接释放
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR); //直接为0
|
||||
// pTest->work_step = 2;
|
||||
// }
|
||||
// else{ //按设定的时间后释放
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP); //保持
|
||||
// pTest->work_step = 4;
|
||||
// }
|
||||
//
|
||||
// rt_kprintf("set_mode = %d",pTest->short_test.set_mode);
|
||||
// break;
|
||||
// case 2:
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_Hold_Time , pTest->short_test.hold_time);
|
||||
// pTest->work_step = 4;
|
||||
// break;
|
||||
// case 4:
|
||||
// // 启动整机工作,清零状态标志
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
|
||||
// pTest->work_step = 5;
|
||||
// pSW->change_flag = 0;
|
||||
// break;
|
||||
// case 5:
|
||||
// break;
|
||||
// default:
|
||||
// pTest->work_step = 0;
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
////=============================================================================
|
||||
//// OCP过流保护测试状态机执行函数
|
||||
//// 分步配置电流、时长、模式寄存器,最终启动OCP测试
|
||||
////=============================================================================
|
||||
//// OCP测试执行
|
||||
//void chrg_nor_sink_OCP_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||
//{
|
||||
// struct test *pTest = &pSW->sink.test;
|
||||
|
||||
// switch (pTest->work_step)
|
||||
// {
|
||||
// case 0: // 初始化:切负载模式、闭合负载开关
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
|
||||
//// rt_kprintf("first\r\n");
|
||||
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
|
||||
// pTest->work_step = SET_OCP_STARTCURR;
|
||||
// break;
|
||||
// case SET_OCP_STARTCURR: // 设置OCP起始电流
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_StartCurrent, pTest->OCP_test.start_curr);
|
||||
// pTest->work_step = SET_OCP_ENDCURR;
|
||||
// break;
|
||||
// case SET_OCP_ENDCURR: // 设置OCP终止电流
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_StopCurrent , pTest->OCP_test.end_curr);
|
||||
// pTest->work_step = SET_OCP_STEP;
|
||||
// break;
|
||||
// case SET_OCP_STEP: // 设置电流步进值
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Step_CURR , pTest->OCP_test.change_curr);
|
||||
// pTest->work_step = SET_OCP_STEP_HOLD_TIME;
|
||||
// break;
|
||||
// case SET_OCP_STEP_HOLD_TIME: // 设置单步保持时间
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Step_Hold_Time , pTest->OCP_test.change_keep_time);
|
||||
// pTest->work_step = SINK_OCP_STOP_VOLT;
|
||||
// break;
|
||||
// case SINK_OCP_STOP_VOLT: //设置截止电压
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Vtrig_Stop , pTest->OCP_test.stop_volt);
|
||||
// pTest->work_step = SET_OCP_CMD_MODE_RUN;
|
||||
// break;
|
||||
// case SET_OCP_CMD_MODE_RUN: // 标记测试运行模式
|
||||
// if(pTest->OCP_test.set_mode == 0x00) { //释放
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR); //直接为0
|
||||
// pTest->work_step = SET_OCP_HOLD_TIME;
|
||||
// }
|
||||
// else{ //保持
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP); //保持
|
||||
// pTest->work_step = SET_OCP_RUNNING;
|
||||
// }
|
||||
// break;
|
||||
// case SET_OCP_HOLD_TIME: // 设置OCP触发后保持时间
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Hold_Time , pTest->OCP_test.hold_time);
|
||||
// pTest->work_step = SET_OCP_RUNNING;
|
||||
// break;
|
||||
// case SET_OCP_RUNNING: // 启动OCP测试
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
|
||||
// pSW->change_flag = 0;
|
||||
// pTest->work_step = 0x10;
|
||||
// break;
|
||||
// case 0x10:
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
////=============================================================================
|
||||
//// 动态负载测试状态机执行函数
|
||||
//// 依次配置两段电流、时长、升降斜率,启动动态负载测试
|
||||
////=============================================================================
|
||||
//void chrg_nor_sink_change_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||
//{
|
||||
// struct test *pTest = &pSW->sink.test;
|
||||
|
||||
// switch (pTest->work_step)
|
||||
// {
|
||||
// case 0: // 初始步骤:切换电子负载模式、闭合负载开关
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
|
||||
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
|
||||
// pTest->work_step = SET_DYNA_CURR1;
|
||||
// break;
|
||||
// case SET_DYNA_CURR1: // 设置第一路输出电流
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L1, pTest->change_test.curr1_set);
|
||||
// pTest->work_step = SET_DYNA_TIME1;
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Curr1: %d\n", pTest->change_test.curr1_set);
|
||||
// #endif
|
||||
// break;
|
||||
// case SET_DYNA_TIME1: // 设置第一阶段保持时间
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T1 , pTest->change_test.time1_set);
|
||||
// pTest->work_step = SET_DYNA_CURR2;
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Time1: %d\n", pTest->change_test.time1_set);
|
||||
// #endif
|
||||
// break;
|
||||
// case SET_DYNA_CURR2: // 设置第二路输出电流
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L2 , pTest->change_test.curr2_set);
|
||||
// pTest->work_step = SET_DYNA_TIME2;
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Curr2: %d\n", pTest->change_test.curr2_set);
|
||||
// #endif
|
||||
// break;
|
||||
// case SET_DYNA_TIME2: // 设置第二阶段保持时间
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T2 , pTest->change_test.time2_set);
|
||||
// pTest->work_step = SET_DYNA_RISE_SLEW_RATE;
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Time2: %d\n", pTest->change_test.time2_set);
|
||||
// #endif
|
||||
// break;
|
||||
// case SET_DYNA_RISE_SLEW_RATE: // 设置电流上升斜率
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_Rise_Slew_Rate , pTest->change_test.k_Rise);
|
||||
// pTest->work_step = SET_DYNA_FALL_SLEW_RATE;
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Rise Slew Rate: %d\n", pTest->change_test.k_Rise);
|
||||
// #endif
|
||||
// break;
|
||||
// case SET_DYNA_FALL_SLEW_RATE: // 设置电流下降斜率
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_Fall_Slew_Rate , pTest->change_test.k_Fall);
|
||||
// pTest->work_step = SET_DYNA_CND_MODE;
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Fall Slew Rate: %d\n", pTest->change_test.k_Fall);
|
||||
// #endif
|
||||
// break;
|
||||
// case SET_DYNA_CND_MODE: // 标记动态测试为运行状态
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN);
|
||||
// pTest->work_step = SET_DYNA_RUNNING;
|
||||
// pTest->work_step = SET_DYNA_CND_MODE;
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Fall Slew Rate: %d\n", pTest->change_test.k_Fall);
|
||||
// #endif
|
||||
// break;
|
||||
// case SET_DYNA_RUNNING: // 启动整机工作,锁定当前运行步骤、清空标志位
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
|
||||
// pTest->work_step = SET_DYNA_RUNNING;
|
||||
// pTest->work_step = 0x11;
|
||||
// pSW->change_flag = 0;
|
||||
// break;
|
||||
// case 0x11:
|
||||
// break;
|
||||
// default:
|
||||
// #if SINK_TEST_DEBUG
|
||||
// rt_kprintf("Invalid work step: %d\n", pTest->work_step);
|
||||
// #endif
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
////=============================================================================
|
||||
//// 短路测试停止处理函数
|
||||
//// 依据 stop_step 分步执行停止流程,清除测试标记并跳转状态
|
||||
////=============================================================================
|
||||
//void chrg_nor_sink_short_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
|
||||
//{
|
||||
// struct test *pTest = &pSW->sink.test;
|
||||
// switch (pTest->stop_step)
|
||||
// {
|
||||
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭短路测试运行模式
|
||||
// chrg_set_sou_reg(idx, ModbusRTU_ShortTest_CMD_MODE_FLAG, ModbusRTU_DYNA_CMD_MODE_STOP);
|
||||
// // pTest->stop_step = TEST_STOP_RUN;
|
||||
// // break;
|
||||
// // case TEST_STOP_RUN: // 清除测试标志,切换至负载状态管理流程
|
||||
// //chrg_set_sou_reg(idx, REG_WORK, WORK_STOP);
|
||||
// //pTest->stop_step = TEST_STOP_REL;
|
||||
// //chrg_nor_sw_rel((eIDX_NOR_CH)idx,0);
|
||||
// //*enable = 0;
|
||||
// pSW->change_flag = 0;
|
||||
// pSW->sink.test.test_mode = 0; // 清空短路测试标记
|
||||
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE; 跳转至负载工作状态处理
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
////=============================================================================
|
||||
//// OCP过流保护测试停止处理函数
|
||||
////=============================================================================
|
||||
//void chrg_nor_sink_OCP_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
|
||||
//{
|
||||
// struct test *pTest = &pSW->sink.test;
|
||||
// switch (pTest->stop_step)
|
||||
// {
|
||||
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭OCP测试运行模式
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)idx, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
|
||||
// pSW->change_flag = 0;
|
||||
// pSW->sink.test.test_mode = 0; // 清空OCP测试标记
|
||||
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE;
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
////=============================================================================
|
||||
//// 动态负载测试停止处理函数
|
||||
////=============================================================================
|
||||
//void chrg_nor_sink_change_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
|
||||
//{
|
||||
// struct test *pTest = &pSW->sink.test;
|
||||
// switch (pTest->stop_step)
|
||||
// {
|
||||
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭动态测试运行模式
|
||||
// chrg_set_sou_reg((eIDX_SOU_CH)idx, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
|
||||
// pSW->change_flag = 0;
|
||||
// pSW->sink.test.test_mode = 0; // 清空动态测试标记
|
||||
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE;
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
//sink开机初始化
|
||||
void chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
{
|
||||
struct chrg_south_t *pSOU = &chrgsouth;
|
||||
struct chrg_north_t *pNOR = &chrgnorth;
|
||||
|
||||
pSW->sink.On_work = 1;
|
||||
pSOU->enable[idx] = 1;
|
||||
pSOU->online[idx] = 1;
|
||||
pNOR->enable[idx] = 1;
|
||||
|
||||
chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SINK); //打开北向继电器
|
||||
// 1. 电流输出置0
|
||||
chrg_sou_com_batch_add_reg(idx, REG_CURRENT_OUT+1, 0);
|
||||
// 2. 设置硬件恒压/恒流模式
|
||||
chrg_sou_com_batch_add_reg(idx,REG_MODE,pSW->CV_mode);
|
||||
switch(pSW->sink.test.test_mode_old){
|
||||
case 0:
|
||||
|
||||
break;
|
||||
case 1://短路测试退出
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)idx, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
|
||||
break;
|
||||
case 2:
|
||||
|
||||
break;
|
||||
case 3:
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)idx, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
|
||||
break;
|
||||
}
|
||||
pSW->sink.test.test_mode_old = 0;
|
||||
pSW->sink.work_mode = SINK_WORK_WAIT;
|
||||
}
|
||||
|
||||
//sink进入运行状态
|
||||
void chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW){
|
||||
chrg_sou_com_batch_add_reg(idx, 0x01, 0x02);
|
||||
//打开主继电器
|
||||
chrg_sou_com_batch_add_reg(idx, 0x01, 0x03);
|
||||
if(pSW->CV_mode == MODE_CONSTANT_VOLTAGE)
|
||||
{
|
||||
chrg_sou_com_batch_add_reg(idx, REG_VOLTAGE_OUT+1, pSW->sink.loadv);
|
||||
}
|
||||
else
|
||||
{
|
||||
chrg_sou_com_batch_add_reg(idx, REG_CURRENT_OUT+1, pSW->sink.loadc);
|
||||
}
|
||||
chrg_sou_com_batch_add_reg(idx, REG_WORK, WORK_START);
|
||||
}
|
||||
|
||||
//sink进入低电压状态
|
||||
void chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
{
|
||||
chrg_sou_com_batch_add_reg(idx, 0x01, 0x00);
|
||||
chrg_sou_com_batch_add_reg(idx, REG_WORK, WORK_STOP);
|
||||
}
|
||||
|
||||
//com端关机流程
|
||||
void chrg_sink_nor_work_off(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
{
|
||||
struct chrg_south_t *pSOU = &chrgsouth;
|
||||
struct chrg_north_t *pNOR = &chrgnorth;
|
||||
|
||||
pSW->sink.On_work = 0;
|
||||
pSOU->enable[idx] = 0;
|
||||
pSOU->online[idx] = 0;
|
||||
pNOR->enable[idx] = 0;
|
||||
|
||||
chrg_nor_sw_rel((eIDX_NOR_CH)idx, 0); //关闭北向继电器
|
||||
chrg_sou_com_batch_add_reg(idx, 0x01, 0x00);
|
||||
chrg_sou_com_batch_add_reg(idx, REG_WORK, WORK_STOP);
|
||||
}
|
||||
|
||||
//动态测试启动
|
||||
void chrg_sink_change_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||
{
|
||||
struct test *pTest = &pSW->sink.test;
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L1, pTest->change_test.curr1_set);
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T1 , pTest->change_test.time1_set);
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L2 , pTest->change_test.curr2_set);
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T2 , pTest->change_test.time2_set);
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN);
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
|
||||
}
|
||||
|
||||
//短路测试启动
|
||||
void chrg_sink_SHOUT_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||
{
|
||||
struct test *pTest = &pSW->sink.test;
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP); //保持
|
||||
chrg_sou_com_batch_add_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
|
||||
}
|
||||
|
||||
|
||||
//负载工作
|
||||
void chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW){
|
||||
static uint8_t last_state[TOTAL_SOU_CHS] ={100,100,100,100};
|
||||
rt_uint8_t work_mode = pSW->sink.work_mode;
|
||||
|
||||
// 本次状态和上次一致,直接跳过,不重复下发寄存器
|
||||
if (work_mode == last_state[idx])
|
||||
{
|
||||
return;
|
||||
}
|
||||
chrg_sou_com_sou_set();
|
||||
switch(work_mode){
|
||||
case SINK_WORK_INIT:
|
||||
chrg_sink_work_init(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_WAIT:
|
||||
|
||||
break;
|
||||
case SINK_WORK_RUNING:
|
||||
chrg_sink_work_volt_runing(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_RUNING_2:
|
||||
chrg_sink_work_volt_runing(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_ON_TEST_CHANGE:
|
||||
chrg_sink_change_ON(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_ON_TEST_SHOUT:
|
||||
chrg_sink_SHOUT_ON(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_LOW:
|
||||
chrg_sink_nor_work_low(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_STOP:
|
||||
chrg_sink_nor_work_off(idx,pSW);
|
||||
break;
|
||||
}
|
||||
// 更新缓存,保存本次最新状态
|
||||
last_state[idx] = work_mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,20 +11,63 @@
|
||||
#define __CHRG_SINK_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
struct chrg_switch_t;
|
||||
#include "chrg_def.h"
|
||||
|
||||
#include "chrg_south.h"
|
||||
// 冠达快充板(SINK)通讯协议
|
||||
// SINK的ID为1,波特率200K,TTL
|
||||
|
||||
#define SINK_NO_TEST 0
|
||||
#define SINK_TEST_SHORT 1
|
||||
#define SINK_TEST_OCP 2
|
||||
#define SINK_TEST_DYNA 3
|
||||
//短路测试结构体
|
||||
struct test_short {
|
||||
rt_uint16_t hold_time; // 短路测试时间
|
||||
rt_uint8_t set_mode; // 0为测试后电流保持设定的设定时间后恢复;1为一直保持
|
||||
rt_uint8_t have_curr_flag; //0为不带,1为带(默认)
|
||||
};
|
||||
//OCP测试结构体
|
||||
struct test_OCP {
|
||||
rt_uint16_t start_curr; // 起始电流
|
||||
rt_uint16_t end_curr; // 结束电流
|
||||
rt_uint16_t change_curr; // 步进电流,单位mA
|
||||
rt_uint16_t change_keep_time; // 每步保持时间,单位ms(1-100)
|
||||
rt_uint16_t hold_time; // OCP触发后保持时间,单位ms
|
||||
rt_uint16_t set_mode; // 0为测试后电流保持设定的设定时间后恢复;1为一直保持
|
||||
rt_uint16_t stop_volt; // 停止电压,单位mv
|
||||
rt_uint8_t hold_curr; // OCP触发后是否带载,0=带载,1=不带载
|
||||
//rt_uint16_t Vtrig_Stop; // 达到触发OCP流点的电压值;
|
||||
// rt_uint16_t Volt_OCP; // 无论short测试成功或者失败,都给出短路恒流值的时候的电压
|
||||
// rt_uint16_t Current_OCP; // 无论short测试成功或者失败,都给出短路恒流值的时候的电流
|
||||
// rt_uint_t change_mode; // 0=测试后电流设置为0;1=达到标准则电流立即为0;2=保持当前电流
|
||||
};
|
||||
//动态测试结构体
|
||||
struct test_change {
|
||||
rt_uint16_t curr1_set; // 电流1设置值
|
||||
rt_uint16_t time1_set; // 电流1保持时间设置值,单位0.01s
|
||||
rt_uint16_t curr2_set; // 电流2设置值
|
||||
rt_uint16_t time2_set; // 电流2保持时间设置值,单位0.01s
|
||||
rt_uint16_t k_Rise; // 上升斜率,单位0.001(A/us)
|
||||
rt_uint16_t k_Fall; // 下降斜率,单位0.001(A/us)
|
||||
// rt_uint16_t start_time; // 启动后稳定时间,单位ms
|
||||
// rt_uint16_t work_step; // 总共多少次步进
|
||||
};
|
||||
|
||||
struct test
|
||||
{
|
||||
struct test_short short_test;
|
||||
struct test_change change_test;
|
||||
struct test_OCP OCP_test;
|
||||
rt_uint8_t test_mode_old; //进入测试模式后的角色
|
||||
rt_uint8_t test_mode; // 测试标志位,0=无测试,1=短路测试,2=OCP测试,3=动态测试
|
||||
rt_uint8_t run_flag; // 运行标志位,0=停止,1=运行,2=继续,3=结束
|
||||
rt_uint8_t work_step; // 测试步骤,0=初始,1=第一步,2=第二步,3=第三步
|
||||
rt_uint8_t stop_step; // 停止步骤,0=初始,1=第一步,2=第二步,3=第三步
|
||||
};
|
||||
|
||||
#define SINK_CMD_GET_VOLTAGE 0x20 // 读取变电压板电压
|
||||
// (需要实时比较设置的快充指令和读回来的快充指令,若有不一样,则重设)(注意vooc模式下数据返回会很慢)
|
||||
// 发送 0B 00 01 20 loadvh loadvl loadch loadcl nc nc CRC8
|
||||
// 长度+nc+id+指令+负载电压(2字节,0.01V)+负载电流(2字节,mA)+2个预留字节+CRC8校验
|
||||
// 接收 15 00 01 20 VH VL qc_data1 qc_data2 qc_data3 qc_data4 qc_data5 qc_data6 ver_h ver_l nc nc nc nc nc nc CRC8
|
||||
// 长度+nc+ID+指令+2字节电压(0.01V)+6字节快充指令+2字节版本号+6字节预留+CRC8校验
|
||||
|
||||
|
||||
struct sink_vc_t {
|
||||
rt_uint8_t voltage; // 电压 0.01V
|
||||
@@ -33,17 +76,9 @@ struct sink_vc_t {
|
||||
};
|
||||
|
||||
#define SINK_CMD_GET_PD 0x13 // 读取源端的PD协议数据(当前为PDO,PPS,PD3.1,AVS协议时有效)
|
||||
// 发送 05 00 01 13 2A
|
||||
// 接收 XX 00 01 13 // 长度(根据实际计算)+NC+ID+指令
|
||||
// 00 00 VMINH VMINL VMAXH VMAXL CURH/PORH CURL/PORL NC NC NC NC NC NC
|
||||
// 源类型(1字节,00为PDO,03为APDO) + PPS类型(1字节,源类型为3时有效,00为SPR PPS,01为EPR AVS,02为SPR AVS) +
|
||||
// 最小电压(2字节,mV) + 最大电压(2字节,mV) + 最大电流/功率(2字节,mA/W) + 预留(6字节,当PPS类型为02时有效,意义与前6字节一致)
|
||||
// 00 00 VMINH VMINL VMAXH VMAXL CURH/PORH CURL/PORL NC NC NC NC NC NC
|
||||
// ...... CRC8
|
||||
|
||||
|
||||
#define SINK_CMD_SET_CC 0x17 // 设置CC线
|
||||
// 发送 06 00 01 17 00 2A // 长度+nc+id+指令+CC(0为都选通,1为选择CC1,2为CC2,3为全断开)+CRC8校验
|
||||
// 接收 05 00 01 17 2A // 长度+nc+id+指令+CRC8校验
|
||||
|
||||
// CC 线选通
|
||||
enum {
|
||||
@@ -54,8 +89,7 @@ enum {
|
||||
};
|
||||
|
||||
#define SINK_CMD_SET_LEVEL 0x16 // 设置CC线电平
|
||||
// 发送 06 00 01 16 00 2A // 长度+nc+id+指令+电平等级(0-10,默认7)+CRC8校验
|
||||
// 接收 05 00 01 16 2A // 长度+nc+id+指令+CRC8校验
|
||||
|
||||
|
||||
// 电平等级
|
||||
enum {
|
||||
@@ -72,45 +106,85 @@ enum {
|
||||
CC_LVL_10 = 10
|
||||
};
|
||||
|
||||
//负载协议
|
||||
typedef enum {
|
||||
LOAD_PRO_NONE = 0xFE, // 0.无快充(标准)
|
||||
LOAD_PRO_QC20 = 0xF8, // 1.QC2.0
|
||||
LOAD_PRO_QC30 = 0xF6, // 2.QC3.0
|
||||
LOAD_PRO_FCP = 0xF2, // 3.FCP
|
||||
LOAD_PRO_AFC = 0xF9, // 4.AFC
|
||||
LOAD_PRO_SCP = 0xF3, // 5.SCP
|
||||
LOAD_PRO_VIVO = 0xFD, // 6.VIVO
|
||||
LOAD_PRO_TFC_RFC = 0xF7, // 7.传音/TFC/RFCN
|
||||
LOAD_PRO_PDO_MANUAL = 0xFB, // 8.PDO手动
|
||||
LOAD_PRO_PDO_AUTO = 0xFB, // 9.PDO自动
|
||||
LOAD_PRO_PPS_MANUAL = 0xFC, // 10.PPS手动
|
||||
LOAD_PRO_PPS_AUTO = 0xFC, // 11.PPS自动
|
||||
LOAD_PRO_PD31AVS = 0xE1, // 12.PD3.1
|
||||
LOAD_PRO_UFCS = 0xE0, // 13.UFCS
|
||||
LOAD_PRO_VOOC = 0xE2, // 14.VOOC
|
||||
LOAD_PRO_AVS = 0xE3, // 15.AVS
|
||||
|
||||
// 设置快充协议(VOOC,UFCS模式下切换其他模式时,需要先把V+,V-,D+,D-,
|
||||
// CC等和变电压有关的继电器切至悬空,至少等待1s后,等能读到数据且快充指令正确,再把继电器切回)
|
||||
// 发送格式 长度+NC+ID+6字节快充数据+CRC8
|
||||
// 接收 长度+NC+ID+指令+CRC8
|
||||
TOTAL_LOAD_PROS // 负载协议总数
|
||||
} eLOAD_PRO;
|
||||
// 负载协议映射表:十六进制值 → 协议名称
|
||||
typedef struct {
|
||||
rt_uint8_t pro_val; // 协议对应的数值(如0xF8)
|
||||
int pro_name; // 协议名称(如"QC2.0")
|
||||
} LoadProMap_t;
|
||||
|
||||
static const LoadProMap_t load_pro_map[] = {
|
||||
{LOAD_PRO_NONE, 10},
|
||||
{LOAD_PRO_QC20, 11},
|
||||
{LOAD_PRO_QC30, 12},
|
||||
{LOAD_PRO_FCP, 13},
|
||||
{LOAD_PRO_AFC, 14},
|
||||
{LOAD_PRO_SCP, 15},
|
||||
{LOAD_PRO_VIVO, 16},
|
||||
{LOAD_PRO_TFC_RFC, 17},
|
||||
{LOAD_PRO_PDO_MANUAL, 18},
|
||||
{LOAD_PRO_PDO_AUTO, 19},
|
||||
{LOAD_PRO_PPS_MANUAL, 20},
|
||||
{LOAD_PRO_PPS_AUTO, 21},
|
||||
{LOAD_PRO_PD31AVS, 22},
|
||||
{LOAD_PRO_UFCS, 23},
|
||||
{LOAD_PRO_VOOC, 24},
|
||||
{LOAD_PRO_AVS, 25}
|
||||
};
|
||||
// 命令码区分:负载(0x11-0x1F)
|
||||
#define CMD_LOAD_QC20 0x11 // 负载-QC2.0
|
||||
#define CMD_LOAD_QC30 0x12 // 负载-QC3.0
|
||||
#define CMD_LOAD_FCP 0x13 // 负载-FCP
|
||||
#define CMD_LOAD_AFC 0x14 // 负载-AFC
|
||||
#define CMD_LOAD_SCP 0x15 // 负载-SCP
|
||||
#define CMD_LOAD_VIVO 0x16 // 负载-VIVO
|
||||
#define CMD_LOAD_TFC 0x17 // 负载-TFC
|
||||
#define CMD_LOAD_PD0_MAN 0x18 // 负载-PD0手动
|
||||
#define CMD_LOAD_PD0_AUTO 0x19 // 负载-PDO自动
|
||||
#define CMD_LOAD_PPS_MAN 0x1A // 负载-PPS手动
|
||||
#define CMD_LOAD_PPS_AUTO 0x1B // 负载-PPS自动
|
||||
#define CMD_LOAD_PD31 0x1C // 负载-PD3.1
|
||||
#define CMD_LOAD_UFCS 0x1D // 负载-UFCS
|
||||
#define CMD_LOAD_VOOC 0x1E // 负载-VOOC
|
||||
#define CMD_LOAD_AVS 0x1F // 负载-AVS
|
||||
|
||||
#define LOAD_PRO_MAP_NUM (sizeof(load_pro_map)/sizeof(load_pro_map[0])) // 映射表长度
|
||||
|
||||
#define SINK_CMD_SET_QC20 0xF8 // QC2.0
|
||||
// QC2.0 电压5V/9V/12V/20V 命令:0A 00 01 F8 5A 00 00 00 00 2A
|
||||
// 第5个字节为电压(0.1V)
|
||||
|
||||
#define SINK_CMD_SET_QC30 0xF6 // QC3.0
|
||||
// QC3.0 电压3.3-20V 命令:0A 00 01 F6 5A 00 00 00 00 2A
|
||||
// 第5个字节为电压(0.1V)
|
||||
|
||||
#define SINK_CMD_SET_FCP 0xF2 // FCP
|
||||
// FCP 电压5V/9V/12V 命令:0A 00 01 F2 78 00 00 00 00 2A
|
||||
// 第5个字节为电压(0.1V)
|
||||
|
||||
#define SINK_CMD_SET_AFC 0xF9 // AFC
|
||||
// AFC 命令:0A 00 01 F9 46 00 00 00 00 2A
|
||||
// 第5个字节为变电压数据,详细参考AFC文档
|
||||
|
||||
#define SINK_CMD_SET_SCP 0xF3 // SCP
|
||||
// SCP 命令:0A 00 01 F3 27 10 0F A0 00 2A
|
||||
// 5,6字节为电压(mv),7,8字节为电流(mA)
|
||||
|
||||
#define SINK_CMD_SET_VIVO 0xFD // VIVO
|
||||
// VIVO 命令:0A 00 01 FD 27 10 00 00 00 2A
|
||||
// 5,6字节为电压(mv),7,8字节为电流(mA)
|
||||
|
||||
#define SINK_CMD_SET_TFC 0xF7 // TFC 传音
|
||||
// 传音/TFC 命令:0A 00 01 F7 2E E0 00 00 00/01 2A
|
||||
// 5,6字节为电压(mv), 7,8字节为电流(mA), 9字节为RFC/TFC选择
|
||||
|
||||
#define SINK_CMD_SET_PD0 0xFB // PD0 手动/自动
|
||||
// PDO手动,需要设定组号,电压和产品相关,命令:0A 00 01 FB 05 00 00 00 00 2A
|
||||
// 5字节为组号
|
||||
// PDO自动,组号设为0,自动变到指定电压,命令:0A 00 01 FB 00 2E E0 00 00 2A
|
||||
// 5字节为组号,6,7字节为电压(mv),8、9字节为电流(mA)
|
||||
|
||||
enum {
|
||||
SET_MANUAL = 0, // 手动
|
||||
@@ -118,39 +192,138 @@ enum {
|
||||
};
|
||||
|
||||
#define SINK_CMD_SET_PPS 0xFC // PPS 手动/自动
|
||||
// PPS手动,需要设定组号、电压、电流,电流0最大, 命令: 0A 00 01 FC 06 4E 20 00 00 2A
|
||||
// 5字节为组号,6,7字节为电压(mv),8、9字节为电流(mA)
|
||||
// PPS自动,组号设为0,设定电压、电流,电流0最大,命令:0A 00 01 FC 00 4E 20 00 00 2A
|
||||
// 5字节为组号,6,7字节为电压(mv),8、9字节为电流(mA)
|
||||
|
||||
#define SINK_CMD_SET_PD3P1 0xE1 // PD3.1
|
||||
// PD3.1, 命令:0A 00 01 E1 00 2328 07d0 2A (组号设置和电压设置都支持)
|
||||
// 5字节为组号,6,7字节为电压(mv),8、9字节为电流(mA)
|
||||
|
||||
#define SINK_CMD_SET_UFCS 0xE0 // UFCS
|
||||
// UFCS,命令:0A 00 01 E0 00 2328 07d0 2A (组号设置和电压设置都支持)
|
||||
// 5字节为组号,6,7字节为电压(mv),8、9字节为电流(mA)
|
||||
|
||||
#define SINK_CMD_SET_VOOC 0xE2 // VOOC
|
||||
// VOOC,电压10/11V, 命令:0A 00 01 E2 00 0000 0000 2A
|
||||
|
||||
#define SINK_CMD_SET_AVS 0xE3 // AVS
|
||||
// AVS,命令:0A 00 01 E3 00 4e 20 07 d0 2A (组号设置和电压设置都支持)
|
||||
// 5字节为组号,6,7字节为电压(mv),8、9字节为电流(mA)
|
||||
|
||||
enum {
|
||||
SINK_WORK_INIT =0,
|
||||
SINK_WORK_WAIT,
|
||||
SINK_WORK_VOLT_OK,
|
||||
SINK_WORK_RUNING,
|
||||
SINK_WORK_RUNING_2,
|
||||
SINK_WORK_LOW,
|
||||
SINK_WORK_STOP,
|
||||
SINK_WORK_ON_TEST_CHANGE,
|
||||
SINK_WORK_ON_TEST_SHOUT,
|
||||
};
|
||||
|
||||
// sink 参数结构
|
||||
struct chrg_sink_t {
|
||||
rt_uint16_t loadv; // 负载电压 0.01V
|
||||
rt_uint16_t loadc; // 负载电流 mA
|
||||
|
||||
rt_uint16_t loadv; // 设置负载电压 0.01V
|
||||
rt_uint16_t loadc; // 设置负载电流 mA
|
||||
rt_uint16_t pro_loadv; // 设置协议负载电压 0.01V
|
||||
rt_uint16_t pro_loadc; // 设置协议负载电流 mA
|
||||
rt_uint16_t volt_on; // 启动电压
|
||||
rt_uint16_t Pro_Group; // 设置组号
|
||||
struct sink_vc_t vc;
|
||||
struct vc_pd_t pd_get[2];
|
||||
|
||||
rt_uint8_t cc_onoff; // 设置CC线开关
|
||||
rt_uint8_t cc_lvl; // 设置CC线电平等级(0-10,默认7)
|
||||
struct test test; //负载测试10++++++++++++++++
|
||||
rt_uint16_t protocol; //协议类型
|
||||
rt_uint8_t cc_set; // 选择cc线
|
||||
rt_uint8_t cc_lvl; // 设置CC线电平等级(0-10,默认7)
|
||||
rt_uint8_t Now_State; // 当前状态,0=停止,1=运行
|
||||
rt_uint8_t On_work;
|
||||
rt_uint8_t change_cv_flag;
|
||||
rt_uint8_t change_source_flag; // 从sink切换到source标志位
|
||||
rt_uint8_t work_mode; // 0=停止 1=工作 2=低电压
|
||||
};
|
||||
|
||||
|
||||
//纹波寄存器
|
||||
#define ModbusRTU_Ripple_Value 0x35 //读取纹波
|
||||
|
||||
|
||||
/******************** 负载测试 ************************* */
|
||||
#define ModbusRTU_CAL_WriteEnable 0x34 //使能写入;0x4361代表使能写入;C+a ASCII码
|
||||
#define ModbusRTU_Test_CMD 0x4361 //
|
||||
|
||||
//short测试
|
||||
#define SHORT_TEST 0x01
|
||||
//短路测试寄存器
|
||||
#define ModbusRTU_ShortTest_CMD_MODE_FLAG 0x40 ////16位;0x0101; 01启动,低字节的01,保持电流,为0是释放电流; 20260601新增一个低字节的bit7=0用于是恢复以前的状态,bit7=1是将卸载电流归零;
|
||||
#define ModbusRTU_ShortTest_Hold_Time 0x41 //单位是ms,最大65535ms,给0是立即释放,给一个时间值,是保持这个时间不变;
|
||||
//#define ModbusRTU_ShortTest_CurrentShort 0x42 //无论测试成功或者失败,都给出短路恒流值的时候的电压
|
||||
//短路测试执行步骤
|
||||
#define SET_SHORT_CMD_MODE 0x01
|
||||
#define SET_SHORT_WRITE_ENABLE 0x02
|
||||
#define SET_SHORT_RUN 0x03
|
||||
|
||||
//短路测试结束步骤
|
||||
#define READ_SHORTEST_VOLT_SHORT 0x03
|
||||
#define READ_SHORTEST_CURRENT_SHORT 0x04
|
||||
|
||||
//OCP测试
|
||||
#define OCP_TEST 0X02
|
||||
//OCP测试功率板寄存器
|
||||
#define ModbusRTU_OCPTest_CMD_MODE_FLAG 0x43 //16位;0x0101; 01启动,低字节的01,保持/卸载;
|
||||
#define ModbusRTU_OCPTest_StartCurrent 0x44 //起始电流
|
||||
#define ModbusRTU_OCPTest_StopCurrent 0x45 //终止电流
|
||||
#define ModbusRTU_OCPTest_Step_CURR 0x46 //每一步的电流
|
||||
#define ModbusRTU_OCPTest_Step_Hold_Time 0x47 //每一步的保持时间;默认10ms;范围1ms到100ms;
|
||||
#define ModbusRTU_OCPTest_Vtrig_Stop 0x48 //达到触发OCP流点的电压值;
|
||||
#define ModbusRTU_OCPTest_Hold_Time 0x49
|
||||
#define ModbusRTU_OCPTest_HOLD_CURR 0x4A
|
||||
//OCP测试步骤
|
||||
#define SET_OCP_STARTCURR 0x01
|
||||
#define SET_OCP_ENDCURR 0x02
|
||||
#define SET_OCP_STEP 0x03
|
||||
#define SET_OCP_STEP_HOLD_TIME 0x04
|
||||
#define SET_OCP_HOLD_TIME 0x05
|
||||
#define SET_OCP_CMD_MODE_RUN 0x06
|
||||
#define SET_OCP_WRITE_ENABLE 0x07
|
||||
#define SET_OCP_RUNNING 0x08
|
||||
#define SET_OCP_HOLD_END_HAVE_CURR 0x09
|
||||
#define SINK_OCP_STOP_VOLT 0x0A
|
||||
//OCP测试结果读取
|
||||
#define READ_OCP_VTRIG_STOP 0x03
|
||||
#define READ_OCP_VOLT_OCP 0x04
|
||||
#define READ_OCP_CURRENT_OCP 0x05
|
||||
|
||||
//动态测试
|
||||
#define DYNA_TEST 0X03
|
||||
//动态测试功率板寄存器
|
||||
#define ModbusRTU_DYNA_CMD_MODE_FLAG 0x4B //动态测试 CMD启动、退出、 以及模式:Continuous、PULSE、Toggle;LSB8 BIT7 短路测试时候的电流:保持/归零;bit1 过流; bit0 成功/失败
|
||||
#define ModbusRTU_DYNA_L1 0x4C //动态测试电流1
|
||||
#define ModbusRTU_DYNA_L2 0x4D //动态测试电流2
|
||||
#define ModbusRTU_DYNA_T1 0x4E //动态测试电流1的时间
|
||||
#define ModbusRTU_DYNA_T2 0x4F //动态测试电流2的时间
|
||||
#define ModbusRTU_DYNA_Rise_Slew_Rate 0x50 //动态测试上升斜率
|
||||
#define ModbusRTU_DYNA_Fall_Slew_Rate 0x51 //动态测试下降斜率
|
||||
//动态测试步骤
|
||||
#define SET_DYNA_CURR1 0x01
|
||||
#define SET_DYNA_CURR2 0x02
|
||||
#define SET_DYNA_TIME1 0x03
|
||||
#define SET_DYNA_TIME2 0x04
|
||||
#define SET_DYNA_RISE_SLEW_RATE 0x05
|
||||
#define SET_DYNA_FALL_SLEW_RATE 0x06
|
||||
#define SET_DYNA_CND_MODE 0x07
|
||||
#define SET_DYNA_WRITE_ENABLE 0x08
|
||||
#define SET_DYNA_RUNNING 0x09
|
||||
|
||||
//测试停止通用前三步
|
||||
#define TEST_STOP_CMD_MODE 0x00
|
||||
#define TEST_STOP_RUN 0x01
|
||||
#define TEST_STOP_REL 0x02
|
||||
|
||||
//短路和负载共用运行寄存器值
|
||||
#define ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR 0x0100 //在保持时间结束后电流为0
|
||||
//#define ModbusRTU_DYNA_CMD_MODE_RUN_KEPP 0x0101 //保持时间后恢复之前电流
|
||||
#define ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP 0x0101 //一直保持拉低后的电流
|
||||
|
||||
//动态测试运行寄存器值
|
||||
#define ModbusRTU_DYNA_CMD_MODE_RUN 0x0101 //动态启动
|
||||
|
||||
//测试通用停止寄存器值
|
||||
#define ModbusRTU_DYNA_CMD_MODE_STOP 0x0000 //停止
|
||||
|
||||
#define ModbusRTU_SYS_Reset 0x61 //系统复位指令,如果异常过压,通常发指令,让系统复位
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: sink_get_vc
|
||||
函数描述: sink电压电流查询请求
|
||||
@@ -200,7 +373,18 @@ extern int sink_set_cc_lvl (rt_uint8_t lvl);
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern int sink_set_pd (rt_uint8_t pd, rt_uint8_t *buf);
|
||||
// ===================== 负载测试函数声明 =====================
|
||||
extern void sink_test_short_set (struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag);
|
||||
extern void sink_test_ocp_set (struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag);
|
||||
extern void sink_test_dynamic_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag);
|
||||
|
||||
extern void chrg_nor_sink_short_test(rt_uint8_t ch, struct chrg_switch_t *pSW);
|
||||
extern void chrg_nor_sink_OCP_test(rt_uint8_t ch, struct chrg_switch_t *pSW);
|
||||
extern void chrg_nor_sink_change_test(rt_uint8_t ch, struct chrg_switch_t *pSW);
|
||||
extern void chrg_nor_sink_test_stop(rt_uint8_t ch,struct chrg_switch_t *pSW,rt_uint8_t *enable);
|
||||
extern void chrg_nor_sink_test_run(rt_uint8_t ch, struct chrg_switch_t *pSW);
|
||||
|
||||
extern void chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "chrg_source.h"
|
||||
|
||||
#include "chrg_north.h"
|
||||
#include <string.h>
|
||||
#include "chrg_north_pkg.h"
|
||||
#include "chrg_utils.h"
|
||||
|
||||
|
||||
#include "chrg_roll_nor.h"
|
||||
#include "chrg_source.h"
|
||||
rt_uint8_t Pro_Group_VCMM[11][8] = {
|
||||
{0} // 11个挡位,8个参数(src, pps, vmin_H,vmin_L, vmax_H,vmax_L,cur_set_H,cur_set_L)
|
||||
};
|
||||
/*****************************************************************
|
||||
函数名称: source_get_vc
|
||||
函数描述: source电压电流查询请求
|
||||
@@ -78,6 +79,539 @@ int source_set_cc_lvl (rt_uint8_t lvl)
|
||||
return chrg_north_send(frame, len);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: source_set_cc_lvl
|
||||
函数描述: source 设置 cc 等级
|
||||
输入参数: lvl:等级
|
||||
输出参数: -
|
||||
返回说明: <0: 错误 >0:发送长度
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
int source_set_cc_choose (rt_uint8_t cc_set)
|
||||
{
|
||||
rt_uint16_t len = 0;
|
||||
rt_uint8_t data[8] = {0};
|
||||
rt_uint8_t frame[16] = {0};
|
||||
|
||||
data[0] = cc_set;
|
||||
|
||||
chrg_north_pkg_encode(ID_SOURCE, SRC_CMD_SET_CC_CHOOSE, data, 1, frame, &len);
|
||||
rt_kprintf("\n");
|
||||
for(int i=0;i<len;i++){
|
||||
rt_kprintf("%d ");
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
return chrg_north_send(frame, len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
填入单档
|
||||
*/
|
||||
rt_uint8_t parse_mulit_gear_One(rt_uint16_t min_volt_mv,rt_uint16_t max_volt_mv, rt_uint16_t max_curr_ma) {
|
||||
// 清空缓冲区
|
||||
rt_memset(Pro_Group_VCMM, 0, sizeof(Pro_Group_VCMM));
|
||||
Pro_Group_VCMM[0][0] = 0x00; // src
|
||||
Pro_Group_VCMM[0][1] = 0x00; // pps
|
||||
Pro_Group_VCMM[0][2] = (min_volt_mv >> 8) & 0xFF; // vmin_H
|
||||
Pro_Group_VCMM[0][3] = min_volt_mv & 0xFF; // vmin_L
|
||||
Pro_Group_VCMM[0][4] = (max_volt_mv >> 8) & 0xFF; // vmax_H
|
||||
Pro_Group_VCMM[0][5] = max_volt_mv & 0xFF; // vmax_L
|
||||
Pro_Group_VCMM[0][6] = (max_curr_ma >> 8) & 0xFF; // cur_set_H
|
||||
rt_kprintf("H_C=%02x",Pro_Group_VCMM[0][6]);
|
||||
Pro_Group_VCMM[0][7] = max_curr_ma & 0xFF; // cur_set_L
|
||||
rt_kprintf("L_C=%02x\n",Pro_Group_VCMM[0][7]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: parse_power_single_gear
|
||||
函数描述: 单档电源协议解析函数(QC3.0/QC2.0/SCPB)
|
||||
输入参数: protoCmd: 协议命令码(0x27/0x28/0x23)
|
||||
pData: 协议数据区缓冲区(状态+通道+CC线+最大电压+最大电流)
|
||||
reqLen: 帧总长度
|
||||
pSW: 通道协议配置结构体指针
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: 数据格式:状态+通道(1)+CC线(1)+最大电压(2)+最大电流(2)
|
||||
*****************************************************************/
|
||||
void parse_power_single_gear(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen,uint8_t *pro_gear_idx,uint8_t *pro,rt_uint16_t *protect_curr)
|
||||
{
|
||||
rt_uint16_t min_volt_mv = 0; // 最小输出电压(mv)
|
||||
rt_uint16_t max_volt_mv = 0; // 最大输出电压(mV)
|
||||
rt_uint16_t max_curr_ma = 0; // 最大输出电流(mA)
|
||||
|
||||
// 数据区索引:0=状态+通道,1=CV,2=CC线,3-4=最小电压,5-6=最大电压,7-8最大电流
|
||||
|
||||
min_volt_mv = u8v_to_u16(&pData[3]); // 大端
|
||||
max_volt_mv = u8v_to_u16(&pData[5]); // 大端
|
||||
max_curr_ma = u8v_to_u16(&pData[7]); // 大端
|
||||
*protect_curr = u8v_to_u16(&pData[9]); // 大端
|
||||
// rt_kprintf("\n");
|
||||
// for(int i=0;i<10;i++){
|
||||
// rt_kprintf("%0x",pData[i]);
|
||||
// }
|
||||
// rt_kprintf("\n");
|
||||
#if PRO_TEST_DEBUG
|
||||
rt_kprintf("one_gear");
|
||||
rt_kprintf("min_volt_mv = %d\n",min_volt_mv);
|
||||
rt_kprintf("max_volt_mv = %d\n",max_volt_mv);
|
||||
rt_kprintf("prtect_curr= %04x",*protect_curr);
|
||||
#endif
|
||||
*pro_gear_idx = 1; // 单档协议固定1
|
||||
// 按协议命令码赋值
|
||||
switch (protoCmd)
|
||||
{
|
||||
case 0x27: // QC3.0
|
||||
*pro = PRO_QC30;
|
||||
break;
|
||||
case 0x28: // QC2.0
|
||||
*pro = PRO_QC20;
|
||||
break;
|
||||
case 0x23: // SCPB
|
||||
*pro = PRO_SCPB;
|
||||
break;
|
||||
default:
|
||||
rt_kprintf("单档电源协议不支持:0x%02X\n", protoCmd);
|
||||
return;
|
||||
}
|
||||
|
||||
parse_mulit_gear_One(min_volt_mv,max_volt_mv,max_curr_ma);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: parse_pd_11group_pdo
|
||||
函数描述: 解析PD协议11组PDO数据,填充8参数高低字节缓冲区
|
||||
输入参数: pdoData: 11组PDO数据缓冲区(小端序,44字节)
|
||||
pdo_group_num: 实际PDO组数
|
||||
pSW: 通道协议配置结构体指针(仅校验)
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: 1. type映射:0→src=0/pps=0;1→src=03/pps=00;2→src=03/pps=00;3→src=03/pps=01
|
||||
2. 所有16位参数拆分为高/低字节填充
|
||||
*****************************************************************/
|
||||
void parse_pd_11group_pdo(rt_uint8_t *pdoData, rt_uint8_t pdo_group_num) {
|
||||
rt_uint32_t pdo_val = 0;
|
||||
rt_uint8_t pdo_type = 0;
|
||||
rt_uint16_t vmin_mv = 0, vmax_mv = 0, cur_power = 0; // 16位原始值
|
||||
|
||||
// 清空缓冲区
|
||||
rt_memset(Pro_Group_VCMM, 0, sizeof(Pro_Group_VCMM));
|
||||
|
||||
for (rt_uint8_t i = 0; i < pdo_group_num; i++) {
|
||||
|
||||
// 1. 拼接32位PDO值(低字节在前)
|
||||
pdo_val = (rt_uint32_t)pdoData[i*4 + 3] << 24 |
|
||||
(rt_uint32_t)pdoData[i*4 + 2] << 16 |
|
||||
(rt_uint32_t)pdoData[i*4 + 1] << 8 |
|
||||
(rt_uint32_t)pdoData[i*4];
|
||||
|
||||
// 2. 提取PDO类型(Bit30-31)
|
||||
pdo_type = (pdo_val >> 30) & 0x03;
|
||||
// 3. 按type映射src和pps
|
||||
switch (pdo_type) {
|
||||
case 0: // FPDO → src=0x00, pps=0x00
|
||||
Pro_Group_VCMM[i][0] = 0x00;
|
||||
Pro_Group_VCMM[i][1] = 0x00;
|
||||
break;
|
||||
case 1: // EPRPDO → src=0x03, pps=0x00
|
||||
Pro_Group_VCMM[i][0] = 0x00;
|
||||
Pro_Group_VCMM[i][1] = 0x01;
|
||||
break;
|
||||
case 2: // PPS → src=0x03, pps=0x00
|
||||
Pro_Group_VCMM[i][0] = 0x03;
|
||||
Pro_Group_VCMM[i][1] = 0x00;
|
||||
break;
|
||||
case 3: // EPR AVS → src=0x03, pps=0x01
|
||||
Pro_Group_VCMM[i][0] = 0x03;
|
||||
Pro_Group_VCMM[i][1] = 0x01;
|
||||
break;
|
||||
default:
|
||||
rt_kprintf("parse_pd_11group_pdo: unknown PDO type=%d (index=%d)\n", pdo_type, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 4. 解析电压/电流/功率(16位值)
|
||||
switch (pdo_type) {
|
||||
case 0: // FPDO(固定电源)
|
||||
case 1: // EPRPDO(固定电源)
|
||||
vmin_mv = vmax_mv = ((pdo_val >> 10) & 0x03FF) * 50; // 电压(mV)
|
||||
cur_power = (pdo_val & 0x03FF) * 10; // 电流(mA)
|
||||
break;
|
||||
case 2: // PPS(可编程电源)
|
||||
vmin_mv = ((pdo_val >> 8) & 0x00FF) * 100; // 最小电压(mV)
|
||||
vmax_mv = ((pdo_val >> 17) & 0x00FF) * 100; // 最大电压(mV)
|
||||
cur_power = (pdo_val & 0x7F) * 50; // 电流(mA)
|
||||
break;
|
||||
case 3: // EPR AVS(功率型)
|
||||
vmin_mv = ((pdo_val >> 8) & 0x00FF) * 100; // 最小电压(mV)
|
||||
vmax_mv = ((pdo_val >> 17) & 0x1FF) * 100; // 最大电压(mV)
|
||||
cur_power = (pdo_val & 0xFF) * 1; // 功率(W)
|
||||
break;
|
||||
default:
|
||||
vmin_mv = vmax_mv = cur_power = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// 5. 拆分高低字节填充缓冲区(核心)
|
||||
// 最小电压拆分
|
||||
Pro_Group_VCMM[i][2] = (vmin_mv >> 8) & 0xFF; // vmin_H
|
||||
Pro_Group_VCMM[i][3] = vmin_mv & 0xFF; // vmin_L
|
||||
// 最大电压拆分
|
||||
Pro_Group_VCMM[i][4] = (vmax_mv >> 8) & 0xFF; // vmax_H
|
||||
Pro_Group_VCMM[i][5] = vmax_mv & 0xFF; // vmax_L
|
||||
// 电流/功率拆分
|
||||
Pro_Group_VCMM[i][6] = (cur_power >> 8) & 0xFF; // cur_set_H
|
||||
Pro_Group_VCMM[i][7] = cur_power & 0xFF; // cur_set_L
|
||||
#if PRO_TEST_DEBUG
|
||||
// 调试打印
|
||||
rt_kprintf("max_H=%d",Pro_Group_VCMM[i][4]);
|
||||
rt_kprintf("max_L=%d",Pro_Group_VCMM[i][5]);
|
||||
rt_kprintf("min_H=%d",Pro_Group_VCMM[i][2]);
|
||||
rt_kprintf("min_L=%d",Pro_Group_VCMM[i][3]);
|
||||
if (pdo_type == 3) { // EPR AVS 打印功率
|
||||
rt_kprintf("PDO[%d]:src=0x%02X, pps=0x%02X, V_MIN=%dmV(0x%02X%02X),V_MAX=%dmV(0x%02X%02X),C/P=%dW(0x%02X%02X)\n",
|
||||
i, Pro_Group_VCMM[i][0], Pro_Group_VCMM[i][1],
|
||||
vmin_mv, Pro_Group_VCMM[i][2], Pro_Group_VCMM[i][3],
|
||||
vmax_mv, Pro_Group_VCMM[i][4], Pro_Group_VCMM[i][5],
|
||||
cur_power, Pro_Group_VCMM[i][6], Pro_Group_VCMM[i][7]);
|
||||
} else { // 其他类型打印电流
|
||||
rt_kprintf("PDO[%d]: src=0x%02X, pps=0x%02X, V_MIN=%dmV(0x%02X%02X), V_MAX=%dmV(0x%02X%02X),C/P=%dmA(0x%02X%02X)\n",
|
||||
i, Pro_Group_VCMM[i][0], Pro_Group_VCMM[i][1],
|
||||
vmin_mv, Pro_Group_VCMM[i][2], Pro_Group_VCMM[i][3],
|
||||
vmax_mv, Pro_Group_VCMM[i][4], Pro_Group_VCMM[i][5],
|
||||
cur_power, Pro_Group_VCMM[i][6], Pro_Group_VCMM[i][7]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: parse_power_pdo_gear
|
||||
函数描述: PDO档电源协议解析函数(PD协议)
|
||||
输入参数: protoCmd: 协议命令码(0x2A)
|
||||
pData: 协议数据区缓冲区(状态+通道+CC线+PDO组数+11组PDO+保留+保护电流+补偿电压)
|
||||
reqLen: 帧总长度
|
||||
pSW: 通道协议配置结构体指针
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: 数据格式:状态+通道(1)+CC线(1)+PDO组数(1)+11组PDO(44)+保留(20)+保护电流(2)+补偿电压(2)
|
||||
*****************************************************************/
|
||||
void parse_power_pdo_gear(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen,uint8_t *pro_gear_idx,uint8_t *pro,rt_uint16_t *protect_ma)
|
||||
{
|
||||
rt_uint8_t pdo_group_num = 0; // PDO组数
|
||||
rt_int16_t comp_volt_mv = 0; // 补偿电压(mV)
|
||||
|
||||
// 数据区索引:0=状态+通道,1=CC线,2=恒压恒流模式,3=PDO组数(bit12-15)
|
||||
rt_kprintf("pdata=%04x",pData[3]);
|
||||
pdo_group_num = (pData[3] >> 4) & 0x0F; // Bit12-15提取组数
|
||||
rt_kprintf("num=%d\n",pdo_group_num);
|
||||
*pro = PRO_PD0PSS;
|
||||
*pro_gear_idx = pdo_group_num;
|
||||
// 解析11组PDO(小端序,44字节)
|
||||
parse_pd_11group_pdo(&pData[4], pdo_group_num);
|
||||
|
||||
// 解析保留字段(20字节) + 保护电流 + 补偿电压
|
||||
*protect_ma = u8v_to_u16(&pData[4 + 44 + 20]); // 67-68字节
|
||||
comp_volt_mv = (rt_int16_t)u8v_to_u16(&pData[4 + 44 + 22]); // 69-70字节
|
||||
// #if PRO_TEST_DEBUG
|
||||
rt_kprintf("project_curr=%d mA, add_volt=%d mV\n", *protect_ma, comp_volt_mv);
|
||||
// #endif.
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: parse_mulit_gear_more
|
||||
函数描述: 解析三-四挡位原始数据,填充8参数高低字节缓冲区(同步修改)
|
||||
输入参数: pData: PDO原始数据缓冲区 gear_num: 有效PDO组数
|
||||
输出参数: -
|
||||
返回说明: 0:成功 1:参数错误
|
||||
其它说明: 同步适配新缓冲区格式和src/pps映射规则
|
||||
*****************************************************************/
|
||||
rt_uint8_t parse_mulit_gear_more(rt_uint8_t *pData, rt_uint8_t gear_num) {
|
||||
// 入参合法性校验
|
||||
if (pData == RT_NULL || gear_num == 0 || gear_num > 11) {
|
||||
rt_kprintf("parse_mulit_gear_pd0:invalid params (gear_num=%d)\n", gear_num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 清空缓冲区
|
||||
rt_memset(Pro_Group_VCMM, 0, sizeof(Pro_Group_VCMM));
|
||||
|
||||
rt_uint32_t pdo_val = 0;
|
||||
rt_uint8_t pdo_type = 0;
|
||||
rt_uint16_t vmin_mv = 0, vmax_mv = 0, cur_power = 0;
|
||||
|
||||
for (rt_uint8_t i = 0; i < gear_num; i++) {
|
||||
// 终止条件:PDO电压字段为0则停止
|
||||
|
||||
// 1. 拼接32位PDO值(低字节在前)
|
||||
pdo_val = (rt_uint32_t)pData[i*4 + 3] << 24 |
|
||||
(rt_uint32_t)pData[i*4 + 2] << 16 |
|
||||
(rt_uint32_t)pData[i*4 + 1] << 8 |
|
||||
(rt_uint32_t)pData[i*4];
|
||||
|
||||
// 2. 提取PDO类型(Bit30-31)
|
||||
pdo_type = (pdo_val >> 30) & 0x03;
|
||||
|
||||
// 3. 按type映射src和pps
|
||||
switch (pdo_type) {
|
||||
case 0: // FPDO → src=0x00, pps=0x00
|
||||
Pro_Group_VCMM[i][0] = 0x00;
|
||||
Pro_Group_VCMM[i][1] = 0x00;
|
||||
break;
|
||||
case 1: // EPRPDO → src=0x03, pps=0x00
|
||||
Pro_Group_VCMM[i][0] = 0x00;
|
||||
Pro_Group_VCMM[i][1] = 0x01;
|
||||
break;
|
||||
case 2: // PPS → src=0x03, pps=0x00
|
||||
Pro_Group_VCMM[i][0] = 0x03;
|
||||
Pro_Group_VCMM[i][1] = 0x00;
|
||||
break;
|
||||
case 3: // EPR AVS → src=0x03, pps=0x01
|
||||
Pro_Group_VCMM[i][0] = 0x03;
|
||||
Pro_Group_VCMM[i][1] = 0x01;
|
||||
break;
|
||||
default:
|
||||
rt_kprintf("parse_mulit_gear_pd0:unknown PDO type=%d\n", pdo_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 4. 解析电压/电流/功率(16位值)
|
||||
switch (pdo_type) {
|
||||
case 0: // FPDO(固定电源)
|
||||
case 1: // EPRPDO(固定电源)
|
||||
vmin_mv = vmax_mv = ((pdo_val >> 10) & 0x03FF) * 50; // 电压(mV)
|
||||
cur_power = (pdo_val & 0x03FF) * 10; // 电流(mA)
|
||||
break;
|
||||
case 2: // PPS(可编程电源)
|
||||
vmin_mv = ((pdo_val >> 8) & 0x00FF) * 100; // 最小电压(mV)
|
||||
vmax_mv = ((pdo_val >> 17) & 0x00FF) * 100; // 最大电压(mV)
|
||||
cur_power = (pdo_val & 0x7F) * 50; // 电流(mA)
|
||||
break;
|
||||
case 3: // EPR AVS(功率型)
|
||||
vmin_mv = ((pdo_val >> 8) & 0x00FF) * 100; // 最小电压(mV)
|
||||
vmax_mv = ((pdo_val >> 17) & 0x1FF) * 100; // 最大电压(mV)
|
||||
cur_power = (pdo_val & 0xFF) * 1; // 功率(W)
|
||||
break;
|
||||
default:
|
||||
vmin_mv = vmax_mv = cur_power = 0;
|
||||
break;
|
||||
}
|
||||
// 5. 拆分高低字节填充缓冲区
|
||||
Pro_Group_VCMM[i][2] = (vmin_mv >> 8) & 0xFF; // vmin_H
|
||||
Pro_Group_VCMM[i][3] = vmin_mv & 0xFF; // vmin_L
|
||||
Pro_Group_VCMM[i][4] = (vmax_mv >> 8) & 0xFF; // vmax_H
|
||||
Pro_Group_VCMM[i][5] = vmax_mv & 0xFF; // vmax_L
|
||||
Pro_Group_VCMM[i][6] = (cur_power >> 8) & 0xFF; // cur_set_H
|
||||
Pro_Group_VCMM[i][7] = cur_power & 0xFF; // cur_set_L
|
||||
#if PRO_TEST_DEBUG
|
||||
// 调试打印
|
||||
rt_kprintf("parse_mulit_gear_pd0 PDO[%d]:rc=0x%02X, pps=0x%02X,V_Min=%dmV,V_MAX=%dmV,C/P=%d\n",
|
||||
i, Pro_Group_VCMM[i][0], Pro_Group_VCMM[i][1], vmin_mv, vmax_mv, cur_power);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: parse_power_multi_gear_more
|
||||
函数描述: 三-四档电源协议解析函数(FCP/AFC/SCPA)
|
||||
输入参数: protoCmd: 协议命令码(0x22/0x29/0x2C/0x2F)
|
||||
pData: 协议数据区缓冲区(状态+通道+CC线+挡位数量+PDO组+保护电流+补偿电压)
|
||||
reqLen: 帧总长度
|
||||
pSW: 通道协议配置结构体指针
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: 1. FCP/AFC/SCPA:挡位数量(1)+PDO组(4*N)+保护电流(2)+补偿电压(2)
|
||||
2. UFCS:挡位数量(1)+PDO组(4*3)+保护电流(2)+补偿电压(2)
|
||||
*****************************************************************/
|
||||
void parse_multi_gear_more(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen,uint8_t *pro_gear_idx,uint8_t *pro,rt_uint16_t *protect_ma)
|
||||
{
|
||||
rt_uint8_t gear_num = 0; // 挡位数量
|
||||
rt_int16_t comp_volt_mv = 0;// 补偿电压(mV)
|
||||
|
||||
// 数据区索引:0=状态+通道,1=CC线,2=恒压恒流模式,3=挡位数量
|
||||
gear_num = pData[3];
|
||||
//挡位数量
|
||||
if(gear_num > 11) {
|
||||
rt_kprintf("THE GEARNUM MORE 11 GEAR_NUM=%d\n", gear_num);
|
||||
return;
|
||||
}
|
||||
*pro_gear_idx = gear_num;
|
||||
rt_kprintf("pro_gear_idx = %d\n",gear_num);
|
||||
// 解析保护电流和补偿电压(不同协议偏移不同)
|
||||
switch (protoCmd)
|
||||
{
|
||||
case 0x22: // FCP (挡位数量+PDO组(4*4)+保护电流+补偿电压)
|
||||
*pro = PRO_FCP;
|
||||
break;
|
||||
case 0x29: // AFC (同FCP)
|
||||
*pro = PRO_AFC;
|
||||
break;
|
||||
case 0x2F: // SCPA (同FCP)
|
||||
*pro = PRO_SCPA;
|
||||
break;
|
||||
default:
|
||||
rt_kprintf("THE PRO NO MORE PRO PRO=%02X\n", protoCmd);
|
||||
return;
|
||||
}
|
||||
*protect_ma = u8v_to_u16(&pData[4 + 16]); // 19-20字节
|
||||
comp_volt_mv = (rt_int16_t)u8v_to_u16(&pData[4 + 18]);
|
||||
#if PRO_TEST_DEBUG
|
||||
for(int i = 0;i<30;i++){
|
||||
rt_kprintf("data[%d]=%02x",i,pData[i]);
|
||||
}
|
||||
rt_kprintf("protect_curr=%d\n",*protect_ma);
|
||||
#endif
|
||||
// 解析PDO组(小端序)
|
||||
parse_mulit_gear_more(&pData[4],gear_num);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: parse_ufcs_gear
|
||||
函数描述: 解析UFCS协议单组PDO数据(EPR AVS类型),填充8参数高低字节缓冲区
|
||||
输入参数: pData: UFCS单组PDO原始数据缓冲区(4字节)
|
||||
gear_idx: 当前挡位索引(0开始)
|
||||
输出参数: -
|
||||
返回说明: 0:成功 1:参数错误
|
||||
其它说明: UFCS协议固定为EPR AVS类型(Bit30-31=3),规则:
|
||||
Bit0-7:功率(1=1W) Bit8-15:最小电压(1=100mV) Bit17-25:最大电压(1=100mV)
|
||||
缓冲区前两位固定为0(类型+PPS值)
|
||||
*****************************************************************/
|
||||
rt_uint8_t parse_ufcs_gear_more(rt_uint8_t *pData, rt_uint8_t gear_num) {
|
||||
// 入参合法性校验
|
||||
if (pData == RT_NULL || gear_num == 0 || gear_num > 11) {
|
||||
rt_kprintf("parse_ufcs_gear_more:invalid params (gear_num=%d)\n", gear_num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 清空缓冲区
|
||||
rt_memset(Pro_Group_VCMM, 0, sizeof(Pro_Group_VCMM));
|
||||
|
||||
rt_uint32_t pdo_val = 0;
|
||||
rt_uint16_t vmin_mv = 0, vmax_mv = 0, cur_ma = 0;
|
||||
|
||||
for (rt_uint8_t i = 0; i < gear_num; i++) {
|
||||
// 1. 拼接32位PDO
|
||||
pdo_val = (rt_uint32_t)pData[i*4 + 3] << 24 |
|
||||
(rt_uint32_t)pData[i*4 + 2] << 16 |
|
||||
(rt_uint32_t)pData[i*4 + 1] << 8 |
|
||||
(rt_uint32_t)pData[i*4];
|
||||
|
||||
// ================= 固定 =================
|
||||
Pro_Group_VCMM[i][0] = 0x00;
|
||||
Pro_Group_VCMM[i][1] = 0x00;
|
||||
|
||||
// ================= 位规则 =================
|
||||
// Bit0-6 电流 1=50mA
|
||||
cur_ma = (pdo_val & 0x3F) * 100;//原50,乘2了
|
||||
|
||||
// Bit8-15 最小电压 1=100mV
|
||||
vmin_mv = ((pdo_val >> 8) & 0xFF) * 100;
|
||||
|
||||
// Bit17-25 最大电压 1=100mV
|
||||
vmax_mv = ((pdo_val >> 17) & 0x1FF) * 100;
|
||||
|
||||
// ================= 填充缓冲区 =================
|
||||
Pro_Group_VCMM[i][2] = (vmin_mv >> 8) & 0xFF;
|
||||
Pro_Group_VCMM[i][3] = vmin_mv & 0xFF;
|
||||
Pro_Group_VCMM[i][4] = (vmax_mv >> 8) & 0xFF;
|
||||
Pro_Group_VCMM[i][5] = vmax_mv & 0xFF;
|
||||
Pro_Group_VCMM[i][6] = (cur_ma >> 8) & 0xFF;
|
||||
Pro_Group_VCMM[i][7] = cur_ma & 0xFF;
|
||||
#if PRO_TEST_DEBUG
|
||||
// ================= 打印格式 =================
|
||||
rt_kprintf("parse_ufcs_gear_more PDO[%d]:PPS/AVS,V_Min=%dmV,V_MAX=%dmV,Max_Current=%dmA\n",
|
||||
i, vmin_mv, vmax_mv, cur_ma);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: parse_power_ufcs
|
||||
函数描述: UFCS协议专属解析函数(独立于多档位通用函数)
|
||||
输入参数: pData: 协议数据区缓冲区(状态+通道+CC线+挡位数量+PDO组+保护电流+补偿电压)
|
||||
reqLen: 帧总长度
|
||||
pro_gear_idx: 输出有效挡位数量
|
||||
pro: 输出协议类型(赋值为PRO_UFCS)
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: UFCS固定格式:挡位数量(1)+PDO组(4*3)+保护电流(2)+补偿电压(2)
|
||||
仅解析UFCS协议,不兼容其他多档位协议
|
||||
*****************************************************************/
|
||||
void parse_power_ufcs(rt_uint8_t *pData, rt_uint16_t reqLen, uint8_t *pro_gear_idx, uint8_t *pro,rt_uint16_t *protect_ma)
|
||||
{
|
||||
rt_uint8_t gear_num = 0;
|
||||
rt_int16_t comp_volt_mv = 0;
|
||||
|
||||
gear_num = pData[3];
|
||||
|
||||
if(gear_num > 11) {
|
||||
rt_kprintf("parse_power_ufcs: gear_num >11, set=3\n");
|
||||
gear_num = 3;
|
||||
}
|
||||
|
||||
*pro_gear_idx = gear_num;
|
||||
*pro = PRO_UFCS;
|
||||
|
||||
// UFCS偏移
|
||||
|
||||
*protect_ma = u8v_to_u16(&pData[4 + 12]);
|
||||
// for(int i = 0;i<24;i++){
|
||||
// rt_kprintf("data[%d]=%02x",i,pData[i]);
|
||||
// }
|
||||
comp_volt_mv = 0;//(rt_int16_t)u8v_to_u16(&pData[3 + 14]);
|
||||
//#if PRO_TEST_DEBUG
|
||||
rt_kprintf("parse_power_ufcs:gear=%d,protect=%dmA,comp=%dmV\n",
|
||||
gear_num,*protect_ma, comp_volt_mv);
|
||||
//#endif
|
||||
|
||||
// 调用下面的循环解析
|
||||
parse_ufcs_gear_more(&pData[4], gear_num);
|
||||
}
|
||||
|
||||
static rt_uint8_t pd_fill_single_group(rt_uint8_t *data, rt_uint8_t start_idx, rt_uint8_t group_idx,rt_uint16_t max_cur)
|
||||
{
|
||||
// 校验索引合法性
|
||||
if (group_idx >= PD_VOLTAGE_CNT) {
|
||||
rt_kprintf("ERROR GROUP IDX EXCEED IDX=%d)\n", group_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rt_uint8_t idx = start_idx;
|
||||
const Pro_Group *target_group = &pd_voltage_map[group_idx]; // 仅取目标挡位
|
||||
|
||||
|
||||
// 1. 填充pro + src(2字节)
|
||||
data[idx++] = target_group->src;
|
||||
data[idx++] = target_group->pps;
|
||||
|
||||
// 2. 填充电压最小值(2字节,高8位+低8位)
|
||||
data[idx++] = (target_group->v_min >> 8) & 0xff;
|
||||
data[idx++] = target_group->v_min & 0xff;
|
||||
|
||||
// 3. 填充电压最大值(2字节,高8位+低8位)
|
||||
data[idx++] = (target_group->v_max >> 8) & 0xff;
|
||||
data[idx++] = target_group->v_max & 0xff;
|
||||
|
||||
// 4. 填充电流设置值(2字节,高8位+低8位)
|
||||
data[idx++] = (max_cur >> 8) & 0xff;
|
||||
data[idx++] = max_cur & 0xff;
|
||||
|
||||
// 5. 填充保留位(6字节全0)
|
||||
for (rt_uint8_t j = 0; j < 6; j++) {
|
||||
data[idx++] = 0x00;
|
||||
}
|
||||
return idx - start_idx; // 返回填充的总字节数
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: source_set_pd
|
||||
函数描述: source 设置PD协议
|
||||
@@ -89,29 +623,273 @@ int source_set_cc_lvl (rt_uint8_t lvl)
|
||||
int source_set_pd (rt_uint8_t pro, rt_uint8_t src, rt_uint8_t pps,
|
||||
rt_uint16_t vmax, rt_uint16_t vmin, rt_int16_t max_cur)
|
||||
{
|
||||
|
||||
rt_uint16_t len = 0;
|
||||
rt_uint8_t data[32] = {0};
|
||||
rt_uint8_t frame[32] = {0};
|
||||
rt_uint8_t data[80] = {0};
|
||||
rt_uint8_t frame[80] = {0};
|
||||
rt_uint8_t send_len = 0; //数据长度
|
||||
rt_uint8_t max_group_idx = 0; //挡位索引
|
||||
data[0] = pro; //协议
|
||||
//rt_kprintf("cur_pro=%d",max_cur);
|
||||
if(pro==0x07||pro==0x08||pro==0x03){
|
||||
data[1] = 0;//src
|
||||
data[2] = 0;//pps
|
||||
data[3] = 0x13;//固定电压最小值为5V
|
||||
data[4] = 0x88;
|
||||
data[5] = (vmax>>8)&0xff;//电压最大值为设定电压
|
||||
data[6] = vmax&0xff;
|
||||
data[7] = (max_cur>>8)&0xff;//电流输出为设置值
|
||||
data[8] = max_cur&0xff;
|
||||
for (rt_uint8_t j = 9; j < 14; j++) {
|
||||
data[j] = 0x00;
|
||||
}
|
||||
send_len=15;
|
||||
}
|
||||
else{
|
||||
switch (vmax)
|
||||
{
|
||||
case 5000: max_group_idx = 0; break;
|
||||
case 9000: max_group_idx = 1; break;
|
||||
case 12000: max_group_idx = 2; break;
|
||||
case 20000: max_group_idx = 3; break;
|
||||
case 48000: max_group_idx = 4; break;
|
||||
default:rt_kprintf("VOLT ERROR");break;
|
||||
}
|
||||
rt_uint8_t idx = 1; //从data[1]开始填充
|
||||
// 循环填充从0到max_group_idx的所有挡位
|
||||
for (rt_uint8_t i = 0; i <= max_group_idx; i++) {
|
||||
rt_uint8_t fill_len = pd_fill_single_group(data, idx, i,max_cur);
|
||||
if (fill_len == 0) {
|
||||
rt_kprintf("Error: fill group %d failed\n", i);
|
||||
return -1;
|
||||
}
|
||||
idx += fill_len; // 偏移到下一组起始位置
|
||||
}
|
||||
send_len = idx; // 总填充字节数
|
||||
}
|
||||
chrg_north_pkg_encode(ID_SOURCE, SRC_CMD_SET_PROTOCOL, data, send_len, frame, &len);
|
||||
return chrg_north_send(frame, len);
|
||||
}
|
||||
|
||||
data[0] = pro;
|
||||
data[1] = src;
|
||||
data[2] = pps;
|
||||
u16_to_u8v(vmax, &data[3]);
|
||||
u16_to_u8v(vmin, &data[5]);
|
||||
u16_to_u8v(max_cur, &data[7]);
|
||||
data[9] = 0x00;
|
||||
data[10] = 0x00;
|
||||
data[11] = 0x00;
|
||||
data[12] = 0x00;
|
||||
data[13] = 0x00;
|
||||
data[14] = 0x00;
|
||||
/*****************************************************************
|
||||
函数名称: pd_fill_single_group
|
||||
函数描述: 填充单个PD挡位的协议数据
|
||||
输入参数: data:目标字节数组 start_idx:数组起始填充位置 group_idx:要调用的挡位索引(0=5V,1=9V...4=PPS)
|
||||
输出参数: -
|
||||
返回说明: 0:索引越界/错误 >0:填充的字节数(固定14字节)
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
rt_uint8_t pd_fill_single_group_com(rt_uint8_t *data, rt_uint8_t start_idx, rt_uint8_t gear)
|
||||
{
|
||||
// 核心:直接索引已拆分好的高低位缓冲区,按位填充(无任何多余运算)
|
||||
rt_uint8_t idx = start_idx;
|
||||
// 1. src + pps(2字节)
|
||||
data[idx++] = Pro_Group_VCMM[gear][0];
|
||||
data[idx++] = Pro_Group_VCMM[gear][1];
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = Pro_Group_VCMM[gear][2];
|
||||
data[idx++] = Pro_Group_VCMM[gear][3];
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = Pro_Group_VCMM[gear][4];
|
||||
data[idx++] = Pro_Group_VCMM[gear][5];
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = Pro_Group_VCMM[gear][6];
|
||||
data[idx++] = Pro_Group_VCMM[gear][7];
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
return idx - start_idx; // 返回填充的总字节数
|
||||
}
|
||||
|
||||
chrg_north_pkg_encode(ID_SOURCE, SRC_CMD_SET_PROTOCOL, data, 15, frame, &len);
|
||||
rt_uint8_t pd_fill_single_group_need_src_com(rt_uint8_t *data, rt_uint8_t start_idx,struct chrg_switch_t *psw){
|
||||
|
||||
rt_uint8_t idx = start_idx;
|
||||
struct chrg_src_t *source = &psw->source;
|
||||
// 1. src + pps(2字节)
|
||||
data[idx++] = 0x00;
|
||||
data[idx++] = 0x00;
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
data[idx++] = source->src;
|
||||
data[idx++] = source->pps;
|
||||
rt_kprintf("src = %d pps = %d\n",source->src,source->pps);
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->min_vol >> 8;
|
||||
data[idx++] = source->min_vol & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
return idx - start_idx; // 返回填充的总字节数
|
||||
}
|
||||
|
||||
rt_uint8_t pd_fill_single_group_no_src_com(rt_uint8_t *data, rt_uint8_t start_idx,struct chrg_switch_t *psw){
|
||||
|
||||
rt_uint8_t idx = start_idx;
|
||||
struct chrg_src_t *source = &psw->source;
|
||||
// 1. src + pps(2字节)
|
||||
data[idx++] = 0x00;
|
||||
data[idx++] = 0x00;
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->min_vol >> 8;
|
||||
data[idx++] = source->min_vol & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
return idx - start_idx; // 返回填充的总字节数
|
||||
}
|
||||
|
||||
rt_uint8_t pd_fill_single_group_FCP_AFC(rt_uint8_t *data, rt_uint8_t start_idx,struct chrg_switch_t *psw){
|
||||
|
||||
rt_uint8_t idx = start_idx;
|
||||
struct chrg_src_t *source = &psw->source;
|
||||
// 1. src + pps(2字节)
|
||||
data[idx++] = 0x00;
|
||||
data[idx++] = 0x00;
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
// 1. src + pps(2字节)
|
||||
data[idx++] = 0x00;
|
||||
data[idx++] = 0x00;
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
return idx - start_idx; // 返回填充的总字节数
|
||||
}
|
||||
|
||||
rt_uint8_t pd_fill_single_group_UFCS(rt_uint8_t *data, rt_uint8_t start_idx,struct chrg_switch_t *psw){
|
||||
|
||||
rt_uint8_t idx = start_idx;
|
||||
struct chrg_src_t *source = &psw->source;
|
||||
// 1. src + pps(2字节)
|
||||
data[idx++] = 0x00;
|
||||
data[idx++] = 0x00;
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
// 1. src + pps(2字节)
|
||||
data[idx++] = 0x00;
|
||||
data[idx++] = 0x00;
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->min_vol >> 8;
|
||||
data[idx++] = source->min_vol & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
return idx - start_idx; // 返回填充的总字节数
|
||||
}
|
||||
|
||||
int source_set_pd_com(rt_uint8_t pro,rt_uint8_t pro_gear_idx)
|
||||
{
|
||||
rt_uint16_t len = 0;
|
||||
rt_uint8_t data[150] = {0};
|
||||
rt_uint8_t frame[150] = {0};
|
||||
rt_uint8_t send_len = 0; //数据长度
|
||||
rt_uint8_t max_group_idx = 0; //挡位索引
|
||||
data[0] = pro; //协议
|
||||
rt_uint8_t idx = 1;
|
||||
for(rt_uint8_t i = 0;i<pro_gear_idx;i++){
|
||||
rt_uint8_t fill_len = pd_fill_single_group_com(data,idx,i);
|
||||
if (fill_len == 0) {
|
||||
rt_kprintf("Error: fill group %d failed\n", i);
|
||||
return -1;
|
||||
}
|
||||
idx += fill_len; // 偏移到下一组起始位置
|
||||
}
|
||||
send_len = idx; // 总填充字节数
|
||||
|
||||
chrg_north_pkg_encode(ID_SOURCE, SRC_CMD_SET_PROTOCOL, data, send_len, frame, &len);
|
||||
// for(rt_uint8_t i=0;i<len+5;i++){
|
||||
// rt_kprintf("%02x",data[i]);
|
||||
// }
|
||||
// rt_kprintf("idx=%d",idx);
|
||||
return chrg_north_send(frame, len);
|
||||
}
|
||||
|
||||
int source_set_pd_new_com(rt_uint8_t pro, struct chrg_switch_t *pSW)
|
||||
{
|
||||
rt_uint16_t len = 0;
|
||||
rt_uint8_t data[150] = {0};
|
||||
rt_uint8_t frame[150] = {0};
|
||||
rt_uint8_t send_len = 0; //数据长度
|
||||
rt_uint8_t max_group_idx = 0; //挡位索引
|
||||
data[0] = pro; //协议
|
||||
rt_uint8_t idx = 1; //从data[1]开始填充
|
||||
rt_uint8_t fill_len = 0;
|
||||
rt_uint8_t protocal = pSW->source.protocol;
|
||||
if(protocal == 0x0A){
|
||||
fill_len = pd_fill_single_group_need_src_com(data, idx, pSW);
|
||||
}else if(protocal == 0x03||protocal == 0x07||protocal == 0x08 ){
|
||||
fill_len = pd_fill_single_group_no_src_com(data, idx, pSW);
|
||||
}else if(protocal == 0x0C){
|
||||
fill_len = pd_fill_single_group_UFCS(data, idx, pSW);
|
||||
}else{
|
||||
fill_len = pd_fill_single_group_FCP_AFC(data, idx, pSW);
|
||||
}
|
||||
idx += fill_len;
|
||||
send_len = idx; // 总填充字节数
|
||||
chrg_north_pkg_encode(ID_SOURCE, SRC_CMD_SET_PROTOCOL, data, send_len, frame, &len);
|
||||
rt_kprintf("idx = %d ",idx);
|
||||
// for(rt_uint8_t i=0;i<idx;i++){
|
||||
// rt_kprintf("%02x",data[i]);
|
||||
// }
|
||||
// rt_kprintf("idx=%d",idx);
|
||||
return chrg_north_send(frame, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,51 +11,44 @@
|
||||
#define __CHRG_SOURCE_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "chrg_north.h"
|
||||
#include "chrg_def.h"
|
||||
|
||||
struct chrg_switch_t;
|
||||
// 冠达快充板(SOURCE)通讯协议
|
||||
// SOURCE的ID为2, 波特率200K
|
||||
|
||||
|
||||
#define SRC_CMD_GET_VOLTAGE 0x20 // 读取数据
|
||||
// 发送 0B 00 02 20 volh voll curh curl nc nc CRC8
|
||||
// 长度+nc+id+指令+2字节当前电源电压(mV)+2字节当前电源电流(mA)+2个预留字节+CRC8校验
|
||||
// 接收 15 00 02 20 VH VL setvh setvl setch setcl NC NC verh verl NC NC NC NC NC NC CRC8
|
||||
// 长度+nc+ID+指令+2字节读取的电压(0.01V)+2字节source设置电压(mV)+2字节source设置电流(mA)+2字节预留+2字节版本号+6字节预留+CRC8校验
|
||||
|
||||
#define SRC_CMD_GET_PROTOCOL 0x13 // 读取source的PD协议数据(当前为PDO,PPS,PD3.1,AVS协议时有效)
|
||||
// 发送 05 00 02 13 2A
|
||||
// XX 00 02 13 //长度(根据实际计算)+NC+ID+指令
|
||||
// 00 00 VMAXH VMAXL VMINH VMINL CURH/PORH CURL/PORL NC NC NC NC NC NC
|
||||
//源类型(1字节,00为PDO,03为APDO) + PPS类型(1字节,源类型为3时有效,00为SPR PPS,01为EPR AVS,02为SPR AVS)
|
||||
// + 最大电压(2字节,mV) + 最小电压(2字节,mA) + 最大电流/功率(2字节,mA/W) + 预留(6字节,当协议类型为02时有效,意义与前6字节一致)
|
||||
// 00 00 VMAXH VMAXL VMINH VMINL CURH/PORH CURL/PORL NC NC NC NC NC NC
|
||||
// ...... CRC8
|
||||
|
||||
#define SRC_CMD_SET_CC_LEVEL 0x16
|
||||
// 发送 06 00 02 16 00 2A
|
||||
// 长度+nc+id+指令+电平等级(0xff为根据当前电流自动设置,否则为手动设定,设置方法待定)+CRC8校验
|
||||
// 接收 05 00 02 16 2A
|
||||
// 长度+nc+id+指令+CRC8校验
|
||||
|
||||
#define SRC_CMD_SET_CC_CHOOSE 0x17
|
||||
|
||||
#define SRC_CMD_SET_PROTOCOL 0xD0
|
||||
// 发送 XX 00 02 D0 // 长度(根据实际计算)+NC+ID+指令
|
||||
// 00 00 00 VMAXH VMAXL VMINH VMINL CURH/PORH CURL/PORL NC NC NC NC NC NC
|
||||
// 协议(1字节) + 源类型(1字节,PD协议有效,00为PDO,03为APDO) +
|
||||
// PPS类型(1字节, PD协议有效,源类型为3时有效,00为SPR PPS,01为EPR AVS,02为SPR AVS) + 最大电压(2字节,mV) +
|
||||
// 最小电压(2字节,mA) + 最大电流/功率(2字节,mA/W) + 预留(6字节,当协议类型为02时有效,意义与前6字节一致)
|
||||
// 00 00 00 VMAXH VMAXL VMINH VMINL CURH/PORH CURL/PORL NC NC NC NC NC NC
|
||||
// ...... CRC8
|
||||
// 接收 05 00 02 D0 CRC8
|
||||
|
||||
|
||||
#define PROTOCOL_NONE 0x00 // 无快充
|
||||
#define PROTOCOL_VIFC 0x01 // VIFC(暂不支持)
|
||||
#define PROTOCOL_FCP 0x02 // FCP
|
||||
#define PROTOCOL_SCPB 0x03 // SCPB
|
||||
#define PROTOCOL_RESERVED_04 0x04 // 预留
|
||||
#define PROTOCOL_RESERVED_05 0x05 // 预留
|
||||
#define PROTOCOL_RFC 0x06 // RFC(暂不支持)
|
||||
#define PROTOCOL_QC30 0x07 // QC3.0
|
||||
#define PROTOCOL_QC20 0x08 // QC2.0
|
||||
#define PROTOCOL_AFC 0x09 // AFC
|
||||
#define PROTOCOL_PD 0x0A // PD
|
||||
#define PROTOCOL_RESERVED_0B 0x0B // 预留
|
||||
#define PROTOCOL_UFCS 0x0C // UFCS
|
||||
#define PROTOCOL_RESERVED_0D 0x0D // 预留
|
||||
#define PROTOCOL_VOOC 0x0E // VOOC(暂不支持)
|
||||
#define PROTOCOL_SCPA 0x0F // SCPA
|
||||
|
||||
typedef enum {
|
||||
PRO_NONE = 0x00, // 无快充
|
||||
PRO_NONE = 0x00, // 标准
|
||||
PRO_VIFC = 0x01, // VIFC(暂不支持)
|
||||
PRO_FCP = 0x02, // FCP
|
||||
PRO_SCP = 0x03, // SCP
|
||||
PRO_SCPB = 0x03, // SCP
|
||||
PRO_SERV1 = 0x04, // 预留
|
||||
PRO_SERV2 = 0x05, // 预留
|
||||
PRO_RFC = 0x06, // RFC(暂不支持)
|
||||
@@ -67,10 +60,38 @@ typedef enum {
|
||||
PRO_UFCS = 0x0C, // UFCS
|
||||
PRO_PD31AVS = 0x0D, // PD3.1/AVS
|
||||
PRO_VOOC = 0x0E, // VOOC(暂不支持)
|
||||
|
||||
PRO_SCPA = 0x0F, // SCPA
|
||||
TOTAL_PROS
|
||||
} eSRC_PRO;
|
||||
|
||||
// 电源协议映射表:枚举值 ↔ 协议名称(和你的 eSRC_PRO 完全对齐)
|
||||
typedef struct {
|
||||
rt_uint8_t pro_val; // 协议数值(对应 eSRC_PRO 枚举)
|
||||
int pro_name; // 协议显示名称(LCD展示用)
|
||||
} SrcProMap_t;
|
||||
|
||||
// 按 eSRC_PRO 枚举顺序定义映射表,确保一一对应
|
||||
static const SrcProMap_t src_pro_map[] = {
|
||||
{PRO_NONE, 30},
|
||||
{PRO_VIFC, 31},
|
||||
{PRO_FCP, 32},
|
||||
{PRO_SCPB, 33},
|
||||
{PRO_SERV1, 34},
|
||||
{PRO_SERV2, 35},
|
||||
{PRO_RFC, 36},
|
||||
{PRO_QC30, 37},
|
||||
{PRO_QC20, 38},
|
||||
{PRO_AFC, 39},
|
||||
{PRO_PD0PSS, 40},
|
||||
{PRO_SERV3, 41},
|
||||
{PRO_UFCS, 42},
|
||||
{PRO_PD31AVS, 43},
|
||||
{PRO_VOOC, 44},
|
||||
{PRO_SCPA, 45}
|
||||
};
|
||||
// 映射表长度宏(自动计算,避免手动维护)
|
||||
#define SRC_PRO_MAP_NUM (sizeof(src_pro_map) / sizeof(src_pro_map[0]))
|
||||
|
||||
// 应答帧头
|
||||
struct pkg_head_t {
|
||||
rt_uint8_t length; // 帧长度
|
||||
@@ -121,22 +142,34 @@ struct src_vc_t {
|
||||
rt_uint16_t version; // 版本号
|
||||
};
|
||||
|
||||
|
||||
#define PD_GEAR_ARRAY_LEN 4 // 非5V挡位最多4个,数组长度设为4
|
||||
// source 参数结构
|
||||
struct chrg_src_t {
|
||||
rt_uint16_t voltage; // 当前电压 mV
|
||||
rt_uint16_t current; // 当前电流 mA
|
||||
|
||||
rt_uint8_t vol_lvl; // CC线电平
|
||||
eSRC_PRO protocol; // 协议类型
|
||||
|
||||
struct src_vc_t vc; // 读取数据
|
||||
struct vc_pd_t pd_get[2]; // 读取PD协议数据
|
||||
struct vc_pd_t pd_set[2]; // 设置PD协议数据
|
||||
|
||||
rt_uint16_t voltage; // 当前电压 mV
|
||||
rt_uint16_t current; // 当前电流 mA
|
||||
|
||||
eSRC_PRO protocol; // 协议类型
|
||||
rt_uint8_t src; // 源类型
|
||||
rt_uint8_t pps; // PPS类型
|
||||
rt_uint8_t pro_gear_idx; // 挡位
|
||||
rt_uint16_t min_vol; // 最小电压 mV
|
||||
rt_uint16_t max_vol; // 最大电压 mV
|
||||
rt_uint8_t vol_lvl; // CC线电平
|
||||
rt_uint8_t cc_set; // cc线选择 //0代表1+2,1代表cc1,2代表cc2
|
||||
rt_uint16_t protective_curr; // 保护电流
|
||||
rt_uint8_t Now_State; // 当前状态
|
||||
rt_uint8_t On_Flag; // 启动总标志(0/1)
|
||||
rt_uint8_t Set_CV_Flag; // 电压/电流切换标志(0/1)
|
||||
rt_uint8_t Set_Pro_Flag; // 设置协议标志位(0/1/2)0代表没设置协议,1代表设置了但还没执行,2代表设置了并执行
|
||||
rt_uint8_t LCD_Set_Pro_Flag; // LCD设置协议标志位
|
||||
rt_uint8_t Work_step_flag; // 工作步骤标志位
|
||||
rt_uint8_t Stop_step_flag; // 停止步骤标志位
|
||||
rt_uint8_t change_sink_Flag; // 从source切换到sink标志位
|
||||
rt_uint8_t work_mode; // 0=停止 1=工作 2=低电压
|
||||
struct src_vc_t vc; // 读取数据
|
||||
struct vc_pd_t pd_get[2]; // 读取PD协议数据
|
||||
struct vc_pd_t pd_set[2]; // 设置PD协议数据
|
||||
};
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: source_get_vc
|
||||
函数描述: source电压电流查询请求
|
||||
@@ -167,6 +200,16 @@ extern int source_get_pd (void);
|
||||
*****************************************************************/
|
||||
extern int source_set_cc_lvl (rt_uint8_t lvl);
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: source_set_cc_choose
|
||||
函数描述: source 设置 cc线 选择
|
||||
输入参数: cc_set 0代表1+2,1代表cc1,2代表cc2
|
||||
输出参数: -
|
||||
返回说明: <0: 错误 >0:发送长度
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern int source_set_cc_choose (rt_uint8_t cc_set);
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: source_set_pd
|
||||
函数描述: source 设置PD协议
|
||||
@@ -178,7 +221,34 @@ extern int source_set_cc_lvl (rt_uint8_t lvl);
|
||||
extern int source_set_pd (rt_uint8_t pro, rt_uint8_t src, rt_uint8_t pps,
|
||||
rt_uint16_t vmax, rt_uint16_t vmin, rt_int16_t max_cur);
|
||||
|
||||
// 挡位参数结构体
|
||||
typedef struct {
|
||||
rt_uint8_t src; // 第1字段(如00/03)
|
||||
rt_uint8_t pps; // 第2字段(如00/01)
|
||||
rt_uint16_t v_min; // 电压最小值(如0x1388=5V)
|
||||
rt_uint16_t v_max; // 电压最大值(如0x1388=5V)
|
||||
rt_uint16_t cur_set; // 电流设置值(如0x0bb8=3A)
|
||||
} Pro_Group;
|
||||
|
||||
// 挡位映射表(索引对应挡位:0=5V,1=9V,2=12V,3=20V,4=PPS)
|
||||
static const Pro_Group pd_voltage_map[] = {
|
||||
{0x00, 0x00, 0x1388, 0x1388, 0x0bb8}, // 0:5V挡位
|
||||
{0x00, 0x00, 0x2328, 0x2328, 0x0bb8}, // 1:9V挡位
|
||||
{0x00, 0x00, 0x2ee0, 0x2ee0, 0x0bb8}, // 2:12V挡位
|
||||
{0x00, 0x00, 0x4e20, 0x4e20, 0x0bb8}, // 3:20V挡位
|
||||
{0x00, 0x00, 0xBB80, 0xBB80, 0X0bb8} // 4:48V
|
||||
// {0x03, 0x00, 0x1388, 0x4e20, 0x1388} // 4:PPS挡位 5-20V
|
||||
};
|
||||
extern rt_uint8_t pd_fill_gear_index(rt_uint8_t *gear_index, rt_uint8_t *gear_cnt, rt_uint8_t hex_code);
|
||||
extern int source_set_pd_com(rt_uint8_t pro,rt_uint8_t pro_gear_idx);
|
||||
#define PD_VOLTAGE_CNT (sizeof(pd_voltage_map) / sizeof(Pro_Group))
|
||||
extern rt_uint16_t pd_gear_parse(rt_uint8_t hex_code);
|
||||
|
||||
extern void parse_power_single_gear(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen,uint8_t *pro_gear_idx,uint8_t *pro,rt_uint16_t *protect_ma);
|
||||
extern void parse_power_pdo_gear(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen,uint8_t *pro_gear_idx,uint8_t *pro,rt_uint16_t *protect_ma);
|
||||
extern void parse_multi_gear_more(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen,uint8_t *pro_gear_idx,uint8_t *pro,rt_uint16_t *protect_ma);
|
||||
extern void parse_power_ufcs(rt_uint8_t *pData, rt_uint16_t reqLen, uint8_t *pro_gear_idx, uint8_t *pro,rt_uint16_t *protect_ma);
|
||||
extern int source_set_pd_new_com(rt_uint8_t pro, struct chrg_switch_t *pSW);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -75,12 +75,19 @@ rt_uint16_t mb_crc16 (rt_uint8_t *pucFrame, rt_uint16_t usLen)
|
||||
rt_uint8_t ucCRCLo = 0xFF;
|
||||
int iIndex;
|
||||
|
||||
if(usLen==8){
|
||||
for(int i = 0;i<usLen;i++){
|
||||
rt_kprintf("%02x ",pucFrame[i]);
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
}
|
||||
|
||||
while ( usLen-- ) {
|
||||
iIndex = ucCRCLo ^ *(pucFrame++);
|
||||
ucCRCLo = (rt_uint8_t)(ucCRCHi ^ aucCRCHi[iIndex]);
|
||||
ucCRCHi = aucCRCLo[iIndex];
|
||||
}
|
||||
|
||||
|
||||
return (rt_uint16_t)(ucCRCHi << 8 | ucCRCLo);
|
||||
}
|
||||
|
||||
@@ -135,13 +142,32 @@ rt_uint8_t u16_to_u8v (rt_uint16_t value, rt_uint8_t *buf)
|
||||
{
|
||||
if (RT_NULL != buf) {
|
||||
buf[0] = (value>>8)&0xFF;
|
||||
// rt_kprintf("%d",buf[0]);
|
||||
buf[1] = value&0xFF;
|
||||
// rt_kprintf("%d",buf[0]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************
|
||||
函数名称: u16_to_u8v_com
|
||||
函数描述: u16 转字节流
|
||||
输入参数: value:数据 *buf:字节流
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: -2026.7.1修改,高低字节互换
|
||||
*****************************************************************/
|
||||
rt_uint8_t u16_to_u8v_com (rt_uint16_t value, rt_uint8_t *buf)
|
||||
{
|
||||
if (RT_NULL != buf) {
|
||||
buf[1] = (value>>8)&0xFF;
|
||||
// rt_kprintf("%d",buf[0]);
|
||||
buf[0] = value&0xFF;
|
||||
// rt_kprintf("%d",buf[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: u8v_to_u16
|
||||
函数描述: 字节流转 u16
|
||||
|
||||
@@ -91,6 +91,15 @@ extern rt_uint16_t swap_u16 (rt_uint16_t x);
|
||||
其它说明: -
|
||||
*****************************************************************/
|
||||
extern rt_uint32_t swap_u32 (rt_uint32_t x);
|
||||
/*****************************************************************
|
||||
函数名称: u16_to_u8v_com
|
||||
函数描述: u16 转字节流
|
||||
输入参数: value:数据 *buf:字节流
|
||||
输出参数: -
|
||||
返回说明: -
|
||||
其它说明: -2026.7.1修改,高低字节互换
|
||||
*****************************************************************/
|
||||
extern rt_uint8_t u16_to_u8v_com (rt_uint16_t value, rt_uint8_t *buf);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Binary file not shown.
+29
-20
@@ -16,8 +16,8 @@
|
||||
<TargetCommonOption>
|
||||
<Device>STM32F405RG</Device>
|
||||
<Vendor>STMicroelectronics</Vendor>
|
||||
<PackID>Keil.STM32F4xx_DFP.2.16.0</PackID>
|
||||
<PackURL>http://www.keil.com/pack/</PackURL>
|
||||
<PackID>Keil.STM32F4xx_DFP.3.1.1</PackID>
|
||||
<PackURL>https://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000-0x2001FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) CPUTYPE("Cortex-M4") FPU2</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile>"Startup\ST\STM32F4xx\startup_stm32f40_41xxx.s" ("STM32F40/41xxx Startup Code")</StartupFile>
|
||||
@@ -132,7 +132,7 @@
|
||||
<UseTargetDll>1</UseTargetDll>
|
||||
<UseExternalTool>0</UseExternalTool>
|
||||
<RunIndependent>0</RunIndependent>
|
||||
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
|
||||
<UpdateFlashBeforeDebugging>0</UpdateFlashBeforeDebugging>
|
||||
<Capability>1</Capability>
|
||||
<DriverSelection>4096</DriverSelection>
|
||||
</Flash1>
|
||||
@@ -313,7 +313,7 @@
|
||||
</ArmAdsMisc>
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
<Optim>2</Optim>
|
||||
<Optim>4</Optim>
|
||||
<oTime>0</oTime>
|
||||
<SplitLS>0</SplitLS>
|
||||
<OneElfS>1</OneElfS>
|
||||
@@ -352,7 +352,7 @@
|
||||
<NoWarn>0</NoWarn>
|
||||
<uSurpInc>0</uSurpInc>
|
||||
<useXO>0</useXO>
|
||||
<ClangAsOpt>1</ClangAsOpt>
|
||||
<ClangAsOpt>4</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
@@ -443,16 +443,16 @@
|
||||
<Group>
|
||||
<GroupName>Applications/thread</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>chrg_north.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\thread\chrg_north.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_roll_nor.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\thread\chrg_roll_nor.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_north.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\thread\chrg_north.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_south.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -468,16 +468,16 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\thread\chrg_roll_sou.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_thread.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\thread\chrg_thread.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_lcd.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\thread\chrg_lcd.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_thread.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\thread\chrg_thread.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
@@ -493,16 +493,16 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\utils\chrg_sink.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_eload.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\utils\chrg_eload.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_north_pkg.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\utils\chrg_north_pkg.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_eload.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>applications\utils\chrg_eload.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>chrg_utils.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -2559,4 +2559,13 @@
|
||||
<files/>
|
||||
</RTE>
|
||||
|
||||
<LayerInfo>
|
||||
<Layers>
|
||||
<Layer>
|
||||
<LayName>chrg</LayName>
|
||||
<LayPrjMark>1</LayPrjMark>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</LayerInfo>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
LOAD %L INCREMENTAL
|
||||
@@ -15,7 +15,7 @@
|
||||
<TargetCommonOption>
|
||||
<Device>STM32F405RG</Device>
|
||||
<Vendor>STMicroelectronics</Vendor>
|
||||
<PackID>Keil.STM32F4xx_DFP.3.1.0</PackID>
|
||||
<PackID>Keil.STM32F4xx_DFP.3.1.1</PackID>
|
||||
<PackURL>https://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000-0x2001FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) CPUTYPE("Cortex-M4") FPU2</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
|
||||
Reference in New Issue
Block a user