/**
 * @file mr16.c
 * @brief MR16 Module Implementation - SX1281 Radio Control with FreeRTOS CLI
 * 
 * ============================================================================
 *                          CODE ORGANIZATION
 * ============================================================================
 * This file is organized into THREE main sections:
 * 
 * [PART 1] MR16 CORE FUNCTIONS (核心功能)
 *          - System initialization and main loop
 *          - Data packet processing (Header + CRC)
 *          - Radio event callbacks
 *          - Failsafe protection logic
 * 
 * [PART 2] UI DISPLAY FUNCTIONS (界面显示)
 *          - LCD power-on animation
 *          - Main status display
 *          - Dynamic status updates
 * 
 * [PART 3] CLI COMMAND FUNCTIONS (命令行接口)
 *          - FreeRTOS CLI registration
 *          - MR16 system commands (save/load/mode/etc)
 *          - Radio parameter commands (modulation/packet/etc)
 *          - Help text and documentation
 * 
 * ============================================================================
 * 
 * @author MR16 Development Team
 * @date 2024
 * @version 2.0
 */

/* Includes ----------------------------------------------------------------- */
#include "module/mr16.h"
#include "module/config.h"

/* STM32 HAL Headers */
#include <main.h>
#include "usart.h"

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/* Device Driver Headers */
#include "bsp/flash.h"
#include "bsp/time.h"
#include "device/sx1281_driver/sx1281.h"
#include "device/sx1281_driver/radio.h"
#include "device/sx1281_driver/sx1281_driver.h"
#include "device/lcd_driver/lcd.h"
#include "device/ws2812.h"
#include "device/ws2812.h"

/* Component Headers */
#include "component/crc16.h"

/* FreeRTOS Headers */
#include "component/FreeRTOS_CLI.h"

/* Private defines --------------------------------------------------------- */
#define RXID_MIN 0x0001
#define RXID_MAX 0xFFFE
#define RXID_INVALID_LOW 0x0000
#define RXID_INVALID_HIGH 0xFFFF
#define PAYLOAD_MIN 1
#define PAYLOAD_MAX 127
#define TX_POWER_MIN -18
#define TX_POWER_MAX 13

/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
/* Radio instance and configuration */
SX1281_t radio;

/* External references */
extern const unsigned char logo_M[];           /* LCD logo bitmap */
extern const unsigned char logo_R[];           /* LCD logo bitmap */
extern uint8_t uart2_data[255], uart2_datalength; /* UART data buffer */
extern volatile bool uart2_data_ready;         /* UART data ready flag */
extern MR16_t mr16;                            /* MR16 main instance */

/* Radio communication buffers */
uint8_t radioRXBuffer[BUFFER_SIZE];
uint8_t radioRXSize;

/* CLI buffers - Static allocation to prevent stack overflow */
static char cInputBuffer[64];   /* CLI input buffer */
static char cOutputBuffer[256]; /* CLI output buffer */

/* Private function prototypes ---------------------------------------------- */

