Skip to content

Commit 955f2d0

Browse files
authored
Add ESP32-C6 and ESP32-C3 support
* Change Id to 2446 * Add ESP32-C6 and ESP32-C3 support * Update release.yml
1 parent f086bac commit 955f2d0

4 files changed

Lines changed: 178 additions & 42 deletions

File tree

.github/workflows/release.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,36 @@ jobs:
4747
cd ..
4848
cp ${pioenv}/firmware.bin firmware_output/${pioenv}.bin
4949
cp ${pioenv}/merged-firmware.bin firmware_output/${pioenv}_full.bin
50+
51+
- name: Build & Package esp32-c6-N4 Firmware
52+
run: |
53+
pioenv=esp32-c6-N4
54+
pio run --environment ${pioenv}
55+
mkdir ${pioenv}
56+
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin ${pioenv}/boot_app0.bin
57+
cp .pio/build/${pioenv}/firmware.bin ${pioenv}/firmware.bin
58+
cp .pio/build/${pioenv}/bootloader.bin ${pioenv}/bootloader.bin
59+
cp .pio/build/${pioenv}/partitions.bin ${pioenv}/partitions.bin
60+
cd ${pioenv}
61+
esptool.py --chip esp32-c6 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 4MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin
62+
cd ..
63+
cp ${pioenv}/firmware.bin firmware_output/${pioenv}.bin
64+
cp ${pioenv}/merged-firmware.bin firmware_output/${pioenv}_full.bin
65+
66+
- name: Build & Package esp32-c3-N4 Firmware
67+
run: |
68+
pioenv=esp32-c3-N4
69+
pio run --environment ${pioenv}
70+
mkdir ${pioenv}
71+
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin ${pioenv}/boot_app0.bin
72+
cp .pio/build/${pioenv}/firmware.bin ${pioenv}/firmware.bin
73+
cp .pio/build/${pioenv}/bootloader.bin ${pioenv}/bootloader.bin
74+
cp .pio/build/${pioenv}/partitions.bin ${pioenv}/partitions.bin
75+
cd ${pioenv}
76+
esptool.py --chip esp32-c6 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 4MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin
77+
cd ..
78+
cp ${pioenv}/firmware.bin firmware_output/${pioenv}.bin
79+
cp ${pioenv}/merged-firmware.bin firmware_output/${pioenv}_full.bin
5080
5181
- name: Upload Release Assets
5282
uses: svenstaro/upload-release-action@v2

platformio.ini

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,38 @@ board_upload.maximum_size = 16777216
3838
board_upload.maximum_ram_size = 327680
3939
board_upload.flash_size = 16MB
4040
monitor_speed = 115200
41-
monitor_filters = esp32_exception_decoder
41+
42+
[env:esp32-c3-N4]
43+
platform = espressif32
44+
framework = arduino
45+
build_flags =
46+
-DTARGET_ESP32
47+
-DARDUINO_USB_MODE=1
48+
-DARDUINO_USB_CDC_ON_BOOT=1
49+
-DCONFIG_FREERTOS_WATCHDOG_TIMEOUT_S=120
50+
board_build.filesystem = littlefs
51+
board = esp32-c3-devkitm-1
52+
monitor_speed = 115200
53+
54+
[env:esp32-c6-N4]
55+
platform = espressif32
56+
framework = arduino
57+
build_flags =
58+
-DTARGET_ESP32
59+
-DARDUINO_USB_MODE=1
60+
-DARDUINO_USB_CDC_ON_BOOT=1
61+
-DCONFIG_FREERTOS_WATCHDOG_TIMEOUT_S=120
62+
board_build.filesystem = littlefs
63+
board = esp32-c6-devkitm-1
64+
monitor_speed = 115200
65+
66+
#[env:esp32-N4]
67+
#platform = espressif32
68+
#framework = arduino
69+
#build_flags =
70+
# -DTARGET_ESP32
71+
# -DCONFIG_FREERTOS_WATCHDOG_TIMEOUT_S=120
72+
#board_build.filesystem = littlefs
73+
#board = esp32dev
74+
#board_build.partitions = huge_app.csv
75+
#monitor_speed = 115200

src/main.cpp

Lines changed: 112 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,50 @@
22

33
#ifdef TARGET_NRF
44
BLEDfu bledfu;
5-
BLEService imageService("1337");
6-
BLECharacteristic imageCharacteristic("1337", BLEWrite | BLEWriteWithoutResponse | BLENotify, 512);
5+
BLEService imageService("2446");
6+
BLECharacteristic imageCharacteristic("2446", BLEWrite | BLEWriteWithoutResponse | BLENotify, 512);
77
#endif
88

