/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2026 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "fatfs.h"
#include "sdio.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ltc2508_driver.h"
#include "rs485_driver.h"
#include "data_packet.h"
#include "correction.h"
#include "data_storage.h"
#include "system_monitor.h"
#include "config_manager.h"
#include "gps_driver.h"
#include "optic_mag_driver.h"
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
// 以下宏从 app_config.h 引入，此处仅做别名映射，保持内部代码不变
#define ENABLE_SYSTEM_MONITOR       CFG_ENABLE_SYSTEM_MONITOR
#define DEBUG_OUTPUT_INTERVAL_MS    CFG_DEBUG_OUTPUT_INTERVAL_MS
#define MONITOR_SAVE_INTERVAL_MS    CFG_MONITOR_SAVE_INTERVAL_MS
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
// 外部SPI句柄声明
extern SPI_HandleTypeDef hspi1;
extern SPI_HandleTypeDef hspi2;
extern SPI_HandleTypeDef hspi3;
extern TIM_HandleTypeDef htim2;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;

// 校正参数
CorrectionParams_t g_correction_params;
// 数据包（标准包 / 扩展包各一份，ProcessAdcData按需选用）
DataPacket_t                   g_data_packet;
DataPacketWithOptic_t          g_data_packet_with_optic;
CorrectedDataPacket_t          g_corrected_packet;
CorrectedDataPacketWithGPS_t   g_corrected_packet_with_gps;
CorrectedDataPacketWithOptic_t g_corrected_packet_with_optic;
// 数据存储句柄
DataStorageHandle_t g_data_storage;
// 系统状态
static uint8_t g_recording_enabled = 0;

// USB连接状态管理
static uint8_t g_usb_connected = 0;
static uint8_t g_fatfs_mounted_for_sampling = 0;
static uint32_t g_last_usb_check = 0;

// 性能监控和调试输出
static uint32_t g_last_debug_output = 0;

// 监控状态保存
static uint32_t g_last_monitor_save = 0;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
static void StartRecording(void);
static void StopRecording(void);
static void ProcessAdcData(void);

// USB连接状态管理函数
static uint8_t CheckUSBConnectionStatus(void);
static void HandleUSBConnectionChange(void);
static HAL_StatusTypeDef MountFileSystemForSampling(void);
static void UnmountFileSystemForSampling(void);

