I'm having difficulties using UART in combination with automatic light sleep.
I enabled PM and tickless idle in menuconfig:
Code: Select all
CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP=2
Code: Select all
#define LOG_LEVEL ESP_LOG_INFO
#include "driver/uart.h"
#include "driver/gpio.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_pm.h"
#define GSM_TX (17)
#define GSM_RX (16)
#define GSM_RST (21)
#define BUF_SIZE (1024)
#define UART_NUM UART_NUM_1
static const char* TAG = "test";
static QueueHandle_t uart_queue;
static void uart_task(void *arg) {
uint8_t *data = (uint8_t*)malloc(BUF_SIZE);
uart_event_t event;
for (;;) {
if (xQueueReceive(uart_queue, &event, portMAX_DELAY)) {
switch(event.type) {
case UART_DATA:
{
int len = uart_read_bytes(UART_NUM, data, event.size, portMAX_DELAY);
if (len) {
*(data + event.size) = '\0';
ESP_LOGI(TAG, "%s", (char *) data);
}
}
break;
default:
break;
}
}
}
}
void app_main() {
esp_log_level_set("*", LOG_LEVEL);
esp_pm_config_esp32_t pm_config = {
.max_freq_mhz = 10,
.min_freq_mhz = 10,
.light_sleep_enable = true
};
// Configure power management
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
// Enable GPIO wakeup on RX
ESP_ERROR_CHECK(esp_sleep_enable_gpio_wakeup());
ESP_ERROR_CHECK(gpio_wakeup_enable((gpio_num_t)GSM_RX, GPIO_INTR_LOW_LEVEL));
// Set GSM_RST pin as output
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1ULL << GSM_RST);
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
// Reset GSM module
gpio_set_level((gpio_num_t)GSM_RST, 1);
vTaskDelay(520 / portTICK_RATE_MS);
gpio_set_level((gpio_num_t)GSM_RST, 0);
// Configure UART
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_REF_TICK,
};
int intr_alloc_flags = 0;
#if CONFIG_UART_ISR_IN_IRAM
intr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif
ESP_ERROR_CHECK(uart_driver_install(UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 32, &uart_queue, 0));
ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(UART_NUM, GSM_TX, GSM_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
xTaskCreate(uart_task, "uart_event_task", 2048, NULL, 12, NULL);
for (;;) {
int len = uart_write_bytes(UART_NUM, "ATI\r\n", 5);
uart_wait_tx_idle_polling(UART_NUM);
if (len <= 0) {
ESP_LOGE(TAG, "TX failed");
}
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
Code: Select all
I (2796) test:
Quectel_Ltd
Quectel_BC66
Revision: BC66NBR01A07
OK
I (3796) test:
Quectel_Ltd
Quectel_BC66
Revision: BC66NBR01A07
OK
Code: Select all
I (277072) test: }1ё5
Quectel_BC66
Revision: BC66NBR01A07
OK
I (278073) test: ��ё5
Quectel_BC66
Revision: BC66NBR01A07
OK
I thought slowing down the UART baud rate will decrease the number of lost/corrupted characters but instead it's even worse. Here's the prinout when using 9600 bps:
Code: Select all
Quectel_BC66t: RQuѕ�}1ё5
�vvis���I�
�7R
_5
I (10839) test: RQuecte}1ё5
�6�ѕ�}
�vvisionI�
�7)
_5
Am I doing something wrong here? Can you please suggest what could I do to remedy this (or even better, point me to an example code)?
Thank you very much!