Adding environment setup and instructions
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -35,7 +35,8 @@
|
|||||||
"semphr.h": "c",
|
"semphr.h": "c",
|
||||||
"lv_spinbox.h": "c",
|
"lv_spinbox.h": "c",
|
||||||
"lv_slider.h": "c",
|
"lv_slider.h": "c",
|
||||||
"lv_menu.h": "c"
|
"lv_menu.h": "c",
|
||||||
|
"stream_buffer.h": "c"
|
||||||
},
|
},
|
||||||
"git.ignoreLimitWarning": true
|
"git.ignoreLimitWarning": true
|
||||||
}
|
}
|
||||||
|
|||||||
211
README.md
Normal file
211
README.md
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
## 🐳 ESP-IDF Dockerized Development Environment (Windows)
|
||||||
|
|
||||||
|
This project includes a fully containerized [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/index.html) development environment using **Docker** and **Visual Studio Code**.
|
||||||
|
|
||||||
|
Follow these instructions to set up, build, and flash the firmware inside a VS Code **Dev Container** on **Windows**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ✅ Prerequisites
|
||||||
|
Ensure the following are installed on your system:
|
||||||
|
|
||||||
|
1. [**Docker Desktop for Windows**](https://www.docker.com/products/docker-desktop)
|
||||||
|
|
||||||
|
* Enable **WSL 2 backend** during installation.
|
||||||
|
2. [**Visual Studio Code**](https://code.visualstudio.com/)
|
||||||
|
3. [**Dev Containers Extension**](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
|
||||||
|
|
||||||
|
* In VS Code: `Extensions → Search "Dev Containers" → Install`
|
||||||
|
4. [**Espressif IDF Extension** for VS Code](https://marketplace.visualstudio.com/items?itemName=espressif.esp-idf-extension)
|
||||||
|
|
||||||
|
* In VS Code: `Extensions → Search "ESP-IDF" → Install`
|
||||||
|
|
||||||
|
> 💡 **Optional (recommended):** Install [WSL 2 with Ubuntu](https://learn.microsoft.com/en-us/windows/wsl/install) for improved Linux compatibility inside Docker.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🚀 Getting Started
|
||||||
|
|
||||||
|
#### 1. Clone this repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.sparksoftdesign.com/firstpass/soundshot.git
|
||||||
|
cd soundshot
|
||||||
|
```
|
||||||
|
---
|
||||||
|
You can also clone with TortoiseGit or VS Code directly.
|
||||||
|
#### 2. Open in Visual Studio Code
|
||||||
|
|
||||||
|
From the project root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
code .
|
||||||
|
```
|
||||||
|
|
||||||
|
> Ensure you're opening the folder that contains `.devcontainer/`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 3. Reopen in Dev Container
|
||||||
|
|
||||||
|
In VS Code:
|
||||||
|
|
||||||
|
* Press `F1` or `Ctrl+Shift+P`
|
||||||
|
* Run: **Dev Containers: Reopen in Container**
|
||||||
|
|
||||||
|
VS Code will:
|
||||||
|
|
||||||
|
* Build the Docker image (based on the provided `Dockerfile`)
|
||||||
|
* Set up the ESP-IDF environment
|
||||||
|
* Install extensions automatically
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 4. Verify Environment
|
||||||
|
|
||||||
|
Once setup is complete:
|
||||||
|
|
||||||
|
* A terminal should launch inside the container
|
||||||
|
* Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
idf.py --version
|
||||||
|
```
|
||||||
|
|
||||||
|
to confirm ESP-IDF is active and available.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 5. Build the Firmware
|
||||||
|
|
||||||
|
Inside the container’s terminal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
idf.py build
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see standard ESP-IDF build output and a `.bin` firmware file in the `build/` directory.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ ESP32 Programming Setup & Workflow Guide
|
||||||
|
|
||||||
|
This project provides a fully portable development and flashing toolchain for ESP32, using Python scripts and configuration-driven workflows.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 📦 1. Environment Setup
|
||||||
|
|
||||||
|
> Run once after cloning the repo (Windows only)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
setup-env.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
This:
|
||||||
|
|
||||||
|
* Creates a `.venv` virtual environment
|
||||||
|
* Installs required Python packages (`esptool`, `pyserial`, etc.)
|
||||||
|
* Prepares the tooling for flashing and monitoring
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ⚙️ 2. Configure `settings.json`
|
||||||
|
|
||||||
|
Customize `settings.json` in the project root:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"project_name": "soundshot",
|
||||||
|
"chip": "esp32",
|
||||||
|
"port": "COM3",
|
||||||
|
"baud": 460800,
|
||||||
|
"flash_mode": "dio",
|
||||||
|
"flash_freq": "48m",
|
||||||
|
"flash_size": "2MB",
|
||||||
|
"before": "default-reset",
|
||||||
|
"after": "hard-reset"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This controls:
|
||||||
|
|
||||||
|
* Flashing chip type and parameters
|
||||||
|
* Serial monitor settings
|
||||||
|
* Build artifact naming
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🚀 3. Flashing the Firmware
|
||||||
|
|
||||||
|
After building your firmware (e.g. via VS Code + Dev Container):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
build/
|
||||||
|
├── bootloader/bootloader.bin
|
||||||
|
├── soundshot.bin ← ← ← (project_name)
|
||||||
|
├── partition_table/partition-table.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the flash tool:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flash.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
This:
|
||||||
|
|
||||||
|
* Loads `settings.json`
|
||||||
|
* Verifies all required binaries
|
||||||
|
* Calls `esptool.py` with all correct arguments and offsets
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🛰 4. Monitoring Serial Output
|
||||||
|
|
||||||
|
To view device output:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
monitor.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* Uses `pyserial`
|
||||||
|
* Displays real-time output from the ESP32
|
||||||
|
* Preserves color formatting (if enabled in firmware)
|
||||||
|
* Cleanly exits with `Ctrl+C` (no "Terminate batch job" prompts)
|
||||||
|
|
||||||
|
> Tip: Run `idf.py menuconfig` and enable
|
||||||
|
> `Component config → Log output → Enable color log output`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ✅ Workflow Summary
|
||||||
|
|
||||||
|
| Action | Tool | Command |
|
||||||
|
| ------------------ | ------------------- | ----------------- |
|
||||||
|
| Install tooling | `setup-env.bat` | `setup-env.bat` |
|
||||||
|
| Flash device | `flash.py` script | `flash.bat` |
|
||||||
|
| Monitor logs | `monitor.py` script | `monitor.bat` |
|
||||||
|
| Configure behavior | `settings.json` | *(edit manually)* |
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🧰 Notes
|
||||||
|
|
||||||
|
* The ESP-IDF version is pinned in the Dockerfile (e.g., `espressif/idf:v5.2.1`)
|
||||||
|
* The container automatically runs `source $IDF_PATH/export.sh` to prepare the environment.
|
||||||
|
* VS Code extensions (`.devcontainer.json`) include:
|
||||||
|
|
||||||
|
* `ms-vscode.cpptools`
|
||||||
|
* `ms-vscode.cmake-tools`
|
||||||
|
* `espressif.esp-idf-extension`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🛠 Troubleshooting
|
||||||
|
|
||||||
|
* If `idf.py` is not found, make sure the container terminal sources `export.sh`
|
||||||
|
|
||||||
22
flash.bat
Normal file
22
flash.bat
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
@echo off
|
||||||
|
REM =============================================
|
||||||
|
REM Flash ESP32 using Python script + settings.json
|
||||||
|
REM =============================================
|
||||||
|
|
||||||
|
REM Check for venv
|
||||||
|
IF NOT EXIST .venv\Scripts\python.exe (
|
||||||
|
echo [ERROR] Python virtual environment not found at .venv\
|
||||||
|
echo Run setup-env.bat first.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Activate venv and run flash.py
|
||||||
|
call .venv\Scripts\activate.bat
|
||||||
|
|
||||||
|
echo [INFO] Flashing firmware using flash.py and settings.json...
|
||||||
|
python flash_tool\flash.py
|
||||||
|
|
||||||
|
REM Pause to view output
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
60
flash_tool/flash.py
Normal file
60
flash_tool/flash.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = Path(__file__).resolve().parent.parent
|
||||||
|
config_file = root / "settings.json"
|
||||||
|
|
||||||
|
if not config_file.exists():
|
||||||
|
print(f"[ERROR] settings.json not found at {config_file}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(config_file) as f:
|
||||||
|
cfg = json.load(f)
|
||||||
|
|
||||||
|
project = cfg["project_name"]
|
||||||
|
chip = cfg.get("chip", "esp32")
|
||||||
|
port = cfg.get("port", "COM3")
|
||||||
|
baud = cfg.get("flash_baud", 460800)
|
||||||
|
flash_mode = cfg.get("flash_mode", "dio")
|
||||||
|
flash_freq = cfg.get("flash_freq", "40m")
|
||||||
|
flash_size = cfg.get("flash_size", "4MB")
|
||||||
|
before = cfg.get("before", "default_reset")
|
||||||
|
after = cfg.get("after", "hard_reset")
|
||||||
|
|
||||||
|
# Define binaries and offsets
|
||||||
|
bootloader = root / "build" / "bootloader" / "bootloader.bin"
|
||||||
|
firmware = root / "build" / f"{project}.bin"
|
||||||
|
partition = root / "build" / "partition_table" / "partition-table.bin"
|
||||||
|
|
||||||
|
# Verify binaries exist
|
||||||
|
for f in [bootloader, firmware, partition]:
|
||||||
|
if not f.exists():
|
||||||
|
print(f"[ERROR] File not found: {f}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Build esptool command
|
||||||
|
cmd = [
|
||||||
|
sys.executable, "-m", "esptool",
|
||||||
|
"--chip", chip,
|
||||||
|
"--port", port,
|
||||||
|
"--baud", str(baud),
|
||||||
|
"--before", before,
|
||||||
|
"--after", after,
|
||||||
|
"write-flash", # ✅ hyphenated command
|
||||||
|
"--flash-mode", flash_mode, # ✅ hyphenated flags
|
||||||
|
"--flash-freq", flash_freq,
|
||||||
|
"--flash-size", flash_size,
|
||||||
|
"0x0", str(bootloader),
|
||||||
|
"0x10000", str(firmware),
|
||||||
|
"0x8000", str(partition)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
print(f"[Flashing] Running: {' '.join(cmd)}")
|
||||||
|
subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
45
flash_tool/monitor.py
Normal file
45
flash_tool/monitor.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import json
|
||||||
|
import serial
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
# import colorama
|
||||||
|
# colorama.just_fix_windows_console()
|
||||||
|
|
||||||
|
print("\x1b[0;32mThis should be green\x1b[0m")
|
||||||
|
print("\x1b[0;31mThis should be red\x1b[0m")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Load config
|
||||||
|
root = Path(__file__).resolve().parent.parent
|
||||||
|
config_file = root / "settings.json"
|
||||||
|
if not config_file.exists():
|
||||||
|
print(f"Error: settings.json not found at {config_file}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(config_file) as f:
|
||||||
|
cfg = json.load(f)
|
||||||
|
|
||||||
|
port = cfg.get("port", "COM3")
|
||||||
|
baud = cfg.get("monitor_baud", 115200)
|
||||||
|
|
||||||
|
print(f"[Serial Monitor] Connecting to {port} at {baud} baud...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with serial.Serial(port, baud, timeout=0.5) as ser:
|
||||||
|
print("[Serial Monitor] Press Ctrl+C to exit.\n")
|
||||||
|
while True:
|
||||||
|
if ser.in_waiting:
|
||||||
|
line = ser.readline().decode(errors="replace")
|
||||||
|
if line:
|
||||||
|
print(line, end="")
|
||||||
|
|
||||||
|
time.sleep(0.01)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[Serial Monitor] Disconnected.")
|
||||||
|
except serial.SerialException as e:
|
||||||
|
print(f"[Error] Could not open serial port {port}: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
14
flashmon.bat
Normal file
14
flashmon.bat
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@echo off
|
||||||
|
REM =============================================
|
||||||
|
REM ESP32 Serial Monitor using settings.json
|
||||||
|
REM =============================================
|
||||||
|
|
||||||
|
IF NOT EXIST .venv\Scripts\python.exe (
|
||||||
|
echo [ERROR] .venv not found. Run setup-env.bat first.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
call .venv\Scripts\activate.bat
|
||||||
|
python flash_tool\flash.py
|
||||||
|
python flash_tool\monitor.py
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
idf_component_register(SRCS "system.c" "bubble.c" "keypad.c" "main.c"
|
idf_component_register(SRCS "bt_app.c" "system.c" "bubble.c" "keypad.c" "main.c"
|
||||||
"bt_app_core.c"
|
|
||||||
"gui.c"
|
"gui.c"
|
||||||
"lsm6dsv.c"
|
"lsm6dsv.c"
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
|
|||||||
@@ -12,9 +12,11 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/stream_buffer.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
#include "bt_app_core.h"
|
#include "bt_app.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
#include "esp_bt.h"
|
#include "esp_bt.h"
|
||||||
#include "esp_bt_main.h"
|
#include "esp_bt_main.h"
|
||||||
@@ -368,17 +370,214 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
|||||||
bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t btData[512];
|
|
||||||
|
|
||||||
static void fillBuffer(uint8_t *data, int32_t len)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
#define SAMPLE_RATE 44100
|
||||||
|
#define TONE_FREQ 440.0f // A4
|
||||||
|
#define FADE_FREQ 1.0f // 1 Hz fade L->R
|
||||||
|
#define STREAM_BUF_SIZE (8192)
|
||||||
|
#define CHUNK_SIZE (512)
|
||||||
|
|
||||||
|
StreamBufferHandle_t audio_stream_buf;
|
||||||
|
|
||||||
|
void generate_synth_pcm(uint8_t *buf, int len) {
|
||||||
|
static float phase = 0.0f;
|
||||||
|
static float fade_phase = 0.0f;
|
||||||
|
|
||||||
|
int16_t *samples = (int16_t *)buf;
|
||||||
|
int samples_needed = len / 4; // 4 bytes per stereo frame (2 bytes L, 2 bytes R)
|
||||||
|
|
||||||
|
for (int i = 0; i < samples_needed; i++) {
|
||||||
|
// Fade L/R amplitude: 0..1 for L, inverted for R
|
||||||
|
float fade = (sinf(2 * M_PI * fade_phase) + 1.0f) * 0.5f;
|
||||||
|
|
||||||
|
// Sine wave sample
|
||||||
|
float sample = sinf(2 * M_PI * phase);
|
||||||
|
|
||||||
|
int16_t left = (int16_t)(sample * fade * 32767);
|
||||||
|
int16_t right = (int16_t)(sample * (1.0f - fade) * 32767);
|
||||||
|
|
||||||
|
samples[i * 2 + 0] = left;
|
||||||
|
samples[i * 2 + 1] = right;
|
||||||
|
|
||||||
|
// Advance phases
|
||||||
|
phase += TONE_FREQ / SAMPLE_RATE;
|
||||||
|
if (phase >= 1.0f) phase -= 1.0f;
|
||||||
|
|
||||||
|
fade_phase += FADE_FREQ / SAMPLE_RATE;
|
||||||
|
if (fade_phase >= 1.0f) fade_phase -= 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MIN_RATE_HZ 1.0f
|
||||||
|
#define MAX_RATE_HZ 440.0f
|
||||||
|
#define CLICK_AMPLITUDE 32000 // 16-bit
|
||||||
|
|
||||||
|
static float click_timer = 0.0f;
|
||||||
|
|
||||||
|
void generate_synth_clicks(uint8_t *buf, int len, float balance) {
|
||||||
|
|
||||||
|
int16_t *samples = (int16_t *)buf;
|
||||||
|
int samples_needed = len / 4;
|
||||||
|
|
||||||
|
float abs_balance = fabsf(balance);
|
||||||
|
float rate_hz = MIN_RATE_HZ * powf(MAX_RATE_HZ / MIN_RATE_HZ, abs_balance);
|
||||||
|
float samples_per_click = SAMPLE_RATE / rate_hz;
|
||||||
|
|
||||||
|
for (int i = 0; i < samples_needed; i++) {
|
||||||
|
int16_t left = 0;
|
||||||
|
int16_t right = 0;
|
||||||
|
|
||||||
|
if (click_timer <= 0.0f) {
|
||||||
|
// Insert a short pulse: single sample spike
|
||||||
|
if (balance < 0) {
|
||||||
|
left = CLICK_AMPLITUDE;
|
||||||
|
} else if (balance > 0) {
|
||||||
|
right = CLICK_AMPLITUDE;
|
||||||
|
}
|
||||||
|
click_timer += samples_per_click;
|
||||||
|
}
|
||||||
|
|
||||||
|
click_timer -= 1.0f;
|
||||||
|
|
||||||
|
samples[i * 2 + 0] = left;
|
||||||
|
samples[i * 2 + 1] = right;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void audio_producer_task(void *pvParameters) {
|
||||||
|
uint8_t chunk[CHUNK_SIZE];
|
||||||
|
|
||||||
|
int core_id = xPortGetCoreID();
|
||||||
|
|
||||||
|
ESP_LOGI("Producer", "Running on core %d", core_id);
|
||||||
|
|
||||||
|
system_subscribe(xTaskGetCurrentTaskHandle());
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
generate_synth_pcm(chunk, sizeof(chunk));
|
||||||
|
|
||||||
|
size_t sent = xStreamBufferSend(audio_stream_buf, chunk, sizeof(chunk), portMAX_DELAY);
|
||||||
|
|
||||||
|
if (sent < sizeof(chunk)) {
|
||||||
|
ESP_LOGW(BT_APP_CORE_TAG, "Dropped %d bytes", sizeof(chunk) - sent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static float phase = 0.0f;
|
||||||
|
|
||||||
|
float balance = 0.0f; // -1.0 = left, +1.0 = right
|
||||||
|
|
||||||
|
uint32_t raw_value;
|
||||||
|
uint32_t notifiedBits = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// Non-blocking check for new notification:
|
||||||
|
|
||||||
|
// clear on entry (first param), wait for any bit, block forever
|
||||||
|
xTaskNotifyWait(
|
||||||
|
0, // clear any old bits on entry
|
||||||
|
0, // clear bits on exit
|
||||||
|
¬ifiedBits,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (notifiedBits & EM_EVENT_NEW_DATA)
|
||||||
|
{
|
||||||
|
ImuData_t d = system_getImuData();
|
||||||
|
|
||||||
|
if (fabs(d.raw[system_getPrimaryAxis()]) > 45.0f)
|
||||||
|
{
|
||||||
|
balance = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
balance = -d.angle / MAX_INDICATION_ANGLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (balance > 1.0f)
|
||||||
|
{
|
||||||
|
balance = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (balance < -1.0f)
|
||||||
|
{
|
||||||
|
balance = -1.0f;
|
||||||
|
}
|
||||||
|
generate_synth_clicks(chunk, sizeof(chunk), balance);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Synthesize audio using latest balance
|
||||||
|
int16_t *samples = (int16_t *)chunk;
|
||||||
|
int samples_needed = CHUNK_SIZE / 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < samples_needed; i++) {
|
||||||
|
float sample = sinf(2 * M_PI * phase);
|
||||||
|
|
||||||
|
float left_gain = 0.5f * (1.0f - balance);
|
||||||
|
float right_gain = 0.5f * (1.0f + balance);
|
||||||
|
|
||||||
|
int16_t left = (int16_t)(sample * left_gain * 32767);
|
||||||
|
int16_t right = (int16_t)(sample * right_gain * 32767);
|
||||||
|
|
||||||
|
samples[i * 2 + 0] = left;
|
||||||
|
samples[i * 2 + 1] = right;
|
||||||
|
|
||||||
|
phase += TONE_FREQ / SAMPLE_RATE;
|
||||||
|
if (phase >= 1.0f) phase -= 1.0f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Push chunk to FIFO
|
||||||
|
xStreamBufferSend(audio_stream_buf, chunk, sizeof(chunk), portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate some random noise to simulate source audio */
|
||||||
|
static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
|
||||||
|
{
|
||||||
|
size_t bytes_read = xStreamBufferReceive(audio_stream_buf, data, len, 0);
|
||||||
|
|
||||||
|
if (bytes_read < len) {
|
||||||
|
memset(data + bytes_read, 0, len - bytes_read); // fill silence
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
#if 0
|
||||||
|
if (data == NULL || len < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t *p_buf = (int16_t *)data;
|
||||||
|
for (int i = 0; i < (len >> 1); i++) {
|
||||||
|
p_buf[i] = rand() % (1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
/* Generate a continuous 440Hz sine wave */
|
/* Generate a continuous 440Hz sine wave */
|
||||||
static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
|
static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (data == NULL || len < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t *p_buf = (int16_t *)data;
|
||||||
|
for (int i = 0; i < (len >> 1); i++) {
|
||||||
|
p_buf[i] = rand() % (1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
#if 0
|
||||||
static double phase = 0.0;
|
static double phase = 0.0;
|
||||||
const double frequency = 440.0; // A4 tone (440 Hz)
|
const double frequency = 440.0; // A4 tone (440 Hz)
|
||||||
const double sample_rate = 44100.0; // 44.1 kHz sample rate
|
const double sample_rate = 44100.0; // 44.1 kHz sample rate
|
||||||
@@ -406,7 +605,9 @@ static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void bt_app_a2d_heart_beat(TimerHandle_t arg)
|
static void bt_app_a2d_heart_beat(TimerHandle_t arg)
|
||||||
{
|
{
|
||||||
@@ -551,6 +752,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
|
|||||||
}
|
}
|
||||||
case APP_AV_MEDIA_STATE_STARTED: {
|
case APP_AV_MEDIA_STATE_STARTED: {
|
||||||
if (event == BT_APP_HEART_BEAT_EVT) {
|
if (event == BT_APP_HEART_BEAT_EVT) {
|
||||||
|
#if 0
|
||||||
/* stop media after 10 heart beat intervals */
|
/* stop media after 10 heart beat intervals */
|
||||||
if (++s_intv_cnt >= 10) {
|
if (++s_intv_cnt >= 10) {
|
||||||
ESP_LOGI(BT_AV_TAG, "a2dp media suspending...");
|
ESP_LOGI(BT_AV_TAG, "a2dp media suspending...");
|
||||||
@@ -558,6 +760,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
|
|||||||
s_media_state = APP_AV_MEDIA_STATE_STOPPING;
|
s_media_state = APP_AV_MEDIA_STATE_STOPPING;
|
||||||
s_intv_cnt = 0;
|
s_intv_cnt = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -791,6 +994,10 @@ static void bt_app_task_handler(void *arg)
|
|||||||
{
|
{
|
||||||
bt_app_msg_t msg;
|
bt_app_msg_t msg;
|
||||||
|
|
||||||
|
int core_id = xPortGetCoreID();
|
||||||
|
|
||||||
|
ESP_LOGI("MY_TASK", "Running on core %d", core_id);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* receive message from work queue and handle it */
|
/* receive message from work queue and handle it */
|
||||||
if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (TickType_t)portMAX_DELAY)) {
|
if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (TickType_t)portMAX_DELAY)) {
|
||||||
@@ -846,7 +1053,9 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
|||||||
void bt_app_task_start_up(void)
|
void bt_app_task_start_up(void)
|
||||||
{
|
{
|
||||||
s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t));
|
s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t));
|
||||||
xTaskCreate(bt_app_task_handler, "BtAppTask", 4096, NULL, 10, &s_bt_app_task_handle);
|
//xTaskCreate(bt_app_task_handler, "BtAppTask", 8192, NULL, 10, &s_bt_app_task_handle);
|
||||||
|
|
||||||
|
xTaskCreatePinnedToCore(bt_app_task_handler, "BtAppTask", 8192, NULL, 10, NULL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_app_task_shut_down(void)
|
void bt_app_task_shut_down(void)
|
||||||
@@ -867,7 +1076,27 @@ void bt_app_init(void)
|
|||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
char bda_str[18] = {0};
|
char bda_str[18] = {0};
|
||||||
|
|
||||||
fillBuffer(btData, 512);
|
|
||||||
|
//esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level)
|
||||||
|
esp_power_level_t pmin;
|
||||||
|
esp_power_level_t pmax;
|
||||||
|
esp_bredr_tx_power_get(&pmin, &pmax);
|
||||||
|
|
||||||
|
ESP_LOGI(BT_APP_CORE_TAG, "BT Power min = %d\nBT Power max = %d", pmin, pmax);
|
||||||
|
|
||||||
|
//pmin = ESP_PWR_LVL_P6;
|
||||||
|
//pmax = ESP_PWR_LVL_P7;
|
||||||
|
pmin = ESP_PWR_LVL_N12;
|
||||||
|
pmax = ESP_PWR_LVL_N9;
|
||||||
|
|
||||||
|
esp_err_t err = esp_bredr_tx_power_set(pmin, pmax);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(BT_APP_CORE_TAG, "Failed to set TX power: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_bredr_tx_power_get(&pmin, &pmax);
|
||||||
|
|
||||||
|
ESP_LOGI(BT_APP_CORE_TAG, "BT Power min = %d\nBT Power max = %d", pmin, pmax);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This example only uses the functions of Classical Bluetooth.
|
* This example only uses the functions of Classical Bluetooth.
|
||||||
@@ -885,6 +1114,10 @@ void bt_app_init(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = esp_bredr_tx_power_set(pmin, pmax);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(BT_APP_CORE_TAG, "Failed to set TX power: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
|
esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
|
||||||
#if (CONFIG_EXAMPLE_SSP_ENABLED == false)
|
#if (CONFIG_EXAMPLE_SSP_ENABLED == false)
|
||||||
bluedroid_cfg.ssp_en = false;
|
bluedroid_cfg.ssp_en = false;
|
||||||
@@ -918,4 +1151,19 @@ void bt_app_init(void)
|
|||||||
bt_app_task_start_up();
|
bt_app_task_start_up();
|
||||||
/* Bluetooth device name, connection mode and profile set up */
|
/* Bluetooth device name, connection mode and profile set up */
|
||||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_STACK_UP_EVT, NULL, 0, NULL);
|
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_STACK_UP_EVT, NULL, 0, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
audio_stream_buf = xStreamBufferCreate(STREAM_BUF_SIZE, 1);
|
||||||
|
assert(audio_stream_buf != NULL);
|
||||||
|
|
||||||
|
//xTaskCreate(audio_producer_task, "audio_producer", 4096, NULL, 5, NULL);
|
||||||
|
xTaskCreatePinnedToCore(audio_producer_task, "audio_producer", 4096, NULL, 5, NULL, 1);
|
||||||
|
|
||||||
|
ESP_LOGI(BT_APP_CORE_TAG, "Audio synth producer started");
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#define PIN_NUM_BUTTON_0 36
|
#define PIN_NUM_BUTTON_0 36
|
||||||
#define PIN_NUM_BUTTON_1 39
|
#define PIN_NUM_BUTTON_1 39
|
||||||
#define PIN_NUM_LED_1 32
|
#define PIN_NUM_LED_1 32
|
||||||
|
#define PIN_NUM_LED_2 33
|
||||||
#define PIN_NUM_nON 26
|
#define PIN_NUM_nON 26
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
90
main/gui.c
90
main/gui.c
@@ -105,9 +105,9 @@ static void create_lvgl_demo(void)
|
|||||||
lvgl_port_lock(0);
|
lvgl_port_lock(0);
|
||||||
// Create a screen with black background
|
// Create a screen with black background
|
||||||
lv_obj_t *scr = lv_scr_act();
|
lv_obj_t *scr = lv_scr_act();
|
||||||
//create_menu(scr);
|
|
||||||
createBubble(scr);
|
createBubble(scr);
|
||||||
build_scrollable_menu();
|
//build_scrollable_menu();
|
||||||
|
|
||||||
lvgl_port_unlock();
|
lvgl_port_unlock();
|
||||||
|
|
||||||
@@ -167,8 +167,8 @@ static void lvgl_init(void)
|
|||||||
#if 1
|
#if 1
|
||||||
const lvgl_port_cfg_t lvgl_cfg = {
|
const lvgl_port_cfg_t lvgl_cfg = {
|
||||||
.task_priority = 4, // LVGL task priority
|
.task_priority = 4, // LVGL task priority
|
||||||
.task_stack = 32768, // LVGL task stack size
|
.task_stack = 16384, // LVGL task stack size
|
||||||
.task_affinity = -1, // LVGL task can run on any core
|
.task_affinity = 0, // LVGL task can run on any core
|
||||||
.task_max_sleep_ms = 500, // Maximum sleep in LVGL task
|
.task_max_sleep_ms = 500, // Maximum sleep in LVGL task
|
||||||
.timer_period_ms = 5 // LVGL timer period
|
.timer_period_ms = 5 // LVGL timer period
|
||||||
};
|
};
|
||||||
@@ -180,7 +180,7 @@ static void lvgl_init(void)
|
|||||||
.io_handle = io_handle,
|
.io_handle = io_handle,
|
||||||
.panel_handle = panel_handle,
|
.panel_handle = panel_handle,
|
||||||
.buffer_size = LCD_H_RES * LCD_V_RES * 2,
|
.buffer_size = LCD_H_RES * LCD_V_RES * 2,
|
||||||
.double_buffer = true,
|
.double_buffer = false,
|
||||||
.hres = LCD_H_RES,
|
.hres = LCD_H_RES,
|
||||||
.vres = LCD_V_RES,
|
.vres = LCD_V_RES,
|
||||||
.monochrome = false,
|
.monochrome = false,
|
||||||
@@ -219,15 +219,10 @@ static void createBubble(lv_obj_t * scr)
|
|||||||
_bubble = level;
|
_bubble = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_test()
|
|
||||||
{
|
|
||||||
lv_obj_t *label = lv_label_create(lv_screen_active());
|
|
||||||
lv_label_set_text(label, "Hello, LVGL 9.2!");
|
|
||||||
lv_obj_center(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gui_start(void)
|
void gui_start(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Initialize LCD
|
// Initialize LCD
|
||||||
lcd_init();
|
lcd_init();
|
||||||
|
|
||||||
@@ -237,7 +232,6 @@ void gui_start(void)
|
|||||||
// Create UI
|
// Create UI
|
||||||
create_lvgl_demo();
|
create_lvgl_demo();
|
||||||
|
|
||||||
|
|
||||||
keypad_start();
|
keypad_start();
|
||||||
|
|
||||||
gpio_set_level(PIN_NUM_BK_LIGHT, 1);
|
gpio_set_level(PIN_NUM_BK_LIGHT, 1);
|
||||||
@@ -333,18 +327,6 @@ static void refresh_highlight(void) {
|
|||||||
next = lv_obj_get_child(page, index);
|
next = lv_obj_get_child(page, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for(int i = 0; i < ITEM_COUNT; i++) {
|
|
||||||
// if(i == selected_idx) {
|
|
||||||
// lv_obj_set_style_bg_color(btn_array[i], lv_color_hex(0xFF8800), 0);
|
|
||||||
// lv_obj_set_style_text_color(lv_obj_get_child(btn_array[i],0),
|
|
||||||
// lv_color_white(), 0);
|
|
||||||
// } else {
|
|
||||||
// lv_obj_set_style_bg_color(btn_array[i], lv_color_white(), 0);
|
|
||||||
// lv_obj_set_style_text_color(lv_obj_get_child(btn_array[i],0),
|
|
||||||
// lv_color_black(), 0);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (selected)
|
if (selected)
|
||||||
{
|
{
|
||||||
lv_obj_scroll_to_view(selected, LV_ANIM_ON);
|
lv_obj_scroll_to_view(selected, LV_ANIM_ON);
|
||||||
@@ -522,39 +504,6 @@ static void build_scrollable_menu(void) {
|
|||||||
|
|
||||||
_currentPage = main;
|
_currentPage = main;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for(int i = 0; i < ITEM_COUNT; i++) {
|
|
||||||
// create a full-width button in that section
|
|
||||||
lv_obj_t * btn = lv_btn_create(main);
|
|
||||||
lv_obj_set_size(btn, LV_PCT(100), ROW_H);
|
|
||||||
|
|
||||||
// style it just like your old list
|
|
||||||
lv_obj_set_style_bg_color(btn, lv_color_white(), 0);
|
|
||||||
lv_obj_set_style_radius(btn, 0, LV_PART_MAIN);
|
|
||||||
lv_obj_set_style_border_width(btn, 0, LV_PART_MAIN);
|
|
||||||
lv_obj_clear_flag(btn, LV_OBJ_FLAG_SCROLLABLE);
|
|
||||||
|
|
||||||
|
|
||||||
// label & center
|
|
||||||
lv_obj_t * lbl = lv_label_create(btn);
|
|
||||||
lv_label_set_text(lbl, items[i]);
|
|
||||||
lv_obj_set_style_radius(lbl, 0, LV_PART_MAIN | LV_STATE_ANY);
|
|
||||||
lv_obj_set_style_border_width(lbl, 0, LV_PART_MAIN | LV_STATE_ANY);
|
|
||||||
//lv_obj_center(lbl);
|
|
||||||
|
|
||||||
// click callback
|
|
||||||
lv_obj_add_event_cb(btn, btn_click_cb, LV_EVENT_CLICKED, NULL);
|
|
||||||
|
|
||||||
// save for highlight/scroll
|
|
||||||
btn_array[i] = btn;
|
|
||||||
}
|
|
||||||
|
|
||||||
// lv_obj_t * content = lv_obj_get_child(page, 0);
|
|
||||||
// lv_obj_set_style_radius(content, 0, LV_PART_MAIN | LV_STATE_ANY);
|
|
||||||
// lv_obj_set_style_border_width(content, 0, LV_PART_MAIN | LV_STATE_ANY);
|
|
||||||
#endif
|
|
||||||
// 6) Initial highlight
|
// 6) Initial highlight
|
||||||
selected_idx = 0;
|
selected_idx = 0;
|
||||||
refresh_highlight();
|
refresh_highlight();
|
||||||
@@ -563,6 +512,7 @@ static void build_scrollable_menu(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void gui_task(void)
|
static void gui_task(void)
|
||||||
{
|
{
|
||||||
system_subscribe(xTaskGetCurrentTaskHandle());
|
system_subscribe(xTaskGetCurrentTaskHandle());
|
||||||
@@ -571,8 +521,12 @@ static void gui_task(void)
|
|||||||
QueueHandle_t q = keypad_getQueue();
|
QueueHandle_t q = keypad_getQueue();
|
||||||
uint32_t ev = 0;
|
uint32_t ev = 0;
|
||||||
|
|
||||||
|
LOCK();
|
||||||
|
// _mode = GUI_MENU;
|
||||||
|
// lv_obj_remove_flag(_menu, LV_OBJ_FLAG_HIDDEN);
|
||||||
lv_obj_remove_flag(_bubble, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_remove_flag(_bubble, LV_OBJ_FLAG_HIDDEN);
|
||||||
lv_obj_add_flag(_menu, LV_OBJ_FLAG_HIDDEN);
|
//lv_obj_add_flag(_menu, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
UNLOCK();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -581,6 +535,19 @@ static void gui_task(void)
|
|||||||
if (xQueueReceive(q, &ev, pdMS_TO_TICKS(10)) == pdTRUE)
|
if (xQueueReceive(q, &ev, pdMS_TO_TICKS(10)) == pdTRUE)
|
||||||
{
|
{
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
|
|
||||||
|
case (KEY_UP << KEY_LONG_PRESS):
|
||||||
|
{
|
||||||
|
system_setZeroAngle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case (KEY_DOWN << KEY_LONG_PRESS):
|
||||||
|
{
|
||||||
|
system_clearZeroAngle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
case (KEY0 << KEY_SHORT_PRESS):
|
case (KEY0 << KEY_SHORT_PRESS):
|
||||||
|
|
||||||
if (_mode == GUI_MENU)
|
if (_mode == GUI_MENU)
|
||||||
@@ -590,6 +557,8 @@ static void gui_task(void)
|
|||||||
ESP_LOGI(TAG, "MAIN: Button 1 SHORT");
|
ESP_LOGI(TAG, "MAIN: Button 1 SHORT");
|
||||||
break;
|
break;
|
||||||
case (KEY0 << KEY_LONG_PRESS):
|
case (KEY0 << KEY_LONG_PRESS):
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
if (_mode != GUI_MENU)
|
if (_mode != GUI_MENU)
|
||||||
{
|
{
|
||||||
@@ -605,8 +574,8 @@ static void gui_task(void)
|
|||||||
// lv_obj_remove_flag(_bubble, LV_OBJ_FLAG_HIDDEN);
|
// lv_obj_remove_flag(_bubble, LV_OBJ_FLAG_HIDDEN);
|
||||||
// lv_obj_add_flag(_menu, LV_OBJ_FLAG_HIDDEN);
|
// lv_obj_add_flag(_menu, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case (KEY1 << KEY_SHORT_PRESS):
|
case (KEY1 << KEY_SHORT_PRESS):
|
||||||
{
|
{
|
||||||
if (_mode == GUI_MENU)
|
if (_mode == GUI_MENU)
|
||||||
@@ -619,6 +588,7 @@ static void gui_task(void)
|
|||||||
ESP_LOGI(TAG, "MAIN: Button 2 LONG");
|
ESP_LOGI(TAG, "MAIN: Button 2 LONG");
|
||||||
gpio_set_level(PIN_NUM_nON, 0);
|
gpio_set_level(PIN_NUM_nON, 0);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -633,7 +603,7 @@ static void gui_task(void)
|
|||||||
0xFFFFFFFF, // clear any old bits on entry
|
0xFFFFFFFF, // clear any old bits on entry
|
||||||
0xFFFFFFFF, // clear bits on exit
|
0xFFFFFFFF, // clear bits on exit
|
||||||
¬ifiedBits,
|
¬ifiedBits,
|
||||||
pdMS_TO_TICKS(10));
|
pdMS_TO_TICKS(100));
|
||||||
|
|
||||||
if (notifiedBits & EM_EVENT_NEW_DATA)
|
if (notifiedBits & EM_EVENT_NEW_DATA)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ typedef enum
|
|||||||
#define KEY_SHORT_PRESS 0
|
#define KEY_SHORT_PRESS 0
|
||||||
#define KEY_LONG_PRESS 4
|
#define KEY_LONG_PRESS 4
|
||||||
|
|
||||||
|
#define KEY_UP KEY0
|
||||||
|
#define KEY_DOWN KEY1
|
||||||
|
|
||||||
void keypad_start(void);
|
void keypad_start(void);
|
||||||
QueueHandle_t keypad_getQueue(void);
|
QueueHandle_t keypad_getQueue(void);
|
||||||
|
|||||||
79
main/main.c
79
main/main.c
@@ -21,7 +21,7 @@
|
|||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
|
|
||||||
#include "bt_app_core.h"
|
#include "bt_app.h"
|
||||||
#include "lsm6dsv.h"
|
#include "lsm6dsv.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
@@ -71,8 +71,9 @@ static void init_gpio(void)
|
|||||||
|
|
||||||
|
|
||||||
// Configure output GPIO
|
// Configure output GPIO
|
||||||
io_conf.pin_bit_mask = (1ULL << PIN_NUM_LED_1);
|
io_conf.pin_bit_mask = (1ULL << PIN_NUM_LED_1) | (1ULL << PIN_NUM_LED_2);
|
||||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||||
gpio_config(&io_conf);
|
gpio_config(&io_conf);
|
||||||
@@ -86,7 +87,8 @@ static void init_gpio(void)
|
|||||||
|
|
||||||
io_conf.pin_bit_mask = (1ULL << PIN_NUM_nON);
|
io_conf.pin_bit_mask = (1ULL << PIN_NUM_nON);
|
||||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||||
|
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||||
gpio_config(&io_conf);
|
gpio_config(&io_conf);
|
||||||
#endif
|
#endif
|
||||||
@@ -95,8 +97,8 @@ static void init_gpio(void)
|
|||||||
|
|
||||||
// Configure LCD Backlight GPIO
|
// Configure LCD Backlight GPIO
|
||||||
io_conf.pin_bit_mask = (1ULL << PIN_NUM_BK_LIGHT);
|
io_conf.pin_bit_mask = (1ULL << PIN_NUM_BK_LIGHT);
|
||||||
|
|
||||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||||
gpio_config(&io_conf);
|
gpio_config(&io_conf);
|
||||||
@@ -116,7 +118,7 @@ static void imu_task(void *pvParameters) {
|
|||||||
ImuData_t imu;
|
ImuData_t imu;
|
||||||
|
|
||||||
LowPassFilter lpf;
|
LowPassFilter lpf;
|
||||||
LPF_Init(&lpf, 0.2, 0);
|
LPF_Init(&lpf, FILTER_COEFF, 0);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
@@ -170,20 +172,20 @@ static void imu_task(void *pvParameters) {
|
|||||||
|
|
||||||
float angle;
|
float angle;
|
||||||
|
|
||||||
if (imu.raw[ANGLE_XY] > MAX_INDICATION_ANGLE)
|
|
||||||
|
angle = system_getAngle();
|
||||||
|
|
||||||
|
if (angle > MAX_INDICATION_ANGLE)
|
||||||
{
|
{
|
||||||
angle = MAX_INDICATION_ANGLE;
|
angle = MAX_INDICATION_ANGLE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (imu.raw[ANGLE_XY] > MAX_INDICATION_ANGLE)
|
if (angle < -MAX_INDICATION_ANGLE)
|
||||||
{
|
{
|
||||||
angle = -MAX_INDICATION_ANGLE;
|
angle = -MAX_INDICATION_ANGLE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
angle = imu.raw[ANGLE_XY];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// low pass filter the angle measurement
|
||||||
imu.angle = LPF_Update(&lpf, angle);
|
imu.angle = LPF_Update(&lpf, angle);
|
||||||
|
|
||||||
//imu.filtered[ANGLE_XY] = LPF_Update(&lpf, imu.raw[ANGLE_XY]);
|
//imu.filtered[ANGLE_XY] = LPF_Update(&lpf, imu.raw[ANGLE_XY]);
|
||||||
@@ -197,7 +199,7 @@ static void imu_task(void *pvParameters) {
|
|||||||
#if 0
|
#if 0
|
||||||
snprintf(data_str, sizeof(data_str),
|
snprintf(data_str, sizeof(data_str),
|
||||||
"(%.1f, %.1f, %.1f) (%.2f, %.2f, %.2f)",
|
"(%.1f, %.1f, %.1f) (%.2f, %.2f, %.2f)",
|
||||||
xz, yz, xy,
|
imu.raw[ANGLE_XZ], imu.raw[ANGLE_YZ], imu.raw[ANGLE_XY],
|
||||||
(float)imu_data.acc_x, (float)imu_data.acc_y, (float)imu_data.acc_z);
|
(float)imu_data.acc_x, (float)imu_data.acc_y, (float)imu_data.acc_z);
|
||||||
ESP_LOGI(TAG, "%s", data_str);
|
ESP_LOGI(TAG, "%s", data_str);
|
||||||
#endif
|
#endif
|
||||||
@@ -218,12 +220,12 @@ void app_main(void)
|
|||||||
{
|
{
|
||||||
|
|
||||||
/* initialize NVS — it is used to store PHY calibration data */
|
/* initialize NVS — it is used to store PHY calibration data */
|
||||||
// esp_err_t ret = nvs_flash_init();
|
esp_err_t ret = nvs_flash_init();
|
||||||
// if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
// ESP_ERROR_CHECK(nvs_flash_erase());
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
// ret = nvs_flash_init();
|
ret = nvs_flash_init();
|
||||||
// }
|
}
|
||||||
// ESP_ERROR_CHECK(ret);
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
init_gpio();
|
init_gpio();
|
||||||
|
|
||||||
@@ -241,26 +243,49 @@ void app_main(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bt_app_init();
|
||||||
|
|
||||||
gui_start();
|
gui_start();
|
||||||
|
|
||||||
|
gpio_set_level(PIN_NUM_LED_2, 1);
|
||||||
|
|
||||||
|
|
||||||
//bt_app_init();
|
#if 0
|
||||||
|
|
||||||
|
keypad_start();
|
||||||
|
QueueHandle_t q = keypad_getQueue();
|
||||||
|
uint32_t ev = 0;
|
||||||
|
|
||||||
|
//gpio_set_level(PIN_NUM_LED_1, 1);
|
||||||
|
gpio_set_level(PIN_NUM_LED_2, 1);
|
||||||
|
|
||||||
// Main loop - LVGL task will run automatically
|
// Main loop - LVGL task will run automatically
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
// int level = gpio_get_level(PIN_NUM_BUTTON_1); // Read input GPIO
|
if (xQueueReceive(q, &ev, pdMS_TO_TICKS(10)) == pdTRUE)
|
||||||
// gpio_set_level(PIN_NUM_LED_1, level);
|
{
|
||||||
|
switch (ev)
|
||||||
|
{
|
||||||
|
case (KEY_UP << KEY_LONG_PRESS):
|
||||||
|
{
|
||||||
|
system_setZeroAngle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//gpio_set_level(PIN_NUM_nON, (level ? 0 : 1));
|
case (KEY_DOWN << KEY_LONG_PRESS):
|
||||||
|
{
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
system_clearZeroAngle();
|
||||||
|
break;
|
||||||
//gui_service();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,12 +8,77 @@ static EventManager_t _eventManager;
|
|||||||
|
|
||||||
void system_init(void)
|
void system_init(void)
|
||||||
{
|
{
|
||||||
|
_systemState.zeroAngle = 0.0f;
|
||||||
|
_systemState.primaryAxis = PRIMARY_AXIS;
|
||||||
|
|
||||||
EventGroupHandle_t evt = xEventGroupCreate();
|
EventGroupHandle_t evt = xEventGroupCreate();
|
||||||
|
|
||||||
_eventManager.count = 0;
|
_eventManager.count = 0;
|
||||||
_eventManager.mutex = xSemaphoreCreateMutex();
|
_eventManager.mutex = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int system_getPrimaryAxis(void)
|
||||||
|
{
|
||||||
|
int axis;
|
||||||
|
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
axis = _systemState.primaryAxis;
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
|
||||||
|
return axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
float system_getAngle(void)
|
||||||
|
{
|
||||||
|
float angle;
|
||||||
|
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
|
||||||
|
angle = _systemState.imu.raw[_systemState.primaryAxis] - _systemState.zeroAngle;
|
||||||
|
|
||||||
|
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void system_setZeroAngle(void)
|
||||||
|
{
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
|
||||||
|
_systemState.zeroAngle = _systemState.imu.raw[_systemState.primaryAxis];
|
||||||
|
|
||||||
|
ESP_LOGI("system", "Zero: %.1f", _systemState.zeroAngle);
|
||||||
|
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void system_clearZeroAngle(void)
|
||||||
|
{
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
_systemState.zeroAngle = 0.0f;
|
||||||
|
|
||||||
|
ESP_LOGI("system", "Zero: %.1f", _systemState.zeroAngle);
|
||||||
|
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float system_getZeroAngle(void)
|
||||||
|
{
|
||||||
|
float angle;
|
||||||
|
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
angle = _systemState.zeroAngle;
|
||||||
|
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
void system_setImuData(ImuData_t imu)
|
void system_setImuData(ImuData_t imu)
|
||||||
{
|
{
|
||||||
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
#define DISABLE_GUI
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ANGLE_XY = 0,
|
ANGLE_XY = 0,
|
||||||
@@ -27,11 +29,15 @@ typedef struct SystemState_s
|
|||||||
|
|
||||||
EventGroupHandle_t event;
|
EventGroupHandle_t event;
|
||||||
|
|
||||||
|
float zeroAngle;
|
||||||
|
int primaryAxis;
|
||||||
|
|
||||||
} SystemState_t;
|
} SystemState_t;
|
||||||
|
|
||||||
|
|
||||||
#define MAX_INDICATION_ANGLE 10.0f
|
#define MAX_INDICATION_ANGLE 5.0f
|
||||||
|
#define FILTER_COEFF 0.2f // 0 to 1 Smaller number is heavier filter
|
||||||
|
#define PRIMARY_AXIS ANGLE_YZ
|
||||||
|
|
||||||
#define EM_MAX_SUBSCRIBERS 8 // tweak as needed
|
#define EM_MAX_SUBSCRIBERS 8 // tweak as needed
|
||||||
#define EM_EVENT_NEW_DATA (1UL<<0)
|
#define EM_EVENT_NEW_DATA (1UL<<0)
|
||||||
@@ -49,6 +55,13 @@ void system_setImuData(ImuData_t imu);
|
|||||||
|
|
||||||
ImuData_t system_getImuData(void);
|
ImuData_t system_getImuData(void);
|
||||||
|
|
||||||
|
int system_getPrimaryAxis(void);
|
||||||
|
float system_getAngle(void);
|
||||||
|
|
||||||
|
void system_setZeroAngle(void);
|
||||||
|
void system_clearZeroAngle(void);
|
||||||
|
float system_getZeroAngle(void);
|
||||||
|
|
||||||
// Subscribe (register) current task to receive events
|
// Subscribe (register) current task to receive events
|
||||||
BaseType_t system_subscribe(TaskHandle_t task);
|
BaseType_t system_subscribe(TaskHandle_t task);
|
||||||
|
|
||||||
|
|||||||
13
monitor.bat
Normal file
13
monitor.bat
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
@echo off
|
||||||
|
REM =============================================
|
||||||
|
REM ESP32 Serial Monitor using settings.json
|
||||||
|
REM =============================================
|
||||||
|
|
||||||
|
IF NOT EXIST .venv\Scripts\python.exe (
|
||||||
|
echo [ERROR] .venv not found. Run setup-env.bat first.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
call .venv\Scripts\activate.bat
|
||||||
|
python flash_tool\monitor.py
|
||||||
10
prepare_config.py
Normal file
10
prepare_config.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
with open("settings.json") as f:
|
||||||
|
cfg = json.load(f)
|
||||||
|
|
||||||
|
with open("project_settings.cmake", "w") as out:
|
||||||
|
out.write(f'set(PROJECT_NAME "{cfg["project_name"]}")\n')
|
||||||
|
out.write(f'set(CHIP "{cfg["chip"]}")\n')
|
||||||
|
out.write(f'set(PORT "{cfg["port"]}")\n')
|
||||||
|
out.write(f'set(BAUD "{cfg["baud"]}")\n')
|
||||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
esptool
|
||||||
|
pyserial
|
||||||
|
|
||||||
23
sdkconfig
23
sdkconfig
@@ -353,14 +353,14 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
|
|||||||
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
|
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
|
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
|
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
|
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||||
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
||||||
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
||||||
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
||||||
@@ -393,8 +393,8 @@ CONFIG_EXAMPLE_SSP_ENABLED=y
|
|||||||
#
|
#
|
||||||
# Compiler options
|
# Compiler options
|
||||||
#
|
#
|
||||||
CONFIG_COMPILER_OPTIMIZATION_DEBUG=y
|
# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
|
# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
||||||
@@ -1448,7 +1448,6 @@ CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1
|
|||||||
#
|
#
|
||||||
# Port
|
# Port
|
||||||
#
|
#
|
||||||
CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y
|
|
||||||
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
||||||
CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y
|
CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y
|
||||||
# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set
|
# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set
|
||||||
@@ -1497,7 +1496,7 @@ CONFIG_HEAP_TRACING_OFF=y
|
|||||||
# CONFIG_HEAP_TRACING_TOHOST is not set
|
# CONFIG_HEAP_TRACING_TOHOST is not set
|
||||||
# CONFIG_HEAP_USE_HOOKS is not set
|
# CONFIG_HEAP_USE_HOOKS is not set
|
||||||
# CONFIG_HEAP_TASK_TRACKING is not set
|
# CONFIG_HEAP_TASK_TRACKING is not set
|
||||||
# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set
|
CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS=y
|
||||||
# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set
|
# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set
|
||||||
# end of Heap memory debugging
|
# end of Heap memory debugging
|
||||||
|
|
||||||
@@ -2496,11 +2495,11 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3
|
|||||||
CONFIG_FLASHMODE_DIO=y
|
CONFIG_FLASHMODE_DIO=y
|
||||||
# CONFIG_FLASHMODE_DOUT is not set
|
# CONFIG_FLASHMODE_DOUT is not set
|
||||||
CONFIG_MONITOR_BAUD=115200
|
CONFIG_MONITOR_BAUD=115200
|
||||||
CONFIG_OPTIMIZATION_LEVEL_DEBUG=y
|
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y
|
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
|
# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set
|
||||||
# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set
|
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
|
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
|
||||||
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
||||||
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||||
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
|
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
|
||||||
|
|||||||
9
sdkconfig.defaults
Normal file
9
sdkconfig.defaults
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Override some defaults so BT stack is enabled and
|
||||||
|
# Classic BT is enabled
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n
|
||||||
|
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y
|
||||||
|
CONFIG_BTDM_CTRL_MODE_BTDM=n
|
||||||
|
CONFIG_BT_BLUEDROID_ENABLED=y
|
||||||
|
CONFIG_BT_CLASSIC_ENABLED=y
|
||||||
|
CONFIG_BT_A2DP_ENABLE=y
|
||||||
2888
sdkconfig.old
Normal file
2888
sdkconfig.old
Normal file
File diff suppressed because it is too large
Load Diff
12
settings.json
Normal file
12
settings.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"project_name": "soundshot",
|
||||||
|
"chip": "esp32h2",
|
||||||
|
"port": "COM8",
|
||||||
|
"monitor_baud": 115200,
|
||||||
|
"flash_baud": 460800,
|
||||||
|
"flash_mode": "dio",
|
||||||
|
"flash_freq": "48m",
|
||||||
|
"flash_size": "2MB",
|
||||||
|
"before": "default-reset",
|
||||||
|
"after": "hard-reset"
|
||||||
|
}
|
||||||
17
setup-env.bat
Normal file
17
setup-env.bat
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
echo [ESP32 Setup] Creating Python virtual environment...
|
||||||
|
python -m venv .venv
|
||||||
|
|
||||||
|
echo [ESP32 Setup] Activating environment...
|
||||||
|
call .venv\Scripts\activate.bat
|
||||||
|
|
||||||
|
echo [ESP32 Setup] Installing dependencies...
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
echo [ESP32 Setup] Done!
|
||||||
|
echo To activate environment later: call .venv\Scripts\activate.bat
|
||||||
|
|
||||||
|
endlocal
|
||||||
|
pause
|
||||||
Reference in New Issue
Block a user