commit eedaac011f8f1aff888e071cf29b386389e55948 Author: imi415 Date: Mon May 24 00:38:59 2021 +0800 Initial commit, with WiFi and disco light. diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b621270 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(playground) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..da4d16c --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := sample_project + +include $(IDF_PATH)/make/project.mk diff --git a/README.md b/README.md new file mode 100644 index 0000000..455eb90 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# _Sample project_ + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This is the simplest buildable example. The example is used by command `idf.py create-project` +that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project) + + + +## How to use example +We encourage the users to use the example as a template for the new projects. +A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project). + +## Example folder contents + +The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main). + +ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` +files that provide set of directives and instructions describing the project's source files and targets +(executable, library, or both). + +Below is short explanation of remaining files in the project folder. + +``` +├── CMakeLists.txt +├── main +│   ├── CMakeLists.txt +│   └── main.c +└── README.md This is the file you are currently reading +``` +Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system. +They are not used or needed when building with CMake and idf.py. diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..6979525 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,8 @@ +idf_component_register(SRCS + "main.c" + "app_wifi.c" + "app_task_led.c" + +INCLUDE_DIRS + "." +) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100644 index 0000000..a7b7de6 --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,20 @@ +menu "WiFi Station Configuration" + + config ESP_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config ESP_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + + config ESP_MAXIMUM_RETRY + int "Maximum retry" + default 5 + help + Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent. +endmenu diff --git a/main/app_task_led.c b/main/app_task_led.c new file mode 100644 index 0000000..3a38ba8 --- /dev/null +++ b/main/app_task_led.c @@ -0,0 +1,92 @@ +#include +#include + +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "driver/ledc.h" + +#define LED_R_PIN (4) +#define LED_G_PIN (3) +#define LED_B_PIN (5) + +#define LED_R_CHANNEL LEDC_CHANNEL_0 +#define LED_G_CHANNEL LEDC_CHANNEL_1 +#define LED_B_CHANNEL LEDC_CHANNEL_2 + +#define FADE_MS 250 + +TaskHandle_t xTaskDiscoLEDHandle = NULL; +void vTaskDiscoLED(void *pvParameters) { + ledc_timer_config_t ledc_timer = { + .duty_resolution = LEDC_TIMER_13_BIT, + .freq_hz = 7500, + .speed_mode = LEDC_LOW_SPEED_MODE, + .timer_num = LEDC_TIMER_0, + .clk_cfg = LEDC_AUTO_CLK + }; + + ledc_timer_config(&ledc_timer); + + ledc_channel_config_t ledc_channels[3] = { + { + .channel = LED_R_CHANNEL, + .duty = 0, + .gpio_num = LED_R_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .hpoint = 0, + .timer_sel = LEDC_TIMER_0, + .flags.output_invert = 0 + }, + { + .channel = LED_G_CHANNEL, + .duty = 0, + .gpio_num = LED_G_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .hpoint = 0, + .timer_sel = LEDC_TIMER_0, + .flags.output_invert = 0 + }, + { + .channel = LED_B_CHANNEL, + .duty = 0, + .gpio_num = LED_B_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .hpoint = 0, + .timer_sel = LEDC_TIMER_0, + .flags.output_invert = 0 + } + }; + + for(uint8_t i = 0; i < 3; i++) { + ledc_channel_config(&ledc_channels[i]); + } + + ledc_fade_func_install(0); + + uint32_t pwm_data[3]; + + for(;;) { + + for(uint8_t i = 0; i < 3; i++) { + uint32_t pwm_new; + uint32_t delta; + do { + pwm_new = esp_random() / 0x80000; // 0-8191 + if(pwm_new > pwm_data[i]) delta = pwm_new - pwm_data[i]; + else delta = pwm_data[i] - pwm_new; + } while(delta < 2 * FADE_MS); + pwm_data[i] = pwm_new; + } + + for(uint8_t i = 0; i < 3; i++) { + ledc_set_fade_with_time(ledc_channels[i].speed_mode, + ledc_channels[i].channel, pwm_data[i], FADE_MS); + ledc_fade_start(ledc_channels[i].speed_mode, + ledc_channels[i].channel, LEDC_FADE_NO_WAIT); + } + + vTaskDelay(pdMS_TO_TICKS(FADE_MS)); + } +} \ No newline at end of file diff --git a/main/app_wifi.c b/main/app_wifi.c new file mode 100644 index 0000000..7f8ae8b --- /dev/null +++ b/main/app_wifi.c @@ -0,0 +1,93 @@ +#include +#include + +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_spi_flash.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" + +#include "lwip/err.h" +#include "lwip/sys.h" + +static const char *TAG = "APP_WIFI"; + +#define WIFI_SSID CONFIG_ESP_WIFI_SSID +#define WIFI_PSK CONFIG_ESP_WIFI_PASSWORD +#define WIFI_RETR CONFIG_ESP_MAXIMUM_RETRY + +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static uint8_t s_retry_num = 0; + +EventGroupHandle_t g_wifi_event_group; + +static void _wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } + + else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if(s_retry_num < WIFI_RETR) { + esp_wifi_connect(); + s_retry_num ++; + ESP_LOGI(TAG, "connection lost, reconnecting..."); + } else { + xEventGroupSetBits(g_wifi_event_group, WIFI_FAIL_BIT); + ESP_LOGE(TAG, "connection failed, no more retries scheduled."); + } + } + + else if(event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + ESP_LOGI(TAG, "got IPv4 address: "IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(g_wifi_event_group, WIFI_CONNECTED_BIT); + } + + else if(event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + ESP_LOGI(TAG, "got IPv6 address: "IPV6STR, IPV62STR(event->ip6_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(g_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +void app_wifi_init(void) { + g_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_wifi_event_handler, NULL, &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &_wifi_event_handler, NULL, &instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_GOT_IP6, &_wifi_event_handler, NULL, &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .ssid = WIFI_SSID, + .password = WIFI_PSK, + .threshold.authmode = WIFI_AUTH_WPA2_PSK, + .pmf_cfg = { + .capable = true, + .required = false + }, + }, + }; + + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} \ No newline at end of file diff --git a/main/component.mk b/main/component.mk new file mode 100644 index 0000000..a98f634 --- /dev/null +++ b/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/main/main.c b/main/main.c new file mode 100644 index 0000000..34f0732 --- /dev/null +++ b/main/main.c @@ -0,0 +1,46 @@ +#include + +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_spi_flash.h" +#include "nvs_flash.h" +#include "esp_log.h" + +static const char *TAG = "APP_MAIN"; + +extern EventGroupHandle_t g_wifi_event_group; + +void app_wifi_init(void); + +// Tasks +extern TaskHandle_t xTaskDiscoLEDHandle; +void vTaskDiscoLED(void *pvParameters); + +void app_main(void) { + + esp_err_t ret = nvs_flash_init(); + if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + printf("Playground started.\r\n"); + + app_wifi_init(); + EventBits_t bits = xEventGroupWaitBits(g_wifi_event_group, 0x03, pdFALSE, pdFALSE, portMAX_DELAY); + if(bits & 0x01) { + ESP_LOGI(TAG, "WiFi connected."); + } else { + ESP_LOGE(TAG, "WiFi failed."); + } + + xTaskCreate(vTaskDiscoLED, "vTaskDisco", 1024, NULL, 3, &xTaskDiscoLEDHandle); + + for(;;) { + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} diff --git a/sdkconfig.defaults b/sdkconfig.defaults new file mode 100644 index 0000000..66174da --- /dev/null +++ b/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_ESP32C3_REV_MIN_2=y +CONFIG_ESP32C3_REV_MIN=2 \ No newline at end of file