Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*===================================================================================================*/
- // Counter_esp32_example.ino --> https://github.com/DavidAntliff/esp32-freqcount/pull/3/files
- // Frequency-count.c --> https://github.com/DavidAntliff/esp32-freqcount/pull/3/files
- // Frequency-count.h --> https://github.com/DavidAntliff/esp32-freqcount/tree/master/include
- // Funciona alterando a linha 176 para enable
- // Esta linha libera a contagem se controle
- // Estudar a liberacao do port RMT
- /*===================================================================================================*/
- #include "frequency_count.h"
- #define TAG "app"
- char message[200];
- #define CONFIG_FREQ_SIGNAL_GPIO 23
- #define CONFIG_SAMPLING_WINDOW_GPIO 2
- #define GPIO_SIGNAL_INPUT ((gpio_num_t)CONFIG_FREQ_SIGNAL_GPIO)
- #define GPIO_RMT_GATE (CONFIG_SAMPLING_WINDOW_GPIO)
- #define GPIO_LED (25) //CONFIG_LED_GPIO)
- // internal signals for GPIO constant levels
- #define GPIO_CONSTANT_LOW 0x30
- #define GPIO_CONSTANT_HIGH 0x38
- #define PCNT_UNIT (PCNT_UNIT_0)
- #define PCNT_CHANNEL (PCNT_CHANNEL_0)
- #define RMT_CHANNEL (RMT_CHANNEL_0)
- #define RMT_MAX_BLOCKS (2) // allow up to 2 * 64 * (2 * 32767) RMT periods in window
- //#define RMT_CLK_DIV 160 // results in 2us steps (80MHz / 160 = 0.5 MHz
- //#define RMT_CLK_DIV 20 // results in 0.25us steps (80MHz / 20 = 4 MHz
- #define RMT_CLK_DIV 1 // results in 25ns steps (80MHz / 2 / 1 = 40 MHz)
- #define SAMPLE_PERIOD 1.2 // seconds
- // The counter is signed 16-bit, so maximum positive value is 32767
- // The filter is unsigned 10-bit, maximum value is 1023. Use full period of maximum frequency.
- // For higher expected frequencies, the sample period and filter must be reduced.
- // suitable up to 16,383.5 Hz
- //#define WINDOW_DURATION 1.0 // seconds
- //#define FILTER_LENGTH 1023 // APB @ 80MHz, limits to < 39,100 Hz
- // suitable up to 163,835 Hz
- //#define WINDOW_DURATION 0.1 // seconds
- //#define FILTER_LENGTH 122 // APB @ 80MHz, limits to < 655,738 Hz
- // suitable up to 1,638,350 Hz
- //#define WINDOW_DURATION 0.01 // seconds
- //#define FILTER_LENGTH 12 // APB @ 80MHz, limits to < 3,333,333 Hz
- // suitable up to 16,383,500 Hz - no filter
- //#define WINDOW_DURATION 0.001 // seconds
- //#define FILTER_LENGTH 1 // APB @ 80MHz, limits to < 40 MHz
- // suitable up to 163,835,000 Hz - no filter
- #define WINDOW_DURATION 0.0001 // seconds
- #define FILTER_LENGTH 0 // APB @ 80MHz, limits to < 40 MHz
- //--------------------------------------------------------------------------------
- static void window_start_callback(void)
- {
- ESP_LOGI(TAG, "Begin sampling");
- gpio_matrix_in(GPIO_SIGNAL_INPUT, SIG_IN_FUNC228_IDX, false);
- }
- //--------------------------------------------------------------------------------
- static volatile double frequency;
- static void frequency_callback(double hz)
- {
- gpio_matrix_in(GPIO_CONSTANT_LOW, SIG_IN_FUNC228_IDX, false);
- frequency = hz;
- ESP_LOGI(TAG, "Frequency %f Hz", hz);
- }
- //--------------------------------------------------------------------------------
- static void config_led(void)
- {
- gpio_pad_select_gpio(GPIO_LED);
- gpio_set_direction((gpio_num_t)GPIO_LED, GPIO_MODE_OUTPUT);
- // route incoming frequency signal to onboard LED when sampling
- gpio_matrix_out(GPIO_LED, SIG_IN_FUNC228_IDX, false, false);
- }
- //--------------------------------------------------------------------------------
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Frequency counter starting");
- delay(500);
- config_led();
- frequency_count_configuration_t * config = (frequency_count_configuration_t*)malloc(sizeof(*config));
- config->pcnt_gpio = GPIO_SIGNAL_INPUT;
- config->pcnt_unit = PCNT_UNIT;
- config->pcnt_channel = PCNT_CHANNEL;
- config->rmt_gpio = (gpio_num_t)GPIO_RMT_GATE;
- config->rmt_channel = RMT_CHANNEL;
- config->rmt_clk_div = RMT_CLK_DIV;
- config->rmt_max_blocks = RMT_MAX_BLOCKS;
- config->sampling_period_seconds = SAMPLE_PERIOD;
- config->sampling_window_seconds = WINDOW_DURATION;
- config->filter_length = FILTER_LENGTH;
- config->window_start_callback = &window_start_callback;
- config->frequency_update_callback = &frequency_callback;
- // task takes ownership of allocated memory
- xTaskCreate(&frequency_count_task_function, "frequency_count_task", 4096, config, 5, NULL);
- }
- //--------------------------------------------------------------------------------
- void loop() {
- sprintf(message, "F=%9.0f Hz", frequency);
- Serial.println(message);
- delay(100);
- }
- //--------------------------------------------------------------------------------
- static void init_rmt(gpio_num_t tx_gpio, rmt_channel_t channel, uint8_t clk_div)
- {
- ESP_LOGD(TAG, "%s", __FUNCTION__);
- rmt_config_t rmt_tx;
- rmt_tx.rmt_mode = RMT_MODE_TX;
- rmt_tx.channel = channel;
- rmt_tx.gpio_num = tx_gpio;
- rmt_tx.mem_block_num = 1; // single block
- rmt_tx.clk_div = clk_div;
- rmt_tx.tx_config.loop_en = false;
- rmt_tx.tx_config.carrier_en = false;
- rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
- rmt_tx.tx_config.idle_output_en = true;
- ESP_ERROR_CHECK(rmt_config(&rmt_tx));
- ESP_ERROR_CHECK(rmt_driver_install(rmt_tx.channel, 0, 0));
- }
- //-------------------------------------------------------------------------------------------------------------------------
- static int create_rmt_window(rmt_item32_t * items, double sampling_window_seconds, double rmt_period)
- {
- ESP_LOGD(TAG, "%s", __FUNCTION__);
- int num_items = 0;
- // enable counter for exactly x seconds:
- int32_t total_duration = (uint32_t)(sampling_window_seconds / rmt_period);
- ESP_LOGD(TAG, "total_duration %f seconds = %d * %g seconds", sampling_window_seconds, total_duration, rmt_period);
- // max duration per item is 2^15-1 = 32767
- while (total_duration > 0)
- {
- uint32_t duration = total_duration > 32767 ? 32767 : total_duration;
- items[num_items].level0 = 1;
- items[num_items].duration0 = duration;
- total_duration -= duration;
- ESP_LOGD(TAG, "duration %d", duration);
- if (total_duration > 0)
- {
- uint32_t duration = total_duration > 32767 ? 32767 : total_duration;
- items[num_items].level1 = 1;
- items[num_items].duration1 = duration;
- total_duration -= duration;
- }
- else
- {
- items[num_items].level1 = 0;
- items[num_items].duration1 = 0;
- }
- ESP_LOGD(TAG, "[%d].level0 %d", num_items, items[num_items].level0);
- ESP_LOGD(TAG, "[%d].duration0 %d", num_items, items[num_items].duration0);
- ESP_LOGD(TAG, "[%d].level1 %d", num_items, items[num_items].level1);
- ESP_LOGD(TAG, "[%d].duration1 %d", num_items, items[num_items].duration1);
- ++num_items;
- }
- ESP_LOGD(TAG, "num_items %d", num_items);
- return num_items;
- }
- //----------------------------------------------------------------------------------------------
- static void init_pcnt(gpio_num_t pulse_gpio, uint8_t ctrl_gpio, pcnt_unit_t unit, pcnt_channel_t channel, uint16_t filter_length)
- {
- ESP_LOGD(TAG, "%s", __FUNCTION__);
- // set up counter
- pcnt_config_t pcnt_config = {
- .pulse_gpio_num = pulse_gpio,
- .ctrl_gpio_num = ctrl_gpio,
- .lctrl_mode = PCNT_MODE_KEEP, // <<<<<<<<<<<
- .hctrl_mode = PCNT_MODE_KEEP,
- .pos_mode = PCNT_COUNT_INC, // count both rising and falling edges
- .neg_mode = PCNT_COUNT_INC,
- .counter_h_lim = 0,
- .counter_l_lim = 0,
- .unit = unit,
- .channel = channel,
- };
- ESP_ERROR_CHECK(pcnt_unit_config(&pcnt_config));
- // set the GPIO back to high-impedance, as pcnt_unit_config sets it as pull-up
- ESP_ERROR_CHECK(gpio_set_pull_mode(pulse_gpio, GPIO_FLOATING));
- // enable counter filter - at 80MHz APB CLK, 1000 pulses is max 80,000 Hz, so ignore pulses less than 12.5 us.
- ESP_ERROR_CHECK(pcnt_set_filter_value(unit, filter_length));
- ESP_ERROR_CHECK(pcnt_filter_enable(unit));
- }
- //-------------------------------------------------------------------------------------------------------------------------
- void frequency_count_task_function(void * pvParameter)
- {
- frequency_count_configuration_t configuration;
- assert(pvParameter);
- ESP_LOGI(TAG, "Core ID %d", xPortGetCoreID());
- configuration = *(frequency_count_configuration_t*)pvParameter;
- frequency_count_configuration_t *task_inputs = &configuration;
- ESP_LOGI(TAG, "pcnt_gpio %d, pcnt_unit %d, pcnt_channel %d, rmt_gpio %d, rmt_clk_div %d, sampling_period_seconds %f, sampling_window_seconds %f, filter_length %d",
- task_inputs->pcnt_gpio,
- task_inputs->pcnt_unit,
- task_inputs->pcnt_channel,
- task_inputs->rmt_gpio,
- task_inputs->rmt_clk_div,
- task_inputs->sampling_period_seconds,
- task_inputs->sampling_window_seconds,
- task_inputs->filter_length);
- init_rmt(task_inputs->rmt_gpio, task_inputs->rmt_channel, task_inputs->rmt_clk_div);
- init_pcnt(task_inputs->pcnt_gpio, task_inputs->rmt_gpio, task_inputs->pcnt_unit, task_inputs->pcnt_channel, task_inputs->filter_length);
- // assuming 80MHz APB clock
- const double rmt_period = (double)(task_inputs->rmt_clk_div) / 80000000.0;
- const size_t items_size = RMT_MEM_BLOCK_BYTE_NUM * task_inputs->rmt_max_blocks;
- rmt_item32_t * rmt_items = (rmt_item32_t *) malloc(items_size);
- assert(rmt_items);
- memset(rmt_items, 0, items_size);
- int num_rmt_items = create_rmt_window(rmt_items, task_inputs->sampling_window_seconds, rmt_period);
- assert(num_rmt_items <= task_inputs->rmt_max_blocks * RMT_MEM_ITEM_NUM);
- TickType_t last_wake_time = xTaskGetTickCount();
- Serial.print(" items_size "); Serial.println(items_size );
- printf(" rmt_items: %d\n", *rmt_items);
- Serial.print(" num_rmt_items "); Serial.println(num_rmt_items );
- double frequency_hz;
- while (1)
- {
- last_wake_time = xTaskGetTickCount();
- //Serial.println(last_wake_time); /// <<<<<<<<<<<<<<<<
- // clear counter
- ESP_ERROR_CHECK(pcnt_counter_clear(task_inputs->pcnt_unit));
- // start sampling window
- ESP_ERROR_CHECK(rmt_write_items(task_inputs->rmt_channel, rmt_items, num_rmt_items, false));
- // call wndow-start callback if set
- if (task_inputs->window_start_callback)
- {
- (task_inputs->window_start_callback)();
- }
- // wait for window to finish
- ESP_ERROR_CHECK(rmt_wait_tx_done(task_inputs->rmt_channel, portMAX_DELAY));
- // read counter
- int16_t count = 0;
- ESP_ERROR_CHECK(pcnt_get_counter_value(task_inputs->pcnt_unit, &count));
- // TODO: check for overflow?
- //frequency_hz = count;
- frequency_hz = (count >> 1) / task_inputs->sampling_window_seconds;
- // call the frequency update callback
- if (task_inputs->frequency_update_callback)
- {
- (task_inputs->frequency_update_callback)(frequency_hz);
- }
- ESP_LOGD(TAG, "counter %d, frequency %f Hz", count, frequency_hz);
- int delay_time = task_inputs->sampling_period_seconds * 1000 / portTICK_PERIOD_MS;
- if (delay_time > 0)
- {
- vTaskDelayUntil(&last_wake_time, delay_time);
- }
- }
- free(rmt_items);
- free(task_inputs); // TODO: avoid this if not dynamically allocated
- vTaskDelete(NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement