/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32l4xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 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 "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "string.h" // memset
#include "uType.h"
#include "cmsis_os.h"
#include "FreeRTOS.h"
#include "queue.h"
#include "circle_buffer.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
//extern volatile uint8_t uart1DataReady ;
//extern volatile uint8_t uart2DataReady ;
//extern volatile uint8_t uart3DataReady ;
extern uint8_t dataReceive1[BUFFER_SIZE];
extern uint8_t dataReceive2[BUFFER_SIZE2];
extern uint8_t uart2RXDATAbuffer[BUFFER_SIZE2];
extern uint8_t receiveBuff4G[BUFFER_SIZE4G];
extern uint8_t receiveBuff4G_MIPURC[BUFFER_SIZE4G];
circle_buf_t uart3CircleBuf;  // 环形缓冲区管理结构体
//circle_buf_t_2 uart3CircleBuf_2;  // 环形缓冲区2管理结构体

#define MAX_FRAME_SIZE 15  // 一帧最大 15 字节

uint8_t rx_len = 1;

extern bool DWIN_stopsend_flag; 
extern bool check_dwin_gas; // 轮流检查can和cloud的队列的标志位

extern int previous_actuator_state;
extern int previous_dwin_warning_state_level;

extern uint8_t DWIN_STARTSHOW_flag;
extern uint8_t DWIN_STARTSHOW_count;
extern osThreadId_t displayHandle; 
volatile uint16_t uart2RXHead = 0, uart2RXTail = 0;

extern QueueHandle_t uart2rxqueueHandle;
extern uint8_t temp_buffer[MAX_FRAME_SIZE];

/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
volatile uint32_t uart2_interrupt_count = 0;
volatile uint32_t uart3_interrupt_count = 0;
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
extern osMessageQueueId_t uart3rxqueueHandle;

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

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

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan1;
extern RTC_HandleTypeDef hrtc;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_usart3_rx;
extern DMA_HandleTypeDef hdma_usart3_tx;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
extern TIM_HandleTypeDef htim6;

/* USER CODE BEGIN EV */

/* USER CODE END EV */

/******************************************************************************/
/*           Cortex-M4 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable interrupt.
  */
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
		
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */

  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}

/**
  * @brief This function handles Prefetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */

  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */

  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32l4xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles RTC wake-up interrupt through EXTI line 20.
  */
void RTC_WKUP_IRQHandler(void)
{
  /* USER CODE BEGIN RTC_WKUP_IRQn 0 */

  /* USER CODE END RTC_WKUP_IRQn 0 */
  HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);
  /* USER CODE BEGIN RTC_WKUP_IRQn 1 */

  /* USER CODE END RTC_WKUP_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel2 global interrupt.
  */
void DMA1_Channel2_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel2_IRQn 0 */

  /* USER CODE END DMA1_Channel2_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart3_tx);
  /* USER CODE BEGIN DMA1_Channel2_IRQn 1 */

  /* USER CODE END DMA1_Channel2_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel3 global interrupt.
  */
void DMA1_Channel3_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel3_IRQn 0 */

  /* USER CODE END DMA1_Channel3_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart3_rx);
  /* USER CODE BEGIN DMA1_Channel3_IRQn 1 */

  /* USER CODE END DMA1_Channel3_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel4 global interrupt.
  */
void DMA1_Channel4_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel4_IRQn 0 */

  /* USER CODE END DMA1_Channel4_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart1_tx);
  /* USER CODE BEGIN DMA1_Channel4_IRQn 1 */

  /* USER CODE END DMA1_Channel4_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel5 global interrupt.
  */
void DMA1_Channel5_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel5_IRQn 0 */

  /* USER CODE END DMA1_Channel5_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart1_rx);
  /* USER CODE BEGIN DMA1_Channel5_IRQn 1 */

  /* USER CODE END DMA1_Channel5_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel6 global interrupt.
  */
void DMA1_Channel6_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */

  /* USER CODE END DMA1_Channel6_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_rx);
  /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */

  /* USER CODE END DMA1_Channel6_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel7 global interrupt.
  */
void DMA1_Channel7_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel7_IRQn 0 */

  /* USER CODE END DMA1_Channel7_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_tx);
  /* USER CODE BEGIN DMA1_Channel7_IRQn 1 */

  /* USER CODE END DMA1_Channel7_IRQn 1 */
}

/**
  * @brief This function handles CAN1 TX interrupt.
  */
void CAN1_TX_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_TX_IRQn 0 */

  /* USER CODE END CAN1_TX_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_TX_IRQn 1 */

  /* USER CODE END CAN1_TX_IRQn 1 */
}

/**
  * @brief This function handles CAN1 RX0 interrupt.
  */
void CAN1_RX0_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_RX0_IRQn 0 */

  /* USER CODE END CAN1_RX0_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_RX0_IRQn 1 */

	__HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
	
  /* USER CODE END CAN1_RX0_IRQn 1 */
}

/**
  * @brief This function handles EXTI line[9:5] interrupts.
  */
