ESP32-WROOM - Problems getting high frequency GPIO working
Posted: Tue Aug 20, 2024 4:29 am
I took this code as a base: https://github.com/espressif/esp-idf/bl ... ple_main.c
When I first compiled and downloaded the code, I saw triangle wave on my scope at 2MHz. I tried dropping the frequency to 10000000 and I've put it back to 20000000 but I have absolutely nothing coming out of GPIO 18 now.
For a sanity check, I can see GPIO 16 flashing an LED every 2 seconds.
Why am I not seeing a 2MHz signal? I don't know if it makes any difference but I'm using IDF 4.3 (I needed that for FabGl compatibility).
Here's my code:
When I first compiled and downloaded the code, I saw triangle wave on my scope at 2MHz. I tried dropping the frequency to 10000000 and I've put it back to 20000000 but I have absolutely nothing coming out of GPIO 18 now.
For a sanity check, I can see GPIO 16 flashing an LED every 2 seconds.
Why am I not seeing a 2MHz signal? I don't know if it makes any difference but I'm using IDF 4.3 (I needed that for FabGl compatibility).
Here's my code:
Code: Select all
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/ledc.h"
#include "sdkconfig.h"
#include "esp_task.h"
#include "esp_task_wdt.h"
#include <Time.h>
ledc_timer_config_t ledc_timer;
ledc_channel_config_t ledc_channel;
int64_t tCpuStep = esp_timer_get_time();
int64_t tPoll = esp_timer_get_time();
extern void serialEventRun(void) __attribute__((weak));
TaskHandle_t loopTaskHandle = NULL;
bool loopTaskWDTEnabled = false;
//-----------------------------------------------------------------------------------------------------------
void enableLoopWDT(){
//-----------------------------------------------------------------------------------------------------------
if(loopTaskHandle != NULL){
if(esp_task_wdt_add(loopTaskHandle) != ESP_OK){
printf("ERROR: Failed to add loop task to WDT");
} else {
loopTaskWDTEnabled = true;
}
}
}
#define ARDUINO_ISR_ATTR
//-----------------------------------------------------------------------------------------------------------
unsigned long ARDUINO_ISR_ATTR millis()
//-----------------------------------------------------------------------------------------------------------
{
return (unsigned long) (esp_timer_get_time() / 1000ULL);
}
#define YIELD_TIME_MS 2000
#define YIELD_TIME_US 2000000
uint64_t tCurrentTime = 0;
//-----------------------------------------------------------------------------------------------------------
void yieldIfNecessary(void){
//-----------------------------------------------------------------------------------------------------------
static uint64_t lastYield = 0;
//uint64_t now = millis();
//if((now - lastYield) > YIELD_TIME_MS) { // Avoid division
if((tCurrentTime - lastYield) > YIELD_TIME_US) {
lastYield = tCurrentTime;
vTaskDelay(5); //delay 1 RTOS tick
}
}
//-----------------------------------------------------------------------------------------------------------
void loopTask(void *pvParameters) {
//-----------------------------------------------------------------------------------------------------------
int64_t tStart = esp_timer_get_time();
/* Configure the IOMUX register for pad BLINK_GPIO (some pads are
muxed to GPIO on reset already, but some default to other
functions and need to be switched to GPIO. Consult the
Technical Reference for a list of pads and their default
functions.)
*/
gpio_pad_select_gpio(GPIO_NUM_16);
/* Set the GPIO as a push/pull output */
gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT);
for(;;)
{
tCurrentTime = esp_timer_get_time();
yieldIfNecessary();
if(loopTaskWDTEnabled){
esp_task_wdt_reset();
}
static int direction = 0;
if (tCurrentTime - tPoll > 2000000) {
tPoll = tCurrentTime;
if( direction == 1) {
gpio_set_level(GPIO_NUM_16, 1);
direction = 0;
} else {
gpio_set_level(GPIO_NUM_16, 0);
direction = 1;
}
}
}
}
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_MODE LEDC_HIGH_SPEED_MODE
//-----------------------------------------------------------------------------------------------------------
extern "C" void app_main(void)
//-----------------------------------------------------------------------------------------------------------
{
ledc_timer.speed_mode = LEDC_MODE;
ledc_timer.duty_resolution = LEDC_TIMER_13_BIT; // 2 ^ 13 = 4096
ledc_timer.timer_num = LEDC_TIMER_0;
//ledc_timer.bit_num = LEDC_TIMER_2_BIT;
ledc_timer.freq_hz = 20000000;
ledc_timer.clk_cfg = LEDC_AUTO_CLK;
// Attempt to create a clock on pin 18..
ledc_channel.speed_mode = LEDC_MODE;
ledc_channel.channel = LEDC_CHANNEL;
ledc_channel.intr_type = LEDC_INTR_DISABLE;
ledc_channel.gpio_num = 18;
ledc_channel.timer_sel = LEDC_TIMER_0;
ledc_channel.duty = 0;
ledc_channel.hpoint = 0;
ledc_timer_config(&ledc_timer);
ledc_channel_config(&ledc_channel);
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 4096); // 50%
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
enableLoopWDT();
xTaskCreatePinnedToCore(
loopTask
, "loopTask"
, 2048 // Stack size
, NULL // When no parameter is used, simply pass NULL
, 1 // Priority
, &loopTaskHandle // With task handle we will be able to manipulate with this task.
, tskNO_AFFINITY // Core on which the task will run
);
}