static void DebugOutput_Init(void);
static void DebugOutput_SendString(const char* str);
static void DebugOutput_PrintSystemStats(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/**
 * @brief  开始数据记录
 * @retval None
 */
static void StartRecording(void)
{
  if (!g_recording_enabled) {
    if (DataStorage_StartRecording(&g_data_storage) == HAL_OK) {
      g_recording_enabled = 1;
    }
  }
}

/**
 * @brief  停止数据记录
 * @retval None
 */
static void StopRecording(void)
{
  if (g_recording_enabled) {
    g_recording_enabled = 0;
    DataStorage_StopRecording(&g_data_storage);
  }
}

/**
 * @brief  处理ADC数据
 * @retval None
 */
static void ProcessAdcData(void)
{
    LTC2508_BufferTypeDef *ready_buffer = NULL;
    if (LTC2508_GetReadyBuffer(&ready_buffer) != LTC2508_OK || ready_buffer == NULL) return;

    // 快照光泵数据：USART2中断优先级(10) < TIM2优先级(3)，此处不会被抢占，无需关中断
    uint8_t  optic_fresh = g_optic_mag_fresh;
    uint32_t optic_val   = g_optic_mag_value;
    if (optic_fresh) g_optic_mag_fresh = 0;

    // 检查存储缓冲区是否可用（取最大包长为基准）
    uint8_t can_store_data = 0;
    if (g_recording_enabled) {
        can_store_data = DataStorage_IsBufferAvailable(&g_data_storage,
                             sizeof(CorrectedDataPacketWithOptic_t));
    }

#if ENABLE_SYSTEM_MONITOR
    SystemMonitor_IncrementSampleCount();
#endif

    // 1. 合并三路ADC原始数据（高16位在前）
    int32_t raw_adc[NUM_LTC2508];
    for (uint8_t i = 0; i < NUM_LTC2508; i++) {
        raw_adc[i] = (int32_t)(((uint32_t)ready_buffer->data[i][0] << 16) | ready_buffer->data[i][1]);
    }

    // 2. 获取GPS数据（时间戳始终使用，位置字段受ENABLE_GPS_POSITION控制）
    GPS_Data_t current_gps_data;
    uint8_t gps_valid = GPS_GetData(&current_gps_data);
    uint32_t gps_time = gps_valid ? (current_gps_data.time.hour   * 10000u +
                                     current_gps_data.time.minute * 100u   +
                                     current_gps_data.time.second) : 0u;
    float lat = (float)current_gps_data.position.latitude;
    float lon = (float)current_gps_data.position.longitude;
    float alt = (float)current_gps_data.position.altitude;

    // 3. 决定发送哪种包（校正×是否有光泵 = 4种组合）
    const uint8_t *send_ptr;
    uint16_t       send_size;

    CorrectionResult_t correction_result;
    if (g_correction_params.params_valid &&
        Apply_Correction(raw_adc[0], raw_adc[1], raw_adc[2],
                         &correction_result, &g_correction_params) == HAL_OK) {

        if (optic_fresh) {
            PackCorrectedDataWithOptic(&g_corrected_packet_with_optic,
                correction_result.corrected_x, correction_result.corrected_y,
                correction_result.corrected_z, gps_time, lat, lon, alt, optic_val);
            send_ptr  = (const uint8_t *)&g_corrected_packet_with_optic;
            send_size = sizeof(CorrectedDataPacketWithOptic_t);
        } else {
            PackCorrectedDataWithGPS(&g_corrected_packet_with_gps,
                correction_result.corrected_x, correction_result.corrected_y,
                correction_result.corrected_z, gps_time, lat, lon, alt);
            send_ptr  = (const uint8_t *)&g_corrected_packet_with_gps;
            send_size = sizeof(CorrectedDataPacketWithGPS_t);
        }

    } else {

        if (optic_fresh) {
            PackDataWithOptic(&g_data_packet_with_optic,
                raw_adc[0], raw_adc[1], raw_adc[2],
                gps_time, lat, lon, alt, optic_val);
            send_ptr  = (const uint8_t *)&g_data_packet_with_optic;
            send_size = sizeof(DataPacketWithOptic_t);
        } else {
            PackData(&g_data_packet,
                raw_adc[0], raw_adc[1], raw_adc[2],
                gps_time, lat, lon, alt);
            send_ptr  = (const uint8_t *)&g_data_packet;
            send_size = sizeof(DataPacket_t);
        }
    }

    // 4. 发送到RS485串口
    if (Config_IsUartOutputEnabled()) {
        RS485_SendData((uint8_t *)send_ptr, send_size);
    }

    // 5. 存储到SD卡（方案Y：直接写原始字节流，与串口格式一致）
    if (Config_IsStorageEnabled() && g_recording_enabled) {
        if (can_store_data) {
            DataStorage_WriteRawBytes(&g_data_storage, send_ptr, send_size);
        } else {
#if ENABLE_SYSTEM_MONITOR
            SystemMonitor_ReportDataDropped();
#endif
        }
    }

    // 6. 释放已处理的缓冲区
    LTC2508_ReleaseBuffer(LTC2508_GetCurrentReadBuffer());
}

/**
 * @brief  初始化调试输出和GPS
 * @retval None
 */
static void DebugOutput_Init(void)
{
  // USART3现在用于GPS接收，不再用于调试输出
  // 初始化GPS驱动
  if (GPS_Init() == HAL_OK) {
    // GPS初始化成功
    // 注意：GPS初始化后，USART3将用于接收GPS数据
  }
}

/**
 * @brief  通过USART3发送字符串（已禁用，USART3用于GPS）
 * @param  str: 要发送的字符串
 * @retval None
 */
static void DebugOutput_SendString(const char* str)
{
#if ENABLE_SYSTEM_MONITOR
  // USART3现在用于GPS接收，调试输出已禁用
  // 如需调试输出，请使用USART1或其他串口
  (void)str;  // 避免未使用参数警告
#endif
}

/**
 * @brief  输出系统监控统计信息
 * @retval None
 */
static void DebugOutput_PrintSystemStats(void)
{
#if ENABLE_SYSTEM_MONITOR
  char buffer[256];
  SystemMonitorStats_t sys_stats;
  SystemMonitor_GetStats(&sys_stats);
  
  // 打印基本统计信息
  snprintf(buffer, sizeof(buffer),
           "\r\n=== System Stats ===\r\n"
           "Total Samples: %lu\r\n"
           "Data Overflow: %lu\r\n",
           sys_stats.total_samples,
           sys_stats.data_overflow_count);
  DebugOutput_SendString(buffer);
  
  // 打印SD卡存储监控信息
  snprintf(buffer, sizeof(buffer),
           "=== SD Card Stats ===\r\n"
           "SD Write Count: %lu\r\n"
           "SD Write Errors: %lu\r\n"
           "SD Buffer Full: %lu\r\n"
           "SD Total Bytes: %lu\r\n"
           "SD File Count: %lu\r\n"
           "SD Data Dropped: %lu\r\n",
           sys_stats.sd_write_count,
           sys_stats.sd_write_error_count,
           sys_stats.sd_buffer_full_count,
           sys_stats.sd_total_bytes_written,
           sys_stats.sd_file_count,
           sys_stats.sd_data_dropped_count);
  DebugOutput_SendString(buffer);
  
  // 计算并打印统计指标
  if (sys_stats.sd_write_count > 0) {
    uint32_t avg_write_size = sys_stats.sd_total_bytes_written / sys_stats.sd_write_count;
    snprintf(buffer, sizeof(buffer),
             "Avg Write Size: %lu bytes\r\n",
             avg_write_size);
    DebugOutput_SendString(buffer);
  }

  if (sys_stats.sd_write_count + sys_stats.sd_write_error_count > 0) {
    uint32_t total_attempts = sys_stats.sd_write_count + sys_stats.sd_write_error_count;
    uint32_t error_rate = (sys_stats.sd_write_error_count * 100) / total_attempts;
    snprintf(buffer, sizeof(buffer),
             "Write Error Rate: %lu%%\r\n",
             error_rate);
    DebugOutput_SendString(buffer);
  }

  DebugOutput_SendString("====================\r\n");
#endif
}

/**
 * @brief  检查USB连接状态
 * @retval 1: USB已连接, 0: USB未连接
 */
static uint8_t CheckUSBConnectionStatus(void)
{
  // 通过检查USB设备状态来判断是否连接到PC
  extern USBD_HandleTypeDef hUsbDeviceFS;
  
  // 检查USB设备是否已配置（枚举完成）
  if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) {
    return 1; // USB已连接并配置
  }
  
  return 0; // USB未连接或未配置
}

