feat: 新增电源/负载切换功能,优化通道切换逻辑
1. 新增SINK_WORK_SWITCH和SOURCE_WORK_SWITCH状态,实现切换流程 2. 实现chrg_sink_work_switch和chrg_source_work_switch切换处理函数 3. 修改Keil工程ROM起始地址为0x8000000 4. 开启north线程调试输出,调整初始通道使能状态 5. 简化串口包编码调试打印,优化source初始化寄存器配置 6. 重构modbus通道切换逻辑,支持活跃状态下的角色切换 7. 清理部分冗余调试代码和注释 8. 重构bootloader代码,简化启动流程
This commit is contained in:
+43
-188
@@ -1,214 +1,69 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "app_config.h"
|
|
||||||
#include "main.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 huart1;
|
||||||
UART_HandleTypeDef huart2;
|
UART_HandleTypeDef huart2;
|
||||||
DMA_HandleTypeDef hdma_usart1_rx;
|
DMA_HandleTypeDef hdma_usart1_rx;
|
||||||
DMA_HandleTypeDef hdma_usart2_rx;
|
DMA_HandleTypeDef hdma_usart2_rx;
|
||||||
|
|
||||||
|
typedef void (*app_entry_t)(void);
|
||||||
|
|
||||||
extern void System_Init(void);
|
void MX_DMA_DeInit(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(STM32F411xE)||defined(STM32F401xC)
|
void MX_USART_DeInit(void)
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
static void boot_jump_to_app(void)
|
||||||
|
|
||||||
static void MX_GPIO_Init (void)
|
|
||||||
{
|
{
|
||||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
uint32_t app_stack = *(volatile uint32_t *)APP_ADDRESS;
|
||||||
|
uint32_t app_reset = *(volatile uint32_t *)(APP_ADDRESS + 4U);
|
||||||
|
app_entry_t app_entry;
|
||||||
|
|
||||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
/* Do not branch through an erased or invalid application vector table. */
|
||||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
if ((app_stack < SRAM_START) || (app_stack >= SRAM_END) ||
|
||||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
(app_reset < APP_ADDRESS) || (app_reset >= APP_FLASH_END)) {
|
||||||
|
while (1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if (ENABLE_FACTORY_FIRMWARE_BUTTON)
|
__disable_irq();
|
||||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = KEY0_Pin;
|
SysTick->CTRL = 0;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
SysTick->LOAD = 0;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
SysTick->VAL = 0;
|
||||||
HAL_GPIO_Init(KEY0_GPIO_Port, &GPIO_InitStruct);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = LED0_Pin;
|
for (uint32_t i = 0; i < 8U; i++) {
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
NVIC->ICER[i] = 0xFFFFFFFFUL;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
NVIC->ICPR[i] = 0xFFFFFFFFUL;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
}
|
||||||
HAL_GPIO_Init(LED0_GPIO_Port, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
|
HAL_DeInit();
|
||||||
|
SCB->VTOR = APP_ADDRESS;
|
||||||
/* Configure the MCO1 pin in alternate function mode */
|
__set_MSP(app_stack);
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_8;
|
__set_CONTROL(0);
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
__DSB();
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
__ISB();
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
app_entry = (app_entry_t)app_reset;
|
||||||
|
app_entry();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
static void MX_DMA_Init(void)
|
|
||||||
{
|
{
|
||||||
|
HAL_Init();
|
||||||
|
boot_jump_to_app();
|
||||||
|
|
||||||
/* DMA controller clock enable */
|
while (1) {
|
||||||
__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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1867,21 +1867,8 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_
|
|||||||
struct chrg_thread_t *pTHR_NOR = &chrgthr[IDX_THR_ROLL_NOR];
|
struct chrg_thread_t *pTHR_NOR = &chrgthr[IDX_THR_ROLL_NOR];
|
||||||
rt_mutex_take(pTHR_NOR->mutex, RT_WAITING_FOREVER);
|
rt_mutex_take(pTHR_NOR->mutex, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
|
/* 保存复制前的真实角色,复制后据此判断是否需要先停后切。 */
|
||||||
eIDX_ID old_id = pReal->id;
|
eIDX_ID old_id = pReal->id;
|
||||||
eIDX_ID new_id = pSW->id;
|
|
||||||
rt_bool_t old_active = RT_FALSE;
|
|
||||||
if (old_id == ID_SOURCE) {
|
|
||||||
old_active = (pReal->source.On_Flag || pReal->source.Now_State);
|
|
||||||
} else if (old_id == ID_SINK) {
|
|
||||||
old_active = (pReal->sink.On_work || pReal->sink.Now_State);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((old_id != new_id) && old_active) {
|
|
||||||
rt_mutex_release(pTHR_NOR->mutex);
|
|
||||||
LOG_W("CH%d direction change rejected while active: %d -> %d",
|
|
||||||
ch + 1, old_id, new_id);
|
|
||||||
return MB_EX_SLAVE_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_shadow_dirty[ch] = 0;
|
g_shadow_dirty[ch] = 0;
|
||||||
chrg_sink_get_proto_diff(pReal, pSW, &diff_info, &pro_change);
|
chrg_sink_get_proto_diff(pReal, pSW, &diff_info, &pro_change);
|
||||||
@@ -1892,6 +1879,31 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_
|
|||||||
rt_uint16_t old_loadc = pReal->sink.loadc;
|
rt_uint16_t old_loadc = pReal->sink.loadc;
|
||||||
//rt_uint8_t old_sink_test = pReal->sink.test.test_mode;
|
//rt_uint8_t old_sink_test = pReal->sink.test.test_mode;
|
||||||
rt_memcpy(pReal, &g_shadow_sw[ch], sizeof(struct chrg_switch_t));
|
rt_memcpy(pReal, &g_shadow_sw[ch], sizeof(struct chrg_switch_t));
|
||||||
|
eIDX_ID new_id = pReal->id;
|
||||||
|
|
||||||
|
if (old_id != new_id)
|
||||||
|
{
|
||||||
|
int switch_ret;
|
||||||
|
|
||||||
|
/* 复制后按新角色选择状态机,保证id与work_mode归属一致。 */
|
||||||
|
if (new_id == ID_SOURCE) {
|
||||||
|
pReal->source.work_mode = SOURCE_WORK_SWITCH;
|
||||||
|
switch_ret = chrg_source_work_state(ch, pReal);
|
||||||
|
} else {
|
||||||
|
pReal->sink.work_mode = SINK_WORK_SWITCH;
|
||||||
|
switch_ret = chrg_sink_work((eIDX_SOU_CH)ch, pReal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_ret != 0) {
|
||||||
|
g_shadow_dirty[ch] = 1;
|
||||||
|
rt_mutex_release(pTHR_NOR->mutex);
|
||||||
|
return MB_EX_SLAVE_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_mutex_release(pTHR_NOR->mutex);
|
||||||
|
return MB_EX_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (new_id == ID_SINK)
|
if (new_id == ID_SINK)
|
||||||
{
|
{
|
||||||
if (sink_work == 0x01) // 负载启动
|
if (sink_work == 0x01) // 负载启动
|
||||||
@@ -1961,6 +1973,7 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_
|
|||||||
else if (new_id == ID_SOURCE && source_work == 0x01)
|
else if (new_id == ID_SOURCE && source_work == 0x01)
|
||||||
{
|
{
|
||||||
/* COM只触发状态,初始化命令由Source状态机统一下发。 */
|
/* COM只触发状态,初始化命令由Source状态机统一下发。 */
|
||||||
|
pReal->sub = IDX_SET_SOURCE_CC_SET;
|
||||||
pReal->source.On_Flag = 1;
|
pReal->source.On_Flag = 1;
|
||||||
pReal->source.work_mode = SOURCE_WORK_INIT;
|
pReal->source.work_mode = SOURCE_WORK_INIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,13 +51,6 @@ void chrg_source_standard_output(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
pSW->source.Set_CV_Flag = 1;
|
pSW->source.Set_CV_Flag = 1;
|
||||||
pSW->change_flag = 0;
|
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;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//电源快充
|
//电源快充
|
||||||
@@ -78,20 +71,7 @@ void chrg_source_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
|||||||
}
|
}
|
||||||
pSW->source.vc.set_voltage = volt_mv;
|
pSW->source.vc.set_voltage = volt_mv;
|
||||||
pSW->source.vc.set_current = Curr_mA;
|
pSW->source.vc.set_current = Curr_mA;
|
||||||
// #if LCD_OPEN
|
if (pSW->source.On_Flag) {
|
||||||
// // 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 (pSW->source.On_Flag && (volt_mv_Now > 2000)) {
|
|
||||||
if ((volt_mv == last_volt_mv[idx])) {
|
if ((volt_mv == last_volt_mv[idx])) {
|
||||||
pSW->source.work_mode = SOURCE_WORK_WAIT;
|
pSW->source.work_mode = SOURCE_WORK_WAIT;
|
||||||
} else {
|
} else {
|
||||||
@@ -145,8 +125,6 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
|||||||
|
|
||||||
if(pSW->sink.On_work == 1 && pSW->sink.test.test_mode == 0) {
|
if(pSW->sink.On_work == 1 && pSW->sink.test.test_mode == 0) {
|
||||||
if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
|
if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
|
||||||
// volt_low[idx]++;
|
|
||||||
/* Treat low voltage as a fault only after voltage was once valid. */
|
|
||||||
if (volt_set_ok[idx] == 1) {
|
if (volt_set_ok[idx] == 1) {
|
||||||
if (++volt_low[idx] >= 3) {
|
if (++volt_low[idx] >= 3) {
|
||||||
volt_set_ok[idx] = 0;
|
volt_set_ok[idx] = 0;
|
||||||
@@ -154,16 +132,13 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
|||||||
pSW->sink.work_mode = SINK_WORK_LOW;
|
pSW->sink.work_mode = SINK_WORK_LOW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if(volt_low[idx]>=5) pSW->sink.work_on_step = SINK_WORK_LOW; // 复位工作状态机
|
|
||||||
}
|
}
|
||||||
else{ // 电压稳定时执行工作状态机(继电器/工作模式切换)
|
else{ // 电压稳定时执行工作状态机(继电器/工作模式切换)
|
||||||
volt_low[idx] = 0;
|
volt_low[idx] = 0;
|
||||||
volt_set_ok[idx] = 1;
|
volt_set_ok[idx] = 1;
|
||||||
pSW->change_flag = 0;
|
pSW->change_flag = 0;
|
||||||
/* Avoid unsigned underflow when actual voltage is above target. */
|
|
||||||
if ((rt_uint32_t)volt_mv + 2000 >= pSW->sink.pro_loadv) {
|
if ((rt_uint32_t)volt_mv + 2000 >= pSW->sink.pro_loadv) {
|
||||||
pSW->sink.work_mode = SINK_WORK_RUNING;
|
pSW->sink.work_mode = SINK_WORK_RUNING;
|
||||||
/* Voltage is normal but current is still zero: retry from WAIT. */
|
|
||||||
if (pSW->Now_current <= 200) {
|
if (pSW->Now_current <= 200) {
|
||||||
if (++no_curr[idx] >= 3) {
|
if (++no_curr[idx] >= 3) {
|
||||||
pSW->sink.work_mode = SINK_WORK_WAIT;
|
pSW->sink.work_mode = SINK_WORK_WAIT;
|
||||||
@@ -182,7 +157,6 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
|||||||
volt_low[idx] = 0;
|
volt_low[idx] = 0;
|
||||||
no_curr[idx] = 0;
|
no_curr[idx] = 0;
|
||||||
volt_set_ok[idx] = 0;
|
volt_set_ok[idx] = 0;
|
||||||
// pSW->sink.work_on_step = SINK_WORK_STOP; // 复位工作状态机
|
|
||||||
}
|
}
|
||||||
chrg_sink_work(idx,pSW);
|
chrg_sink_work(idx,pSW);
|
||||||
}
|
}
|
||||||
@@ -212,7 +186,7 @@ static void chrg_north_handle_Seting_Volt(rt_uint8_t *frame_data, rt_uint16_t fr
|
|||||||
struct chrg_north_t chrgnorth = {
|
struct chrg_north_t chrgnorth = {
|
||||||
.devname = DEV_NAME_NORTH, // 设备名
|
.devname = DEV_NAME_NORTH, // 设备名
|
||||||
.tty = RT_NULL, // 串口句柄初始为空
|
.tty = RT_NULL, // 串口句柄初始为空
|
||||||
.enable = {1, 0, 0, 0}, // 4个通道使能初始关闭
|
.enable = {0, 0, 0, 0}, // 4个通道使能初始关闭
|
||||||
.free_flag = 1,
|
.free_flag = 1,
|
||||||
// 通道1(IDX_NOR_CH1)初始化
|
// 通道1(IDX_NOR_CH1)初始化
|
||||||
.sw[IDX_NOR_CH1] = {
|
.sw[IDX_NOR_CH1] = {
|
||||||
@@ -224,6 +198,7 @@ struct chrg_north_t chrgnorth = {
|
|||||||
.source = { // 电源侧参数初始化
|
.source = { // 电源侧参数初始化
|
||||||
.On_Flag = 0, // 启动标志初始关闭
|
.On_Flag = 0, // 启动标志初始关闭
|
||||||
.Set_CV_Flag = 1, // 启停控制初始置1
|
.Set_CV_Flag = 1, // 启停控制初始置1
|
||||||
|
.work_mode = SOURCE_WORK_WAIT,
|
||||||
}, // 关键:补充逗号分隔source和sink
|
}, // 关键:补充逗号分隔source和sink
|
||||||
.sink = {
|
.sink = {
|
||||||
.protocol = 0xFE,
|
.protocol = 0xFE,
|
||||||
@@ -241,6 +216,7 @@ struct chrg_north_t chrgnorth = {
|
|||||||
.source = {
|
.source = {
|
||||||
.On_Flag = 0,
|
.On_Flag = 0,
|
||||||
.Set_CV_Flag = 1,
|
.Set_CV_Flag = 1,
|
||||||
|
.work_mode = SOURCE_WORK_WAIT,
|
||||||
},
|
},
|
||||||
.sink = {
|
.sink = {
|
||||||
.protocol = 0xFE,
|
.protocol = 0xFE,
|
||||||
@@ -257,6 +233,7 @@ struct chrg_north_t chrgnorth = {
|
|||||||
.source = {
|
.source = {
|
||||||
.On_Flag = 0,
|
.On_Flag = 0,
|
||||||
.Set_CV_Flag = 1,
|
.Set_CV_Flag = 1,
|
||||||
|
.work_mode = SOURCE_WORK_WAIT,
|
||||||
},
|
},
|
||||||
.sink = {
|
.sink = {
|
||||||
.protocol = 0xFE,
|
.protocol = 0xFE,
|
||||||
@@ -273,6 +250,7 @@ struct chrg_north_t chrgnorth = {
|
|||||||
.source = {
|
.source = {
|
||||||
.On_Flag = 0,
|
.On_Flag = 0,
|
||||||
.Set_CV_Flag = 1,
|
.Set_CV_Flag = 1,
|
||||||
|
.work_mode = SOURCE_WORK_WAIT,
|
||||||
},
|
},
|
||||||
.sink = {
|
.sink = {
|
||||||
.protocol = 0xFE,
|
.protocol = 0xFE,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#define LEN_FRAME_HEAD (3) // [帧长, 0x00, id]
|
#define LEN_FRAME_HEAD (3) // [帧长, 0x00, id]
|
||||||
#define MIN_FRAME_LENGTH (5) // 帧最短5字节
|
#define MIN_FRAME_LENGTH (5) // 帧最短5字节
|
||||||
#define WORK_MIN_VOLT 3000 // 工作电压下限,单位mV
|
#define WORK_MIN_VOLT 3000 // 工作电压下限,单位mV
|
||||||
#define DEBUG_NORTH 0x00 // 0 = 关闭,1 = 开启
|
#define DEBUG_NORTH 0x01 // 0 = 关闭,1 = 开启
|
||||||
#define LCD_OPEN 0x01 // 0为关闭屏幕显示 1为打开
|
#define LCD_OPEN 0x01 // 0为关闭屏幕显示 1为打开
|
||||||
#define TRIM_NORTH 0x00 // 0 = 关闭, 1 = 开启
|
#define TRIM_NORTH 0x00 // 0 = 关闭, 1 = 开启
|
||||||
#define SINK_TEST_DEBUG 0x00 // 0 = 关闭,1 = 开启
|
#define SINK_TEST_DEBUG 0x00 // 0 = 关闭,1 = 开启
|
||||||
|
|||||||
@@ -356,6 +356,18 @@ void chrg_roll_nor_thread_entry (void *data)
|
|||||||
switch (run) {
|
switch (run) {
|
||||||
case RUN_AUTO: {
|
case RUN_AUTO: {
|
||||||
idx = index%TOTAL_NOR_CHS;
|
idx = index%TOTAL_NOR_CHS;
|
||||||
|
pSW = &pNOR->sw[idx];
|
||||||
|
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||||
|
/* INIT/STOP必须在enable过滤前执行,否则停机通道无法重新启动。 */
|
||||||
|
if ((pSW->id == ID_SOURCE) &&
|
||||||
|
((pSW->source.work_mode == SOURCE_WORK_INIT) ||
|
||||||
|
(pSW->source.work_mode == SOURCE_WORK_STOP))) {
|
||||||
|
chrg_source_work_state(idx, pSW);
|
||||||
|
} else if ((pSW->id == ID_SINK) &&
|
||||||
|
(pSW->sink.work_mode == SINK_WORK_INIT)) {
|
||||||
|
chrg_sink_work((eIDX_SOU_CH)idx, pSW);
|
||||||
|
}
|
||||||
|
rt_mutex_release(pTHR->mutex);
|
||||||
if (0 == pNOR->enable[idx]) {
|
if (0 == pNOR->enable[idx]) {
|
||||||
index++;
|
index++;
|
||||||
rt_thread_mdelay(2);
|
rt_thread_mdelay(2);
|
||||||
@@ -365,7 +377,6 @@ void chrg_roll_nor_thread_entry (void *data)
|
|||||||
chrg_north_switch((eIDX_NOR_CH)idx);
|
chrg_north_switch((eIDX_NOR_CH)idx);
|
||||||
chrgnorth.idx = idx;
|
chrgnorth.idx = idx;
|
||||||
pROLL->idx = idx;
|
pROLL->idx = idx;
|
||||||
pSW = &pNOR->sw[idx];
|
|
||||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||||
if(pNOR->north_mode == 0){
|
if(pNOR->north_mode == 0){
|
||||||
chrg_roll_nor_set(pROLL->idx,pSW,&pNOR->enable[idx]);
|
chrg_roll_nor_set(pROLL->idx,pSW,&pNOR->enable[idx]);
|
||||||
|
|||||||
@@ -42,13 +42,8 @@ int chrg_north_pkg_encode (eIDX_ID id, rt_uint8_t cmd, rt_uint8_t *data_in,
|
|||||||
rt_memcpy(&data_out[4], data_in, len_in);
|
rt_memcpy(&data_out[4], data_in, len_in);
|
||||||
}
|
}
|
||||||
data_out[len_in+4] = 0x2a;//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;
|
*len_out = 5+len_in;
|
||||||
// for(int i = 0; i < *len_out;i++)
|
|
||||||
// {
|
|
||||||
// rt_kprintf("%02x ",data_out[i]);
|
|
||||||
// }
|
|
||||||
// rt_kprintf("\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -523,6 +523,24 @@ static int chrg_sink_nor_work_off(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换进入负载:停止旧电源后,从负载初始化状态开始运行
|
||||||
|
static int chrg_sink_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||||
|
{
|
||||||
|
rt_uint16_t reg = REG_WORK;
|
||||||
|
rt_uint16_t value = WORK_STOP;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = chrg_sou_com_batch_submit(idx, ®, &value, 1);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSW->source.On_Flag = 0;
|
||||||
|
pSW->sub = IDX_SET_SINK_CCLINE;
|
||||||
|
pSW->sink.work_mode = SINK_WORK_INIT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//动态测试启动
|
//动态测试启动
|
||||||
static int chrg_sink_TEST_DYNA_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
static int chrg_sink_TEST_DYNA_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||||
{
|
{
|
||||||
@@ -598,6 +616,9 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
case SINK_WORK_STOP:
|
case SINK_WORK_STOP:
|
||||||
ret = chrg_sink_nor_work_off(idx,pSW);
|
ret = chrg_sink_nor_work_off(idx,pSW);
|
||||||
break;
|
break;
|
||||||
|
case SINK_WORK_SWITCH:
|
||||||
|
ret = chrg_sink_work_switch(idx,pSW);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ enum {
|
|||||||
SINK_WORK_RUNING,
|
SINK_WORK_RUNING,
|
||||||
SINK_WORK_LOW,
|
SINK_WORK_LOW,
|
||||||
SINK_WORK_STOP,
|
SINK_WORK_STOP,
|
||||||
|
SINK_WORK_SWITCH, // 停止旧电源后进入负载INIT
|
||||||
SINK_WORK_ON_TEST_DYNA,
|
SINK_WORK_ON_TEST_DYNA,
|
||||||
SINK_WORK_ON_TEST_SHORT,
|
SINK_WORK_ON_TEST_SHORT,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,17 +20,19 @@
|
|||||||
int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW)
|
int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW)
|
||||||
{
|
{
|
||||||
/* Source启动参数一次入队,最后发送WORK_START使功率板开始输出。 */
|
/* Source启动参数一次入队,最后发送WORK_START使功率板开始输出。 */
|
||||||
rt_uint16_t regs[5] = {
|
rt_uint16_t regs[6] = {
|
||||||
REG_ELOAD,
|
REG_ELOAD,
|
||||||
REG_MODE,
|
REG_MODE,
|
||||||
|
0x01,
|
||||||
REG_VOLTAGE_OUT + 1,
|
REG_VOLTAGE_OUT + 1,
|
||||||
REG_CURRENT_OUT + 1,
|
REG_CURRENT_OUT + 1,
|
||||||
REG_WORK
|
REG_WORK
|
||||||
};
|
};
|
||||||
rt_uint16_t vals[5] = {
|
rt_uint16_t vals[6] = {
|
||||||
ELOAD_SOURCE,
|
ELOAD_SOURCE,
|
||||||
pSW->CV_mode,
|
pSW->CV_mode,
|
||||||
pSW->source.max_vol,
|
0x03,
|
||||||
|
0,
|
||||||
pSW->source.protective_curr,
|
pSW->source.protective_curr,
|
||||||
WORK_START
|
WORK_START
|
||||||
};
|
};
|
||||||
@@ -38,7 +40,7 @@ int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW)
|
|||||||
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return chrg_sou_com_batch_submit(idx, regs, vals, 5);
|
return chrg_sou_com_batch_submit(idx, regs, vals, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||||
@@ -55,7 +57,7 @@ static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
|
|
||||||
pSW->source.On_Flag = 1;
|
pSW->source.On_Flag = 1;
|
||||||
pSOU->enable[idx] = 1;
|
pSOU->enable[idx] = 1;
|
||||||
pNOR->enable[idx] = 1;
|
pNOR->enable[idx] = 1;
|
||||||
pSOU->online[idx] = 1;
|
pSOU->online[idx] = 1;
|
||||||
chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SOURCE);
|
chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SOURCE);
|
||||||
pSW->source.work_mode = SOURCE_WORK_WAIT;
|
pSW->source.work_mode = SOURCE_WORK_WAIT;
|
||||||
@@ -110,6 +112,24 @@ static int chrg_source_work_stop(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换进入电源:关闭旧负载继电器并停止输出,然后进入电源初始化
|
||||||
|
static int chrg_source_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||||
|
{
|
||||||
|
rt_uint16_t regs[2] = {REG_REL_ON, REG_WORK};
|
||||||
|
rt_uint16_t vals[2] = {ALL_REL_OFF, WORK_STOP};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = chrg_sou_com_batch_submit(idx, regs, vals, 2);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSW->sink.On_work = 0;
|
||||||
|
pSW->sub = IDX_SET_SOURCE_CC_SET;
|
||||||
|
pSW->source.work_mode = SOURCE_WORK_INIT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int chrg_source_work_state(rt_uint8_t idx, struct chrg_switch_t *pSW)
|
int chrg_source_work_state(rt_uint8_t idx, struct chrg_switch_t *pSW)
|
||||||
{
|
{
|
||||||
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
||||||
@@ -128,6 +148,8 @@ int chrg_source_work_state(rt_uint8_t idx, struct chrg_switch_t *pSW)
|
|||||||
return chrg_source_work_low(idx, pSW);
|
return chrg_source_work_low(idx, pSW);
|
||||||
case SOURCE_WORK_STOP:
|
case SOURCE_WORK_STOP:
|
||||||
return chrg_source_work_stop(idx, pSW);
|
return chrg_source_work_stop(idx, pSW);
|
||||||
|
case SOURCE_WORK_SWITCH:
|
||||||
|
return chrg_source_work_switch(idx, pSW);
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ enum {
|
|||||||
SOURCE_WORK_RUNING, // 协商电压变化,下发一次新电压
|
SOURCE_WORK_RUNING, // 协商电压变化,下发一次新电压
|
||||||
SOURCE_WORK_LOW, // 电压过低,停止功率板输出
|
SOURCE_WORK_LOW, // 电压过低,停止功率板输出
|
||||||
SOURCE_WORK_STOP, // 主动停止并关闭通道
|
SOURCE_WORK_STOP, // 主动停止并关闭通道
|
||||||
|
SOURCE_WORK_SWITCH, // 停止旧负载后进入电源INIT
|
||||||
SOURCE_WORK_ON_TEST_DYNA,
|
SOURCE_WORK_ON_TEST_DYNA,
|
||||||
SOURCE_WORK_ON_TEST_SHORT,
|
SOURCE_WORK_ON_TEST_SHORT,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -275,7 +275,7 @@
|
|||||||
</OCR_RVCT3>
|
</OCR_RVCT3>
|
||||||
<OCR_RVCT4>
|
<OCR_RVCT4>
|
||||||
<Type>1</Type>
|
<Type>1</Type>
|
||||||
<StartAddress>0x8040000</StartAddress>
|
<StartAddress>0x8000000</StartAddress>
|
||||||
<Size>0x40000</Size>
|
<Size>0x40000</Size>
|
||||||
</OCR_RVCT4>
|
</OCR_RVCT4>
|
||||||
<OCR_RVCT5>
|
<OCR_RVCT5>
|
||||||
|
|||||||
Reference in New Issue
Block a user