#include "Ultrasound.h"
TX_THREAD ultrasonic_task_handle;
TX_EVENT_FLAGS_GROUP ultrasonic_event;


extern TIM_HandleTypeDef htim2;

volatile uint32_t ic_val1 = 0; // 捕获值1
volatile uint32_t ic_val2 = 0; // 捕获值2
volatile uint8_t  is_first_capture = 0; // 是否为第一次捕获
volatile uint32_t distance_cm = 0;  // 距离按照 cm计算

/*******
对于 超声波的配置
Psc: 250 - 1  以达到   1tick = 1us的效果
*******/

/****

DWT的初始化  待确认

放到main.c中进行初始化
****/
void DWT_Init(void)
{
	CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
	DWT->CYCCNT = (uint32_t)0u; //新加入的
	DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}




/********
delay_us() 函数实现 (使用DWT)  待确认
*********/
void delay_us(uint32_t us)
{
	uint32_t start = DWT->CYCCNT;
	uint32_t ticks = us * (SystemCoreClock / 1000000U); // us * 64
	while((DWT->CYCCNT - start) < ticks);
}




/******
Trig 触发

 You only need to supply a short 10uS 
pulse to the trigger input to start the ranging

尤其在周期性测距中，如果前一个测距周期残留了 Trig 为高电平，可能导致错误测距或模块死机。因此加上 HAL_GPIO_WritePin(..., RESET); HAL_Delay(); 是一种保险写法。
******/
void HCSR04_Trigger(void)
{
	HAL_GPIO_WritePin(HC_Trig_GPIO_Port,HC_Trig_Pin,GPIO_PIN_RESET);
	delay_us(2);  //拉低2~5us
	HAL_GPIO_WritePin(HC_Trig_GPIO_Port,HC_Trig_Pin,GPIO_PIN_SET);
	delay_us(10); // 保持高电平10us 
	HAL_GPIO_WritePin(HC_Trig_GPIO_Port,HC_Trig_Pin,GPIO_PIN_RESET);
}


#ifdef TEST
void ultrasonic_task_entry(ULONG thread_input) {
    HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
	DWT_Init();
	
    while (1) {
        HCSR04_Trigger();

        ULONG events;
        if (tx_event_flags_get(&ultrasonic_event, EVENT_ECHO_DONE, TX_OR_CLEAR,
                               &events, TX_WAIT_FOREVER) == TX_SUCCESS) {
            if (distance_cm < 30) {
                tx_event_flags_set(&system_events,EVENT_OBSTACLE_DETECTED,TX_OR);// 执行避障处理：如振动、停机、语音提示等
				
            }
        }

        tx_thread_sleep(50);  // 每次测距间隔 50 ticks  20Hz 测距频率
    }
}
#endif






/*******
Echo 输入捕获回调函数

******/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) {
        if (is_first_capture == 0) {
            ic_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
            __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING);
            is_first_capture = 1;
        } else {
            ic_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
            __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
            is_first_capture = 0;

            uint32_t delta = (ic_val2 > ic_val1) ? (ic_val2 - ic_val1) : (0xFFFF - ic_val1 + ic_val2);
            distance_cm = delta / 58;

            // 通知任务 取消注释以唤醒测距线程
            tx_event_flags_set(&ultrasonic_event, EVENT_ECHO_DONE, TX_OR);
        }
    }
}

