Initialize makefile

This commit is contained in:
2022-07-26 04:39:32 +02:00
commit a123d46b43
34 changed files with 2319 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
build
main/build
sdkconfig.old
*.bak
*.old
.vscode

42
.gitmodules vendored Normal file
View File

@@ -0,0 +1,42 @@
[submodule "esp-idf"]
path = esp-idf
url = https://github.com/espressif/esp-idf.git
[submodule "components/bus-i2c"]
path = components/bus-i2c
url = https://github.com/Nicolai-Electronics/esp32-component-bus-i2c.git
[submodule "components/i2c-bno055"]
path = components/i2c-bno055
url = https://github.com/Nicolai-Electronics/esp32-component-i2c-bno055.git
[submodule "components/spi-ili9341"]
path = components/spi-ili9341
url = https://github.com/Nicolai-Electronics/esp32-component-spi-ili9341.git
[submodule "components/spi-ice40"]
path = components/spi-ice40
url = https://github.com/Nicolai-Electronics/esp32-component-spi-ice40.git
[submodule "components/sdcard"]
path = components/sdcard
url = https://github.com/Nicolai-Electronics/esp32-component-sdcard.git
[submodule "components/pax-graphics"]
path = components/pax-graphics
url = https://github.com/robotman2412/pax-graphics.git
[submodule "components/mch2022-rp2040"]
path = components/mch2022-rp2040
url = https://github.com/badgeteam/esp32-component-mch2022-rp2040.git
[submodule "components/esp32-component-appfs"]
path = components/appfs
url = https://github.com/badgeteam/esp32-component-appfs.git
[submodule "components/ws2812"]
path = components/ws2812
url = https://github.com/badgeteam/esp32-component-ws2812.git
[submodule "components/mch2022-efuse"]
path = components/mch2022-efuse
url = https://github.com/badgeteam/esp32-component-mch2022-efuse.git
[submodule "components/mch2022-bsp"]
path = components/mch2022-bsp
url = https://github.com/badgeteam/esp32-component-mch2022-bsp.git
[submodule "components/pax-codecs"]
path = components/pax-codecs
url = https://github.com/robotman2412/pax-codecs.git
[submodule "main/pax-keyboard"]
path = components/pax-keyboard
url = https://github.com/robotman2412/pax-keyboard

8
CMakeLists.txt Normal file
View File

@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(PROJECT_NAME "MCH2022 launcher")
set(PROJECT_VER "0.1")
project(main)

9
LICENSE Normal file
View File

@@ -0,0 +1,9 @@
Copyright 2022 Julian Scheffers
Copyright 2022 Jeroen Domburg
Copyright 2022 Renze Nicolai
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

31
Makefile Normal file
View File

@@ -0,0 +1,31 @@
PORT ?= /dev/ttyACM0
BUILDDIR ?= build
IDF_PATH ?= $(shell pwd)/esp-idf
IDF_EXPORT_QUIET ?= 0
SHELL := /usr/bin/env bash
.PHONY: prepare clean build flash erase monitor menuconfig
all: prepare build
prepare:
git submodule update --init --recursive
cd esp-idf; bash install.sh
clean:
rm -rf "$(BUILDDIR)"
build:
source "$(IDF_PATH)/export.sh" && idf.py build
flash: build
source "$(IDF_PATH)/export.sh" && idf.py flash -p $(PORT)
erase:
source "$(IDF_PATH)/export.sh" && idf.py erase-flash -p $(PORT)
monitor:
source "$(IDF_PATH)/export.sh" && idf.py monitor -p $(PORT)
menuconfig:
source "$(IDF_PATH)/export.sh" && idf.py menuconfig

31
README.md Normal file
View File

@@ -0,0 +1,31 @@
# MCH2022 template app
This repository contains a template app for the MCH2022 badge.
## License
The source code contained in this repository is licensed under terms of the MIT license, more information can be found in the LICENSE file.
Source code included as submodules is licensed separately, please check the following table for details.
| Submodule | License | Author |
|-----------------------------|-----------------------------------|--------------------------------------------------------|
| esp-idf | Apache License 2.0 | Espressif Systems (Shanghai) CO LTD |
| components/appfs | THE BEER-WARE LICENSE Revision 42 | Jeroen Domburg <jeroen@spritesmods.com> |
| components/bus-i2c | MIT | Nicolai Electronics |
| components/i2c-bno055 | MIT | Nicolai Electronics |
| components/mch2022-rp2040 | MIT | Renze Nicolai |
| components/pax-graphics | MIT | Julian Scheffers |
| components/pax-keyboard | MIT | Julian Scheffers |
| components/sdcard | MIT | Nicolai Electronics |
| components/spi-ice40 | MIT | Nicolai Electronics |
| components/spi-ili9341 | MIT | Nicolai Electronics |
| components/ws2812 | MIT | Unlicense / Public domain |
## How to make
```sh
git clone --recursive https://github.com/badgeteam/mch2022-template-app
cd mch2022-template-app
make prepare
make
```

