pile_com_stm32/main_old/stm32/capture.c
2024-03-30 18:47:02 +08:00

154 lines
5.2 KiB
C

/*
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_check.h"
#include "soc/rtc.h"
#include "driver/mcpwm.h"
#include "driver/gpio.h"
const static char *TAG = "capture";
typedef struct capture_event
{
int ch;
uint32_t val;
} capture_event_t;
#define FLOW1_PIN_ECHO GPIO_NUM_39 // 捕获GPIO端口
#define FLOW2_PIN_ECHO GPIO_NUM_38 // 捕获GPIO端口
#define TRIGGER_THREAD_PRIORITY 5
typedef struct
{
uint32_t capture_signal;
mcpwm_capture_signal_t sel_cap_signal;
} capture;
static uint32_t cap_val_begin_of_flow1 = 0;
static uint32_t cap_val_end_of_flow1 = 0;
static uint32_t cap_val_begin_of_flow2 = 0;
static uint32_t cap_val_end_of_flow2 = 0;
// static xQueueHandle cap_queue;
extern uint32_t rtc_clk_apb_freq;
uint32_t volatile t15_ccr[2];
uint16_t volatile t15_ccr_times[2];
static bool flow1_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata,
void *arg)
{
// calculate the interval in the ISR,
// so that the interval will be always correct even when cap_queue is not handled in time and overflow.
BaseType_t high_task_wakeup = pdFALSE;
cap_val_end_of_flow1 = edata->cap_value;
capture_event_t cap_event = {.val = 0, .ch = 1};
cap_event.val = cap_val_end_of_flow1 - cap_val_begin_of_flow1;
t15_ccr_times[0] = cap_event.val * (1000000.0 / rtc_clk_apb_freq);
t15_ccr[0]++;
return high_task_wakeup == pdTRUE;
}
void capture_flow1_init()
{
ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM_CAP_1, FLOW1_PIN_ECHO));
// enable pull down CAP0, to reduce noise
ESP_ERROR_CHECK(gpio_pullup_en(FLOW1_PIN_ECHO));
// enable both edge capture on CAP0
mcpwm_capture_config_t conf = {
.cap_edge = MCPWM_NEG_EDGE,
.cap_prescale = 1,
.capture_cb = flow1_isr_handler, // 绑定流量捕获中断处理函数
.user_data = NULL};
ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_1, MCPWM_SELECT_CAP1, &conf));
mcpwm_set_frequency(MCPWM_UNIT_1, MCPWM_TIMER_1, 1000000);
int value = mcpwm_capture_signal_get_value(MCPWM_UNIT_1, MCPWM_SELECT_CAP1);
ESP_LOGI(TAG, "capture_flow_init value=%d", value);
}
static bool flow2_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata,
void *arg)
{
// calculate the interval in the ISR,
// so that the interval will be always correct even when cap_queue is not handled in time and overflow.
BaseType_t high_task_wakeup = pdFALSE;
cap_val_end_of_flow2 = edata->cap_value;
capture_event_t cap_event = {.val = 0, .ch = 2};
cap_event.val = cap_val_end_of_flow2 - cap_val_begin_of_flow2;
t15_ccr_times[1] = cap_event.val * (1000000.0 / rtc_clk_apb_freq);
t15_ccr[1]++;
// send measurement back though queue
// xQueueSendFromISR(cap_queue, &cap_event, &high_task_wakeup);
return high_task_wakeup == pdTRUE;
}
void capture_flow2_init()
{
ESP_ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM_CAP_2, FLOW2_PIN_ECHO));
// enable pull down CAP0, to reduce noise
ESP_ERROR_CHECK(gpio_pulldown_en(FLOW2_PIN_ECHO));
// enable both edge capture on CAP0
mcpwm_capture_config_t conf = {
.cap_edge = MCPWM_NEG_EDGE,
.cap_prescale = 1,
.capture_cb = flow2_isr_handler, // 绑定流量捕获中断处理函数
.user_data = NULL};
ESP_ERROR_CHECK(mcpwm_capture_enable_channel(MCPWM_UNIT_1, MCPWM_SELECT_CAP2, &conf));
mcpwm_set_frequency(MCPWM_UNIT_1, MCPWM_TIMER_2, 1000000);
// ESP_LOGI(TAG, "capture_flow_init");
}
// void capture_task(void)
// {
// while (true) {
// capture_event_t cap_event = {.val = 0, .ch = 1};
// uint32_t pulse_width_us = 0;
// // block and wait for new measurement
// // ESP_LOGI(TAG, "xQueueReceive started");
// xQueueReceive(cap_queue, &cap_event, portMAX_DELAY);
// // ESP_LOGI(TAG, "xQueueReceive after");
// // ESP_LOGI(TAG, " cap_event.val: %d, cap_event.ch : %d", cap_event.val, cap_event.ch);
// switch (cap_event.ch)
// {
// case 1: //flow1 capture
// pulse_width_us = cap_event.val * (1000000.0 / rtc_clk_apb_freq);
// ESP_LOGI(TAG, " (flow1 capture) Pulse width: %uus", pulse_width_us);
// break;
// case 2: //flow2 capture
// pulse_width_us = cap_event.val * (1000000.0 / rtc_clk_apb_freq);
// ESP_LOGI(TAG, "(flow2 capture) Pulse width: %uus", pulse_width_us);
// break;
// default: ESP_LOGI(TAG, " default\n");
// break;
// }
// }
// }
// void capture_depth_init();
// void pcnt_rotary_encoder_init(void);
void capture_init(void)
{
// cap_queue = xQueueCreate(3, sizeof(capture_event_t));
// if (cap_queue == NULL) {
// ESP_LOGE(TAG, "failed to alloc cap_queue");
// return;
// }
// capture_depth_init();
capture_flow1_init();
capture_flow2_init();
// start gcapture_task
// xTaskCreate(capture_task, "capture_task", 4096, NULL, TRIGGER_THREAD_PRIORITY, NULL);
// ESP_LOGI(TAG, "capture_task started");
// pcnt_rotary_encoder_init();
}