int8_t MR16_CLI_Init(void);
static BaseType_t mr16CommandHandler(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
static BaseType_t radioCommandHandler(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
static BaseType_t outputHelpText(char *pcWriteBuffer, size_t xWriteBufferLen, 
                                 const char *helpText, size_t *position);
static void copyCLIArg(const char *param, BaseType_t len, char *output, size_t outputSize);
static const char* getFormatString(MR16_DataFormat_t format);
static const char* getRadioModeString(SX1281_RadioMode_t mode);
static bool isValidRXID(uint16_t rxid);
static int8_t setRXID(uint16_t *rxid, const char *value, char *response, size_t responseLen);

/* ========================================================================== */
/* ========================================================================== */
/*                                                                            */
/*                    [PART 1] MR16 CORE FUNCTIONS                           */
/*                          (核心功能模块)                                     */
/*                                                                            */
/* ========================================================================== */
/* ========================================================================== */

/*----------------------------------------------------------------------------
  System Initialization & Main Loop (系统初始化与主循环)
 *---------------------------------------------------------------------------*/

/**
 * @brief 初始化MR16系统(智能配置加载)
 * @param mr16 MR16实例指针
 * @param param 参数配置指针(将被配置覆盖)
 * @return 0-成功, -1-失败
 * 
 * 完整的初始化流程:
 * 1. 从Flash智能加载配置(无效则使用默认值)
 * 2. 初始化CLI系统
 * 3. 使用加载的参数初始化SX1281无线模块
 * 4. 初始化LCD显示并启动UI
 */
int8_t MR16_Init(MR16_t *mr16, MR16_Param_t *param) {
    if (!mr16 || !param) {
        return -1; /* Invalid parameters */
    }

    /* Smart config loading: try Flash first, fallback to defaults */
    if (!Config_LoadMR16FromFlashBool()) {
        /* Flash invalid or corrupt, use safe defaults */
        Config_SetDefaults();
        printf("[MR16] Flash config invalid, using defaults\r\n");
    } else {
        printf("[MR16] Config loaded from Flash successfully\r\n");
    }
    memset(&mr16->timer, 0, sizeof(MR16_Timer_t));
	
    /* Initialize CLI system */
    MR16_CLI_Init();
    
    /* Initialize MR16 parameters - config should be loaded before calling this function */
    mr16->param = &Config_Get()->mr16;
    
    /* Initialize SX1281 radio using persistent parameters */
    if (SX1281_Init(&radio, &mr16->param->radioParams, mr16->param->radioParams.radioMode) != DEVICE_OK) {
        return -1; /* Radio initialization failed */
    }
    
    /* 根据工作模式设置 PayloadLength */
    Radio.SetStandby(STDBY_RC);

    switch (mr16->param->format) {
      case MR16_FORMAT_VARIABLE:
          /* 可变长度模式: 使用最大长度127 */
          radio.param->packetParams.Params.LoRa.PayloadLength = 127;
          radio.param->packetParams.Params.Flrc.PayloadLength = 127;
          radio.param->packetParams.Params.Gfsk.PayloadLength = 127;
        break;
      case MR16_FORMAT_FIXED:
          /* 固定长度模式: Header(2) + 用户数据(fixedLength) + CRC(2) */
          radio.param->packetParams.Params.LoRa.PayloadLength = MR16_HEADER_LEN + mr16->param->fixedLength + MR16_CRC_LEN;
          radio.param->packetParams.Params.Flrc.PayloadLength = MR16_HEADER_LEN + mr16->param->fixedLength + MR16_CRC_LEN;
          radio.param->packetParams.Params.Gfsk.PayloadLength = MR16_HEADER_LEN + mr16->param->fixedLength + MR16_CRC_LEN;
        break;
      default:
        break;
    }

    Radio.SetPacketParams(&radio.param->packetParams);
    
    if (radio.param->RadioRole == RadioRoleRX) {
        SX1281_SetRXSuccessive(&radio);
    } else if (radio.param->RadioRole == RadioRoleTX) {
        uint16_t txLen;
        switch (mr16->param->format) {
            case MR16_FORMAT_VARIABLE:
                /* 可变长度: 使用UART当前接收长度 */
                txLen = uart2_datalength;
                break;
            case MR16_FORMAT_FIXED:
                /* 固定长度: Header(2) + 用户数据(fixedLength) + CRC(2) */
                txLen = MR16_HEADER_LEN + mr16->param->fixedLength + MR16_CRC_LEN;
                break;
            default:
                txLen = 0;
                break;
        }
        if (txLen > 0) {
            SX1281_SetTX(&radio, mr16->txbuffer, txLen);
        }
    }
    
    /* Initialize LCD display and show UI */
    LCD_Init(1);
    MR16_UI_PowerON();
    HAL_Delay(1500);
    MR16_UI_Home(mr16);
    
    return 0; /* Success */
}
/*----------------------------------------------------------------------------
  Radio Event Callbacks (无线事件回调)
 *---------------------------------------------------------------------------*/

/**
 * @brief SX1281无线模块事件回调函数
 * @param source 事件源状态
 * @return 0-成功, -1-错误
 * 
 * 处理无线收发事件:
 * - RX_DONE: 接收成功,验证ID和CRC,输出数据
 * - RX_ERROR: 接收失败,重新开启接收
 * - TX_DONE: 发送成功,继续发送
 * - TX_TIMEOUT: 发送超时
 */
int8_t SX1281_Callback(SX1281_States_t source) {
  switch (source) {
  case RX_DONE:
    printf("\r\n[RX] <<< Packet Received >>>\r\n");

    /* Extract payload from radio buffer */
    radioRXSize = 0;
    Radio.GetPayload(radioRXBuffer, &radioRXSize, BUFFER_SIZE);
    if (radioRXSize < BUFFER_SIZE) {
      radioRXBuffer[radioRXSize] = 0;  /* Null terminate */
    } else {
      radioRXBuffer[BUFFER_SIZE - 1] = 0;
    }

    /* Parse header and update packet counters */
    uint16_t RXheader = (((uint16_t)radioRXBuffer[0]) << 8) | (uint16_t)radioRXBuffer[1];
    for (int i = 0; i < 3; i++) {
      /* Skip disabled RX_ID slots - 用于扩展自动配对功能，保留 */
      if (mr16.param->RX_ID[i] == RXID_INVALID_LOW || mr16.param->RX_ID[i] == RXID_INVALID_HIGH) {
        continue;
      }
      if (RXheader == mr16.param->RX_ID[i]) {
        mr16.packetCount[i]++;
        mr16.timer.lastDataReceived = mr16.timer.now; /* 更新接收时间戳 */
        /* 更新LED状态指示: 接收成功 */
        WS2812_SetStatus(WS2812_STATUS_RX_OK);
        WS2812_NotifyCommSuccess();
        printf("[ch%d] Header: 0x%04X | Size: %d bytes | Count: %d\r\n", 
         i+1, RXheader, radioRXSize, mr16.packetCount[i]);
        break;
      }
    }
  
    break;
  

    case RX_TIMEOUT:
        /* 打印状态 */
        printf( "\r\n[RX] ... Timeout (Restarting RX)\r\n" );
        /* 超时设置ERROR状态,不重置通信时间戳 */
        WS2812_SetStatus(WS2812_STATUS_ERROR);
		SX1281_SetRXSuccessive(&radio);
      break;    case RX_ERROR:
        /* 打印状态 */
        printf( "\r\n[RX] !!! ERROR - Reception Failed !!!\r\n" );
        /* 接收错误设置ERROR状态,不重置通信时间戳 */
        WS2812_SetStatus(WS2812_STATUS_ERROR);
        Radio.SetRx( ( TickTime_t ) { RADIO_TICK_SIZE_1000_US, 0x1000 } );
      break;

    case TX_DONE:
        /* 打印状态 */
        printf( "\r\n[TX] <<< Packet Sent Successfully >>>\r\n" );
        /* 更新LED状态指示: 发送成功 */
        WS2812_SetStatus(WS2812_STATUS_TX_OK);
        WS2812_NotifyCommSuccess();
        /* 根据数据格式重新发送 */
        uint16_t txLen;
        if (mr16.param->format == MR16_FORMAT_VARIABLE) {
            txLen = uart2_datalength;
        } else {
            /* FIXED: Header(2) + 用户数据(fixedLength) + CRC(2) */
            txLen = MR16_HEADER_LEN + mr16.param->fixedLength + MR16_CRC_LEN;
        }
        printf( "[TX] Length: %d bytes\r\n", txLen ); 
        SX1281_SetTX(&radio, mr16.txbuffer, txLen);
      break;

    case TX_TIMEOUT:
        /* 打印状态 */
        printf( "\r\n[TX] !!! TIMEOUT - Transmission Failed !!!\r\n" ); 
        /* 发送超时设置ERROR状态,不重置通信时间戳 */
        WS2812_SetStatus(WS2812_STATUS_ERROR);
        /* 重新尝试发送 */
        uint16_t retryLen;
        if (mr16.param->format == MR16_FORMAT_VARIABLE) {
            retryLen = uart2_datalength;
        } else {
            retryLen = MR16_HEADER_LEN + mr16.param->fixedLength + MR16_CRC_LEN;
        }
        SX1281_SetTX(&radio, mr16.txbuffer, retryLen);
      break;

    case LORA_CAD_DONE:
        /* 打印状态 */
        printf( "\r\n[CAD] Channel Activity Detected\r\n" );
      break;
    default:
      break;
  }
  return 0;  
}

/* ========================================================================== */
/* ========================================================================== */
/*                                                                            */
/*                    [PART 2] UI DISPLAY FUNCTIONS                          */
/*                          (界面显示模块)                                     */
/*                                                                            */
/* ========================================================================== */
/* ========================================================================== */

/**
 * @brief 显示LCD开机动画
 * @return 0-成功
 * 
 * 显示"MR16"标志和版本信息
 */
int8_t MR16_UI_PowerON() {
  LCD_Clear(BLACK);
  LCD_DrawString(110, 119, "Initializing...", CYAN, 16, LSB);
  LCD_DrawBitmap(logo_M, 0, 0, 48, 32, CRIMSON, MSB);
  HAL_Delay(100);
  LCD_DrawBitmap(logo_R, 48, 4, 28, 28, CRIMSON, MSB);
  HAL_Delay(100);
  LCD_DrawString(0, 48, "MR16--Wireless", CRIMSON, 24, LSB);
  LCD_DrawString(0, 72, "transmission tool", CRIMSON, 24, LSB);
  return 0;
}

/**
 * @brief 显示LCD主界面
 * @param mr16 MR16实例指针
 * @return 0-成功, -1-失败
 * 
 * 显示内容:
 * - TX模式: TX ID和发射功率
 * - RX模式: 三个通道的接收计数
 * - 工作模式、无线协议、频率等信息
 */
int8_t MR16_UI_Home(MR16_t *mr16) {
  if (!mr16 || !mr16->param) return -1;
  
  LCD_Clear(BLACK);
  
  /* Title */
  LCD_DrawString(5, 5, "MR16 Status", CRIMSON, 24, LSB);
  
  /* TX/RX Indicator in top right corner */
  if (radio.appMode == APPMODE_TX) {
    LCD_DrawString(200, 5, "TX", ORANGE, 24, LSB);
  } else {
    LCD_DrawString(200, 5, "RX", LIME, 24, LSB);
  }
  
  LCD_DrawLine(0, 30, 135, 30, GRAY);
  
  /* Mode Display */
  LCD_DrawString(5, 40, "Mode:", CYAN, 16, LSB);
  const char* mode_str = "UNKNOWN";
  uint16_t mode_color = WHITE;
  switch(mr16->param->format) {
    case MR16_FORMAT_VARIABLE:
      mode_str = "VARIABLE";
      mode_color = WHITE;
      break;
    case MR16_FORMAT_FIXED:
      mode_str = "FIXED";
      mode_color = LIME;
      break;
    default:
      mode_str = "NONE";
      mode_color = DARKGRAY;
      break;
  }
  LCD_DrawString(65, 40, mode_str, mode_color, 16, LSB);
  
  /* Radio Mode */
  LCD_DrawString(5, 65, "Radio:", CYAN, 16, LSB);
  const char* radio_mode = "NONE";
  switch(radio.param->packetParams.PacketType) {
    case PACKET_TYPE_BLE:  radio_mode = "BLE";  break;
    case PACKET_TYPE_GFSK: radio_mode = "GFSK"; break;
    case PACKET_TYPE_LORA: radio_mode = "LORA"; break;
    case PACKET_TYPE_FLRC: radio_mode = "FLRC"; break;
    default: break;
  }
  LCD_DrawString(65, 65, radio_mode, WHITE, 16, LSB);
  
  /* RF Frequency */
  LCD_DrawString(5, 90, "Freq:", CYAN, 16, LSB);
  char freq_buf[15];
  snprintf(freq_buf, sizeof(freq_buf), "%lluMHz", radio.param->rfFrequency / 1000000);
  LCD_DrawString(50, 90, freq_buf, WHITE, 16, LSB);
  
  uint16_t yPos = 35;
  
  /* TX Mode: Show TXID and Power */
  if (radio.appMode == APPMODE_TX) {
    LCD_DrawString(5, 115, "TXID:", CYAN, 16, LSB);
    char id_buf[10];
    snprintf(id_buf, sizeof(id_buf), "0x%04X", mr16->param->TX_ID);
    LCD_DrawString(65, 115, id_buf, WHITE, 16, LSB);
    yPos += 25;
    
    LCD_DrawString(120, 40, "Power:", CYAN, 16, LSB);
    char pwr_buf[10];
    snprintf(pwr_buf, sizeof(pwr_buf), "%ddBm", radio.param->txOutputPower);
    LCD_DrawString(180, 40, pwr_buf, ORANGE, 16, LSB);
    yPos += 25;
    
    /* 如果是固定长度模式,显示数据长度 */
    if (mr16->param->format == MR16_FORMAT_FIXED) {
      LCD_DrawString(120, 65, "DataLen:", CYAN, 16, LSB);
      char len_buf[10];
      snprintf(len_buf, sizeof(len_buf), "%dB", mr16->param->fixedLength);
      LCD_DrawString(190, 65, len_buf, ORANGE, 16, LSB);
    }
  }
  /* RX Mode: Show packet counts per channel */
  else {
    /* RX Count Label */
    LCD_DrawString(120, yPos, "rxcount:", CYAN, 16, LSB);
    yPos += 20;
    
    /* Channel counts */
    char ch_buf[20];
    snprintf(ch_buf, sizeof(ch_buf), "ch1:%lu", mr16->packetCount[0]);
    LCD_DrawString(120, yPos, ch_buf, LIME, 16, LSB);
    yPos += 20;
    
    snprintf(ch_buf, sizeof(ch_buf), "ch2:%lu", mr16->packetCount[1]);
    LCD_DrawString(120, yPos, ch_buf, LIME, 16, LSB);
    yPos += 20;
    
    snprintf(ch_buf, sizeof(ch_buf), "ch3:%lu", mr16->packetCount[2]);
    LCD_DrawString(120, yPos, ch_buf, LIME, 16, LSB);

    
    /* RX ID Label */
    LCD_DrawString(5, 115, "rxid:", CYAN, 16, LSB);
    snprintf(ch_buf, sizeof(ch_buf), "0x%04X", mr16->param->RX_ID[0]);
    LCD_DrawString(65, 115, ch_buf, WHITE, 16, LSB);
    snprintf(ch_buf, sizeof(ch_buf), "0x%04X", mr16->param->RX_ID[1]);
    LCD_DrawString(125, 115, ch_buf, WHITE, 16, LSB);
    snprintf(ch_buf, sizeof(ch_buf), "0x%04X", mr16->param->RX_ID[2]);
    LCD_DrawString(185, 115, ch_buf, WHITE, 16, LSB);
  }
  
  return 0;
}

/**
 * @brief 更新LCD屏幕上的动态状态显示
 * @param mr16 MR16实例指针
 * @return 0-成功, -1-失败
 * 
 * 仅在RX模式下更新通道接收计数
 */
int8_t MR16_UI_UpdateStatus(MR16_t *mr16) {
  if (!mr16) return -1;
  
  /* Only update in RX mode */
  if (radio.appMode == APPMODE_RXSUCCESSIVE) {
    /* Clear and update channel counts */
    
    uint16_t yPos = 35;
    char ch_buf[20];
    yPos += 20;
    
    /* ch1 - use background color for auto-clear */
    snprintf(ch_buf, sizeof(ch_buf), "ch1:%lu", mr16->packetCount[0]);
    LCD_DrawStringBG(120, yPos, ch_buf, LIME, BLACK, 16, LSB);
    yPos += 20;
    
    /* ch2 */
    snprintf(ch_buf, sizeof(ch_buf), "ch2:%lu", mr16->packetCount[1]);
    LCD_DrawStringBG(120, yPos, ch_buf, LIME, BLACK, 16, LSB);
    yPos += 20;
    
    /* ch3 */
    snprintf(ch_buf, sizeof(ch_buf), "ch3:%lu", mr16->packetCount[2]);
    LCD_DrawStringBG(120, yPos, ch_buf, LIME, BLACK, 16, LSB);
  }
  
  return 0;
}



/*----------------------------------------------------------------------------
  Data Packet Processing (数据包处理)
 *---------------------------------------------------------------------------*/

/**
 * @brief 封装数据包到TX缓冲区(添加Header和CRC)
 * @param mr16 MR16实例指针
 * @param userData 用户纯数据指针
 * @param userDataLen 用户数据长度
 * @return 0-成功, -1-失败
 * 
 * 数据包格式:
 * [0] Header高字节 (TX_ID >> 8)
 * [1] Header低字节 (TX_ID & 0xFF)
 * [2..N+1] 用户数据
 * [N+2] CRC高字节
 * [N+3] CRC低字节
 */
int8_t MR16_PackTxBuffer(MR16_t *mr16, const uint8_t *userData, uint16_t userDataLen) {
    if (!mr16 || !userData || userDataLen == 0 || userDataLen > 123) {
        return -1; /* Invalid parameters */
    }
    
    /* 1. 添加Header (TX_ID) */
    mr16->txbuffer[0] = (uint8_t)(mr16->param->TX_ID >> 8);   /* High byte */
    mr16->txbuffer[1] = (uint8_t)(mr16->param->TX_ID & 0xFF); /* Low byte */
    
    /* 2. 复制用户数据 */
    memcpy(&mr16->txbuffer[2], userData, userDataLen);
    
    /* 3. 计算并添加CRC (Header + 用户数据) */
    uint16_t crc = CRC16_Calc(mr16->txbuffer, userDataLen + 2, CRC16_INIT);
    mr16->txbuffer[userDataLen + 2] = (uint8_t)(crc >> 8);   /* CRC高字节 */
    mr16->txbuffer[userDataLen + 3] = (uint8_t)(crc & 0xFF); /* CRC低字节 */
    
    return 0;
}

/**
 * @brief MR16主循环函数
 * @param mr16 MR16实例指针
 * @return 0-成功
 * 
 * 主要功能:
 * 1. 处理UART接收数据(自动区分CLI命令和用户数据)
 * 2. 根据数据格式(VARIABLE/FIXED)执行相应操作
 * 3. 运行SX1281无线通信
 * 4. 定期更新LCD显示
 */
int8_t MR16_Main(MR16_t *mr16) {
    /* Handle UART data */
    if (uart2_data_ready) {
        
        bool isRCData = false;
        
        /* Distinguish RC data from CLI commands by checking first byte:
         * CLI commands start with ASCII letters (a-z, A-Z)
         * RC data is binary and won't start with letter
         * Skip leading whitespace/newlines for CLI detection
         */
        uint8_t firstCharIndex = 0;
        /* Skip leading whitespace, \r, \n */
        while (firstCharIndex < uart2_datalength && 
               (uart2_data[firstCharIndex] == ' ' || 
                uart2_data[firstCharIndex] == '\t' ||
                uart2_data[firstCharIndex] == '\r' || 
                uart2_data[firstCharIndex] == '\n')) {
            firstCharIndex++;
        }
        
        if (firstCharIndex < uart2_datalength && 
            ((uart2_data[firstCharIndex] >= 'a' && uart2_data[firstCharIndex] <= 'z') || 
             (uart2_data[firstCharIndex] >= 'A' && uart2_data[firstCharIndex] <= 'Z'))) {
            /* Starts with letter - CLI command */
            isRCData = false;
        } else if (uart2_datalength > 0) {
            /* Binary data - RC data, pack with TX_ID header */
					  MR16_PackTxBuffer(mr16, uart2_data, uart2_datalength);
            isRCData = true;
        }
        
        if(!isRCData) {
            /* CLI Mode: Process as command */
            if (uart2_datalength > 0 && uart2_datalength < sizeof(cInputBuffer)) {
                memcpy(cInputBuffer, uart2_data, uart2_datalength);
                cInputBuffer[uart2_datalength] = '\0';
                
                /* Remove trailing \r\n for better compatibility */
                int len = uart2_datalength;
                while (len > 0 && (cInputBuffer[len-1] == '\r' || cInputBuffer[len-1] == '\n')) {
                    cInputBuffer[--len] = '\0';
                }
            } else {
                cInputBuffer[0] = '\0';
            }
            
            /* 暂停无线收发 */
            Radio.SetStandby(STDBY_RC);
            
            /* CLI模式: 设置调试状态指示 */
            WS2812_SetStatus(WS2812_STATUS_DEBUG);
            
            /* Process CLI command */
            cOutputBuffer[0] = '\0';
            BaseType_t xMore = pdTRUE;
            do {
                xMore = FreeRTOS_CLIProcessCommand(cInputBuffer, cOutputBuffer, sizeof(cOutputBuffer));
                if (cOutputBuffer[0] != '\0') {
                    printf("%s", cOutputBuffer);
                }
                cOutputBuffer[0] = '\0';
            } while (xMore == pdTRUE);

        }

        WS2812_SetStatus(WS2812_STATUS_DEBUG);
        /* 数据处理完成,允许接收下一帧 */
        uart2_data_ready = false;
    }
    mr16->timer.now = BSP_TIME_Get_us() / 1000000.0f;
    mr16->timer.dt = (BSP_TIME_Get_us() - mr16->timer.last_wakeup) / 1000000.0f;
    mr16->timer.last_wakeup = BSP_TIME_Get_us();
    
    /* RX端失控保护: 若100ms未收到数据,构造安全帧 */
    if (radio.param->RadioRole == RadioRoleRX) {
        if (mr16->timer.now - mr16->timer.lastDataReceived > 0.1f) {
            /* 构造安全帧: Header + [0xFF 0x00 0xFF 0x00] + [0x00...] */
            mr16->txbuffer[0] = (uint8_t)(mr16->param->TX_ID >> 8);  // Header高字节
            mr16->txbuffer[1] = (uint8_t)(mr16->param->TX_ID & 0xFF); // Header低字节
            mr16->txbuffer[2] = MR16_FAILSAFE_BYTE0; // 0xFF
            mr16->txbuffer[3] = MR16_FAILSAFE_BYTE1; // 0x00
            mr16->txbuffer[4] = MR16_FAILSAFE_BYTE2; // 0xFF
            mr16->txbuffer[5] = MR16_FAILSAFE_BYTE3; // 0x00
            /* 其余字节置0 */
            uint16_t totalLen;
            if (mr16->param->format == MR16_FORMAT_VARIABLE) {
                totalLen = MR16_HEADER_LEN + uart2_datalength + MR16_CRC_LEN;
            } else {
                totalLen = MR16_HEADER_LEN + mr16->param->fixedLength + MR16_CRC_LEN;
            }
            for (uint16_t i = 6; i < totalLen; i++) {
                mr16->txbuffer[i] = 0x00;
            }
        }
    }
    
    /* Handle MR16 data format operations */
    switch (mr16->param->format) {
        case MR16_FORMAT_VARIABLE:
            switch (radio.param->RadioRole) {
                case RadioRoleTX:
                    SX1281_Running(&radio);
                    break;
                    
                case RadioRoleRX:
                    SX1281_Running(&radio);
                    break;
                    
                default:
                    break;
            }
            break;
            
        case MR16_FORMAT_FIXED:
            /* Fixed length mode */
            switch (radio.param->RadioRole) {
                case RadioRoleTX:
                    SX1281_Running(&radio);
                    break;
                    
                case RadioRoleRX:
                    SX1281_Running(&radio);
                    if(mr16->timer.now-mr16->timer.lastUIupdata>=1.0f) {
						          MR16_UI_UpdateStatus(mr16);
						          mr16->timer.lastUIupdata=mr16->timer.now;
					          }
                    
                    break;
                    
                default:
                    break;
            }
            break;
        default:
            /* Idle mode */
            break;
    }
    
    /* LED状态指示任务: 使用HAL_GetTick()获取当前时间(ms) */
    WS2812_StatusTask(HAL_GetTick());
    
    return 0;
}

/* ========================================================================== */
/* ========================================================================== */
/*                                                                            */
/*                   [PART 3] CLI COMMAND FUNCTIONS                          */
/*                          (命令行接口模块)                                   */
/*                                                                            */
/* ========================================================================== */
/* ========================================================================== */

/*----------------------------------------------------------------------------
  CLI Initialization (CLI系统初始化)
 *---------------------------------------------------------------------------*/

/**
 * @brief 初始化MR16 CLI命令系统
 * @return 0-成功, -1-失败
 * 
 * 注册两个主要命令:
 * - mr16: MR16系统控制命令
 * - radio: SX1281无线参数配置命令
 */
int8_t MR16_CLI_Init(void) {
    static const CLI_Command_Definition_t mr16Command = {
      "mr16",
      "mr16 <subcmd> [args] - MR16 system commands. Use 'mr16 help' for details\r\n",
      mr16CommandHandler,
      -1
    };
    
    static const CLI_Command_Definition_t radioCommand = {
        "radio",
        "radio <cmd> - SX1281 radio control commands. Use 'radio help' for details\r\n",
        radioCommandHandler,
        -1
    };
    
    /* Register commands */
    if (FreeRTOS_CLIRegisterCommand(&mr16Command) != pdPASS) {
        return -1;
    }
    
    if (FreeRTOS_CLIRegisterCommand(&radioCommand) != pdPASS) {
        return -1;
    }
    
    return 0;
}

/*----------------------------------------------------------------------------
  CLI Help Text Documentation
 *---------------------------------------------------------------------------*/
static const char radio_help_en[] =
"============================================================================\r\n"
"radio <subcmd> [args]  - SX1281 radio control\r\n"
"----------------------------------------------------------------------------\r\n"
"Mode Configuration:\r\n"
"  mode <BLE|LORA|GFSK|FLRC>        - Change working mode\r\n"
"  rffreq <Hz>                      - Set RF frequency\r\n"
"----------------------------------------------------------------------------\r\n"
"Parameter Configuration:\r\n"
"  modulation <field> <value>       - Set modulation parameters\r\n"
"  packet <field> <value>           - Set packet parameters\r\n"
"  baudrate [index]                 - Set baudrate (auto-detect mode)\r\n"
"  power <dBm>                      - Set TX power (-18..+13)\r\n"
"  ramptime <us>                    - Set ramp time (2|4|6|8|10|12|16|20)\r\n"
"----------------------------------------------------------------------------\r\n"
"Operation Commands:\r\n"
"  tx | rx                          - TX/RX operations\r\n"
"----------------------------------------------------------------------------\r\n"
"Help Commands:\r\n"
"  modulation help | packet help    - Show detailed help\r\n"
"  baudrate help                    - Show baudrate details\r\n"
"============================================================================\r\n";

static const char modulation_help[] =
"============================================================================================================\r\n"
"modulation <field> <value>  - Set modulation parameters\r\n"
"  BLE/GFSK fields:\r\n"
"    br_bw    : 0x04(2.0M/2.4M)||0x28(1.6M/2.4M)||0x4C(1.0M/2.4M)||0x45(1.0M/1.2M)\r\n"
"               0x70(0.8M/2.4M)||0x69(0.8M/1.2M)||0x8D(0.5M/1.2M)||0x86(0.5M/0.6M)\r\n"
"               0xB1(0.4M/1.2M)||0xAA(0.4M/0.6M)||0xCE(0.25M/0.6M)||0xC7(0.25M/0.3M)||0xEF(0.125M/0.3M)\r\n"
"    modindex : 0(0.35)||1(0.50)||2(0.75)||3(1.00)||4(1.25)||5(1.50)||6(1.75)||7(2.00)\r\n"
"               8(2.25)||9(2.50)||10(2.75)||11(3.00)||12(3.25)||13(3.50)||14(3.75)||15(4.00)\r\n"
"    shaping  : 0x00(OFF)||0x10(BT_1_0)||0x20(BT_0_5)\r\n"
"  LORA fields:\r\n"
"    sf : 0x50(SF5)||0x60(SF6)||0x70(SF7)||0x80(SF8)||0x90(SF9)||0xA0(SF10)||0xB0(SF11)||0xC0(SF12)\r\n"
"    bw : 0x34(BW_200K)||0x26(BW_400K)||0x18(BW_800K)||0x0A(BW_1600K)\r\n"
"    cr : 0x01(4/5)||0x02(4/6)||0x03(4/7)||0x04(4/8)||0x05(LI_4/5)||0x06(LI_4/6)||0x07(LI_4/7)\r\n"
"  FLRC fields:\r\n"
"    br_bw    : 0x04(2.6M/2.4M)||0x28(2.08M/2.4M)||0x45(1.3M/1.2M)||0x69(1.04M/1.2M)\r\n"
"               0x86(0.65M/0.6M)||0xAA(0.52M/0.6M)||0xC7(0.325M/0.3M)||0xEB(0.26M/0.3M)\r\n"
"    cr       : 0x00(CR_1/2)||0x02(CR_3/4)||0x04(CR_1/0)\r\n"
"    shaping  : 0x00(OFF)||0x10(BT_1_0)||0x20(BT_0_5)\r\n"
"Examples: radio modulation br_bw 0x4C\r\n"
"          radio modulation sf 0x70\r\n"
"============================================================================================================\r\n";
static const char packet_help[] =
"================================================================================================\r\n"
"packet <field> <value>  - Set packet parameters (current PacketType based)\r\n"
"  BLE fields:\r\n"
"    ConnectionState : 0(MASTER_SLAVE)||1(ADVERTISER)||2(TX_TEST)||3(RX_TEST)||4(RXTX_TEST)\r\n"
"    CrcField        : 0(OFF)||1(CRC_3B)\r\n"
"    BlePacketType   : 0(PRBS_9)||1(PRBS_15)||2(EYELONG_1_0)||3(EYELONG_0_1)\r\n"
"                      4(EYESHORT_1_0)||5(EYESHORT_0_1)||6(ALL_1)||7(ALL_0)\r\n"
"    Whitening       : 0x00(ON)||0x08(OFF)\r\n"
"  GFSK fields:\r\n"
"    Preamble        : 0x00(4bits)||0x10(8bits)||0x20(12bits)||0x30(16bits)\r\n"
"                      0x40(20bits)||0x50(24bits)||0x60(28bits)||0x70(32bits)\r\n"
"    SyncWordLength  : 0x00(1byte)||0x02(2bytes)||0x04(3bytes)||0x06(4bytes)||0x08(5bytes)\r\n"
"    SyncWordMatch   : 0x00(OFF)||0x10(1)||0x20(2)||0x30(1_2)||0x40(3)||0x50(1_3)||0x60(2_3)||0x70(1_2_3)\r\n"
"    SyncWord1/2/3   : <hex_bytes> - Set sync word 1/2/3 (max 5 bytes for GFSK)\r\n"
"    SyncWord        : Show all sync words\r\n"
"    Header          : 0x00(VARIABLE)||0x20(FIXED)\r\n"
"    Payload         : 1-255 (bytes)\r\n"
"    Crc             : 0x00(OFF)||0x10(1byte)||0x20(2bytes)||0x30(3bytes)\r\n"
"    Whitening       : 0x00(ON)||0x08(OFF)\r\n"
"  LORA fields:\r\n"
"    Preamble        : 0-255 (symbols count)\r\n"
"    Header          : 0x00(VARIABLE/EXPLICIT)||0x80(FIXED/IMPLICIT)\r\n"
"    Payload         : 1-255 (bytes)\r\n"
"    Crc             : 0x20(ON)||0x00(OFF)\r\n"
"    InvertIQ        : 0x40(NORMAL)||0x00(INVERTED)\r\n"
"  FLRC fields: Same as GFSK (Preamble/SyncWordLength/SyncWordMatch/SyncWord1/2/3/Header/Payload/Crc/Whitening)\r\n"
"    SyncWord1/2/3   : <hex_bytes> - Set sync word 1/2/3 (max 4 bytes for FLRC)\r\n"
"Examples: radio packet Payload 64\r\n"
"          radio packet Crc 0x20\r\n"
"          radio packet SyncWord1 0x12345678\r\n"
"          radio packet SyncWord\r\n"
"================================================================================================\r\n";

static const char mr16_help[] =
"======================================================\r\n"
//"mr16 <subcmd> [args] - MR16 system commands\r\n"
//"------------------------------------------------------\r\n"
//"Configuration Commands:\r\n"
//"  save        : Save MR16 configuration to Flash\r\n"
//"  get         : Load configuration from Flash\r\n"
//"  reset       : Restore default configuration\r\n"
//"  mode <arg>  : Set/get data format (VARIABLE|FIXED)\r\n"
//"  fixedlen <len> : Set user data length (1-123 bytes)\r\n"
//"                   !!!Only user data length, NOT packet length!\r\n"
//"                   !!!MR16 auto adds: Header(2)+Data+CRC(2)\r\n"
//"  power <dBm> : Set/show TX power (-18 to +13 dBm)\r\n"
//"  rxid1/2/3 <hex>     : Set/get RX ID (hex value)\r\n"
//"------------------------------------------------------\r\n"
//"Operation Commands:\r\n"
//"  tx          : Transmit current TX buffer\r\n"
//"  rx          : Start continuous receive\r\n"
//"------------------------------------------------------\r\n"
//"Information Commands:\r\n"
//"  show        : Show all MR16 configuration\r\n"
//"  rxid        : Show all three RX IDs\r\n"
//"------------------------------------------------------\r\n"
//"Help Commands:\r\n"
//"  help        : Show this help (supports paging)\r\n"
//"  mode help   : Show mode details\r\n"
"======================================================\r\n";

static const char baudrate_help[] =
"=====================================================================\r\n"
//"baudrate [index]  - Set baudrate for current radio mode\r\n"
//"---------------------------------------------------------------------\r\n"
//"BLE Mode:\r\n"
//"  0 = 250Kbps  | 1 = 500Kbps  | 2 = 1Mbps\r\n"
//"---------------------------------------------------------------------\r\n"
//"LoRa Mode:\r\n"
//"  0 = 216bps   | 1 = 1Kbps    | 2 = 5Kbps    | 3 = 10Kbps\r\n"
//"  4 = 20Kbps   | 5 = 61Kbps   | 6 = 127Kbps  | 7 = 203Kbps\r\n"
//"---------------------------------------------------------------------\r\n"
//"GFSK Mode:\r\n"
//"  0 = 125Kbps  | 1 = 250Kbps  | 2 = 500Kbps  | 3 = 1Mbps\r\n"
//"---------------------------------------------------------------------\r\n"
//"FLRC Mode:\r\n"
//"  0 = 130Kbps  | 1 = 260Kbps  | 2 = 520Kbps  | 3 = 1040Kbps\r\n"
//"---------------------------------------------------------------------\r\n"
//"Examples:\r\n"
//"  radio baudrate        - Show current baudrates for all modes\r\n"
//"  radio baudrate 2      - Set baudrate index 2 for current mode\r\n"
//"  radio baudrate help   - Show this help\r\n"
"=====================================================================\r\n";

/*----------------------------------------------------------------------------
  CLI Command Handlers (命令处理器)
 *---------------------------------------------------------------------------*/


/**
 * @brief 复制CLI参数到缓冲区(带长度限制)
 * @param param 源参数字符串指针
 * @param len 参数长度
 * @param output 目标缓冲区指针
 * @param outputSize 目标缓冲区大小
 */
static void copyCLIArg(const char *param, BaseType_t len, char *output, size_t outputSize) {
    if (!param || !output || outputSize == 0) return;
    size_t copyLen = (len < (BaseType_t)(outputSize - 1)) ? (size_t)len : (outputSize - 1);
    strncpy(output, param, copyLen);
    output[copyLen] = '\0';
}

/**
 * @brief 获取数据格式字符串(用于显示)
 * @param format 数据格式枚举值
 * @return 格式字符串 ("VARIABLE"/"FIXED"/"UNKNOWN")
 */
static const char* getFormatString(MR16_DataFormat_t format) {
    switch (format) {
        case MR16_FORMAT_VARIABLE: return "VARIABLE";
        case MR16_FORMAT_FIXED:    return "FIXED";
        default:                   return "UNKNOWN";
    }
}

/**
 * @brief 获取无线模式字符串(用于显示)
 * @param mode 无线模式枚举值
 * @return 模式字符串 ("BLE"/"LORA"/"GFSK"/"FLRC"/"UNKNOWN")
 */
static const char* getRadioModeString(SX1281_RadioMode_t mode) {
    switch (mode) {
        case RADIOMODE_BLE:  return "BLE";
        case RADIOMODE_LORA: return "LORA";
        case RADIOMODE_GFSK: return "GFSK";
        case RADIOMODE_FLRC: return "FLRC";
        default:             return "UNKNOWN";
    }
}

/**
 * @brief 验证RX ID是否在有效范围内
 * @param rxid 待验证的RX ID
 * @return true-有效(0x0001-0xFFFE), false-无效
 */
static bool isValidRXID(uint16_t rxid) {
    return (rxid >= RXID_MIN && rxid <= RXID_MAX);
}

/**
 * @brief 设置RX ID(带校验)
 * @param rxid RX ID变量指针
 * @param value 十六进制字符串值
 * @param response 响应消息缓冲区
 * @param responseLen 响应缓冲区大小
 * @return 0-成功, -1-失败
 */
static int8_t setRXID(uint16_t *rxid, const char *value, char *response, size_t responseLen) {
    uint16_t newID;
    sscanf(value, "%hx", &newID);
    if (!isValidRXID(newID)) {
        snprintf(response, responseLen, "RXID set failed: invalid value\r\nValid range: 0x%04X-0x%04X\r\n", 
                 RXID_MIN, RXID_MAX);
        return -1;
    }
    *rxid = newID;
    snprintf(response, responseLen, "RXID set to: 0x%04X\r\n", *rxid);
    return 0;
}

/**
 * @brief 分块输出帮助信息(防止缓冲区溢出)
 * @param pcWriteBuffer 输出缓冲区
 * @param xWriteBufferLen 缓冲区长度
 * @param helpText 待输出的帮助文本
 * @param position 当前输出位置指针
 * @return pdTRUE-还有更多内容, pdFALSE-输出完成
 */
static BaseType_t outputHelpText(char *pcWriteBuffer, size_t xWriteBufferLen, 
                                 const char *helpText, size_t *position) {
    size_t help_len = strlen(helpText);
    
    if (*position >= help_len) {
        *position = 0;
        return pdFALSE;
    }
    
    size_t chunk = (xWriteBufferLen > 1) ? (xWriteBufferLen - 1) : 0;
    size_t remain = help_len - *position;
    size_t to_copy = (remain < chunk) ? remain : chunk;
    
    if (to_copy > 0) {
        memcpy(pcWriteBuffer, helpText + *position, to_copy);
        pcWriteBuffer[to_copy] = '\0';
        *position += to_copy;
        return (*position < help_len) ? pdTRUE : pdFALSE;
    }
    
    *position = 0;
    return pdFALSE;
}

/**
 * @brief MR16命令处理器(CLI)
 * @param pcWriteBuffer CLI写入缓冲区
 * @param xWriteBufferLen 缓冲区长度
 * @param pcCommandString 完整命令字符串
 * @return pdTRUE-还有输出, pdFALSE-命令处理完成
 * 
 * 支持的命令: save, get, reset, mode, fixedlen, tx, rx, 
 *            rxid1/2/3, power, show, help
 */
static BaseType_t mr16CommandHandler(char *pcWriteBuffer, size_t xWriteBufferLen, 
                                     const char *pcCommandString) {
    BaseType_t len1 = 0, len2 = 0, len3 = 0;
    const char *p1 = FreeRTOS_CLIGetParameter(pcCommandString, 1, &len1);
    const char *p2 = FreeRTOS_CLIGetParameter(pcCommandString, 2, &len2);
    const char *p3 = FreeRTOS_CLIGetParameter(pcCommandString, 3, &len3);
    
    char arg1[32] = {0}, arg2[32] = {0}, arg3[32] = {0};
    
    /* Extract parameters using common function */
    if (p1) copyCLIArg(p1, len1, arg1, sizeof(arg1));
    if (p2) copyCLIArg(p2, len2, arg2, sizeof(arg2));
    if (p3) copyCLIArg(p3, len3, arg3, sizeof(arg3));
    
    /* Built-in help support */
    if (strcasecmp(arg1, "help") == 0) {
      static size_t help_pos = 0;
      /* 每次新命令调用时重置位置 */
      if (help_pos >= strlen(mr16_help)) {
          help_pos = 0;
      }
      BaseType_t result = outputHelpText(pcWriteBuffer, xWriteBufferLen, mr16_help, &help_pos);
      /* 如果本次输出完成,重置位置为下次准备 */
      if (result == pdFALSE) {
          help_pos = 0;
      }
      return result;
    }

    /* Command: save - Save configuration to Flash */
    if (strcasecmp(arg1, "save") == 0) {
        Config_Get()->earsed_count++;
        STMFLASH_Write(FLASH_SAVE_ADDR, (uint16_t*)Config_Get(), sizeof(Config_t)/2);
        snprintf(pcWriteBuffer, xWriteBufferLen, "Configuration saved to Flash!\r\n");
        
    /* Command: get - Read configuration from Flash */
    } else if (strcasecmp(arg1, "get") == 0) {
        STMFLASH_Read(FLASH_SAVE_ADDR, (uint16_t*)Config_Get(), sizeof(Config_t)/2);
        snprintf(pcWriteBuffer, xWriteBufferLen, "Configuration loaded from Flash\r\n");
        
    /* Command: reset - Restore default configuration */
    } else if (strcasecmp(arg1, "reset") == 0) {
        Config_SetDefaults();
        MR16_Init(&mr16,&Config_Get()->mr16);
        snprintf(pcWriteBuffer, xWriteBufferLen, "Configuration reset to defaults!\r\n");
        
    /* Command: mode - Set MR16 data format */
    } else if (strcasecmp(arg1, "mode") == 0) {
      if (strcasecmp(arg2, "help") == 0) {
        snprintf(pcWriteBuffer, xWriteBufferLen, 
                 "mode: 'VARIABLE' - variable length (UART idle)\r\n"
                 "      'FIXED' - fixed length\r\n");
        return pdFALSE;
      }
      if (arg2[0] != '\0') {
            if (strcasecmp(arg2, "VARIABLE") == 0) {
                mr16.param->format = MR16_FORMAT_VARIABLE;
                MR16_UI_UpdateStatus(&mr16);
                snprintf(pcWriteBuffer, xWriteBufferLen, "Data format set to: VARIABLE\r\n");
            } else if (strcasecmp(arg2, "FIXED") == 0) {
                mr16.param->format = MR16_FORMAT_FIXED;
                MR16_UI_UpdateStatus(&mr16);
                snprintf(pcWriteBuffer, xWriteBufferLen, "Data format set to: FIXED\r\n");
            } else {
                snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid format: %s\r\n", arg2);
            }
        } else {
          snprintf(pcWriteBuffer, xWriteBufferLen, "Current format: %s\r\n", getFormatString(mr16.param->format));
        }
        
    /* Command: fixedlen - Set/show fixed packet length */
    } else if (strcasecmp(arg1, "fixedlen") == 0) {
        if (arg2[0] != '\0') {
            char *endptr = NULL;
            unsigned long len = strtoul(arg2, &endptr, 0);
            if (endptr == arg2) {
                snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid length value: %s\r\n", arg2);
            } else if (len < 1 || len > 123) {  /* Max 127 - Header(2) - CRC(2) */
                snprintf(pcWriteBuffer, xWriteBufferLen, 
                         "Length out of range: %lu (valid: 1..123)\r\n", len);
            } else {
                mr16.param->fixedLength = (uint16_t)len;
                MR16_UI_UpdateStatus(&mr16);
                snprintf(pcWriteBuffer, xWriteBufferLen, 
                         "Fixed length set to %u bytes (user data)\r\n"
                         "Total packet: %u bytes (Header[2]+Data[%u]+CRC[2])\r\n",
                         mr16.param->fixedLength, 
                         MR16_HEADER_LEN + mr16.param->fixedLength + MR16_CRC_LEN,
                         mr16.param->fixedLength);
            }
        } else {
            snprintf(pcWriteBuffer, xWriteBufferLen, 
                     "Current fixed length: %u bytes (user data)\r\n"
                     "Total packet: %u bytes (Header[2]+Data[%u]+CRC[2])\r\n",
                     mr16.param->fixedLength,
                     MR16_HEADER_LEN + mr16.param->fixedLength + MR16_CRC_LEN,
                     mr16.param->fixedLength);
        }
        
    /* Command: tx - Transmit packet */
    } else if (strcasecmp(arg1, "tx") == 0) {
        radio.param->RadioRole=RadioRoleTX;
        uint16_t txLen;
        switch (mr16.param->format) {
          case MR16_FORMAT_VARIABLE:
              txLen = uart2_datalength;
              break;
          case MR16_FORMAT_FIXED:
              txLen = MR16_HEADER_LEN + mr16.param->fixedLength;
              break;
          default:
              snprintf(pcWriteBuffer, xWriteBufferLen, "Cannot transmit: invalid format\r\n");
              return pdFALSE;
        }
        SX1281_SetTX(&radio, mr16.txbuffer, txLen);
        MR16_UI_Home(&mr16);
        MR16_UI_UpdateStatus(&mr16);
        snprintf(pcWriteBuffer, xWriteBufferLen, "Transmitting packet...\r\n");
        
    /* Command: rx - Start continuous receive */
    } else if (strcasecmp(arg1, "rx") == 0) {
        radio.param->RadioRole=RadioRoleRX;
        SX1281_SetRXSuccessive(&radio);
        MR16_UI_Home(&mr16);
        MR16_UI_UpdateStatus(&mr16);
        snprintf(pcWriteBuffer, xWriteBufferLen, "Starting continuous receive...\r\n");
    /* Commands: rxid1/rxid2/rxid3 - Set RX IDs */
    } else if (strcasecmp(arg1, "rxid1") == 0 || strcasecmp(arg1, "rxid2") == 0 || strcasecmp(arg1, "rxid3") == 0) {
        int idx = arg1[4] - '1';  /* Extract index from "rxid1/2/3" */
        if (arg2[0] != '\0') {
            setRXID(&mr16.param->RX_ID[idx], arg2, pcWriteBuffer, xWriteBufferLen);
        } else {
            snprintf(pcWriteBuffer, xWriteBufferLen, "Current RXID%d: 0x%04X\r\n", idx + 1, mr16.param->RX_ID[idx]);
        }
        
    /* Command: rxid - Show all RX IDs */
    } else if (strcasecmp(arg1, "rxid") == 0 && arg2[0] == '\0') {
        snprintf(pcWriteBuffer, xWriteBufferLen, 
                "RX IDs:\r\n  RXID1: 0x%04X\r\n  RXID2: 0x%04X\r\n  RXID3: 0x%04X\r\n",
                mr16.param->RX_ID[0], mr16.param->RX_ID[1], mr16.param->RX_ID[2]);
                
    /* Command: power - Set/show TX power */
    } else if (strcasecmp(arg1, "power") == 0) {
      if (arg2[0] == '\0') {
        if (radio.param) {
          snprintf(pcWriteBuffer, xWriteBufferLen, "Current power: %d dBm\r\n", radio.param->txOutputPower);
        } else {
          snprintf(pcWriteBuffer, xWriteBufferLen, "Current power: (radio not initialized)\r\n");
        }
      } else {
        char *endptr = NULL;
        long v = strtol(arg2, &endptr, 0);
        if (endptr == arg2) {
          snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid power value: %s\r\n", arg2);
        } else if (v < TX_POWER_MIN || v > TX_POWER_MAX) {
          snprintf(pcWriteBuffer, xWriteBufferLen, "Power out of range: %ld dBm (valid: %d..%d)\r\n", 
                   v, TX_POWER_MIN, TX_POWER_MAX);
        } else {
          int8_t p = (int8_t)v;
          if (radio.param) {
            radio.param->txOutputPower = p;
            Radio.SetTxParams(radio.param->txOutputPower, radio.param->rampTime);
            MR16_UI_UpdateStatus(&mr16);
          }
          snprintf(pcWriteBuffer, xWriteBufferLen, "Power set to %d dBm\r\n", p);
        }
      }
        
    /* Command: show - Display all MR16 configuration */
    } else if (strcasecmp(arg1, "show") == 0) {
        snprintf(pcWriteBuffer, xWriteBufferLen,
                 "======== MR16 Configuration ========\r\n"
                 "Data Format  : %s\r\n"
                 "User Data Len: %u bytes (pure data)\r\n"
                 "Total Packet : %u bytes (Header+Data+CRC)\r\n"
                 "TX ID        : 0x%04X\r\n"
                 "RX ID 1      : 0x%04X\r\n"
                 "RX ID 2      : 0x%04X\r\n"
                 "RX ID 3      : 0x%04X\r\n"
                 "TX Power     : %d dBm\r\n"
                 "Radio Mode   : %s\r\n"
                 "Radio Role   : %s\r\n"
                 "=====================================\r\n",
                 getFormatString(mr16.param->format),
                 mr16.param->fixedLength,
                 MR16_HEADER_LEN + mr16.param->fixedLength + MR16_CRC_LEN,
                 mr16.param->TX_ID,
                 mr16.param->RX_ID[0],
                 mr16.param->RX_ID[1],
                 mr16.param->RX_ID[2],
                 radio.param->txOutputPower,
                 getRadioModeString(radio.param->radioMode),
                 (radio.param->RadioRole == RadioRoleTX) ? "TX" : "RX");
        
        
    /* Invalid command */
    } else {
      snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid command: %s\r\nUse 'mr16 help' for available commands\r\n", arg1);
    }
    
    return pdFALSE;
}

/**
 * @brief Radio命令处理器(CLI) - 控制SX1281无线参数
 * @param pcWriteBuffer CLI写入缓冲区
 * @param xWriteBufferLen 缓冲区长度
 * @param pcCommandString 完整命令字符串
 * @return pdTRUE-还有输出, pdFALSE-命令处理完成
 * 
 * 支持的命令: help, mode, modulation, packet, syncword, bandwidth, txid
 * 可配置参数: 无线协议、调制参数、包参数、同步字等
 */
static BaseType_t radioCommandHandler(char *pcWriteBuffer, size_t xWriteBufferLen, 
                                      const char *pcCommandString) {
    BaseType_t len1 = 0, len2 = 0, len3 = 0, len4 = 0;
    const char *p1 = FreeRTOS_CLIGetParameter(pcCommandString, 1, &len1);
    const char *p2 = FreeRTOS_CLIGetParameter(pcCommandString, 2, &len2);
    const char *p3 = FreeRTOS_CLIGetParameter(pcCommandString, 3, &len3);
    const char *p4 = FreeRTOS_CLIGetParameter(pcCommandString, 4, &len4);
    
    char arg1[32] = {0}, arg2[32] = {0}, arg3[32] = {0}, arg4[32] = {0};
    
    /* Extract parameters using common function */
    if (p1) copyCLIArg(p1, len1, arg1, sizeof(arg1));
    if (p2) copyCLIArg(p2, len2, arg2, sizeof(arg2));
    if (p3) copyCLIArg(p3, len3, arg3, sizeof(arg3));
    if (p4) copyCLIArg(p4, len4, arg4, sizeof(arg4));
    
    /* Command: help - Display help information */
    if (strcasecmp(arg1, "help") == 0) {
        static size_t help_pos = 0;
        if (help_pos >= strlen(radio_help_en)) help_pos = 0;
        BaseType_t result = outputHelpText(pcWriteBuffer, xWriteBufferLen, radio_help_en, &help_pos);
        if (result == pdFALSE) help_pos = 0;
        return result;
        
    } else if (strcasecmp(arg1, "modulation") == 0 && strcasecmp(arg2, "help") == 0) {
        static size_t mod_help_pos = 0;
        if (mod_help_pos >= strlen(modulation_help)) mod_help_pos = 0;
        BaseType_t result = outputHelpText(pcWriteBuffer, xWriteBufferLen, modulation_help, &mod_help_pos);
        if (result == pdFALSE) mod_help_pos = 0;
        return result;
        
    } else if (strcasecmp(arg1, "packet") == 0 && strcasecmp(arg2, "help") == 0) {
        static size_t pkt_help_pos = 0;
        if (pkt_help_pos >= strlen(packet_help)) pkt_help_pos = 0;
        BaseType_t result = outputHelpText(pcWriteBuffer, xWriteBufferLen, packet_help, &pkt_help_pos);
        if (result == pdFALSE) pkt_help_pos = 0;
        return result;
        
    /* Parameter processing commands */
    } else {
        /* Parse numeric value from arg3 or arg4 */
        unsigned long val = 0;
        if (arg4[0] != '\0') {
            val = strtoul(arg4, NULL, 0);
        } else if (arg3[0] != '\0') {
            val = strtoul(arg3, NULL, 0);
        }
        
        /* Command: mode - Change or show radio mode */
        if (strcasecmp(arg1, "mode") == 0) {
          if (arg2[0] == '\0') {
            snprintf(pcWriteBuffer, xWriteBufferLen, "Current radio mode: %s\r\n", 
                     getRadioModeString(radio.param->radioMode));
          } else {
            SX1281_RadioMode_t proto;
            if (strcasecmp(arg2, "BLE") == 0) {
              proto = RADIOMODE_BLE;
            } else if (strcasecmp(arg2, "LORA") == 0) {
              proto = RADIOMODE_LORA;
            } else if (strcasecmp(arg2, "GFSK") == 0) {
              proto = RADIOMODE_GFSK;
            } else if (strcasecmp(arg2, "FLRC") == 0) {
              proto = RADIOMODE_FLRC;
            } else {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown radio mode: %s\r\n", arg2);
              return pdFALSE;
            }

            if (SX1281_SetMode(&radio, proto) == DEVICE_OK) {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Radio mode set to %s\r\n", arg2);
            } else {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Failed to set radio mode\r\n");
            }
          }
        
        /* Command: modulation - Set modulation parameters */
        } else if (strcasecmp(arg1, "modulation") == 0) {
          /* Show current modulation params when no field provided */
          if (arg2[0] == '\0') {
            switch (radio.param->modulationParams.PacketType) {
              case PACKET_TYPE_BLE:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Modulation(BLE): br_bw=0x%X modindex=%u shaping=0x%X\r\n",
                    radio.param->modulationParams.Params.Ble.BitrateBandwidth,
                    radio.param->modulationParams.Params.Ble.ModulationIndex,
                    radio.param->modulationParams.Params.Ble.ModulationShaping);
                break;
              case PACKET_TYPE_GFSK:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Modulation(GFSK): br_bw=0x%X modindex=%u shaping=0x%X\r\n",
                    radio.param->modulationParams.Params.Gfsk.BitrateBandwidth,
                    radio.param->modulationParams.Params.Gfsk.ModulationIndex,
                    radio.param->modulationParams.Params.Gfsk.ModulationShaping);
                break;
              case PACKET_TYPE_LORA:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Modulation(LoRa): sf=0x%X bw=0x%X cr=0x%X\r\n",
                    radio.param->modulationParams.Params.LoRa.SpreadingFactor,
                    radio.param->modulationParams.Params.LoRa.Bandwidth,
                    radio.param->modulationParams.Params.LoRa.CodingRate);
                break;
              case PACKET_TYPE_FLRC:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Modulation(FLRC): br_bw=0x%X cr=0x%X shaping=0x%X\r\n",
                    radio.param->modulationParams.Params.Flrc.BitrateBandwidth,
                    radio.param->modulationParams.Params.Flrc.CodingRate,
                    radio.param->modulationParams.Params.Flrc.ModulationShaping);
                break;
              default:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown modulation packet type\r\n");
                break;
            }
            return pdFALSE;
          }
            /* Handle different packet types for modulation */
            switch (radio.param->modulationParams.PacketType) {
                case PACKET_TYPE_BLE:
                    if (strcasecmp(arg2, "br_bw") == 0) {
                        if (val > 0xEF) {
                            snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid br_bw value for BLE (max: 0xEF)\r\n");
                            return pdFALSE;
                        }
                        radio.param->modulationParams.Params.Ble.BitrateBandwidth = (RadioGfskBleBitrates_t)val;
                    } else if (strcasecmp(arg2, "modindex") == 0) {
                        if (val > 15) {
                            snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid modindex value for BLE (max: 15)\r\n");
                            return pdFALSE;
                        }
                        radio.param->modulationParams.Params.Ble.ModulationIndex = (RadioGfskBleModIndexes_t)val;
                    } else if (strcasecmp(arg2, "shaping") == 0) {
                        if (val != 0x00 && val != 0x10 && val != 0x20) {
                            snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid shaping value for BLE (0x00/0x10/0x20)\r\n");
                            return pdFALSE;
                        }
                        radio.param->modulationParams.Params.Ble.ModulationShaping = (RadioModShapings_t)val;
                    } else {
                        snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown modulation field for BLE: %s\r\n", arg2);
                        return pdFALSE;
                    }
                    break;
				case PACKET_TYPE_GFSK:
					if (strcasecmp(arg2, "br_bw") == 0) {
						if (val > 0xEF) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid br_bw value for GFSK (max: 0xEF)\r\n"); return pdFALSE; }
						radio.param->modulationParams.Params.Gfsk.BitrateBandwidth = (RadioGfskBleBitrates_t)val;
					} else if (strcasecmp(arg2, "modindex") == 0) {
						if (val > 15) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid modindex value for GFSK (max: 15)\r\n"); return pdFALSE; }
						radio.param->modulationParams.Params.Gfsk.ModulationIndex = (RadioGfskBleModIndexes_t)val;
					} else if (strcasecmp(arg2, "shaping") == 0) {
						if (val != 0x00 && val != 0x10 && val != 0x20) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid shaping value for GFSK (0x00/0x10/0x20)\r\n"); return pdFALSE; }
						radio.param->modulationParams.Params.Gfsk.ModulationShaping = (RadioModShapings_t)val;
					} else {
						snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown modulation field for GFSK: %s\r\n", arg2);
						return pdFALSE;
					}
					break;
				case PACKET_TYPE_LORA:
					if (strcasecmp(arg2, "sf") == 0) {
						if (val != 0x50 && val != 0x60 && val != 0x70 && val != 0x80 && val != 0x90 && val != 0xA0 && val != 0xB0 && val != 0xC0) {
						snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid sf value for LORA\r\n"); return pdFALSE;
						}
						radio.param->modulationParams.Params.LoRa.SpreadingFactor = (RadioLoRaSpreadingFactors_t)val;
					}
					else if (strcasecmp(arg2, "bw") == 0) {
						if (val != 0x34 && val != 0x26 && val != 0x18 && val != 0x0A) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid bw value for LORA\r\n"); return pdFALSE; }
						radio.param->modulationParams.Params.LoRa.Bandwidth = (RadioLoRaBandwidths_t)val;
					}
					else if (strcasecmp(arg2, "cr") == 0) {
						if (val < 0x01 || val > 0x07) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid cr value for LORA\r\n"); return pdFALSE; }
						radio.param->modulationParams.Params.LoRa.CodingRate = (RadioLoRaCodingRates_t)val;
					}
					else { snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown modulation field\r\n"); return pdFALSE; }
					break;
				case PACKET_TYPE_FLRC:
					if (strcasecmp(arg2, "br_bw") == 0) {
						if (val != 0x04 && val != 0x28 && val != 0x45 && val != 0x69 && val != 0x86 && val != 0xAA && val != 0xC7 && val != 0xEB) {
						snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid br_bw value for FLRC\r\n"); return pdFALSE;
						}
						radio.param->modulationParams.Params.Flrc.BitrateBandwidth = (RadioFlrcBitrates_t)val;
					}
					else if (strcasecmp(arg2, "cr") == 0) {
						if (val != 0x00 && val != 0x02 && val != 0x04) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid cr value for FLRC\r\n"); return pdFALSE; }
						radio.param->modulationParams.Params.Flrc.CodingRate = (RadioFlrcCodingRates_t)val;
					}
					else if (strcasecmp(arg2, "shaping") == 0) {
						if (val != 0x00 && val != 0x10 && val != 0x20) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid shaping value for FLRC\r\n"); return pdFALSE; }
						radio.param->modulationParams.Params.Flrc.ModulationShaping = (RadioModShapings_t)val;
					}
					else { snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown modulation field\r\n"); return pdFALSE; }
					break;
				default:
					snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown current packet type\r\n");
					return pdFALSE;
			}
            Radio.SetModulationParams(&radio.param->modulationParams);
            snprintf(pcWriteBuffer, xWriteBufferLen, "Modulation updated\r\n");
            
          } else if (strcasecmp(arg1, "packet") == 0) {
          /* Show current packet params when no field provided */
          if (arg2[0] == '\0') {
            switch (radio.param->packetParams.PacketType) {
              case PACKET_TYPE_BLE:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Packet(BLE): ConnectionState=%u CrcField=%u BlePacketType=%u Whitening=0x%X\r\n",
                     radio.param->packetParams.Params.Ble.ConnectionState,
                     radio.param->packetParams.Params.Ble.CrcField,
                     radio.param->packetParams.Params.Ble.BlePacketType,
                     radio.param->packetParams.Params.Ble.Whitening);
                break;
              case PACKET_TYPE_GFSK:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Packet(GFSK): Preamble=0x%X SyncLen=0x%X SyncMatch=0x%X Header=0x%X Payload=%u Crc=0x%X Whitening=0x%X\r\n",
                     radio.param->packetParams.Params.Gfsk.PreambleLength,
                     radio.param->packetParams.Params.Gfsk.SyncWordLength,
                     radio.param->packetParams.Params.Gfsk.SyncWordMatch,
                     radio.param->packetParams.Params.Gfsk.HeaderType,
                     radio.param->packetParams.Params.Gfsk.PayloadLength,
                     radio.param->packetParams.Params.Gfsk.CrcLength,
                     radio.param->packetParams.Params.Gfsk.Whitening);
                break;
              case PACKET_TYPE_LORA:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Packet(LoRa): Preamble=%u Header=0x%X Payload=%u Crc=0x%X InvertIQ=0x%X\r\n",
                     radio.param->packetParams.Params.LoRa.PreambleLength,
                     radio.param->packetParams.Params.LoRa.HeaderType,
                     radio.param->packetParams.Params.LoRa.PayloadLength,
                     radio.param->packetParams.Params.LoRa.CrcMode,
                     radio.param->packetParams.Params.LoRa.InvertIQ);
                break;
              case PACKET_TYPE_FLRC:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Packet(FLRC): Preamble=0x%X SyncLen=0x%X SyncMatch=0x%X Header=0x%X Payload=%u Crc=0x%X Whitening=0x%X\r\n",
                     radio.param->packetParams.Params.Flrc.PreambleLength,
                     radio.param->packetParams.Params.Flrc.SyncWordLength,
                     radio.param->packetParams.Params.Flrc.SyncWordMatch,
                     radio.param->packetParams.Params.Flrc.HeaderType,
                     radio.param->packetParams.Params.Flrc.PayloadLength,
                     radio.param->packetParams.Params.Flrc.CrcLength,
                     radio.param->packetParams.Params.Flrc.Whitening);
                break;
              default:
                snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown packet type\r\n");
                break;
            }
            return pdFALSE;
          }
    /* packet <proto> <field> <value>
       fields examples: payload | preamble | header | crc | whitening
    */
    /* 根据当前 packet type 设置对应字段 */
    switch (radio.param->packetParams.PacketType) {

      case PACKET_TYPE_BLE:
          /* BLE 使用 Ble 子结构 */
          if (strcasecmp(arg2, "ConnectionState") == 0) {
            if (val > 4) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid BLE ConnectionState (0-4)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Ble.ConnectionState = (RadioBleConnectionStates_t)val;
          } else if (strcasecmp(arg2, "CrcField") == 0) {
            if (val > 1) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid BLE CrcField (0-1)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Ble.CrcField = (RadioBleCrcFields_t)val;
          } else if (strcasecmp(arg2, "BlePacketType") == 0) {
            if (val > 7) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid BLEPacketType (0-7)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Ble.BlePacketType = (RadioBlePacketTypes_t)val;
          } else if (strcasecmp(arg2, "Whitening") == 0) {
            if (val != 0x00 && val != 0x08) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid BLE Whitening (0x00/0x08)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Ble.Whitening = (RadioWhiteningModes_t)val;
          } else {
            snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown BLE packet field\r\n");
            return pdFALSE;
          }
          break;

      case PACKET_TYPE_GFSK:
          /* GFSK 子结构 */
          if (strcasecmp(arg2, "Preamble") == 0) {
            if (val != 0x00 && val != 0x10 && val != 0x20 && val != 0x30 && val != 0x40 && val != 0x50 && val != 0x60 && val != 0x70) {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK Preamble (0x00/0x10/0x20/0x30/0x40/0x50/0x60/0x70)\r\n"); return pdFALSE;
            }
            radio.param->packetParams.Params.Gfsk.PreambleLength = (RadioPreambleLengths_t)val;
          } else if (strcasecmp(arg2, "SyncWordLength") == 0) {
            if (val != 0x00 && val != 0x02 && val != 0x04 && val != 0x06 && val != 0x08) {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK SyncWordLength (0x00/0x02/0x04/0x06/0x08)\r\n"); return pdFALSE;
            }
            radio.param->packetParams.Params.Gfsk.SyncWordLength = (RadioSyncWordLengths_t)val;
          } else if (strcasecmp(arg2, "SyncWordMatch") == 0) {
            if (val != 0x00 && val != 0x10 && val != 0x20 && val != 0x30 && val != 0x40 && val != 0x50 && val != 0x60 && val != 0x70) {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK SyncWordMatch (0x00/0x10/0x20/0x30/0x40/0x50/0x60/0x70)\r\n"); return pdFALSE;
            }
            radio.param->packetParams.Params.Gfsk.SyncWordMatch = (RadioSyncWordRxMatchs_t)val;
          } else if (strcasecmp(arg2, "SyncWord") == 0) {
            /* Show all GFSK sync words */
            snprintf(pcWriteBuffer, xWriteBufferLen, 
                    "GFSK Sync Words:\r\n"
                    "  Word 1: %02X%02X%02X%02X%02X\r\n"
                    "  Word 2: %02X%02X%02X%02X%02X\r\n"
                    "  Word 3: %02X%02X%02X%02X%02X\r\n",
                    mr16.param->radioParams.syncWord.gfsk.first[0],
                    mr16.param->radioParams.syncWord.gfsk.first[1],
                    mr16.param->radioParams.syncWord.gfsk.first[2],
                    mr16.param->radioParams.syncWord.gfsk.first[3],
                    mr16.param->radioParams.syncWord.gfsk.first[4],
                    mr16.param->radioParams.syncWord.gfsk.second[0],
                    mr16.param->radioParams.syncWord.gfsk.second[1],
                    mr16.param->radioParams.syncWord.gfsk.second[2],
                    mr16.param->radioParams.syncWord.gfsk.second[3],
                    mr16.param->radioParams.syncWord.gfsk.second[4],
                    mr16.param->radioParams.syncWord.gfsk.third[0],
                    mr16.param->radioParams.syncWord.gfsk.third[1],
                    mr16.param->radioParams.syncWord.gfsk.third[2],
                    mr16.param->radioParams.syncWord.gfsk.third[3],
                    mr16.param->radioParams.syncWord.gfsk.third[4]);
            return pdFALSE;
          } else if (strcasecmp(arg2, "SyncWord1") == 0) {
            if (arg3[0] != '\0') {
                /* Set GFSK sync word 1 */
                uint32_t sync_val = (uint32_t)strtoul(arg3, NULL, 0);
                mr16.param->radioParams.syncWord.gfsk.first[0] = (sync_val >> 24) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.first[1] = (sync_val >> 16) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.first[2] = (sync_val >> 8) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.first[3] = sync_val & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.first[4] = 0;
                snprintf(pcWriteBuffer, xWriteBufferLen, "GFSK sync word 1 set to 0x%08lX\r\n", (unsigned long)sync_val);
            } else {
                snprintf(pcWriteBuffer, xWriteBufferLen, "GFSK Sync Word 1: %02X%02X%02X%02X%02X\r\n",
                        mr16.param->radioParams.syncWord.gfsk.first[0],
                        mr16.param->radioParams.syncWord.gfsk.first[1],
                        mr16.param->radioParams.syncWord.gfsk.first[2],
                        mr16.param->radioParams.syncWord.gfsk.first[3],
                        mr16.param->radioParams.syncWord.gfsk.first[4]);
            }
            return pdFALSE;
          } else if (strcasecmp(arg2, "SyncWord2") == 0) {
            if (arg3[0] != '\0') {
                /* Set GFSK sync word 2 */
                uint32_t sync_val = (uint32_t)strtoul(arg3, NULL, 0);
                mr16.param->radioParams.syncWord.gfsk.second[0] = (sync_val >> 24) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.second[1] = (sync_val >> 16) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.second[2] = (sync_val >> 8) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.second[3] = sync_val & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.second[4] = 0;
                snprintf(pcWriteBuffer, xWriteBufferLen, "GFSK sync word 2 set to 0x%08lX\r\n", (unsigned long)sync_val);
            } else {
                snprintf(pcWriteBuffer, xWriteBufferLen, "GFSK Sync Word 2: %02X%02X%02X%02X%02X\r\n",
                        mr16.param->radioParams.syncWord.gfsk.second[0],
                        mr16.param->radioParams.syncWord.gfsk.second[1],
                        mr16.param->radioParams.syncWord.gfsk.second[2],
                        mr16.param->radioParams.syncWord.gfsk.second[3],
                        mr16.param->radioParams.syncWord.gfsk.second[4]);
            }
            return pdFALSE;
          } else if (strcasecmp(arg2, "SyncWord3") == 0) {
            if (arg3[0] != '\0') {
                /* Set GFSK sync word 3 */
                uint32_t sync_val = (uint32_t)strtoul(arg3, NULL, 0);
                mr16.param->radioParams.syncWord.gfsk.third[0] = (sync_val >> 24) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.third[1] = (sync_val >> 16) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.third[2] = (sync_val >> 8) & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.third[3] = sync_val & 0xFF;
                mr16.param->radioParams.syncWord.gfsk.third[4] = 0;
                snprintf(pcWriteBuffer, xWriteBufferLen, "GFSK sync word 3 set to 0x%08lX\r\n", (unsigned long)sync_val);
            } else {
                snprintf(pcWriteBuffer, xWriteBufferLen, "GFSK Sync Word 3: %02X%02X%02X%02X%02X\r\n",
                        mr16.param->radioParams.syncWord.gfsk.third[0],
                        mr16.param->radioParams.syncWord.gfsk.third[1],
                        mr16.param->radioParams.syncWord.gfsk.third[2],
                        mr16.param->radioParams.syncWord.gfsk.third[3],
                        mr16.param->radioParams.syncWord.gfsk.third[4]);
            }
            return pdFALSE;
          } else if (strcasecmp(arg2, "Header") == 0) {
            if (val != 0x00 && val != 0x20) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK Header (0x00/0x20)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Gfsk.HeaderType = (RadioPacketLengthModes_t)val;
          } else if (strcasecmp(arg2, "Payload") == 0) {
            if (val < 1 || val > 255) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK Payload (1-255)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Gfsk.PayloadLength = (uint8_t)val;
          } else if (strcasecmp(arg2, "Crc") == 0) {
            if (val != 0x00 && val != 0x10 && val != 0x20 && val != 0x30) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK Crc (0x00/0x10/0x20/0x30)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Gfsk.CrcLength = (RadioCrcTypes_t)val;
          } else if (strcasecmp(arg2, "Whitening") == 0) {
            if (val != 0x00 && val != 0x08) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK Whitening (0x00/0x08)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Gfsk.Whitening = (RadioWhiteningModes_t)val;
          } else {
            snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown GFSK packet field\r\n");
            return pdFALSE;
          }
          break;

      case PACKET_TYPE_LORA:
          /* LoRa 子结构 */
          if (strcasecmp(arg2, "Preamble") == 0) {
            if (val < 0 || val > 255) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid LoRa Preamble (0-255)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.LoRa.PreambleLength = (uint8_t)val;
          } else if (strcasecmp(arg2, "Header") == 0) {
            if (val != 0x00 && val != 0x80) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid LoRa Header (0x00/0x80)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.LoRa.HeaderType = (RadioLoRaPacketLengthsModes_t)val;
          } else if (strcasecmp(arg2, "Payload") == 0) {
            if (val < 1 || val > 255) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid LoRa Payload (1-255)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.LoRa.PayloadLength = (uint8_t)val;
          } else if (strcasecmp(arg2, "Crc") == 0) {
            if (val != 0x00 && val != 0x20) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid LoRa Crc (0x00/0x20)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.LoRa.CrcMode = (RadioLoRaCrcModes_t)val;
          } else if (strcasecmp(arg2, "InvertIQ") == 0) {
            if (val != 0x00 && val != 0x40) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid LoRa InvertIQ (0x00/0x40)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.LoRa.InvertIQ = (RadioLoRaIQModes_t)val;
          } else {
            snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown LoRa packet field\r\n");
            return pdFALSE;
          }
          break;

      case PACKET_TYPE_FLRC:
          /* FLRC 子结构 */
          if (strcasecmp(arg2, "Preamble") == 0) {
            if (val != 0x00 && val != 0x10 && val != 0x20 && val != 0x30 && val != 0x40 && val != 0x50 && val != 0x60 && val != 0x70) {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC Preamble (0x00/0x10/0x20/0x30/0x40/0x50/0x60/0x70)\r\n"); return pdFALSE;
            }
            radio.param->packetParams.Params.Flrc.PreambleLength = (RadioPreambleLengths_t)val;
          } else if (strcasecmp(arg2, "SyncWordLength") == 0) {
            if (val != 0x00 && val != 0x02 && val != 0x04 && val != 0x06 && val != 0x08) {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC SyncWordLength (0x00/0x02/0x04/0x06/0x08)\r\n"); return pdFALSE;
            }
            radio.param->packetParams.Params.Flrc.SyncWordLength = (RadioFlrcSyncWordLengths_t)val;
          } else if (strcasecmp(arg2, "SyncWordMatch") == 0) {
            if (val != 0x00 && val != 0x10 && val != 0x20 && val != 0x30 && val != 0x40 && val != 0x50 && val != 0x60 && val != 0x70) {
              snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC SyncWordMatch (0x00/0x10/0x20/0x30/0x40/0x50/0x60/0x70)\r\n"); return pdFALSE;
            }
            radio.param->packetParams.Params.Flrc.SyncWordMatch = (RadioSyncWordRxMatchs_t)val;
          } else if (strcasecmp(arg2, "SyncWord") == 0) {
            /* Show all FLRC sync words */
            snprintf(pcWriteBuffer, xWriteBufferLen, 
                    "FLRC Sync Words:\r\n"
                    "  Word 1: %02X%02X%02X%02X\r\n"
                    "  Word 2: %02X%02X%02X%02X\r\n"
                    "  Word 3: %02X%02X%02X%02X\r\n",
                    mr16.param->radioParams.syncWord.flrc.first[0],
                    mr16.param->radioParams.syncWord.flrc.first[1],
                    mr16.param->radioParams.syncWord.flrc.first[2],
                    mr16.param->radioParams.syncWord.flrc.first[3],
                    mr16.param->radioParams.syncWord.flrc.second[0],
                    mr16.param->radioParams.syncWord.flrc.second[1],
                    mr16.param->radioParams.syncWord.flrc.second[2],
                    mr16.param->radioParams.syncWord.flrc.second[3],
                    mr16.param->radioParams.syncWord.flrc.third[0],
                    mr16.param->radioParams.syncWord.flrc.third[1],
                    mr16.param->radioParams.syncWord.flrc.third[2],
                    mr16.param->radioParams.syncWord.flrc.third[3]);
            return pdFALSE;
          } else if (strcasecmp(arg2, "SyncWord1") == 0) {
            if (arg3[0] != '\0') {
                /* Set FLRC sync word 1 */
                uint32_t sync_val = (uint32_t)strtoul(arg3, NULL, 0);
                mr16.param->radioParams.syncWord.flrc.first[0] = (sync_val >> 24) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.first[1] = (sync_val >> 16) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.first[2] = (sync_val >> 8) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.first[3] = sync_val & 0xFF;
                snprintf(pcWriteBuffer, xWriteBufferLen, "FLRC sync word 1 set to 0x%08lX\r\n", (unsigned long)sync_val);
            } else {
                snprintf(pcWriteBuffer, xWriteBufferLen, "FLRC Sync Word 1: %02X%02X%02X%02X\r\n",
                        mr16.param->radioParams.syncWord.flrc.first[0],
                        mr16.param->radioParams.syncWord.flrc.first[1],
                        mr16.param->radioParams.syncWord.flrc.first[2],
                        mr16.param->radioParams.syncWord.flrc.first[3]);
            }
            return pdFALSE;
          } else if (strcasecmp(arg2, "SyncWord2") == 0) {
            if (arg3[0] != '\0') {
                /* Set FLRC sync word 2 */
                uint32_t sync_val = (uint32_t)strtoul(arg3, NULL, 0);
                mr16.param->radioParams.syncWord.flrc.second[0] = (sync_val >> 24) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.second[1] = (sync_val >> 16) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.second[2] = (sync_val >> 8) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.second[3] = sync_val & 0xFF;
                snprintf(pcWriteBuffer, xWriteBufferLen, "FLRC sync word 2 set to 0x%08lX\r\n", (unsigned long)sync_val);
            } else {
                snprintf(pcWriteBuffer, xWriteBufferLen, "FLRC Sync Word 2: %02X%02X%02X%02X\r\n",
                        mr16.param->radioParams.syncWord.flrc.second[0],
                        mr16.param->radioParams.syncWord.flrc.second[1],
                        mr16.param->radioParams.syncWord.flrc.second[2],
                        mr16.param->radioParams.syncWord.flrc.second[3]);
            }
            return pdFALSE;
          } else if (strcasecmp(arg2, "SyncWord3") == 0) {
            if (arg3[0] != '\0') {
                /* Set FLRC sync word 3 */
                uint32_t sync_val = (uint32_t)strtoul(arg3, NULL, 0);
                mr16.param->radioParams.syncWord.flrc.third[0] = (sync_val >> 24) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.third[1] = (sync_val >> 16) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.third[2] = (sync_val >> 8) & 0xFF;
                mr16.param->radioParams.syncWord.flrc.third[3] = sync_val & 0xFF;
                snprintf(pcWriteBuffer, xWriteBufferLen, "FLRC sync word 3 set to 0x%08lX\r\n", (unsigned long)sync_val);
            } else {
                snprintf(pcWriteBuffer, xWriteBufferLen, "FLRC Sync Word 3: %02X%02X%02X%02X\r\n",
                        mr16.param->radioParams.syncWord.flrc.third[0],
                        mr16.param->radioParams.syncWord.flrc.third[1],
                        mr16.param->radioParams.syncWord.flrc.third[2],
                        mr16.param->radioParams.syncWord.flrc.third[3]);
            }
            return pdFALSE;
          } else if (strcasecmp(arg2, "Header") == 0) {
            if (val != 0x00 && val != 0x20) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC Header (0x00/0x20)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Flrc.HeaderType = (RadioPacketLengthModes_t)val;
          } else if (strcasecmp(arg2, "Payload") == 0) {
            if (val < 1 || val > 255) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC Payload (1-255)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Flrc.PayloadLength = (uint8_t)val;
          } else if (strcasecmp(arg2, "Crc") == 0) {
            if (val != 0x00 && val != 0x10 && val != 0x20 && val != 0x30) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC Crc (0x00/0x10/0x20/0x30)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Flrc.CrcLength = (RadioCrcTypes_t)val;
          } else if (strcasecmp(arg2, "Whitening") == 0) {
            if (val != 0x00 && val != 0x08) { snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC Whitening (0x00/0x08)\r\n"); return pdFALSE; }
            radio.param->packetParams.Params.Flrc.Whitening = (RadioWhiteningModes_t)val;
          } else {
            snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown FLRC packet field\r\n");
            return pdFALSE;
          }
          break;

      default:
        snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown current packet type\r\n");
        return pdFALSE;
    }

    /* 应用并返回 */
    Radio.SetPacketParams(&radio.param->packetParams);
    snprintf(pcWriteBuffer, xWriteBufferLen, "Packet parameters updated\r\n");
  } else if (strcasecmp(arg1, "baudrate") == 0) {
    /* baudrate [index] - 根据当前模式自动设置波特率 */
    
    /* 显示帮助 */
    if (strcasecmp(arg2, "help") == 0) {
        static size_t baudrate_help_pos = 0;
        if (baudrate_help_pos >= strlen(baudrate_help)) baudrate_help_pos = 0;
        BaseType_t result = outputHelpText(pcWriteBuffer, xWriteBufferLen, baudrate_help, &baudrate_help_pos);
        if (result == pdFALSE) baudrate_help_pos = 0;
        return result;
    }
    
    /* 无参数: 显示所有模式的波特率 */
    if (arg2[0] == '\0') {
        const char* current_mode = getRadioModeString(radio.param->radioMode);
        snprintf(pcWriteBuffer, xWriteBufferLen, 
                 "Current mode: %s\r\n"
                 "Baudrates: BLE=%u | LORA=%u | GFSK=%u | FLRC=%u\r\n",
                 current_mode,
                 radio.param->baudrate.ble,
                 radio.param->baudrate.lora,
                 radio.param->baudrate.gfks,
                 radio.param->baudrate.flrc);
        return pdFALSE;
    }
    
    /* 有参数: 根据当前模式设置波特率 */
    int8_t ret = -1;
    const char* mode_name = "";
    
    switch (radio.param->radioMode) {
        case RADIOMODE_BLE:
            if (val > 2) {
                snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid BLE baudrate index: %lu (valid: 0-2)\r\n", (unsigned long)val);
                return pdFALSE;
            }
            radio.param->baudrate.ble = (SX1281_BLEBaudrate_t)val;
            ret = SX1281_SetBLEBaudrate(&radio, radio.param->baudrate.ble);
            mode_name = "BLE";
            break;
            
        case RADIOMODE_LORA:
            if (val > 7) {
                snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid LoRa baudrate index: %lu (valid: 0-7)\r\n", (unsigned long)val);
                return pdFALSE;
            }
            radio.param->baudrate.lora = (SX1281_LORABaudrate_t)val;
            ret = SX1281_SetLORABaudrate(&radio, radio.param->baudrate.lora);
            mode_name = "LoRa";
            break;
            
        case RADIOMODE_GFSK:
            if (val > 3) {
                snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid GFSK baudrate index: %lu (valid: 0-3)\r\n", (unsigned long)val);
                return pdFALSE;
            }
            radio.param->baudrate.gfks = (SX1281_GFKSBaudrate_t)val;
            ret = SX1281_SetGFSKBaudrate(&radio, radio.param->baudrate.gfks);
            mode_name = "GFSK";
            break;
            
        case RADIOMODE_FLRC:
            if (val > 3) {
                snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid FLRC baudrate index: %lu (valid: 0-3)\r\n", (unsigned long)val);
                return pdFALSE;
            }
            radio.param->baudrate.flrc = (SX1281_FLRCBaudrate_t)val;
            ret = SX1281_SetFLRCBaudrate(&radio, radio.param->baudrate.flrc);
            mode_name = "FLRC";
            break;
            
        default:
            snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown radio mode\r\n");
            return pdFALSE;
    }
    
    if (ret == DEVICE_OK) {
        snprintf(pcWriteBuffer, xWriteBufferLen, "Baudrate updated for %s mode -> index %lu\r\n", 
                 mode_name, (unsigned long)val);
    } else {
        snprintf(pcWriteBuffer, xWriteBufferLen, "Failed to update baudrate for %s mode\r\n", mode_name);
    }
  } else if (strcasecmp(arg1, "power") == 0) {
    /* power <value> */
    if (arg2[0] == '\0') {
        snprintf(pcWriteBuffer, xWriteBufferLen, "Current TX power: %d dBm\r\n", radio.param->txOutputPower);
        return pdFALSE;
    }
    int8_t p = (int8_t)val;
    radio.param->txOutputPower = p;
    Radio.SetTxParams(radio.param->txOutputPower, radio.param->rampTime);
    snprintf(pcWriteBuffer, xWriteBufferLen, "TX power set to %d dBm\r\n", p);
  } else if (strcasecmp(arg1, "ramptime") == 0) {
    /* ramptime <us> - accepts 2/4/6/8/10/12/16/20 */
    RadioRampTimes_t rt = RADIO_RAMP_02_US;
    unsigned long us = val;
    if (arg2[0] == '\0') {
        /* print current ramptime */
        unsigned long cur_us = 2;
        switch (radio.param->rampTime) {
            case RADIO_RAMP_02_US: cur_us = 2; break;
            case RADIO_RAMP_04_US: cur_us = 4; break;
            case RADIO_RAMP_06_US: cur_us = 6; break;
            case RADIO_RAMP_08_US: cur_us = 8; break;
            case RADIO_RAMP_10_US: cur_us = 10; break;
            case RADIO_RAMP_12_US: cur_us = 12; break;
            case RADIO_RAMP_16_US: cur_us = 16; break;
            case RADIO_RAMP_20_US: cur_us = 20; break;
            default: break;
        }
        snprintf(pcWriteBuffer, xWriteBufferLen, "Current ramp time: %lu us\r\n", cur_us);
        return pdFALSE;
    }
    switch (us) {
      case 2: rt = RADIO_RAMP_02_US; break;
      case 4: rt = RADIO_RAMP_04_US; break;
      case 6: rt = RADIO_RAMP_06_US; break;
      case 8: rt = RADIO_RAMP_08_US; break;
      case 10: rt = RADIO_RAMP_10_US; break;
      case 12: rt = RADIO_RAMP_12_US; break;
      case 16: rt = RADIO_RAMP_16_US; break;
      case 20: rt = RADIO_RAMP_20_US; break;
      default: snprintf(pcWriteBuffer, xWriteBufferLen, "Invalid ramptime\r\n"); return pdFALSE;
    }
    radio.param->rampTime = rt;
    Radio.SetTxParams(radio.param->txOutputPower, radio.param->rampTime);
    snprintf(pcWriteBuffer, xWriteBufferLen, "Ramp time set to %lu us\r\n", us);
  } else if (strcasecmp(arg1, "rffreq") == 0 || strcasecmp(arg1, "rffrequency") == 0) {
    /* rffreq <value in Hz> */
    if (arg2[0] == '\0') {
        snprintf(pcWriteBuffer, xWriteBufferLen, "Current RF freq: %llu Hz\r\n", (unsigned long long)radio.param->rfFrequency);
        return pdFALSE;
    }
    uint32_t f = (uint32_t)val;
    SX1281_SetRFFrequency(&radio, f);
    snprintf(pcWriteBuffer, xWriteBufferLen, "RF freq set to %lu Hz\r\n", (unsigned long)f);
  } else {
    snprintf(pcWriteBuffer, xWriteBufferLen, "Unknown radio command\r\n");
  }
        }

  return pdFALSE;
}