void EXTI9_5_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI9_5_IRQn 0 */

  /* USER CODE END EXTI9_5_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
  /* USER CODE BEGIN EXTI9_5_IRQn 1 */

  /* USER CODE END EXTI9_5_IRQn 1 */
}

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

	if(__HAL_UART_GET_FLAG(&huart1 , UART_FLAG_IDLE)!= RESET)
	{
		
		__HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除IDLE标志
		HAL_UART_DMAStop(&huart1); // 关闭 DMA

    uint32_t uart1_rx_len = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx);// 计算接收长度
		dataReceive1[uart1_rx_len] = '\0'; // 添加字符串结束符

    parse_uart1_command(dataReceive1);  // 解析串口指令
		HAL_UART_Receive_DMA(&huart1, dataReceive1, BUFFER_SIZE);
		
	}
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

	uint32_t temp;

	if(__HAL_UART_GET_FLAG(&huart2 , UART_FLAG_IDLE)!= RESET)
	{		

		__HAL_UART_CLEAR_IDLEFLAG(&huart2); 

		HAL_UART_DMAStop(&huart2);
		
		temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
		rx_len =  BUFFER_SIZE2 - temp;

//		if(rx_len == 9 || rx_len ==15 || rx_len ==27 ){	
			if(rx_len > 7){			
			HAL_UART_RxCpltCallback(&huart2);  // 调用回调函数			
		}

		HAL_UART_Receive_DMA(&huart2, dataReceive2, BUFFER_SIZE2);
		
	}
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

/**
  * @brief This function handles USART3 global interrupt.
  */
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
	uart3_dma_idle_CircleBufhandler(); 
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}

/**
  * @brief This function handles TIM6 global interrupt, DAC channel1 and channel2 underrun error interrupts.
  */
void TIM6_DAC_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */

  /* USER CODE END TIM6_DAC_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */

  /* USER CODE END TIM6_DAC_IRQn 1 */
}

/* USER CODE BEGIN 1 */
void uart3_dma_idle_CircleBufhandler(void)
{	
	static uint16_t last_dma_pos = 0; // 记录上次 DMA 停止的位置
  uint16_t current_dma_pos, recvLength = 0;
	Uart3Rx_msg uart3_msg;	
	
	
	if(__HAL_UART_GET_FLAG(&huart3 , UART_FLAG_IDLE)!= RESET)
	{
		__HAL_UART_CLEAR_FLAG(&huart3, UART_FLAG_IDLE); // 清除 IDLE 标志

		// 计算当前 DMA 传输到的位置
    current_dma_pos = BUFFER_SIZE4G - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
        
		// 计算这次 IDLE 触发后接收到的数据长度
		if (current_dma_pos >= last_dma_pos)
		{
				recvLength = current_dma_pos - last_dma_pos;
		}
		else
		{
				recvLength = (BUFFER_SIZE4G - last_dma_pos) + current_dma_pos;
		}
//		printf("recvLength = %d\r\n", recvLength);
		if (recvLength > 0) 
    {
			if (recvLength < 256)
			{
				uart3_msg.length = recvLength;
//				memcpy(uart3_msg.data, receiveBuff4G + last_dma_pos, recvLength);
				for (uint16_t i = 0; i < recvLength; i++)
				{
						uart3_msg.data[i] = receiveBuff4G[(last_dma_pos + i) % BUFFER_SIZE4G];
//						printf("uart3_msg.data[%d] %c (0x%02X)\r\n", i, uart3_msg.data[i], uart3_msg.data[i]);
				}
				BaseType_t xHigherPriorityTaskWoken = pdFALSE;
				if (xQueueSendToBackFromISR(uart3rxqueueHandle, &uart3_msg, &xHigherPriorityTaskWoken) != pdPASS) 
				{
						Uart3Rx_msg discard_msg;
						xQueueReceiveFromISR(uart3rxqueueHandle, &discard_msg, &xHigherPriorityTaskWoken);
						xQueueSendToBackFromISR(uart3rxqueueHandle, &uart3_msg, &xHigherPriorityTaskWoken);
				}
			}
      // 把数据存入环形缓冲区
			for (uint16_t i = 0; i < recvLength; i++)
			{
//				uint8_t val = receiveBuff4G[(last_dma_pos + i) % BUFFER_SIZE4G];
//				printf("DMA data[%d]: 0x%02X\r\n", i, val);
					circle_buf_write(&uart3CircleBuf, receiveBuff4G[(last_dma_pos + i) % BUFFER_SIZE4G]);	
			}
			
		}
		// 更新 DMA 读取的最后位置
    last_dma_pos = current_dma_pos;

		HAL_UART_Receive_DMA(&huart3, receiveBuff4G, BUFFER_SIZE4G);

		
	}
}

void parse_uart1_command(uint8_t *buf)
{
    //  AT+READFLASH=0,10\r\n 读取外部flash内容
    if (strncmp((char*)buf, "AT+READFLASH=", 13) == 0)
    {
        int start, end;
        if (sscanf((char*)buf + 13, "%d,%d", &start, &end) == 2)
        {
            print_flash_pages(start, end);
        }
        else
        {
            printf("AT Error\r\n");
        }
    }
		//  AT+VERSION?\r\n 读取软件版本号
    if (strncmp((char*)buf, "AT+VERSION?", 11) == 0)
    {
        Load_version_From_Flash();
    }
		//  AT+ERASEFLASH\r\n 擦除外部flash
    if (strncmp((char*)buf, "AT+ERASEFLASH", 13) == 0)
    {
        flash_clear_all_data();
    }
}


void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART2)
    {
        __HAL_UART_CLEAR_PEFLAG(huart);  // 清除错误标志
        HAL_UART_Receive_DMA(&huart2, dataReceive2, BUFFER_SIZE2);  // 重启接收
    }
}



/* USER CODE END 1 */