/**
 * @brief  处理USB连接状态变化
 * @retval None
 */
static void HandleUSBConnectionChange(void)
{
  uint8_t current_usb_status = CheckUSBConnectionStatus();
  
  if (current_usb_status != g_usb_connected) {
    g_usb_connected = current_usb_status;
    
    if (g_usb_connected) {
      // USB连接：停止数据采集，卸载文件系统用于USB存储
      DebugOutput_SendString("USB Connected: Stopping data acquisition\r\n");
      
      // 停止数据记录
      StopRecording();
      
      // 卸载用于采样的文件系统
      UnmountFileSystemForSampling();

      while(1)
      {
    	  ;
      }

    } else {
      // USB断开：重新挂载文件系统，开始数据采集
      DebugOutput_SendString("USB Disconnected: Starting data acquisition\r\n");
      
      // 挂载文件系统用于数据采集
      if (MountFileSystemForSampling() == HAL_OK) {
        // 重新初始化数据存储
        if (DataStorage_Init(&g_data_storage) == HAL_OK) {
          StartRecording();
        }
      }
    }
  }
}

/**
 * @brief  为数据采集挂载文件系统
 * @retval HAL_OK: 成功, HAL_ERROR: 失败
 */
static HAL_StatusTypeDef MountFileSystemForSampling(void)
{
  extern FATFS SDFatFS;
  extern char SDPath[4];
  extern SD_HandleTypeDef hsd;
  BYTE work[_MAX_SS];
  
  if (g_fatfs_mounted_for_sampling) {
    return HAL_OK; // 已经挂载
  }
  
  // 初始化SD卡
  if (HAL_SD_Init(&hsd) != HAL_OK) {
    DebugOutput_SendString("SD card init failed\r\n");
    return HAL_ERROR;
  }
  
  // 目标格式参数：FAT32，簇大小32768字节（512字节/扇区 × 64扇区/簇）
  #define TARGET_CLUSTER_SIZE_BYTES  32768U
  #define TARGET_SECTOR_SIZE_BYTES   512U
  #define TARGET_SECTORS_PER_CLUSTER (TARGET_CLUSTER_SIZE_BYTES / TARGET_SECTOR_SIZE_BYTES)  // 64

  // 尝试挂载文件系统
  FRESULT mount_result = f_mount(&SDFatFS, SDPath, 1);
  
  uint8_t need_format = 0;

  if (mount_result == FR_OK) {
    // 挂载成功，验证文件系统类型和簇大小是否符合目标格式
    if (SDFatFS.fs_type != FS_FAT32) {
      DebugOutput_SendString("Not FAT32, reformatting...\r\n");
      f_mount(NULL, SDPath, 0);
      need_format = 1;
    } else if (SDFatFS.csize != TARGET_SECTORS_PER_CLUSTER) {
      DebugOutput_SendString("Cluster size mismatch, reformatting...\r\n");
      f_mount(NULL, SDPath, 0);
      need_format = 1;
    }
  } else if (mount_result == FR_NO_FILESYSTEM) {
    DebugOutput_SendString("No filesystem found, formatting...\r\n");
    need_format = 1;
  } else {
    DebugOutput_SendString("Mount failed with other error\r\n");
    return HAL_ERROR;
  }

  if (need_format) {
    FRESULT format_result = f_mkfs(SDPath, FM_FAT32, TARGET_CLUSTER_SIZE_BYTES, work, sizeof(work));

    if (format_result == FR_OK) {
      DebugOutput_SendString("Format successful, remounting...\r\n");
      mount_result = f_mount(&SDFatFS, SDPath, 1);

      if (mount_result != FR_OK) {
        DebugOutput_SendString("Remount after format failed\r\n");
        return HAL_ERROR;
      }
    } else {
      DebugOutput_SendString("Format failed\r\n");
      return HAL_ERROR;
    }
  }
  
  g_fatfs_mounted_for_sampling = 1;
  DebugOutput_SendString("Filesystem mounted for sampling\r\n");
  return HAL_OK;
}

