#include "HCBle.h"

/**
接收任务 未处理好

提示: 虽然 BLE 以及 GPS都是DMA+ UART接收，但是它们都有所不同
BLE --- DMA + IDLE 中断  循环 DMA + 空闲中断触发处理  UART IDLE  
GPS --- DMA +固定长度 + TC中断   设置固定长度 DMA    DMA传输完成中断

#{
  "lat": 23.123456,
  "lon": 113.654321,
  "angle": 95.0
}\n
**/

// 外部变量引入区

extern   UART_HandleTypeDef huart4;
extern DMA_HandleTypeDef handle_GPDMA1_Channel5;
extern DMA_HandleTypeDef handle_GPDMA1_Channel4;

/*
变量定义区
*/
char HC_Send_Data[128];
uint8_t HC_Recevie[RX_DataSize]; // 蓝牙接收缓存
volatile uint16_t rx_index = 0; //作为接收字符串指针
volatile uint8_t data_received = 0;  // 0 --- 未接收    1 --- 接收

uint8_t  rx_data;    //接收字符
// dma
uint8_t uart_dma_rx_buf[UART_DMA_RX_BUF_SIZE];
RingBuffer ble_rx_ring = {0}; //初始化
MotorCommand cmd;
BleMessage current_location = {0};
float imu_angle = 0.0f;

TX_EVENT_FLAGS_GROUP ble_event_flags;
#define BLE_EVENT_DATA_READY  0x01


void HCBle_InitEventFlags(void)
{	tx_event_flags_create(&ble_event_flags, "BLE Events");
	tx_event_flags_create(&system_events,"gps Events");
//	tx_event_flags_create(&sensor_events,"Sensor Events");
}

//初始化DMA接收函数
void HCBle_InitDMAReception(void)
{
	HAL_UARTEx_ReceiveToIdle_IT(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE);
//	HAL_UART_Receive_DMA(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE);
//	HAL_UARTEx_ReceiveToIdle_DMA(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE);
	// 只需要直接打开 串口空闲接收 
	// HAL_UARTEx_RxEventCallback --- 到时候会回调
}




// 发送数据
void HCBle_SendData(char *p,...)
{
	va_list ap;
	va_start(ap,p);
	vsprintf(HC_Send_Data,p,ap);
	va_end(ap);
// 编译控制
#ifdef DEBUG_EN
	//  信息输出接口
	HAL_UART_Transmit(&huart4,(uint8_t *)HC_Send_Data,strlen(HC_Send_Data),100);
// HAL_UART_Transmi(&huart1,(uint8_t *)formatBuf,strlen(formatBuf),1);
// 对于没有使用中断的串口发送，是需要加入一个阻塞的 
#else 
	HAL_UART_Transmit_DMA(&huart4, (uint8_t *)HC_Send_Data, strlen(HC_Send_Data));
#endif	
	
}
// 对于发送数据 可以加入一个DMA


// 我发现的问题 --- \n 被分开解析了 ，所以就一直进不了这个任务解析
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart->Instance == UART4)
    {
        for (uint16_t i = 0; i < Size; i++)
        {
            uint8_t ch = uart_dma_rx_buf[i];
            uint16_t next_head = (ble_rx_ring.head + 1) % RING_BUFFER_SIZE;

			if(next_head != ble_rx_ring.tail)
			{
				 ble_rx_ring.buffer[ble_rx_ring.head] = ch;
				 ble_rx_ring.head = next_head;
			}
        }

		tx_event_flags_set(&ble_event_flags, BLE_EVENT_DATA_READY, TX_OR);
        HAL_UARTEx_ReceiveToIdle_IT(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE);
    }
	else if(huart->Instance == USART2) // gps的接收任务
	{
		
		//		// 根据 Size 拷贝接收到的数据
		memcpy(GPS.GPS_Buffer,GPS_DMA_RX_BUF,Size);
		GPS.GPS_Buffer[Size] = '\0';
		GPS.isGetData = 1;  //数据接收标志位置为1
		
		tx_event_flags_set(&system_events, EVENT_GPS_DATA_READY, TX_OR);

		//重新开启接收
		HAL_UARTEx_ReceiveToIdle_IT(&huart2,GPS_DMA_RX_BUF,GPS_DMA_RX_BUF_LEN);
//		HAL_UARTEx_ReceiveToIdle_DMA(&huart2,GPS_DMA_RX_BUF,GPS_DMA_RX_BUF_LEN);
	}
	
}



// 已成功实现 Ble数值接收
void HCBle_ParseAndHandleFrame(const char *frame)
{
    int left, right;
    float lat, lon, angle;

    if (sscanf(frame, "#{\"leftSpeed\":%d,\"rightSpeed\":%d}$", &left, &right) == 2) {
        cmd.LeftSpeed = left;
        cmd.RightSpeed = right;
		
		// 这里先加入
		target_rpm_L = map_speed_to_rpm(cmd.LeftSpeed);
		target_rpm_R = map_speed_to_rpm(cmd.RightSpeed);

        HCBle_SendData("left=%d, right=%d\r\n", cmd.LeftSpeed, cmd.RightSpeed);
//		HCBle_SendData("left=%d, right=%d\r\n", left, right);
		DriveBOTH(cmd.LeftSpeed,cmd.RightSpeed); //驱动电机
//		DriveBOTH(cmd.LeftSpeed,cmd.RightSpeed);
        return;
    }



    HCBle_SendData("? 解析失败: %s\r\n", frame);
}




//为啥一直使用不了，就是一直再等待TX传输过来
// 在后台运行的一个线程；负责等待UART收到BLE数据后触发的事件，然后解析这些数据
void ble_rx_task_entry(ULONG thread_input)
{
    HCBle_InitDMAReception();

    ULONG actual_flags;
    static char json_buf[128];
    static int idx = 0;
    static int parsing = 0;

    while (1)
    {
        tx_event_flags_get(&ble_event_flags, BLE_EVENT_DATA_READY, TX_OR_CLEAR, &actual_flags, TX_WAIT_FOREVER);

        while (ble_rx_ring.tail != ble_rx_ring.head)
        {
            char c = ble_rx_ring.buffer[ble_rx_ring.tail];
            ble_rx_ring.tail = (ble_rx_ring.tail + 1) % RING_BUFFER_SIZE;

            if (!parsing) {
                if (c == '#') {
                    parsing = 1;
                    idx = 0;
                    json_buf[idx++] = c;
                }
                continue;
            }

            if (idx < sizeof(json_buf) - 1) {
                json_buf[idx++] = c;
                if (c == '$') {
                    json_buf[idx] = '\0';
                    HCBle_ParseAndHandleFrame(json_buf);
                    parsing = 0;
                    idx = 0;
                }
            } else {
                parsing = 0;
                idx = 0;
            }
        }
    }
}



// "#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.2f}\n",23.123456, 113.654321, 95.0);
//                 HCBle_SendData("#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.2f}\n", 
//                                  current_location.lat, current_location.lon, current_location.angle);
void ble_tx_task_entry(ULONG thread_input) {
	BleMessage msg;
    while(1) {

//        HCBle_SendData("#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.2f}\n",23.123456, 113.654321, 95.0);
//        tx_thread_sleep(500);
		if(tx_queue_receive(&ble_tx_queue,&msg,TX_WAIT_FOREVER) == TX_SUCCESS)
		{
			HCBle_SendData("#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.1f}\n", 
                              msg.lat, msg.lon,msg.angle);
			
		}
		tx_thread_sleep(100);
    }
}