99
#ifdef TARGET_ESP32
10-
// BLE Server Callbacks
10+
// Define queue sizes and structures first
11+
#define RESPONSE_QUEUE_SIZE 10
12+
#define MAX_RESPONSE_SIZE 512
13+
#define COMMAND_QUEUE_SIZE 5
14+
#define MAX_COMMAND_SIZE 512
15+
16+
struct ResponseQueueItem {
17+
uint8_t data[MAX_RESPONSE_SIZE];
18+
uint16_t len;
19+
bool pending;
20+
};
21+
22+
struct CommandQueueItem {
23+
uint8_t data[MAX_COMMAND_SIZE];
24+
uint16_t len;
25+
bool pending;
26+
};
27+
28+
ResponseQueueItem responseQueue[RESPONSE_QUEUE_SIZE];
29+
uint8_t responseQueueHead = 0;
30+
uint8_t responseQueueTail = 0;
31+
32+
CommandQueueItem commandQueue[COMMAND_QUEUE_SIZE];
33+
uint8_t commandQueueHead = 0;
34+
uint8_t commandQueueTail = 0;
35+
1136
class MyBLEServerCallbacks : public BLEServerCallbacks {
1237
void onConnect(BLEServer* pServer) {
1338
writeSerial("=== BLE CLIENT CONNECTED (ESP32) ===");
1439
writeSerial("Client connected to ESP32 BLE server");
1540
delay(100); // Give connection time to fully establish
1641
writeSerial("Number of connected clients: " + String(pServer->getConnectedCount()));
1742
}
18-
1943
void onDisconnect(BLEServer* pServer) {
2044
writeSerial("=== BLE CLIENT DISCONNECTED (ESP32) ===");
2145
writeSerial("Client disconnected from ESP32 BLE server");
2246
writeSerial("Number of remaining clients: " + String(pServer->getConnectedCount()));
23-
24-
if (currentImage.data || currentImage.blocksReceived ||
25-
currentImage.blockBytesReceived || currentImage.blockPacketsReceived) {
26-
writeSerial("Cleaning up image data due to disconnect...");
27-
cleanupImageMemory();
28-
}
29-
30-
// Restart advertising to allow new connections
3147
writeSerial("Waiting before restarting advertising...");
3248
delay(500);
33-
3449
if (pServer->getConnectedCount() == 0) {
3550
BLEDevice::startAdvertising();
3651
writeSerial("Advertising restarted");
@@ -40,14 +55,13 @@ class MyBLEServerCallbacks : public BLEServerCallbacks {
4055
}
4156
};
4257

43-
// BLE Characteristic Callbacks
4458
class MyBLECharacteristicCallbacks : public BLECharacteristicCallbacks {
4559
public:
4660
void onWrite(BLECharacteristic* pCharacteristic) {
4761
writeSerial("=== BLE WRITE RECEIVED (ESP32) ===");
4862
String value = pCharacteristic->getValue();
4963
writeSerial("Received data length: " + String(value.length()) + " bytes");
50-
if (value.length() > 0) {
64+
if (value.length() > 0 && value.length() <= MAX_COMMAND_SIZE) {
5165
uint8_t* data = (uint8_t*)value.c_str();
5266
uint16_t len = value.length();
5367
// Log first few bytes
@@ -57,15 +71,26 @@ class MyBLECharacteristicCallbacks : public BLECharacteristicCallbacks {
5771
hexDump += String(data[i], HEX) + " ";
5872
}
5973
writeSerial(hexDump);
60-
imageDataWritten(NULL, NULL, data, len);
74+
75+
// Queue command for processing in main loop to avoid blocking callback
76+
uint8_t nextHead = (commandQueueHead + 1) % COMMAND_QUEUE_SIZE;
77+
if (nextHead != commandQueueTail) {
78+
memcpy(commandQueue[commandQueueHead].data, data, len);
79+
commandQueue[commandQueueHead].len = len;
80+
commandQueue[commandQueueHead].pending = true;
81+
commandQueueHead = nextHead;
82+
writeSerial("ESP32: Command queued for processing");
83+
} else {
84+
writeSerial("ERROR: Command queue full, dropping command");
85+
}
86+
} else if (value.length() > MAX_COMMAND_SIZE) {
87+
writeSerial("WARNING: Command too large, dropping");
6188
} else {
6289
writeSerial("WARNING: Empty data received");
6390
}
6491
}
6592
};
66-
#endif
6793

68-
#ifdef TARGET_ESP32
6994
BLEServer* pServer = nullptr;
7095
BLEService* pService = nullptr;
7196
BLECharacteristic* pTxCharacteristic = nullptr;
@@ -91,15 +116,57 @@ void setup() {
91116
}
92117

93118
void loop() {
119+
#ifdef TARGET_ESP32
120+
// Process queued commands outside of callback context
121+
if (commandQueueTail != commandQueueHead) {
122+
writeSerial("ESP32: Processing queued command (" + String(commandQueue[commandQueueTail].len) + " bytes)");
123+
imageDataWritten(NULL, NULL, commandQueue[commandQueueTail].data, commandQueue[commandQueueTail].len);
124+
commandQueue[commandQueueTail].pending = false;
125+
commandQueueTail = (commandQueueTail + 1) % COMMAND_QUEUE_SIZE;
126+
writeSerial("Command processed");
127+
}
128+
129+
// Process queued BLE responses outside of callback context (one per loop for better responsiveness)
130+
if (responseQueueTail != responseQueueHead && pTxCharacteristic && pServer && pServer->getConnectedCount() > 0) {
131+
writeSerial("ESP32: Sending queued response (" + String(responseQueue[responseQueueTail].len) + " bytes)");
132+
pTxCharacteristic->setValue(responseQueue[responseQueueTail].data, responseQueue[responseQueueTail].len);
133+
pTxCharacteristic->notify();
134+
responseQueue[responseQueueTail].pending = false;
135+
responseQueueTail = (responseQueueTail + 1) % RESPONSE_QUEUE_SIZE;
136+
writeSerial("Response sent successfully");
137+
delay(20); // Brief delay to let BLE stack process
138+
}
139+
#endif
140+
94141
if (currentImage.ready) {
95142
writeSerial("Processing received image...");
96143
displayReceivedImage();
97144
currentImage.ready = false;
98145
cleanupImageMemory();
99146
writeSerial("Image processing complete");
100147
}
101-
if(globalConfig.power_option.sleep_timeout_ms > 0)delay(globalConfig.power_option.sleep_timeout_ms);
102-
else delay(2000);
148+
149+
#ifdef TARGET_ESP32
150+
// Use shorter delay when BLE transfers are active for faster response
151+
bool bleActive = (commandQueueTail != commandQueueHead) ||
152+
(responseQueueTail != responseQueueHead) ||
153+
(pServer && pServer->getConnectedCount() > 0);
154+
155+
if (bleActive) {
156+
delay(10); // Fast polling when BLE is active
157+
} else {
158+
if(globalConfig.power_option.sleep_timeout_ms > 0)
159+
delay(globalConfig.power_option.sleep_timeout_ms);
160+
else
161+
delay(2000);
162+
}
163+
#else
164+
if(globalConfig.power_option.sleep_timeout_ms > 0)
165+
delay(globalConfig.power_option.sleep_timeout_ms);
166+
else
167+
delay(2000);
168+
#endif
169+
103170
writeSerial("Loop end: " + String(millis() / 100));
104171
}
105172

@@ -144,7 +211,7 @@ void updatemsdata(){
144211
//THIS IS A PLACEHOLDER FOR THE ACTUAL PAYLOAD
145212
//carefull, the size is limited
146213
uint8_t msd_payload[13];
147-
uint16_t msd_cid = 0x1337;
214+
uint16_t msd_cid = 0x2446;
148215
memset(msd_payload, 0, sizeof(msd_payload));
149216
memcpy(msd_payload, (uint8_t*)&msd_cid, sizeof(msd_cid));
150217
msd_payload[2] = 0x02;
@@ -192,7 +259,7 @@ void ble_init(){
192259
bledfu.begin();
193260
writeSerial("BLE DFU initialized successfully");
194261
writeSerial("BLE initialized successfully");
195-
writeSerial("Setting up BLE service 0x1337...");
262+
writeSerial("Setting up BLE service 0x2446...");
196263
imageService.begin();
197264
writeSerial("BLE service started");
198265
imageCharacteristic.setWriteCallback(imageDataWritten);
@@ -235,14 +302,14 @@ void ble_init(){
235302
MyBLEServerCallbacks* serverCallbacks = new MyBLEServerCallbacks();
236303
pServer->setCallbacks(serverCallbacks);
237304
writeSerial("Server callbacks configured");
238-
BLEUUID serviceUUID("00001337-0000-1000-8000-00805F9B34FB");
305+
BLEUUID serviceUUID("00002446-0000-1000-8000-00805F9B34FB");
239306
pService = pServer->createService(serviceUUID);
240307
if (pService == nullptr) {
241308
writeSerial("ERROR: Failed to create BLE service");
242309
return;
243310
}
244-
writeSerial("BLE service 0x1337 created successfully");
245-
BLEUUID charUUID("00001337-0000-1000-8000-00805F9B34FB");
311+
writeSerial("BLE service 0x2446 created successfully");
312+
BLEUUID charUUID("00002446-0000-1000-8000-00805F9B34FB");
246313
pTxCharacteristic = pService->createCharacteristic(
247314
charUUID,
248315
BLECharacteristic::PROPERTY_READ |
@@ -266,10 +333,12 @@ void ble_init(){
266333
}
267334
pAdvertising->addServiceUUID(serviceUUID);
268335
writeSerial("Service UUID added to advertising");
269-
// Add manufacturer data
270336
BLEAdvertisementData advertisementData;
337+
advertisementData.setName(deviceName);
338+
writeSerial("Device name added to advertising");
339+
// Add manufacturer data
271340
uint8_t msd_payload[13];
272-
uint16_t msd_cid = 0x1337;
341+
uint16_t msd_cid = 0x2446;
273342
memset(msd_payload, 0, sizeof(msd_payload));
274343
memcpy(msd_payload, (uint8_t*)&msd_cid, sizeof(msd_cid));
275344
msd_payload[2] = 0x02;
@@ -290,7 +359,7 @@ void ble_init(){
290359
advertisementData.setManufacturerData(manufacturerDataStr);
291360
pAdvertising->setAdvertisementData(advertisementData);
292361
writeSerial("Manufacturer data added to advertising");
293-
pAdvertising->setScanResponse(true);
362+
pAdvertising->setScanResponse(false);
294363
pAdvertising->setMinPreferred(0x0006);
295364
pAdvertising->setMinPreferred(0x0012);
296365
writeSerial("Advertising intervals set");
@@ -424,11 +493,6 @@ void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
424493
(void)reason;
425494
writeSerial("=== BLE CLIENT DISCONNECTED ===");
426495
writeSerial("Disconnect reason: " + String(reason));
427-
if (currentImage.data || currentImage.blocksReceived ||
428-
currentImage.blockBytesReceived || currentImage.blockPacketsReceived) {
429-
writeSerial("Cleaning up image data due to disconnect...");
430-
cleanupImageMemory();
431-
}
432496
}
433497

434498
String getChipIdHex() {
@@ -738,18 +802,26 @@ void sendResponse(uint8_t* response, uint8_t len){
738802
writeSerial("Response notified (nRF52)");
739803
#endif
740804
#ifdef TARGET_ESP32
741-
if (pTxCharacteristic) {
742-
writeSerial("ESP32: Setting characteristic value...");
743-
pTxCharacteristic->setValue(response, len);
744-
// Need to explicitly notify for ESP32
745-
pTxCharacteristic->notify(true);
746-
writeSerial("SetValue and notify called successfully");
805+
// Queue response to avoid calling notify() from callback context
806+
if (len <= MAX_RESPONSE_SIZE) {
807+
uint8_t nextHead = (responseQueueHead + 1) % RESPONSE_QUEUE_SIZE;
808+
if (nextHead != responseQueueTail) {
809+
memcpy(responseQueue[responseQueueHead].data, response, len);
810+
responseQueue[responseQueueHead].len = len;
811+
responseQueue[responseQueueHead].pending = true;
812+
responseQueueHead = nextHead;
813+
writeSerial("ESP32: Response queued (queue size: " + String((responseQueueHead - responseQueueTail + RESPONSE_QUEUE_SIZE) % RESPONSE_QUEUE_SIZE) + ")");
814+
} else {
815+
writeSerial("ERROR: Response queue full, dropping response");
816+
}
747817
} else {
748-
writeSerial("ERROR: pTxCharacteristic is null");
818+
writeSerial("ERROR: Response too large for queue (" + String(len) + " > " + String(MAX_RESPONSE_SIZE) + ")");
749819
}
750820
#endif
821+
#ifndef TARGET_ESP32
751822
delay(20);
752823
writeSerial("Response sent successfully");
824+
#endif
753825
}
754826

755827
uint32_t calculateCRC32(uint8_t* data, uint32_t len) {

src/main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,4 @@ chunked_write_state_t chunkedWriteState = {false, 0, 0, {0}, 0, 0};
154154
struct GlobalConfig globalConfig = {0};
155155
uint8_t configReadResponseBuffer[128];
156156

157-
extern struct GlobalConfig globalConfig;
157+
extern struct GlobalConfig globalConfig;

0 commit comments

Comments
 (0)