From 1fc998f168dcf603db35d60a5a931a8de997a196 Mon Sep 17 00:00:00 2001 From: wrh Date: Thu, 23 Jul 2026 14:31:41 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=A0=A1?= =?UTF-8?q?=E5=87=86=E6=B5=81=E7=A8=8B=EF=BC=8C=E6=8B=86=E5=88=86=E6=A0=A1?= =?UTF-8?q?=E5=87=86=E9=80=BB=E8=BE=91=E5=88=B0=E5=8D=97=E5=90=91=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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,新增完整的系统初始化和跳转流程 --- apps/boot/application/main.c | 233 ++++++++++++++---- apps/chrg/applications/thread/chrg_comm.c | 27 +- apps/chrg/applications/thread/chrg_north.h | 2 - apps/chrg/applications/thread/chrg_roll_nor.c | 175 +------------ apps/chrg/applications/thread/chrg_roll_nor.h | 1 - apps/chrg/applications/thread/chrg_roll_sou.c | 175 +++++++++++++ apps/chrg/applications/thread/chrg_roll_sou.h | 10 + 7 files changed, 389 insertions(+), 234 deletions(-) diff --git a/apps/boot/application/main.c b/apps/boot/application/main.c index 944868a..8c11db6 100644 --- a/apps/boot/application/main.c +++ b/apps/boot/application/main.c @@ -1,69 +1,214 @@ + +#include +#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; +} + + diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index 9fbce17..f57780e 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -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;itrim_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; } diff --git a/apps/chrg/applications/thread/chrg_north.h b/apps/chrg/applications/thread/chrg_north.h index abefd28..f217a5d 100644 --- a/apps/chrg/applications/thread/chrg_north.h +++ b/apps/chrg/applications/thread/chrg_north.h @@ -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; diff --git a/apps/chrg/applications/thread/chrg_roll_nor.c b/apps/chrg/applications/thread/chrg_roll_nor.c index d2fcbcd..5467673 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.c +++ b/apps/chrg/applications/thread/chrg_roll_nor.c @@ -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; - } -} - - - diff --git a/apps/chrg/applications/thread/chrg_roll_nor.h b/apps/chrg/applications/thread/chrg_roll_nor.h index 8fbc669..7fc29f1 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.h +++ b/apps/chrg/applications/thread/chrg_roll_nor.h @@ -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 diff --git a/apps/chrg/applications/thread/chrg_roll_sou.c b/apps/chrg/applications/thread/chrg_roll_sou.c index 34e6542..8fb6887 100644 --- a/apps/chrg/applications/thread/chrg_roll_sou.c +++ b/apps/chrg/applications/thread/chrg_roll_sou.c @@ -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, ®, &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, ®s[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, ®s[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, ®s[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, ®s[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; + } +} //启动批量下发(填充完影子结构体后调用) /***************************************************************** diff --git a/apps/chrg/applications/thread/chrg_roll_sou.h b/apps/chrg/applications/thread/chrg_roll_sou.h index af2c1e0..3836c7b 100644 --- a/apps/chrg/applications/thread/chrg_roll_sou.h +++ b/apps/chrg/applications/thread/chrg_roll_sou.h @@ -12,6 +12,7 @@ #include +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