refactor: 重构校准流程,拆分校准逻辑到南向模块

1. 删除chrg_roll_nor.h中的chrg_roll_trim_set声明
2. 从chrg_north.h中移除trim_step和north_mode成员变量
3. 在chrg_roll_sou.h中新增chrg_sou_trim_submit函数声明
4. 重构chrg_comm.c的校准处理逻辑:
   - 移除旧的通道关闭逻辑和本地寄存器操作
   - 新增校准模式合法性校验
   - 调用南向模块提交校准指令
5. 从chrg_roll_nor.c中删除全部校准相关代码
6. 在chrg_roll_sou.c中实现完整的校准指令组包和提交逻辑
7. 重构boot目录下的main.c,新增完整的系统初始化和跳转流程
This commit is contained in:
wrh
2026-07-23 14:31:41 +08:00
parent 8f44ae6877
commit 1fc998f168
7 changed files with 389 additions and 234 deletions
+189 -44
View File
@@ -1,69 +1,214 @@
#include <stdio.h>
#include "app_config.h"
#include "main.h"
#define APP_ADDRESS 0x08040000UL
#define APP_FLASH_END 0x08100000UL
#define SRAM_START 0x20000000UL
#define SRAM_END 0x20020000UL
/* Kept for legacy source files that remain in the Keil project. */
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart2_rx;
typedef void (*app_entry_t)(void);
void MX_DMA_DeInit(void)
extern void System_Init(void);
extern void APP_Init(void);
extern void APP_Running(void);
#if defined(STM32F405xx)
void SystemClock_Config (void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 192;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
}
void MX_USART_DeInit(void)
#elif defined(STM32F411xE)||defined(STM32F401xC)
void SystemClock_Config (void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
}
static void boot_jump_to_app(void)
#endif
static void MX_GPIO_Init (void)
{
uint32_t app_stack = *(volatile uint32_t *)APP_ADDRESS;
uint32_t app_reset = *(volatile uint32_t *)(APP_ADDRESS + 4U);
app_entry_t app_entry;
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Do not branch through an erased or invalid application vector table. */
if ((app_stack < SRAM_START) || (app_stack >= SRAM_END) ||
(app_reset < APP_ADDRESS) || (app_reset >= APP_FLASH_END)) {
while (1) {
}
}
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__disable_irq();
#if (ENABLE_FACTORY_FIRMWARE_BUTTON)
__HAL_RCC_GPIOE_CLK_ENABLE();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
GPIO_InitStruct.Pin = KEY0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY0_GPIO_Port, &GPIO_InitStruct);
#endif
for (uint32_t i = 0; i < 8U; i++) {
NVIC->ICER[i] = 0xFFFFFFFFUL;
NVIC->ICPR[i] = 0xFFFFFFFFUL;
}
GPIO_InitStruct.Pin = LED0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(LED0_GPIO_Port, &GPIO_InitStruct);
HAL_DeInit();
SCB->VTOR = APP_ADDRESS;
__set_MSP(app_stack);
__set_CONTROL(0);
__DSB();
__ISB();
app_entry = (app_entry_t)app_reset;
app_entry();
while (1) {
}
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);
}
int main(void)
{
HAL_Init();
boot_jump_to_app();
while (1) {
}
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
// usart1 rx
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
// usart2 rx
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
}
void MX_DMA_DeInit (void)
{
HAL_DMA_DeInit(&hdma_usart1_rx);
HAL_DMA_DeInit(&hdma_usart2_rx);
}
static void MX_USART_Init (void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart1);
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
void MX_USART_DeInit (void)
{
HAL_UART_DeInit(&huart1);
HAL_UART_DeInit(&huart2);
}
int main (void)
{
HAL_Init();
SystemClock_Config();
System_Init();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART_Init();
#if 0
printf("\r\n\r\n========================================\r\n");
printf("\t%s boot V%d.%d.%d\r\n", NAME_CHIP,
VERSION_MAIN, VERSION_SUB, VERSION_FIX);
printf("\tbuilt @ %s\r\n", BUILD_TIMESTAMP);
printf("Chip UID: %08X - %08X - %08X\r\n",
HAL_GetUIDw0(), HAL_GetUIDw1(), HAL_GetUIDw2());
printf("========================================\r\n");
#else
printf("\tboot V%d.%d.%d built @ %s\r\n",
VERSION_MAIN, VERSION_SUB, VERSION_FIX, BUILD_TIMESTAMP);
#endif
APP_Init();
while (1) {
APP_Running();
}
return -1;
}
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE * f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart2,&ch, 1, 0xffff);
return ch;
}
+14 -13
View File
@@ -1199,13 +1199,10 @@ eMBException funcTrimELoad (rt_uint8_t *reqFrame, rt_uint16_t reqLen,
rt_uint8_t *resFrame, rt_uint16_t *resLen)
{
struct chrg_north_t *pNOR = &chrgnorth;
struct chrg_south_t *pSOU = &chrgsouth;
struct chrg_switch_t *pSW = RT_NULL;
rt_uint16_t regAddress = 0, cntReg = 0;
rt_uint16_t regAddress = 0;
rt_uint8_t RegCount;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if (4+MB_PDU_FUNC_WRITE_MUL_SIZE_MIN > reqLen) {
rt_kprintf("LEN ERROR");
@@ -1217,7 +1214,7 @@ eMBException funcTrimELoad (rt_uint8_t *reqFrame, rt_uint16_t reqLen,
regAddress = reqFrame[3];
RegCount = u8v_to_u16(&reqFrame[4]);
rt_kprintf("ch=%d,enable=%d,reg=0x%02x,count=%d\n",ch+1,enable_flag,regAddress,RegCount);
if(ch<0||ch>3){
if(ch >= TOTAL_SOU_CHS){
rt_kprintf("CH ERROR");
return MB_EX_ILLEGAL_DATA_VALUE;
}
@@ -1226,13 +1223,11 @@ eMBException funcTrimELoad (rt_uint8_t *reqFrame, rt_uint16_t reqLen,
rt_kprintf("Enable Flag ERROR");
return MB_EX_ILLEGAL_DATA_VALUE;
}
set_ymodem_update_channel(pNOR, pSOU, ch); //关掉除选定通道外的其他通道使能
//提取首指针
struct chrg_trim *pTrim = &pNOR->trim[ch];
rt_uint8_t *pWriteData = &reqFrame[7];
pNOR->north_mode = 1;
pTrim->trim_enable_flag = enable_flag;
pTrim->trim_step = 0;
pTrim->trim_mode = 0;
//多寄存器控制操作
for(int i =0;i<RegCount;i++){
//计算当前寄存器的协议地址和本地偏移
@@ -1281,13 +1276,19 @@ eMBException funcTrimELoad (rt_uint8_t *reqFrame, rt_uint16_t reqLen,
//寄存器操作
rt_kprintf("com ch=:%d,reg=%02x,value=%d\n",ch,Curr_reg_addr,Curr_write_value);
}
if (pTrim->trim_mode == 0) {
return MB_EX_ILLEGAL_DATA_ADDRESS;
}
/*
* COM只负责解析校准数据。完整校准序列由南向模块组装并加入RUN_COM队列,
* 目标通道由队列项确定,因此无需关闭任何南向通道的正常轮询使能。
*/
if (chrg_sou_trim_submit(ch, pTrim) != 0) {
return MB_EX_SLAVE_BUSY;
}
rt_memcpy(resFrame, reqFrame, reqLen);
*resLen = 6;
//eRegStatus = mb_reg_holding_cb(&reqFrame[7], &resFrame[3], regAddress, cntReg, MB_REG_WRITE);
if (eRegStatus != MB_ENOERR) {
eStatus = mb_error(eRegStatus);
}
return eStatus;
}
@@ -95,7 +95,6 @@ struct chrg_trim {
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则写出场数据区
};
@@ -112,7 +111,6 @@ struct chrg_north_t {
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;
+1 -174
View File
@@ -400,12 +400,7 @@ void chrg_roll_nor_thread_entry (void *data)
chrgnorth.idx = idx;
pROLL->idx = idx;
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
if(pNOR->north_mode == 0){
chrg_roll_nor_set(pROLL->idx,pSW,&pNOR->enable[idx]);
}
if(pNOR->north_mode == 1){
chrg_roll_trim_set(pROLL->idx,pNOR);
}
chrg_roll_nor_set(pROLL->idx,pSW,&pNOR->enable[idx]);
rt_mutex_release(pTHR->mutex);
}
index++;
@@ -667,171 +662,3 @@ MSH_CMD_EXPORT(source, north source test);
#endif
//校准CRC计算
rt_uint16_t chrg_trim_crc(rt_uint8_t ch, struct chrg_north_t *pNOR)
{
struct chrg_trim *pTrim = &pNOR->trim[ch];
rt_uint8_t buf[22];
int idx = 0;
buf[idx++] = (pTrim->trim_volt_k_H >> 8) & 0xFF;
buf[idx++] = pTrim->trim_volt_k_H & 0xFF;
buf[idx++] = (pTrim->trim_volt_k_L >> 8) & 0xFF;
buf[idx++] = pTrim->trim_volt_k_L & 0xFF;
buf[idx++] = (pTrim->trim_volt_b >> 8) & 0xFF;
buf[idx++] = pTrim->trim_volt_b & 0xFF;
buf[idx++] = (pTrim->trim_curr_k_H >> 8) & 0xFF;
buf[idx++] = pTrim->trim_curr_k_H & 0xFF;
buf[idx++] = (pTrim->trim_curr_k_L >> 8) & 0xFF;
buf[idx++] = pTrim->trim_curr_k_L & 0xFF;
buf[idx++] = (pTrim->trim_curr_b >> 8) & 0xFF;
buf[idx++] = pTrim->trim_curr_b & 0xFF;
buf[idx++] = (pTrim->trim_source_curr_k_H >> 8) & 0xFF;
buf[idx++] = pTrim->trim_source_curr_k_H & 0xFF;
buf[idx++] = (pTrim->trim_source_curr_k_L >> 8) & 0xFF;
buf[idx++] = pTrim->trim_source_curr_k_L & 0xFF;
buf[idx++] = (pTrim->trim_source_curr_b >> 8) & 0xFF;
buf[idx++] = pTrim->trim_source_curr_b & 0xFF;
buf[idx++] = (pTrim->trim_zero >> 8) & 0xFF;
buf[idx++] = pTrim->trim_zero & 0xFF;
return mb_crc16(buf, 20);
}
//电源校准设置
void chrg_trim_set_volt(rt_uint8_t ch,struct chrg_north_t *pNOR){
struct chrg_trim *pTRIM = &pNOR->trim[ch];
switch(pTRIM->trim_step){
case 0:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Volt_CAL_K_H, pTRIM->trim_volt_k_H);
break;
case 1:
break;
case 2:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Volt_CAL_K_L, pTRIM->trim_volt_k_L);
break;
case 3:
break;
case 4:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Volt_CAL_B, pTRIM->trim_volt_b);
break;
pNOR->north_mode = 0;
break;
}
pTRIM->trim_step++;
}
//电流校准设置
void chrg_trim_set_curr(rt_uint8_t ch,struct chrg_north_t *pNOR){
struct chrg_trim *pTRIM = &pNOR->trim[ch];
switch(pTRIM->trim_step){
case 0:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Current_CAL_K_H, pTRIM->trim_curr_k_H);
break;
case 1:
break;
case 2:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Current_CAL_K_L, pTRIM->trim_curr_k_L);
break;
case 3:
break;
case 4:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Current_CAL_B, pTRIM->trim_curr_b);
pNOR->north_mode = 0;
break;
}
pTRIM->trim_step++;
}
//电源校准设置
void chrg_trim_set_source_curr(rt_uint8_t ch,struct chrg_north_t *pNOR){
struct chrg_trim *pTRIM = &pNOR->trim[ch];
rt_uint16_t crc = 0;
switch(pTRIM->trim_step){
case 0:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_SourceCurrent_CAL_K_H, pTRIM->trim_source_curr_k_H);
break;
case 1:
break;
case 2:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_SourceCurrent_CAL_K_L, pTRIM->trim_source_curr_k_L);
break;
case 3:
break;
case 4:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_SourceCurrent_CAL_B, pTRIM->trim_source_curr_b);
break;
case 5:
break;
case 6:
crc = chrg_trim_crc(ch, pNOR);
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Trim_CRC_CAL, crc);
rt_kprintf("crc=%04X\n",crc);
break;
case 7:
break;
case 8:
if(pTRIM->trim_enable_flag == 0){
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteEnable_ADD,ModbusRTU_CAL_WriteValue);
}else{
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteRecovery,ModbusRTU_CAL_WriteRecovery_Value);
}
pNOR->north_mode = 0;
break;
}
pTRIM->trim_step++;
}
//校准飘零设置
void chrg_trim_set_zero(rt_uint8_t ch,struct chrg_north_t *pNOR){
struct chrg_trim *pTRIM = &pNOR->trim[ch];
rt_uint16_t crc = 0;
switch(pTRIM->trim_step){
case 0:
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Trim_Zero_CAL, pTRIM->trim_zero);
break;
case 1:
break;
case 2:
crc = chrg_trim_crc(ch, pNOR);
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_Trim_CRC_CAL, crc);
break;
case 3:
break;
case 4:
if(pTRIM->trim_enable_flag == 0){
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteEnable_ADD,ModbusRTU_CAL_WriteValue);
}else{
chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_CAL_WriteRecovery,ModbusRTU_CAL_WriteRecovery_Value);
}
pNOR->north_mode = 0;
break;
}
pTRIM->trim_step++;
}
//校准设置
void chrg_roll_trim_set(rt_uint8_t ch, struct chrg_north_t *pNOR){
struct chrg_trim *pTRIM = &pNOR->trim[ch];
switch(pTRIM->trim_mode){
case MODE_VOLT_CAL:
chrg_trim_set_volt(ch, pNOR);
break;
case MODE_CURR_CAL:
chrg_trim_set_curr(ch, pNOR);
break;
case MODE_SOURCE_CURR_CAL:
chrg_trim_set_source_curr(ch, pNOR);
break;
case MODE_ZERO_CAL:
chrg_trim_set_zero(ch, pNOR);
break;
}
}
@@ -80,7 +80,6 @@ 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
@@ -15,6 +15,7 @@
#include "chrg_led.h"
#include "chrg_thread.h"
#include "chrg_roll_sou.h"
#include "chrg_north.h"
#include "chrg_eload.h"
#include "chrg_utils.h"
@@ -118,6 +119,180 @@ int chrg_sou_com_batch_add_reg(eIDX_SOU_CH ch, rt_uint16_t reg, rt_uint16_t val)
{
return chrg_sou_com_batch_submit(ch, &reg, &val, 1);
}
/*****************************************************************
函数名称: chrg_sou_trim_crc
函数描述: 按功率板协议顺序计算全部校准参数的Modbus CRC16
输入参数: pTrim:校准参数结构体
输出参数: -
返回说明: 校准参数CRC16
其它说明: CRC覆盖电压、负载电流、电源电流及零点共20字节
*****************************************************************/
static rt_uint16_t chrg_sou_trim_crc(const struct chrg_trim *pTrim)
{
rt_uint8_t buf[20];
rt_uint8_t idx = 0;
rt_uint16_t value;
#define TRIM_CRC_APPEND(_value) \
do { \
value = (rt_uint16_t)(_value); \
buf[idx++] = (rt_uint8_t)(value >> 8); \
buf[idx++] = (rt_uint8_t)(value & 0xFF); \
} while (0)
TRIM_CRC_APPEND(pTrim->trim_volt_k_H);
TRIM_CRC_APPEND(pTrim->trim_volt_k_L);
TRIM_CRC_APPEND(pTrim->trim_volt_b);
TRIM_CRC_APPEND(pTrim->trim_curr_k_H);
TRIM_CRC_APPEND(pTrim->trim_curr_k_L);
TRIM_CRC_APPEND(pTrim->trim_curr_b);
TRIM_CRC_APPEND(pTrim->trim_source_curr_k_H);
TRIM_CRC_APPEND(pTrim->trim_source_curr_k_L);
TRIM_CRC_APPEND(pTrim->trim_source_curr_b);
TRIM_CRC_APPEND(pTrim->trim_zero);
#undef TRIM_CRC_APPEND
return mb_crc16(buf, sizeof(buf));
}
/*****************************************************************
函数名称: chrg_sou_trim_set_commit
函数描述: 根据校准区标志填写最后一条写使能命令
输入参数: pTrim:校准参数 reg:寄存器地址指针 value:寄存器值指针
输出参数: reg:写使能地址 value:对应魔数
返回说明: -
其它说明: 0写用户校准区,1写出厂校准区
*****************************************************************/
static void chrg_sou_trim_set_commit(const struct chrg_trim *pTrim,
rt_uint16_t *reg, rt_uint16_t *value)
{
if (pTrim->trim_enable_flag == 0) {
*reg = ModbusRTU_CAL_WriteEnable_ADD;
*value = ModbusRTU_CAL_WriteValue;
} else {
*reg = ModbusRTU_CAL_WriteRecovery;
*value = ModbusRTU_CAL_WriteRecovery_Value;
}
}
/*****************************************************************
函数名称: chrg_sou_trim_set_volt
函数描述: 组装电源电压校准、CRC和写使能指令
输入参数: ch:南向通道 pTrim:校准参数
输出参数: -
返回说明: 0:提交成功 <0:队列提交失败
其它说明: 指令顺序为K_H、K_L、B、CRC、写使能
*****************************************************************/
static int chrg_sou_trim_set_volt(eIDX_SOU_CH ch, const struct chrg_trim *pTrim)
{
rt_uint16_t regs[5] = {
ModbusRTU_Volt_CAL_K_H, ModbusRTU_Volt_CAL_K_L,
ModbusRTU_Volt_CAL_B, ModbusRTU_Trim_CRC_CAL, 0
};
rt_uint16_t vals[5] = {
pTrim->trim_volt_k_H, pTrim->trim_volt_k_L,
(rt_uint16_t)pTrim->trim_volt_b, chrg_sou_trim_crc(pTrim), 0
};
chrg_sou_trim_set_commit(pTrim, &regs[4], &vals[4]);
return chrg_sou_com_batch_submit(ch, regs, vals, 5);
}
/*****************************************************************
函数名称: chrg_sou_trim_set_curr
函数描述: 组装负载电流校准、CRC和写使能指令
输入参数: ch:南向通道 pTrim:校准参数
输出参数: -
返回说明: 0:提交成功 <0:队列提交失败
其它说明: 指令顺序为K_H、K_L、B、CRC、写使能
*****************************************************************/
static int chrg_sou_trim_set_curr(eIDX_SOU_CH ch, const struct chrg_trim *pTrim)
{
rt_uint16_t regs[5] = {
ModbusRTU_Current_CAL_K_H, ModbusRTU_Current_CAL_K_L,
ModbusRTU_Current_CAL_B, ModbusRTU_Trim_CRC_CAL, 0
};
rt_uint16_t vals[5] = {
pTrim->trim_curr_k_H, pTrim->trim_curr_k_L,
(rt_uint16_t)pTrim->trim_curr_b, chrg_sou_trim_crc(pTrim), 0
};
chrg_sou_trim_set_commit(pTrim, &regs[4], &vals[4]);
return chrg_sou_com_batch_submit(ch, regs, vals, 5);
}
/*****************************************************************
函数名称: chrg_sou_trim_set_source_curr
函数描述: 组装电源电流校准、CRC和写使能指令
输入参数: ch:南向通道 pTrim:校准参数
输出参数: -
返回说明: 0:提交成功 <0:队列提交失败
其它说明: 指令顺序为K_H、K_L、B、CRC、写使能
*****************************************************************/
static int chrg_sou_trim_set_source_curr(eIDX_SOU_CH ch,
const struct chrg_trim *pTrim)
{
rt_uint16_t regs[5] = {
ModbusRTU_SourceCurrent_CAL_K_H, ModbusRTU_SourceCurrent_CAL_K_L,
ModbusRTU_SourceCurrent_CAL_B, ModbusRTU_Trim_CRC_CAL, 0
};
rt_uint16_t vals[5] = {
pTrim->trim_source_curr_k_H, pTrim->trim_source_curr_k_L,
(rt_uint16_t)pTrim->trim_source_curr_b, chrg_sou_trim_crc(pTrim), 0
};
chrg_sou_trim_set_commit(pTrim, &regs[4], &vals[4]);
return chrg_sou_com_batch_submit(ch, regs, vals, 5);
}
/*****************************************************************
函数名称: chrg_sou_trim_set_zero
函数描述: 组装零点校准、CRC和写使能指令
输入参数: ch:南向通道 pTrim:校准参数
输出参数: -
返回说明: 0:提交成功 <0:队列提交失败
其它说明: 指令顺序为ZERO、CRC、写使能
*****************************************************************/
static int chrg_sou_trim_set_zero(eIDX_SOU_CH ch, const struct chrg_trim *pTrim)
{
rt_uint16_t regs[3] = {ModbusRTU_Trim_Zero_CAL, ModbusRTU_Trim_CRC_CAL, 0};
rt_uint16_t vals[3] = {
(rt_uint16_t)pTrim->trim_zero, chrg_sou_trim_crc(pTrim), 0
};
chrg_sou_trim_set_commit(pTrim, &regs[2], &vals[2]);
return chrg_sou_com_batch_submit(ch, regs, vals, 3);
}
/*****************************************************************
函数名称: chrg_sou_trim_submit
函数描述: 根据校准类型选择组包函数并提交到南向RUN_COM队列
输入参数: ch:南向功率板通道 pTrim:已解析的校准参数
输出参数: -
返回说明: 0:提交成功 <0:参数、校准模式或队列提交失败
其它说明: 本函数不修改南向enable,RUN_COM按ch主动切换目标通道
*****************************************************************/
int chrg_sou_trim_submit(eIDX_SOU_CH ch, const struct chrg_trim *pTrim)
{
if ((ch >= TOTAL_SOU_CHS) || (pTrim == RT_NULL)) {
return -1;
}
switch (pTrim->trim_mode) {
case MODE_VOLT_CAL:
return chrg_sou_trim_set_volt(ch, pTrim);
case MODE_CURR_CAL:
return chrg_sou_trim_set_curr(ch, pTrim);
case MODE_SOURCE_CURR_CAL:
return chrg_sou_trim_set_source_curr(ch, pTrim);
case MODE_ZERO_CAL:
return chrg_sou_trim_set_zero(ch, pTrim);
default:
return -1;
}
}
//启动批量下发(填充完影子结构体后调用)
/*****************************************************************
@@ -12,6 +12,7 @@
#include <rtthread.h>
struct chrg_trim;
#define THR_NAME_ROLL_SOU "thr.rollsou"
@@ -87,6 +88,15 @@ extern void chrg_send_sou_upadata_data (rt_uint8_t *buf,rt_uint16_t leng);
extern int chrg_sou_com_batch_add_reg(eIDX_SOU_CH ch, rt_uint16_t reg, rt_uint16_t val);
extern int chrg_sou_com_batch_submit(eIDX_SOU_CH ch, const rt_uint16_t *regs,
const rt_uint16_t *vals, rt_uint8_t count);
/*****************************************************************
函数名称: chrg_sou_trim_submit
函数描述: 根据校准类型组装功率板校准指令并提交到南向COM队列
输入参数: ch:南向功率板通道 pTrim:已解析的校准参数
输出参数: -
返回说明: 0:提交成功 <0:参数、校准模式或队列提交失败
其它说明: 实际发送、应答校验和重试由RUN_COM分支统一管理
*****************************************************************/
extern int chrg_sou_trim_submit(eIDX_SOU_CH ch, const struct chrg_trim *pTrim);
#endif