| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * this case is used for test PCNT | 
					
						
							|  |  |  |  * prepare job for test environment UT_T1_PCNT: | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |  * We use internal signals instead of external wiring, but please keep the following IO connections, or connect nothing to prevent the signal from being disturbed. | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |  *  1. prepare one ESP-WROOM-32 board and connect it to PC. | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |  *  2. connect GPIO21 with GPIO4 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |  *  3. GPIO5 connect to 3.3v | 
					
						
							|  |  |  |  *  4. GPIO19 connect to GND | 
					
						
							|  |  |  |  *  5. logic analyzer will help too if possible | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * the GPIO18 is the pulse producer, the GPIO4 is the input GPIO | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							|  |  |  | #include "freertos/task.h"
 | 
					
						
							|  |  |  | #include "freertos/queue.h"
 | 
					
						
							| 
									
										
										
										
											2020-10-12 14:23:49 +08:00
										 |  |  | #include "soc/soc_caps.h"
 | 
					
						
							|  |  |  | #if SOC_PCNT_SUPPORTED
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | #include "driver/periph_ctrl.h"
 | 
					
						
							|  |  |  | #include "driver/gpio.h"
 | 
					
						
							|  |  |  | #include "driver/pcnt.h"
 | 
					
						
							|  |  |  | #include "driver/ledc.h"
 | 
					
						
							|  |  |  | #include "esp_attr.h"
 | 
					
						
							|  |  |  | #include "esp_log.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-13 18:02:45 +08:00
										 |  |  | #include "soc/gpio_periph.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | #include "unity.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-19 12:00:58 +08:00
										 |  |  | #include "esp_rom_gpio.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | #define PULSE_IO 21
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | #define PCNT_INPUT_IO 4
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | #define PCNT_CTRL_VCC_IO 5
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | #define PCNT_CTRL_GND_IO 19
 | 
					
						
							|  |  |  | #define HIGHEST_LIMIT 10
 | 
					
						
							|  |  |  | #define LOWEST_LIMIT 0
 | 
					
						
							|  |  |  | #define MAX_THRESHOLD 5
 | 
					
						
							|  |  |  | #define MIN_THRESHOLD 0
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | #define PCNT_CTRL_HIGH_LEVEL 1
 | 
					
						
							|  |  |  | #define PCNT_CTRL_LOW_LEVEL 0
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | static xQueueHandle pcnt_evt_queue = NULL; | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     int zero_times; | 
					
						
							|  |  |  |     int h_limit; | 
					
						
							|  |  |  |     int l_limit; | 
					
						
							|  |  |  |     int h_threshold; | 
					
						
							|  |  |  |     int l_threshold; | 
					
						
							|  |  |  |     int filter_time; | 
					
						
							|  |  |  | } event_times; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | static void pcnt_test_io_config(int ctrl_level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Connect internal signals using IO matrix.
 | 
					
						
							|  |  |  |     gpio_set_direction(PULSE_IO, GPIO_MODE_INPUT_OUTPUT); | 
					
						
							| 
									
										
										
										
											2020-06-19 12:00:58 +08:00
										 |  |  |     esp_rom_gpio_connect_out_signal(PULSE_IO, LEDC_LS_SIG_OUT1_IDX, 0, 0); // LEDC_TIMER_1, LEDC_LOW_SPEED_MODE
 | 
					
						
							|  |  |  |     esp_rom_gpio_connect_in_signal(PULSE_IO, PCNT_SIG_CH0_IN0_IDX, 0); // PCNT_UNIT_0, PCNT_CHANNEL_0
 | 
					
						
							|  |  |  |     esp_rom_gpio_connect_in_signal(ctrl_level ? GPIO_MATRIX_CONST_ONE_INPUT: GPIO_MATRIX_CONST_ZERO_INPUT, PCNT_CTRL_CH0_IN0_IDX, 0); // PCNT_UNIT_0, PCNT_CHANNEL_0
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | /* use LEDC to produce pulse for PCNT
 | 
					
						
							|  |  |  |  * the frequency of LEDC is 1000, so every second will get 1000 count values | 
					
						
							|  |  |  |  * the PCNT count the LEDC pulse | 
					
						
							|  |  |  |  * */ | 
					
						
							|  |  |  | static void produce_pulse(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ledc_timer_config_t ledc_timer = { | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |         .speed_mode = LEDC_LOW_SPEED_MODE, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         .timer_num  = LEDC_TIMER_1, | 
					
						
							|  |  |  |         .duty_resolution = LEDC_TIMER_10_BIT, | 
					
						
							|  |  |  |         .freq_hz = 1, | 
					
						
							| 
									
										
										
										
											2018-11-01 12:23:11 +08:00
										 |  |  |         .clk_cfg = LEDC_AUTO_CLK, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2019-08-11 15:48:17 +10:00
										 |  |  |     ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ledc_channel_config_t ledc_channel = { | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |         .speed_mode = LEDC_LOW_SPEED_MODE, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         .channel = LEDC_CHANNEL_1, | 
					
						
							|  |  |  |         .timer_sel = LEDC_TIMER_1, | 
					
						
							|  |  |  |         .intr_type = LEDC_INTR_DISABLE, | 
					
						
							|  |  |  |         .gpio_num = PULSE_IO, | 
					
						
							|  |  |  |         .duty = 100, | 
					
						
							|  |  |  |         .hpoint = 0, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2019-08-11 15:48:17 +10:00
										 |  |  |     ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void IRAM_ATTR pcnt_intr_handler(void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t intr_status = PCNT.int_st.val; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     uint32_t status; | 
					
						
							|  |  |  |     BaseType_t port_status = pdFALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < PCNT_UNIT_MAX; i++) { | 
					
						
							|  |  |  |         if (intr_status & (BIT(i))) { | 
					
						
							|  |  |  |             status = PCNT.status_unit[i].val; | 
					
						
							|  |  |  |             PCNT.int_clr.val = BIT(i); | 
					
						
							|  |  |  |             xQueueSendFromISR(pcnt_evt_queue, &status, &port_status); | 
					
						
							|  |  |  |             if (port_status == pdTRUE) { | 
					
						
							|  |  |  |                 portYIELD_FROM_ISR(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void event_calculate(event_times* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int16_t test_counter = 0; | 
					
						
							|  |  |  |     int times = 0; | 
					
						
							|  |  |  |     BaseType_t port_status; | 
					
						
							|  |  |  |     uint32_t status = 0; | 
					
						
							|  |  |  |     while (times < 10) { | 
					
						
							|  |  |  |         port_status = xQueueReceive(pcnt_evt_queue, &status, 1000 / portTICK_PERIOD_MS); | 
					
						
							|  |  |  |         if (port_status == pdTRUE) { | 
					
						
							|  |  |  |             event->filter_time++; | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |             printf("Current counter value :%d\n", test_counter); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |             if (status & PCNT_EVT_THRES_1) { | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |                 printf("THRES1 EVT\n"); | 
					
						
							|  |  |  |                 event->h_threshold++; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |             if (status & PCNT_EVT_THRES_0) { | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |                 printf("THRES0 EVT\n"); | 
					
						
							|  |  |  |                 event->l_threshold++; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |             if (status & PCNT_EVT_L_LIM) { | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |                 printf("L_LIM EVT\n"); | 
					
						
							|  |  |  |                 event->l_limit++; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |             if (status & PCNT_EVT_H_LIM) { | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |                 printf("H_LIM EVT\n"); | 
					
						
							|  |  |  |                 event->h_limit++; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |             if (status & PCNT_EVT_ZERO) { | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |                 printf("ZERO EVT\n"); | 
					
						
							|  |  |  |                 event->zero_times++; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |             printf("Current counter value :%d\n", test_counter); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         times++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     printf("%d, %d, %d, %d, %d, %d\n", event->h_threshold, event->l_threshold, | 
					
						
							|  |  |  |             event->l_limit, event->h_limit, event->zero_times, event->filter_time); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * There exist 2 kind of counting methods: positive and negative counting method | 
					
						
							|  |  |  |  * 1. when control IO is high level, PCNT is positive counting mode | 
					
						
							|  |  |  |  * 2. when control IO is low level, PCNT is positive negative mode | 
					
						
							|  |  |  |  * the positive method standard is as below: | 
					
						
							|  |  |  |  *   ---------------------------------------------------------------------------------- | 
					
						
							|  |  |  |  *   POS_ MODE | LCTRL_ MODE | HCTRL_ MODE | sig l→h when ctrl=0 | sig l→h when ctrl=1 | 
					
						
							|  |  |  |  *   NEG_ MODE |             |             |                     | | 
					
						
							|  |  |  |  *   =================================================================================== | 
					
						
							|  |  |  |  *   1 (inc)   | 0 (-)       | 0 (-)       | Inc ctr             | Inc ctr | 
					
						
							|  |  |  |  *   2 (dec)   | 0 (-)       | 0 (-)       | Dec ctr             | Dec ctr | 
					
						
							|  |  |  |  *   0 (-)     | x           | x           | No action           | No action | 
					
						
							|  |  |  |  *   1 (inc)   | 0 (-)       | 1 (inv)     | Inc ctr             | Dec ctr | 
					
						
							|  |  |  |  *   1 (inc)   | 1 (inv)     | 0 (-)       | Dec ctr             | Inc ctr | 
					
						
							|  |  |  |  *   2 (dec)   | 0 (-)       | 1 (inv)     | Dec ctr             | Inc ctr | 
					
						
							|  |  |  |  *   1 (inc)   | 0 (-)       | 2 (dis)     | Inc ctr             | No action | 
					
						
							|  |  |  |  *   1 (inc)   | 2 (dis)     | 0 (-)       | No action           | Inc ctr | 
					
						
							|  |  |  |  *  ----------------------------------------------------------------------------------- | 
					
						
							|  |  |  |  * */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void count_mode_test(gpio_num_t ctl_io) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int16_t test_counter; | 
					
						
							|  |  |  |     //produce pulse, 100HZ
 | 
					
						
							|  |  |  |     ledc_timer_config_t ledc_timer = { | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |         .speed_mode = LEDC_LOW_SPEED_MODE, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         .timer_num  = LEDC_TIMER_1, | 
					
						
							|  |  |  |         .duty_resolution = LEDC_TIMER_10_BIT, | 
					
						
							|  |  |  |         .freq_hz = 100, | 
					
						
							| 
									
										
										
										
											2018-11-01 12:23:11 +08:00
										 |  |  |         .clk_cfg = LEDC_AUTO_CLK, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     }; | 
					
						
							|  |  |  |     ledc_timer_config(&ledc_timer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ledc_channel_config_t ledc_channel = { | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |         .speed_mode = LEDC_LOW_SPEED_MODE, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         .channel = LEDC_CHANNEL_1, | 
					
						
							|  |  |  |         .timer_sel = LEDC_TIMER_1, | 
					
						
							|  |  |  |         .intr_type = LEDC_INTR_DISABLE, | 
					
						
							|  |  |  |         .gpio_num = PULSE_IO, | 
					
						
							|  |  |  |         .duty = 100, | 
					
						
							|  |  |  |         .hpoint = 0, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     ledc_channel_config(&ledc_channel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pcnt_config_t pcnt_config = { | 
					
						
							|  |  |  |         .pulse_gpio_num = PCNT_INPUT_IO, | 
					
						
							|  |  |  |         .ctrl_gpio_num = ctl_io, | 
					
						
							|  |  |  |         .channel = PCNT_CHANNEL_0, | 
					
						
							|  |  |  |         .unit = PCNT_UNIT_0, | 
					
						
							|  |  |  |         .pos_mode = PCNT_COUNT_INC, | 
					
						
							|  |  |  |         .neg_mode = PCNT_COUNT_DIS, | 
					
						
							|  |  |  |         .lctrl_mode = PCNT_MODE_REVERSE, | 
					
						
							|  |  |  |         .hctrl_mode = PCNT_MODE_KEEP, | 
					
						
							|  |  |  |         .counter_h_lim = 101, | 
					
						
							|  |  |  |         .counter_l_lim = -101, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_unit_config(&pcnt_config)); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_test_io_config((ctl_io == PCNT_CTRL_VCC_IO) ? PCNT_CTRL_HIGH_LEVEL : PCNT_CTRL_LOW_LEVEL); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     int16_t result1[8] = {100, -100, 0, -100, 100, 100, 0, 100}; | 
					
						
							|  |  |  |     int16_t result2[8] = {100, -100, 0, 100, -100, -100, 100, 0}; | 
					
						
							|  |  |  |     int16_t *result; | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     if (ctl_io == PCNT_CTRL_VCC_IO) { | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         result = result1; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         result = result2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 1, 0, 0, 0
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_INC, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_KEEP, PCNT_MODE_KEEP)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //2, 0, 0, 0
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_DEC, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_KEEP, PCNT_MODE_KEEP)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //0,0,0,0
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_DIS, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_KEEP, PCNT_MODE_KEEP)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[2]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //1,0,1,0
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_INC, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_REVERSE, PCNT_MODE_KEEP)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //1,0,0,1
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_INC, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_KEEP, PCNT_MODE_REVERSE)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[4]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //2,0,0,1
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_DEC, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_REVERSE, PCNT_MODE_KEEP)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[5]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //1,0,2,0
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_INC, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_DISABLE, PCNT_MODE_KEEP)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[6]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //1,0,0,2
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0, | 
					
						
							|  |  |  |                               PCNT_COUNT_INC, PCNT_COUNT_DIS, | 
					
						
							|  |  |  |                               PCNT_MODE_KEEP, PCNT_MODE_DISABLE)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     printf("value: %d\n", test_counter); | 
					
						
							|  |  |  |     TEST_ASSERT_INT16_WITHIN(1, test_counter, result[7]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // test PCNT basic configuration
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | TEST_CASE("PCNT test config", "[pcnt]") | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     pcnt_config_t pcnt_config = { | 
					
						
							|  |  |  |         .pulse_gpio_num = PCNT_INPUT_IO, | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |         .ctrl_gpio_num = PCNT_CTRL_VCC_IO, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         .channel = PCNT_CHANNEL_0, | 
					
						
							|  |  |  |         .unit = PCNT_UNIT_0, | 
					
						
							|  |  |  |         .pos_mode = PCNT_COUNT_INC, | 
					
						
							|  |  |  |         .neg_mode = PCNT_COUNT_DIS, | 
					
						
							|  |  |  |         .lctrl_mode = PCNT_MODE_REVERSE, | 
					
						
							|  |  |  |         .hctrl_mode = PCNT_MODE_KEEP, | 
					
						
							|  |  |  |         .counter_h_lim = 100, | 
					
						
							|  |  |  |         .counter_l_lim = 0, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     // basic configuration
 | 
					
						
							|  |  |  |     pcnt_config_t temp_pcnt_config = pcnt_config; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     // test PCNT_UNIT_MAX units, from 0-(PCNT_UNIT_MAX-1)
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							|  |  |  |     pcnt_config.unit = PCNT_UNIT_MAX; | 
					
						
							|  |  |  |     TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config)); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     for (int i = 0; i < PCNT_UNIT_MAX; i++) { | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         pcnt_config.unit = i; | 
					
						
							|  |  |  |         TEST_ESP_OK(pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // test channels
 | 
					
						
							|  |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							|  |  |  |     pcnt_config.channel = PCNT_CHANNEL_MAX; | 
					
						
							|  |  |  |     TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							|  |  |  |     pcnt_config.pulse_gpio_num = -1; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_config.pulse_gpio_num = GPIO_NUM_MAX + 1; | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // test pulse_gpio_num and ctrl_gpio_num is the same
 | 
					
						
							|  |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							|  |  |  |     pcnt_config.pulse_gpio_num = PCNT_INPUT_IO; | 
					
						
							|  |  |  |     pcnt_config.ctrl_gpio_num = PCNT_INPUT_IO; | 
					
						
							|  |  |  |     TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							|  |  |  |     pcnt_config.pos_mode = PCNT_COUNT_MAX; | 
					
						
							|  |  |  |     TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							|  |  |  |     pcnt_config.hctrl_mode = PCNT_MODE_MAX; | 
					
						
							|  |  |  |     TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pcnt_config = temp_pcnt_config; | 
					
						
							|  |  |  |     pcnt_config.lctrl_mode = PCNT_MODE_MAX; | 
					
						
							|  |  |  |     TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* PCNT basic property:
 | 
					
						
							|  |  |  |  * 1. pause counter | 
					
						
							|  |  |  |  * 2. resume counter | 
					
						
							|  |  |  |  * 3. clear counter | 
					
						
							|  |  |  |  * 4. check the counter value*/ | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | TEST_CASE("PCNT basic function test", "[pcnt]") | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     int16_t test_counter; | 
					
						
							|  |  |  |     int16_t time = 0; | 
					
						
							|  |  |  |     int clear_count = 0; | 
					
						
							|  |  |  |     int resume_count = 0; | 
					
						
							|  |  |  |     int temp_value = 0; | 
					
						
							|  |  |  |     pcnt_config_t pcnt_config = { | 
					
						
							|  |  |  |         .pulse_gpio_num = PCNT_INPUT_IO, | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |         .ctrl_gpio_num = PCNT_CTRL_VCC_IO, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         .channel = PCNT_CHANNEL_0, | 
					
						
							|  |  |  |         .unit = PCNT_UNIT_0, | 
					
						
							|  |  |  |         .pos_mode = PCNT_COUNT_INC, | 
					
						
							|  |  |  |         .neg_mode = PCNT_COUNT_DIS, | 
					
						
							|  |  |  |         .lctrl_mode = PCNT_MODE_REVERSE, | 
					
						
							|  |  |  |         .hctrl_mode = PCNT_MODE_KEEP, | 
					
						
							|  |  |  |         .counter_h_lim = 10, | 
					
						
							|  |  |  |         .counter_l_lim = -10, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_unit_config(&pcnt_config)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // use LEDC to produce the pulse, then the PCNT to count it
 | 
					
						
							|  |  |  |     produce_pulse(); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_test_io_config(PCNT_CTRL_HIGH_LEVEL); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // initialize first, the initail value should be 0
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     TEST_ASSERT_EQUAL_INT16(test_counter, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // resume the PCNT
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     TEST_ASSERT_EQUAL_INT16(test_counter, 0); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |     TEST_ASSERT_EQUAL_INT16(test_counter, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //count now
 | 
					
						
							|  |  |  |     while (time != 10) { | 
					
						
							|  |  |  |         vTaskDelay(1001 / portTICK_RATE_MS);  // in case of can't wait to get counter(edge effect)
 | 
					
						
							|  |  |  |         TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |         printf("COUNT: %d\n", test_counter); | 
					
						
							|  |  |  |         TEST_ASSERT_NOT_EQUAL(test_counter, temp_value); | 
					
						
							|  |  |  |         temp_value = test_counter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (test_counter == 5 || test_counter == -5) { | 
					
						
							|  |  |  |             //test clear
 | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL_INT16(test_counter, 0); | 
					
						
							|  |  |  |             clear_count++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (test_counter == 0) { | 
					
						
							|  |  |  |             //test pause
 | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |             vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |             printf("PAUSE: %d\n", test_counter); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL_INT16(test_counter, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // test resume
 | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |             vTaskDelay(1000 / portTICK_RATE_MS); | 
					
						
							|  |  |  |             TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); | 
					
						
							|  |  |  |             printf("RESUME: %d\n", test_counter); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |             TEST_ASSERT_EQUAL_INT16(test_counter, 1); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |             resume_count++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         time++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TEST_ASSERT_EQUAL_INT16(clear_count, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_EQUAL_INT16(resume_count, 2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * there are 4 situations will be tested: | 
					
						
							|  |  |  |  * 1. set event to interrupt triggered | 
					
						
							|  |  |  |  * 2. disable interrupt to stop triggering interrupt | 
					
						
							|  |  |  |  * 3. enable interrupt to interrupt triggered again | 
					
						
							|  |  |  |  * 4. disable event to stop triggering interrupt | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PCNT interrupt type: | 
					
						
							|  |  |  |  *   1. PCNT_EVT_THRES_1 | 
					
						
							|  |  |  |  *   2. PCNT_EVT_THRES_0 | 
					
						
							|  |  |  |  *   3. PCNT_EVT_ZERO | 
					
						
							|  |  |  |  *   4. PCNT_EVT_H_LIM | 
					
						
							|  |  |  |  *   5. PCNT_EVT_L_LIM | 
					
						
							|  |  |  |  * */ | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | TEST_CASE("PCNT interrupt method test(control IO is high)", "[pcnt][timeout=120]") | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     pcnt_config_t config = { | 
					
						
							|  |  |  |         .pulse_gpio_num = PCNT_INPUT_IO, | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |         .ctrl_gpio_num = PCNT_CTRL_VCC_IO, | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |         .channel = PCNT_CHANNEL_0, | 
					
						
							|  |  |  |         .unit = PCNT_UNIT_0, | 
					
						
							|  |  |  |         .pos_mode = PCNT_COUNT_INC, | 
					
						
							|  |  |  |         .neg_mode = PCNT_COUNT_DIS, | 
					
						
							|  |  |  |         .lctrl_mode = PCNT_MODE_REVERSE, | 
					
						
							|  |  |  |         .hctrl_mode = PCNT_MODE_KEEP, | 
					
						
							|  |  |  |         .counter_h_lim = 5, | 
					
						
							|  |  |  |         .counter_l_lim = 0, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_unit_config(&config)); | 
					
						
							|  |  |  |     produce_pulse(); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_test_io_config(PCNT_CTRL_HIGH_LEVEL); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     event_times event = { | 
					
						
							|  |  |  |         .zero_times = 0, | 
					
						
							|  |  |  |         .h_limit = 0, | 
					
						
							|  |  |  |         .l_limit = 0, | 
					
						
							|  |  |  |         .h_threshold = 0, | 
					
						
							|  |  |  |         .l_threshold = 0, | 
					
						
							|  |  |  |         .filter_time = 0, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //interrupt set
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_filter_value(PCNT_UNIT_0, 2)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_filter_enable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_1, 4));  // when arrive to max threshold trigger
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_1)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_0, 1));  // when arrive to minimum threshold trigger
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_ZERO)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM));  // when arrive to max limit trigger
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_L_LIM));  // when arrive to minimum limit trigger
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     // initialize first, the initail value should be 0
 | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_evt_queue = xQueueCreate(10, sizeof(uint32_t)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pcnt_isr_handle_t pcnt_isr_service; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_isr_register(pcnt_intr_handler, NULL, 0, &pcnt_isr_service)); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // test event
 | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 2); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 2); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT(event.l_limit == 0); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_limit, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(3, event.filter_time, 4); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // test interrupt disable
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_intr_disable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     // for the original control io disable interrupt status
 | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 2); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 2); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT(event.l_limit == 0); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_limit, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(3, event.filter_time, 4); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // enable the intr
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 4); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 4); | 
					
						
							|  |  |  |     TEST_ASSERT(event.l_limit == 0); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_limit, 4); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 4); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(3, event.filter_time, 10); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // disable part of events
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_ZERO)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_L_LIM)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_THRES_0)); | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 5); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 4); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT(event.l_limit == 0); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(3, event.h_limit, 6); | 
					
						
							| 
									
										
										
										
											2018-06-26 09:07:51 +08:00
										 |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 4); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(3, event.filter_time, 14); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     // Because this test uses its own ISR, we need to release it with `pcnt_isr_unregister` instead of `pcnt_isr_service_uninstall`
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_isr_unregister(pcnt_isr_service)); | 
					
						
							|  |  |  |     vQueueDelete(pcnt_evt_queue); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | TEST_CASE("PCNT interrupt method test(control IO is low)", "[pcnt][timeout=120]") | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     pcnt_config_t config = { | 
					
						
							|  |  |  |         .pulse_gpio_num = PCNT_INPUT_IO, | 
					
						
							|  |  |  |         .ctrl_gpio_num = PCNT_CTRL_GND_IO, | 
					
						
							|  |  |  |         .channel = PCNT_CHANNEL_0, | 
					
						
							|  |  |  |         .unit = PCNT_UNIT_0, | 
					
						
							|  |  |  |         .pos_mode = PCNT_COUNT_INC, | 
					
						
							|  |  |  |         .neg_mode = PCNT_COUNT_DIS, | 
					
						
							|  |  |  |         .lctrl_mode = PCNT_MODE_REVERSE, | 
					
						
							|  |  |  |         .hctrl_mode = PCNT_MODE_KEEP, | 
					
						
							|  |  |  |         .counter_h_lim = 0, | 
					
						
							|  |  |  |         .counter_l_lim = -5, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_unit_config(&config)); | 
					
						
							|  |  |  |     produce_pulse(); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_test_io_config(PCNT_CTRL_LOW_LEVEL); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     event_times event = { | 
					
						
							|  |  |  |         .zero_times = 0, | 
					
						
							|  |  |  |         .h_limit = 0, | 
					
						
							|  |  |  |         .l_limit = 0, | 
					
						
							|  |  |  |         .h_threshold = 0, | 
					
						
							|  |  |  |         .l_threshold = 0, | 
					
						
							|  |  |  |         .filter_time = 0, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //interrupt set
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_filter_value(PCNT_UNIT_0, 2)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_filter_enable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_1, -4));  // when arrive to max threshold trigger
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_1)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_0, 0));  // when arrive to minimum threshold trigger
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_ZERO)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM));  // when arrive to max limit trigger
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_L_LIM));  // when arrive to minimum limit trigger
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // to initialize for PCNT
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_evt_queue = xQueueCreate(10, sizeof(uint32_t)); | 
					
						
							| 
									
										
										
										
											2020-09-10 10:37:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_isr_handle_t pcnt_isr_service; | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_isr_register(pcnt_intr_handler, NULL, 0, &pcnt_isr_service)); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // test event
 | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_limit, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.filter_time, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // test interrupt disable
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_intr_disable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     // for the original control io disable interrupt status
 | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_limit, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 1); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.filter_time, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // enable the intr
 | 
					
						
							|  |  |  |     pcnt_unit_config(&config); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     pcnt_test_io_config(PCNT_CTRL_LOW_LEVEL); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 3); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_limit, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.filter_time, 6); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // disable part of events
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_ZERO)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_L_LIM)); | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_THRES_0)); | 
					
						
							|  |  |  |     event_calculate(&event); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 4); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 3); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.l_limit, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2); | 
					
						
							|  |  |  |     TEST_ASSERT_INT_WITHIN(2, event.filter_time, 8); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     // Because this test uses its own ISR, we need to release it with `pcnt_isr_unregister` instead of `pcnt_isr_service_uninstall`
 | 
					
						
							|  |  |  |     TEST_ESP_OK(pcnt_isr_unregister(pcnt_isr_service)); | 
					
						
							|  |  |  |     vQueueDelete(pcnt_evt_queue); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  | TEST_CASE("PCNT counting mode test", "[pcnt]") | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     printf("PCNT mode test for positive count\n"); | 
					
						
							| 
									
										
										
										
											2019-12-02 16:34:59 +08:00
										 |  |  |     count_mode_test(PCNT_CTRL_VCC_IO); | 
					
						
							| 
									
										
										
										
											2018-06-06 19:56:43 +08:00
										 |  |  |     printf("PCNT mode test for negative count\n"); | 
					
						
							|  |  |  |     count_mode_test(PCNT_CTRL_GND_IO); | 
					
						
							| 
									
										
										
										
											2020-08-20 12:22:36 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-12 14:23:49 +08:00
										 |  |  | #endif // #if SOC_PCNT_SUPPORTED
 |