/**
 * @brief  卸载用于数据采集的文件系统
 * @retval None
 */
static void UnmountFileSystemForSampling(void)
{
  extern FATFS SDFatFS;
  extern char SDPath[4];
  
  if (!g_fatfs_mounted_for_sampling) {
    return; // 已经卸载
  }
  
  // 卸载文件系统
  f_mount(NULL, SDPath, 0);
  g_fatfs_mounted_for_sampling = 0;
  
  DebugOutput_SendString("Filesystem unmounted for USB mode\r\n");
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  HAL_Delay(200);
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SDIO_SD_Init();
  MX_SPI1_Init();
  MX_SPI2_Init();
  MX_SPI3_Init();
  MX_USART1_UART_Init();
  MX_FATFS_Init();
  MX_USB_DEVICE_Init();
  MX_USART3_UART_Init();
  MX_TIM2_Init();
  MX_TIM1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */

  // 初始化系统监控
#if ENABLE_SYSTEM_MONITOR
  SystemMonitor_Init();
#endif

  // 初始化调试输出（含GPS）
  DebugOutput_Init();

  // 初始化光泵磁力仪接收（USART2 RX，115200）
  OpticMag_Init(&huart2);
  
  // 初始化配置管理器（设置默认值）
  Config_Init();
  
  // 初始化RS485通信
  RS485_Init(&huart1, RS485_DE_RE_PORT, RS485_DE_RE_PIN);
  
  // 初始化校正参数
  Init_CorrectionParams(&g_correction_params);
  Load_CorrectionParams_FromFlash(&g_correction_params);
  
  // 检查初始USB连接状态并相应初始化
  HAL_Delay(2000);
  g_usb_connected = CheckUSBConnectionStatus();
  if (!g_usb_connected) {
    // USB未连接，挂载文件系统用于数据采集
    if (MountFileSystemForSampling() == HAL_OK) {
#if CFG_LOAD_FROM_FILE
      Config_Load();
#endif
      // 初始化数据存储
      if (DataStorage_Init(&g_data_storage) == HAL_OK) {
        // 开始数据记录（如果存储功能已启用）
        if (Config_IsStorageEnabled()) {
          StartRecording();
        }
      }
    }
  } else {
    // USB已连接，不进行数据采集
    DebugOutput_SendString("USB connected at startup - data acquisition disabled\r\n");

    while(1)
    {
    	;
    }
  }

// #define NEED_FORMAT_SD
#ifdef NEED_FORMAT_SD
//  Raw_Hardware_Test();
  SDNAND_ForceFormat_and_Mount();
  Run_SDNAND_SpeedTest_V2();
  while(1)
  {
	  ;
  }
#endif

  // 启动TIM2定时器用于1ms周期的ADC数据处理
  if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK) {
    Error_Handler();
  }
  
  // 初始化LTC2508驱动
  if (LTC2508_Init(&hspi1, &hspi2, &hspi3) != LTC2508_OK) {
    Error_Handler();
  }

  // 输出时钟到ADC
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

  // 触发信号引脚初始化
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); 

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    // 定期任务
    uint32_t current_tick = HAL_GetTick();
    
    // USB连接状态检测 (每500ms检测一次)
    if (current_tick - g_last_usb_check >= 500) {
      HandleUSBConnectionChange();
      g_last_usb_check = current_tick;
    }
    
    // 处理数据存储后台任务 (轮询方式)
    // 优化：连续处理3次，加快缓冲区刷新速度
    if (g_recording_enabled) {
      // for (int i = 0; i < 3; i++) {
        DataStorage_ProcessBackgroundTasks(&g_data_storage);
      // }
    }
    
    // GPS数据处理
    GPS_Process();
    
    // 定期输出调试信息 (每1秒输出一次)
#if ENABLE_SYSTEM_MONITOR
    if (current_tick - g_last_debug_output >= DEBUG_OUTPUT_INTERVAL_MS) {
      DebugOutput_PrintSystemStats();
      g_last_debug_output = current_tick;
    }
#endif
    
    // 定期保存监控状态 (每1分钟保存一次)
#if ENABLE_SYSTEM_MONITOR
    if (current_tick - g_last_monitor_save >= MONITOR_SAVE_INTERVAL_MS) {
      SystemMonitor_SaveStatus();
      g_last_monitor_save = current_tick;
    }
#endif
    
    // ADC采样由PA1外部中断触发，不在主循环中触发
    // 可以在这里添加其他低优先级任务
  }
  
  // 停止数据记录
  StopRecording();

  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  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 = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  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;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/**
 * @brief  外部中断回调函数 - ADC数据就绪信号
 * @param  GPIO_Pin: 触发中断的GPIO引脚
 * @retval None
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	static uint32_t cnt = 0;
	if(LTC2508_IsInited() == 0) return;  
	cnt ++;
	  // if(cnt % 2 == 0)
	{
    // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
    if (GPIO_Pin == ADC_DRY_Pin) {
      // ADC数据就绪，触发DMA读取
      if(LTC2508_ERROR_TIMEOUT == LTC2508_TriggerDmaRead())
      {
          // 数据来不及处理
  #if ENABLE_SYSTEM_MONITOR
          SystemMonitor_ReportDataOverflow();
  #endif
      }
    }
    // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
	}
}

/**
 * @brief  SPI DMA传输完成回调函数
 * @param  hspi: SPI句柄指针
 * @retval None
 */
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
  // 调用LTC2508驱动的DMA完成回调
  LTC2508_DmaComplete_Callback(hspi);
}

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
  // 调用LTC2508驱动的DMA完成回调
  LTC2508_DmaComplete_Callback(hspi);
}

/**
 * @brief  SPI错误回调函数
 * @param  hspi: SPI句柄指针
 * @retval None
 */
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
  // 调用LTC2508驱动的错误回调
  LTC2508_ErrorCallback(hspi);
}

/**
 * @brief  TIM2回调函数 - 1ms定时器中断处理ADC数据
 * @param  htim: TIM句柄指针
 * @retval None
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2) {
        // ADC是4KHz采样率，定时器是8KHz
        // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
        ProcessAdcData();
        // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
    }
}

/**
 * @brief  UART传输完成回调函数
 * @param  huart: UART句柄指针
 * @retval None
 */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart == &huart1) {
    // RS485传输完成回调
    RS485_TxCpltCallback(huart);
  }
}

/**
 * @brief  UART接收完成回调函数
 * @param  huart: UART句柄指针
 * @retval None
 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart == &huart3) {
    GPS_UART_RxCpltCallback(huart);
  } else if (huart == &huart2) {
    OpticMag_UART_RxCpltCallback(huart);
  }
}

/**
 * @brief  UART错误回调函数
 * @param  huart: UART句柄指针
 * @retval None
 */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
  if (huart == &huart2) {
    OpticMag_UART_ErrorCallback(huart);
  }
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  
  // 停止所有DMA传输
  HAL_SPI_DMAStop(&hspi1);
  HAL_SPI_DMAStop(&hspi2);
  HAL_SPI_DMAStop(&hspi3);
  
  // 停止数据记录
  g_recording_enabled = 0;
  DataStorage_StopRecording(&g_data_storage);
  
  // 禁用中断并进入无限循环
  __disable_irq();
  while (1)
  {
    // 可以在这里添加LED指示或其他错误指示
    HAL_Delay(500);
  }
  /* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