1
components/appfs Submodule

Submodule components/appfs added at 3311e975db

1
components/bus-i2c Submodule

Submodule components/bus-i2c added at f775f174c3

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "bme680.c"
INCLUDE_DIRS include
REQUIRES "bus-i2c"
)

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2022 Nicolai Electronics
*
* SPDX-License-Identifier: MIT
*/
#include <sdkconfig.h>
#include <esp_log.h>
#include <driver/gpio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
#include "bme680.h"
#include "managed_i2c.h"
static const char *TAG = "BME680";
esp_err_t bme680_check_id(BME680* device) {
uint8_t chip_id;
esp_err_t res = i2c_read_reg(device->i2c_bus, device->i2c_address, BME680_REG_CHIP_ID, &chip_id, 1);
if (res != ESP_OK) return res;
if (chip_id != BME680_CHIP_ID) {
ESP_LOGE(TAG, "Unexpected chip id value 0x%02X, expected 0x%02X", chip_id, BME680_CHIP_ID);
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t bme680_reset(BME680* device) {
uint8_t value = 0xFF;
esp_err_t res = i2c_write_reg_n(device->i2c_bus, device->i2c_address, BME680_REG_RESET, &value, 1);
if (res != ESP_OK) return res;
return ESP_OK;
}
esp_err_t bme680_init(BME680* device) {
esp_err_t res = bme680_reset(device);
if (res != ESP_OK) return res;
vTaskDelay(100 / portTICK_PERIOD_MS);
res = bme680_check_id(device);
if (res != ESP_OK) return res;
return res;
}
esp_err_t bme680_deinit(BME680* device) {
return bme680_reset(device);
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <esp_err.h>
#include <stdint.h>
#define BME680_REG_RESET 0xE0
#define BME680_REG_CHIP_ID 0xD0
#define BME680_CHIP_ID 0x61
typedef struct BME680 {
int i2c_bus;
int i2c_address;
} BME680;
esp_err_t bme680_init(BME680* device);
esp_err_t bme680_deinit(BME680* device);
esp_err_t bme680_check_id(BME680* device);
esp_err_t bme680_reset(BME680* device);

1
components/i2c-bno055 Submodule

Submodule components/i2c-bno055 added at 0812d28db9

1
components/pax-codecs Submodule

Submodule components/pax-codecs added at 11b9e4f964

1
components/sdcard Submodule

Submodule components/sdcard added at 2b6630e85e

1
components/spi-ice40 Submodule

Submodule components/spi-ice40 added at abdc7b2350

1
components/ws2812 Submodule

Submodule components/ws2812 added at c1c750d2ce

1
esp-idf Submodule

Submodule esp-idf added at 9f303290d8

41
fpga/fpga.py Normal file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import binascii, serial, time, sys, argparse
parser = argparse.ArgumentParser(description='MCH2022 badge FPGA bitstream programming tool')
parser.add_argument("port", help="Serial port")
parser.add_argument("bitstream", help="Bitstream binary")
args = parser.parse_args()
with open(args.bitstream, "rb") as f:
bitstream = f.read()
port = serial.Serial(args.port, 921600, timeout=1)
print("Waiting for badge...")
while True:
data = port.read(4)
if (data == b"FPGA"):
break
port.write(b'FPGA' + (len(bitstream).to_bytes(4, byteorder='little')) + binascii.crc32(bitstream).to_bytes(4, byteorder='little'))
time.sleep(0.5)
sent = 0
print("Sending data", end="")
while len(bitstream) - sent > 0:
print(".", end="")
sys.stdout.flush()
txLength = len(bitstream)
if txLength > 2048:
txLength = 2048
port.write(bitstream[sent:sent + txLength])
time.sleep(0.05)
sent += txLength
while port.is_open:
inLen = port.in_waiting
if inLen > 0:
data = port.read(inLen).decode('utf-8','ignore');
if data == 'FPGA':
print(data)
else:
print(data, end='')
port.close()
print("\n")

8
main/CMakeLists.txt Normal file
View File

@@ -0,0 +1,8 @@
idf_component_register(
SRCS
"main.c"
"wifi_connect.c"
"wifi_connection.c"
INCLUDE_DIRS
"." "include"
)

0
main/include/main.h Normal file
View File

View File

@@ -0,0 +1,5 @@
#pragma once
#include <stdbool.h>
bool wifi_connect_to_stored();

View File

@@ -0,0 +1,46 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "esp_wpa2.h"
#define WIFI_MCH2022_SSID "MCH2022"
#define WIFI_MCH2022_USER "mch2022"
#define WIFI_MCH2022_IDENT "mch2022"
#define WIFI_MCH2022_PASSWORD "mch2022"
#define WIFI_MCH2022_AUTH WIFI_AUTH_WPA2_ENTERPRISE
#define WIFI_MCH2022_PHASE2 ESP_EAP_TTLS_PHASE2_MSCHAPV2
// Simpler interpretation of WiFi signal strength.
typedef enum {
WIFI_STRENGTH_VERY_BAD,
WIFI_STRENGTH_BAD,
WIFI_STRENGTH_GOOD,
WIFI_STRENGTH_VERY_GOOD,
} wifi_strength_t;
// Thresholds for aforementioned signal strength definitions.
#define WIFI_THRESH_BAD -80
#define WIFI_THRESH_GOOD -70
#define WIFI_THRESH_VERY_GOOD -67
// Firt time initialisation of the WiFi stack.
void wifi_init();
// Connect to a traditional username/password WiFi network.
bool wifi_connect(const char* aSsid, const char* aPassword, wifi_auth_mode_t aAuthmode, uint8_t aRetryMax);
// Connect to a WPA2 enterprise WiFi network.
bool wifi_connect_ent(const char* aSsid, const char *aIdent, const char *aAnonIdent, const char* aPassword, esp_eap_ttls_phase2_types phase2, uint8_t aRetryMax);
// Scan for WiFi networks.
// Updates the APs pointer if non-null.
// Returns the number of APs found.
size_t wifi_scan(wifi_ap_record_t **aps);
// Get the strength value for a given RSSI.
wifi_strength_t wifi_rssi_to_strength(int8_t rssi);

54
main/main.c Normal file
View File

@@ -0,0 +1,54 @@
// This file contains a simple hello world app which you can base you own apps on.
#include "main.h"
#include "hardware.h"
#include "pax_gfx.h"
#include "pax_codecs.h"
#include "ili9341.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
static pax_buf_t buf;
xQueueHandle buttonQueue;
static const char *TAG = "mch2022-demo-app";
void disp_flush() {
ili9341_write(get_ili9341(), buf.buf);
}
void app_main() {
// Init HW.
bsp_init();
bsp_rp2040_init();
buttonQueue = get_rp2040()->queue;
// Init GFX.
pax_buf_init(&buf, NULL, 320, 240, PAX_BUF_16_565RGB);
while (1) {
// Pick a random background color.
int hue = esp_random() & 255;
pax_col_t col = pax_col_hsv(hue, 255 /*saturation*/, 255 /*brighness*/);
// Show some random color hello world.
pax_background(&buf, col);
char *text = "Hello, World!";
const pax_font_t *font = pax_get_font("saira condensed");
pax_vec1_t dims = pax_text_size(font, font->default_size, text);
pax_draw_text(
&buf, 0xff000000, font, font->default_size,
(buf.width - dims.x) / 2.0,
(buf.height - dims.y) / 2.0,
text
);
disp_flush();
// Await any button press and do another cycle.
rp2040_input_message_t message;
xQueueReceive(buttonQueue, &message, portMAX_DELAY);
}
}

102
main/wifi_connect.c Normal file
View File

@@ -0,0 +1,102 @@
#include <stdio.h>
#include <string.h>
#include <sdkconfig.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <esp_system.h>
#include <esp_err.h>
#include <esp_log.h>
#include <nvs_flash.h>
#include <nvs.h>
#include "pax_gfx.h"
#include "wifi_connection.h"
static const char *TAG = "wifi_connect";
bool wifi_connect_to_stored() {
bool result = false;
// Open NVS.
nvs_handle_t handle;
nvs_open("system", NVS_READWRITE, &handle);
wifi_auth_mode_t authmode = 0;
esp_eap_ttls_phase2_types phase2 = 0;
char *ssid = NULL;
char *ident = NULL;
char *anon_ident = NULL;
char *password = NULL;
size_t len;
// Read NVS.
esp_err_t res;
// Read SSID.
res = nvs_get_str(handle, "wifi.ssid", NULL, &len);
if (res) goto errcheck;
ssid = malloc(len);
res = nvs_get_str(handle, "wifi.ssid", ssid, &len);
if (res) goto errcheck;
// Check whether connection is enterprise.
res = nvs_get_u8(handle, "wifi.authmode", &authmode);
bool use_ent = authmode == WIFI_AUTH_WPA2_ENTERPRISE;
if (res) goto errcheck;
if (use_ent) {
// Read enterprise-specific parameters.
// Read phase2 mode.
res = nvs_get_u8(handle, "wifi.phase2", &phase2);
if (res) goto errcheck;
// Read identity.
res = nvs_get_str(handle, "wifi.username", NULL, &len);
if (res) goto errcheck;
ident = malloc(len);
res = nvs_get_str(handle, "wifi.username", ident, &len);
// Read anonymous identity.
res = nvs_get_str(handle, "wifi.anon_ident", NULL, &len);
if (res == ESP_ERR_NVS_NOT_FOUND) {
// Default is use the same thing.
anon_ident = strdup(ident);
} else {
if (res) goto errcheck;
anon_ident = malloc(len);
res = nvs_get_str(handle, "wifi.anon_ident", anon_ident, &len);
if (res) goto errcheck;
}
}
// Read password.
res = nvs_get_str(handle, "wifi.password", NULL, &len);
if (res) goto errcheck;
password = malloc(len);
res = nvs_get_str(handle, "wifi.password", password, &len);
if (res) goto errcheck;
// Close NVS.
nvs_close(handle);
// Open the appropriate connection.
if (use_ent) {
result = wifi_connect_ent(ssid, ident, anon_ident, password, phase2, 3);
} else {
result = wifi_connect(ssid, password, authmode, 3);
}
errcheck:
if (res == ESP_ERR_NVS_NOT_FOUND || res == ESP_ERR_NVS_NOT_INITIALIZED) {
// When NVS is not initialised.
ESP_LOGI(TAG, "WiFi settings not stored in NVS.");
} else if (res) {
// Other errors.
ESP_LOGE(TAG, "Error connecting to WiFi: %s", esp_err_to_name(res));
}
// Free memory.
if (ssid) free(ssid);
if (ident) free(ident);
if (anon_ident) free(anon_ident);
if (password) free(password);
return result;
}

287
main/wifi_connection.c Normal file
View File

@@ -0,0 +1,287 @@
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "wifi_connection.h"
static const char *TAG = "wifi_connection";
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
#define WIFI_STARTED_BIT BIT2
static EventGroupHandle_t wifiEventGroup;
static uint8_t retryCount = 0;
static uint8_t maxRetries = 3;
static bool isScanning = false;
#define WIFI_SORT_ERRCHECK(err) do {int res = (err); if(res) {ESP_LOGE(TAG, "WiFi connection error: %s", esp_err_to_name(res)); goto error; } } while(0)
static void 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) {
xEventGroupSetBits(wifiEventGroup, WIFI_STARTED_BIT);
if (!isScanning) {
// Connect only if we're not scanning the WiFi.
esp_wifi_connect();
}
ESP_LOGI(TAG, "WiFi station start.");
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_STOP) {
xEventGroupClearBits(wifiEventGroup, WIFI_STARTED_BIT);
ESP_LOGI(TAG, "WiFi station stop.");
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (retryCount < 3) {
esp_wifi_connect();
retryCount++;
ESP_LOGI(TAG, "Retrying connection");
} else {
ESP_LOGI(TAG, "Connection failed");
xEventGroupSetBits(wifiEventGroup, WIFI_FAIL_BIT);
}
} 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 ip:" IPSTR, IP2STR(&event->ip_info.ip));
retryCount = 0;
xEventGroupSetBits(wifiEventGroup, WIFI_CONNECTED_BIT);
}
}
void wifi_init() {
// Create an event group for WiFi things.
wifiEventGroup = xEventGroupCreate();
// Initialise WiFi stack.
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));
// Register event handlers for WiFi.
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, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
// Turn off WiFi hardware.
ESP_ERROR_CHECK(esp_wifi_stop());
}
bool wifi_connect(const char* aSsid, const char* aPassword, wifi_auth_mode_t aAuthmode, uint8_t aRetryMax) {
// Set the retry counts.
retryCount = 0;
maxRetries = aRetryMax;
// Create a config.
wifi_config_t wifi_config = {0};
strcpy((char*) wifi_config.sta.ssid, aSsid);
strcpy((char*) wifi_config.sta.password, aPassword);
wifi_config.sta.threshold.authmode = aAuthmode;
// Set WiFi config.
WIFI_SORT_ERRCHECK(esp_wifi_set_mode(WIFI_MODE_STA));
WIFI_SORT_ERRCHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
// Disable 11b as NOC asked.
esp_wifi_config_11b_rate(WIFI_IF_STA, true);
// Start WiFi.
WIFI_SORT_ERRCHECK(esp_wifi_start());
ESP_LOGI(TAG, "Connecting to WiFi...");
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(wifiEventGroup, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "Connected to WiFi");
return true;
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGE(TAG, "Failed to connect");
WIFI_SORT_ERRCHECK(esp_wifi_stop());
} else {
ESP_LOGE(TAG, "Unknown event received while waiting on connection");
WIFI_SORT_ERRCHECK(esp_wifi_stop());
}
error:
return false;
}
bool wifi_connect_ent(const char* aSsid, const char *aIdent, const char *aAnonIdent, const char* aPassword, esp_eap_ttls_phase2_types phase2, uint8_t aRetryMax) {
retryCount = 0;
maxRetries = aRetryMax;
wifi_config_t wifi_config = {0};
if (strlen(aSsid) > 32) {
ESP_LOGE(TAG, "SSID is too long (%zu > 32)!", strlen(aSsid));
return false;
}
strncpy((char*) wifi_config.sta.ssid, aSsid, 32);
// Set WiFi config.
WIFI_SORT_ERRCHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
WIFI_SORT_ERRCHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
// Set WPA2 ENT config.
WIFI_SORT_ERRCHECK(esp_wifi_sta_wpa2_ent_set_identity((const uint8_t *) aAnonIdent, strlen(aAnonIdent)));
WIFI_SORT_ERRCHECK(esp_wifi_sta_wpa2_ent_set_username((const uint8_t *) aIdent, strlen(aIdent)));
WIFI_SORT_ERRCHECK(esp_wifi_sta_wpa2_ent_set_password((const uint8_t *) aPassword, strlen(aPassword)));
WIFI_SORT_ERRCHECK(esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(phase2));
// Enable enterprise auth.
WIFI_SORT_ERRCHECK(esp_wifi_sta_wpa2_ent_enable());
// Disable 11b as NOC asked.
WIFI_SORT_ERRCHECK(esp_wifi_config_11b_rate(WIFI_IF_STA, true));
// Start the connection.
WIFI_SORT_ERRCHECK(esp_wifi_start());
ESP_LOGI(TAG, "Connecting to '%s' as '%s'/'%s': %s", aSsid, aIdent, aAnonIdent, aPassword);
ESP_LOGI(TAG, "Phase2 mode: %d", phase2);
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(wifiEventGroup, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "Connected to WiFi");
return true;
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGE(TAG, "Failed to connect");
WIFI_SORT_ERRCHECK(esp_wifi_stop());
} else {
ESP_LOGE(TAG, "Unknown event received while waiting on connection");
WIFI_SORT_ERRCHECK(esp_wifi_stop());
}
error:
return false;
}
// Shows a nice info message describing an AP record.
static inline void wifi_desc_record(wifi_ap_record_t *record) {
// Make a string representation of BSSID.
char *bssid_str = malloc(3*6);
if (!bssid_str) return;
snprintf(bssid_str, 3*6, "%02X:%02X:%02X:%02X:%02X:%02X",
record->bssid[0], record->bssid[1], record->bssid[2],
record->bssid[3], record->bssid[4], record->bssid[5]
);
// Make a string representation of 11b/g/n modes.
char *phy_str = malloc(9);
if (!phy_str) {
free(bssid_str);
return;
}
*phy_str = 0;
if (record->phy_11b | record->phy_11g | record->phy_11n) {
strcpy(phy_str, " 1");
}
if (record->phy_11b) {
strcat(phy_str, "/b");
}
if (record->phy_11g) {
strcat(phy_str, "/g");
}
if (record->phy_11n) {
strcat(phy_str, "/n");
}
phy_str[2] = '1';
ESP_LOGI(TAG, "AP %s %s rssi=%hhd%s", bssid_str, record->ssid, record->rssi, phy_str);
free(bssid_str);
free(phy_str);
}
// Scan for WiFi access points.
size_t wifi_scan(wifi_ap_record_t **aps_out) {
isScanning = true;
wifi_ap_record_t *aps = NULL;
// Scan for any non-hidden APs on all channels.
wifi_scan_config_t cfg = {
.ssid = NULL,
.bssid = NULL,
.channel = 0,
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
.scan_time = { .active={ 0, 0 } },
};
// Start the scan now.
ESP_LOGI(TAG, "Starting scan...");
esp_err_t res = esp_wifi_scan_start(&cfg, true);
// Whether to call esp_wifi_stop() on finish.
bool stopWhenDone = false;
if (res == ESP_ERR_WIFI_NOT_STARTED) {
// If it complains that the wifi wasn't started, then do so.
ESP_LOGI(TAG, "Starting WiFi for scan");
// Set to station but don't connect.
res = esp_wifi_set_mode(WIFI_MODE_STA);
if (res) goto ohno;
// Start WiFi.
res = esp_wifi_start();
if (res) goto ohno;
stopWhenDone = true;
// Await the STA started bit.
xEventGroupWaitBits(wifiEventGroup, WIFI_STARTED_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(2000));
// Try again.
res = esp_wifi_scan_start(&cfg, true);
}
if (res) {
ohno:
ESP_LOGE(TAG, "Error in WiFi scan: %s", esp_err_to_name(res));
isScanning = false;
return 0;
}
// Allocate memory for AP list.
uint16_t num_ap = 0;
WIFI_SORT_ERRCHECK(esp_wifi_scan_get_ap_num(&num_ap));
aps = malloc(sizeof(wifi_ap_record_t) * num_ap);
if (!aps) {
ESP_LOGE(TAG, "Out of memory (%zd bytes)", sizeof(wifi_ap_record_t) * num_ap);
num_ap = 0;
esp_wifi_scan_get_ap_records(&num_ap, NULL);
return 0;
}
// Collect APs and report findings.
WIFI_SORT_ERRCHECK(esp_wifi_scan_get_ap_records(&num_ap, aps));
for (uint16_t i = 0; i < num_ap; i++) {
wifi_desc_record(&aps[i]);
}
// Clean up.
if (aps_out) {
// Output pointer is non-null, return the APs list.
*aps_out = aps;
} else {
// Output pointer is null, free the APs list.
free(aps);
}
if (stopWhenDone) {
// Stop WiFi because it was started only for this scan.
esp_wifi_stop();
}
isScanning = false;
return num_ap;
error:
if (aps) free(aps);
return 0;
}
// Get the strength value for a given RSSI.
wifi_strength_t wifi_rssi_to_strength(int8_t rssi) {
if (rssi > WIFI_THRESH_VERY_GOOD) return WIFI_STRENGTH_VERY_GOOD;
else if (rssi > WIFI_THRESH_GOOD) return WIFI_STRENGTH_GOOD;
else if (rssi > WIFI_THRESH_BAD) return WIFI_STRENGTH_BAD;
else return WIFI_STRENGTH_VERY_BAD;
}

9
partitions.csv Normal file
View File

@@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0xA000, 12K,
otadata, data, ota, 0xD000, 8K,
phy_init, data, phy, 0xF000, 4K,
ota_0, 0, ota_0, 0x10000, 1600K,
ota_1, 0, ota_1, 0x1A0000, 1600K,
appfs, 0x43, 3, 0x330000, 8000K,
locfd, data, fat, 0xB00000, 5120K,
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0xA000, 12K,
4 otadata, data, ota, 0xD000, 8K,
5 phy_init, data, phy, 0xF000, 4K,
6 ota_0, 0, ota_0, 0x10000, 1600K,
7 ota_1, 0, ota_1, 0x1A0000, 1600K,
8 appfs, 0x43, 3, 0x330000, 8000K,
9 locfd, data, fat, 0xB00000, 5120K,

BIN
partitions.ods Normal file

Binary file not shown.

1555
sdkconfig Normal file

File diff suppressed because it is too large Load Diff