Merge remote-tracking branch 'origin/new_flasher_pcb'
BIN
3D-printed cases and programming jigs/Flasher Jig 1.54 base.stl
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 1.54 latch.stl
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 1.54.skp
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 2.9 base.stl
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 2.9 latch.stl
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 2.9.skp
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 4.2 base.stl
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 4.2 latch.stl
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig 4.2.skp
Normal file
BIN
3D-printed cases and programming jigs/Flasher Jig Segmented.skp
Normal file
BIN
3D-printed cases and programming jigs/OpenEPaperLink AP Case.skp
Normal file
3
ESP32_AP-Flasher/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(esp32_fw)
|
||||
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
9
ESP32_AP-Flasher/dependencies.lock
Normal file
@@ -0,0 +1,9 @@
|
||||
dependencies:
|
||||
idf:
|
||||
component_hash: null
|
||||
source:
|
||||
type: idf
|
||||
version: 4.4.4
|
||||
manifest_hash: dcf4d39b94252de130019eadceb989d72b0dbc26b552cfdcbb50f6da531d2b92
|
||||
target: esp32s3
|
||||
version: 1.0.0
|
||||
5
ESP32_AP-Flasher/include/leds.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <Arduino.h>
|
||||
#include <FastLED.h>
|
||||
|
||||
void ledTask(void* parameter);
|
||||
void shortBlink(CRGB cname);
|
||||
5
ESP32_AP-Flasher/include/powermgt.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
void doLeds();
|
||||
void rampTagPower(uint8_t pin, bool up);
|
||||
66
ESP32_AP-Flasher/include/settings.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
// how long the we should keep the transfer metadata
|
||||
#define PENDING_TIMEOUT 24 * 3600
|
||||
// this determines how long images will be cached;
|
||||
#define PENDING_DATA_TIMEOUT 60
|
||||
// maximum time (in minutes) that a tag is put to sleep if no update is expected.
|
||||
#define MIN_RESPONSE_TIME 10
|
||||
|
||||
// flasher options
|
||||
#define CUSTOM_MAC_HDR 0x0000
|
||||
|
||||
#if (PINOUT == OPENEPAPERLINK_PCB)
|
||||
#define FLASHER_AP_SS 4
|
||||
#define FLASHER_AP_CLK 5
|
||||
#define FLASHER_AP_MOSI 7
|
||||
#define FLASHER_AP_MISO 6
|
||||
#define FLASHER_AP_RESET 15
|
||||
#define FLASHER_AP_POWER 0
|
||||
#define FLASHER_AP_TXD 16
|
||||
#define FLASHER_AP_RXD 18
|
||||
#define FLASHER_AP_TEST 17
|
||||
|
||||
#define FLASHER_EXT_SS 40
|
||||
#define FLASHER_EXT_CLK 41
|
||||
#define FLASHER_EXT_MOSI 2
|
||||
#define FLASHER_EXT_MISO 42
|
||||
#define FLASHER_EXT_RESET 1
|
||||
#define FLASHER_EXT_POWER 8
|
||||
#define FLASHER_EXT_TXD 38
|
||||
#define FLASHER_EXT_RXD 39
|
||||
#define FLASHER_EXT_TEST 47
|
||||
|
||||
#define FLASHER_ALT_SS 3
|
||||
#define FLASHER_ALT_CLK 46
|
||||
#define FLASHER_ALT_MOSI 10
|
||||
#define FLASHER_ALT_MISO 9
|
||||
#define FLASHER_ALT_RESET 11
|
||||
#define FLASHER_ALT_TXD 12
|
||||
#define FLASHER_ALT_RXD 14
|
||||
#define FLASHER_ALT_TEST 13
|
||||
|
||||
#define FLASHER_LED 21
|
||||
#define FLASHER_RGB_LED 48
|
||||
#endif
|
||||
|
||||
#if (PINOUT == SIMPLE_AP)
|
||||
/* Lolin32 lite connections to AP tag*/
|
||||
#define RXD1 16
|
||||
#define TXD1 17
|
||||
|
||||
#define FLASHER_AP_SS 5
|
||||
#define FLASHER_AP_CLK 18
|
||||
#define FLASHER_AP_MOSI 23
|
||||
#define FLASHER_AP_MISO 19
|
||||
#define FLASHER_AP_RESET 2
|
||||
#define FLASHER_AP_POWER 13
|
||||
#define FLASHER_AP_POWER2 15
|
||||
#define FLASHER_AP_TXD 17
|
||||
#define FLASHER_AP_RXD 16
|
||||
#define FLASHER_AP_TEST -1
|
||||
|
||||
#define FLASHER_LED 22
|
||||
#endif
|
||||
|
||||
#define MAX_WRITE_ATTEMPTS 5
|
||||
4
ESP32_AP-Flasher/include/usbflasher.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
void usbFlasherTask(void* parameter);
|
||||
@@ -1,15 +1,16 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <SPI.h>
|
||||
|
||||
/* Autor: Aaron Christophel ATCnetz.de */
|
||||
#include <Arduino.h>
|
||||
|
||||
void simplePowerOn();
|
||||
|
||||
class ZBS_interface {
|
||||
public:
|
||||
uint8_t begin();
|
||||
class ZBS_interface
|
||||
{
|
||||
public:
|
||||
uint8_t begin(uint8_t SS, uint8_t CLK, uint8_t MOSI, uint8_t MISO, uint8_t RESET, uint8_t POWER = -1, uint32_t spi_speed = 8000000);
|
||||
void setSpeed(uint32_t speed);
|
||||
void set_power(uint8_t state);
|
||||
void enable_debug();
|
||||
void reset();
|
||||
@@ -27,8 +28,11 @@ class ZBS_interface {
|
||||
uint8_t select_flash(uint8_t page);
|
||||
void erase_flash();
|
||||
void erase_infoblock();
|
||||
~ZBS_interface();
|
||||
|
||||
private:
|
||||
private:
|
||||
SPIClass *spi = NULL;
|
||||
SPISettings spiSettings;
|
||||
uint8_t _SS_PIN = -1;
|
||||
uint8_t _CLK_PIN = -1;
|
||||
uint8_t _MOSI_PIN = -1;
|
||||
@@ -36,8 +40,11 @@ class ZBS_interface {
|
||||
uint8_t _RESET_PIN = -1;
|
||||
uint8_t _POWER_PIN = -1;
|
||||
int ZBS_spi_delay = 1;
|
||||
uint8_t spi_ready = 0;
|
||||
uint32_t after_byte_delay = 10;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
ZBS_CMD_W_RAM = 0x02,
|
||||
ZBS_CMD_R_RAM = 0x03,
|
||||
ZBS_CMD_W_FLASH = 0x08,
|
||||
@@ -48,10 +55,9 @@ class ZBS_interface {
|
||||
ZBS_CMD_ERASE_INFOBLOCK = 0x48,
|
||||
} ZBS_CMD_LIST;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
ZBS_ON = 1,
|
||||
ZBS_OFF = 0,
|
||||
} ZBS_POWER_STATE;
|
||||
};
|
||||
|
||||
extern ZBS_interface zbs;
|
||||
};
|
||||
81
ESP32_AP-Flasher/platformio.ini
Normal file
@@ -0,0 +1,81 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects the 16MB Flash / 8MB Ram version of the ESP32-S3-DevkitC1
|
||||
; ----------------------------------------------------------------------------------------
|
||||
|
||||
[env:OpenEPaperLink-AP-Flasher]
|
||||
platform = https://github.com/platformio/platform-espressif32.git
|
||||
board = esp32-s3-devkitc-1
|
||||
framework = arduino
|
||||
board_build.partitions = default_16MB.csv
|
||||
platform_packages =
|
||||
monitor_filters = esp32_exception_decoder
|
||||
monitor_speed = 115200
|
||||
board_build.f_cpu = 240000000L
|
||||
board_build.filesystem = littlefs
|
||||
lib_deps =
|
||||
https://github.com/me-no-dev/ESPAsyncWebServer
|
||||
https://github.com/tzapu/WiFiManager.git#feature_asyncwebserver
|
||||
bblanchon/ArduinoJson
|
||||
bodmer/TFT_eSPI
|
||||
https://github.com/Bodmer/TJpg_Decoder.git
|
||||
https://github.com/garretlab/shoddyxml2
|
||||
https://github.com/Bodmer/U8g2_for_TFT_eSPI
|
||||
https://github.com/ricmoo/qrcode
|
||||
fastled/FastLED
|
||||
upload_port = COM17
|
||||
monitor_port = COM17
|
||||
build_unflags =
|
||||
-D ARDUINO_USB_MODE=1
|
||||
build_flags =
|
||||
-D OPENEPAPERLINK_PCB=1
|
||||
-D ARDUINO_USB_MODE=0
|
||||
-D CONFIG_ESP32S3_SPIRAM_SUPPORT=1
|
||||
-D BOARD_HAS_PSRAM
|
||||
-D CONFIG_SPIRAM_USE_MALLOC=y
|
||||
-D PINOUT=OPENEPAPERLINK_PCB
|
||||
-D HAS_USB=1
|
||||
|
||||
|
||||
board_build.flash_mode=qio
|
||||
board_build.arduino.memory_type = qio_opi
|
||||
board_build.psram_type=qspi_opi
|
||||
|
||||
board_upload.maximum_size = 16777216
|
||||
board_upload.maximum_ram_size = 327680
|
||||
board_upload.flash_size = 16MB
|
||||
|
||||
[env:Simple_AP]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
board_build.partitions = no_ota.csv
|
||||
platform_packages =
|
||||
monitor_filters = esp32_exception_decoder
|
||||
monitor_speed = 115200
|
||||
board_build.f_cpu = 240000000L
|
||||
board_build.filesystem = littlefs
|
||||
lib_deps =
|
||||
https://github.com/me-no-dev/ESPAsyncWebServer
|
||||
https://github.com/tzapu/WiFiManager.git#feature_asyncwebserver
|
||||
bblanchon/ArduinoJson
|
||||
bodmer/TFT_eSPI
|
||||
https://github.com/Bodmer/TJpg_Decoder.git
|
||||
https://github.com/garretlab/shoddyxml2
|
||||
https://github.com/Bodmer/U8g2_for_TFT_eSPI
|
||||
https://github.com/ricmoo/qrcode
|
||||
upload_port = COM12
|
||||
monitor_port = COM12
|
||||
|
||||
build_flags =
|
||||
-D SIMPLE_AP=2
|
||||
-D PINOUT=SIMPLE_AP
|
||||
BIN
ESP32_AP-Flasher/readtest.bin2
Normal file
1450
ESP32_AP-Flasher/sdkconfig.openepaperlink-flasher-ap
Normal file
6
ESP32_AP-Flasher/src/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
# This file was automatically generated for projects
|
||||
# without default 'CMakeLists.txt' file.
|
||||
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources})
|
||||
@@ -27,6 +27,9 @@ typedef enum {
|
||||
uint8_t *infoblock = nullptr;
|
||||
uint8_t *flashbuffer = nullptr;
|
||||
|
||||
static class ZBS_interface* zbs;
|
||||
|
||||
|
||||
// look for the latest version of the firmware file... It's supposed to be something like zigbeebase0003.bin
|
||||
String lookupFirmwareFile(uint16_t &version) {
|
||||
String filename;
|
||||
@@ -58,9 +61,9 @@ uint16_t getDeviceType() {
|
||||
uint8_t type29[8] = {0x7d, 0x22, 0xff, 0x02, 0xa4, 0x58, 0xf0, 0x90};
|
||||
uint8_t type154[8] = {0xa1, 0x23, 0x22, 0x02, 0xa4, 0xc3, 0xe4, 0xf0};
|
||||
uint8_t buffer[8] = {0};
|
||||
zbs.select_flash(0);
|
||||
zbs->select_flash(0);
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer[c] = zbs.read_flash(0x08 + c);
|
||||
buffer[c] = zbs->read_flash(0x08 + c);
|
||||
}
|
||||
if (memcmp(buffer, type29, 8) == 0) {
|
||||
return 0x3B10;
|
||||
@@ -73,10 +76,10 @@ uint16_t getDeviceType() {
|
||||
|
||||
// extract original mac from firmware and make it 2 bytes longer based on info in settings.h
|
||||
uint64_t getOriginalTagMac() {
|
||||
zbs.select_flash(0);
|
||||
zbs->select_flash(0);
|
||||
uint8_t mac[8] = {0};
|
||||
for (uint8_t c = 0; c < 6; c++) {
|
||||
mac[c + 2] = zbs.read_flash(0xFC06 + c);
|
||||
mac[c + 2] = zbs->read_flash(0xFC06 + c);
|
||||
}
|
||||
mac[0] = (uint8_t)(CUSTOM_MAC_HDR >> 8);
|
||||
mac[1] = (uint8_t)CUSTOM_MAC_HDR;
|
||||
@@ -96,10 +99,10 @@ uint64_t getOriginalTagMac() {
|
||||
|
||||
// extract custom firmware mac from Infoblock
|
||||
uint64_t getInfoBlockMac() {
|
||||
zbs.select_flash(1);
|
||||
zbs->select_flash(1);
|
||||
uint8_t mac[8] = {0};
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
mac[c] = zbs.read_flash(0x10 + c);
|
||||
mac[c] = zbs->read_flash(0x10 + c);
|
||||
}
|
||||
return *((uint64_t *)(mac));
|
||||
}
|
||||
@@ -110,9 +113,9 @@ void readInfoBlock() {
|
||||
// allocate room for infopage
|
||||
infoblock = (uint8_t *)calloc(1024, 1);
|
||||
}
|
||||
zbs.select_flash(1); // select info page
|
||||
zbs->select_flash(1); // select info page
|
||||
for (uint16_t c = 0; c < 1024; c++) {
|
||||
infoblock[c] = zbs.read_flash(c);
|
||||
infoblock[c] = zbs->read_flash(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,13 +124,13 @@ void writeInfoBlock() {
|
||||
if (infoblock == nullptr) {
|
||||
return;
|
||||
}
|
||||
zbs.select_flash(1);
|
||||
zbs.erase_infoblock();
|
||||
zbs.select_flash(1); // select info page
|
||||
zbs->select_flash(1);
|
||||
zbs->erase_infoblock();
|
||||
zbs->select_flash(1); // select info page
|
||||
for (uint16_t c = 0; c < 1024; c++) {
|
||||
for (uint8_t i = 0; i < MAX_WRITE_ATTEMPTS; i++) {
|
||||
zbs.write_flash(c, infoblock[c]);
|
||||
if (zbs.read_flash(c) == infoblock[c]) {
|
||||
zbs->write_flash(c, infoblock[c]);
|
||||
if (zbs->read_flash(c) == infoblock[c]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -139,15 +142,15 @@ void writeFlashBlock(uint16_t size) {
|
||||
if (flashbuffer == nullptr) {
|
||||
return;
|
||||
}
|
||||
zbs.select_flash(0);
|
||||
zbs.erase_flash();
|
||||
zbs.select_flash(0);
|
||||
zbs->select_flash(0);
|
||||
zbs->erase_flash();
|
||||
zbs->select_flash(0);
|
||||
Serial.printf("Starting flash, size=%d\n", size);
|
||||
uint8_t i = 0;
|
||||
for (uint16_t c = 0; c < size; c++) {
|
||||
for (i = 0; i < MAX_WRITE_ATTEMPTS; i++) {
|
||||
zbs.write_flash(c, flashbuffer[c]);
|
||||
if (zbs.read_flash(c) == flashbuffer[c]) {
|
||||
zbs->write_flash(c, flashbuffer[c]);
|
||||
if (zbs->read_flash(c) == flashbuffer[c]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -165,11 +168,11 @@ void writeFlashBlock(uint16_t size) {
|
||||
void performDeviceFlash() {
|
||||
uint8_t interfaceWorking = 0;
|
||||
Serial.printf("Power cycling to get everything up and running...\n");
|
||||
zbs.set_power(0);
|
||||
zbs->set_power(0);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
zbs.set_power(1);
|
||||
zbs->set_power(1);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
interfaceWorking = zbs.begin();
|
||||
//interfaceWorking = zbs.begin();
|
||||
if (!interfaceWorking) {
|
||||
Serial.print("I wasn't able to connect to a ZBS tag, please check wiring and definitions in the settings.h file.\n");
|
||||
return;
|
||||
@@ -182,11 +185,11 @@ void performDeviceFlash() {
|
||||
if (*((uint64_t *)(mac)) == 0xFFFFFFFFFFFFFFFF) {
|
||||
// mac not set in infopage, get it from the original firmware
|
||||
*((uint64_t *)(mac)) = getOriginalTagMac();
|
||||
zbs.select_flash(1);
|
||||
zbs->select_flash(1);
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
infoblock[0x17 - c] = mac[c];
|
||||
// write mac directly to infoblock without erasing; the bytes should all be 0xFF anyway
|
||||
zbs.write_flash(0x17 - c, mac[c]);
|
||||
zbs->write_flash(0x17 - c, mac[c]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +222,6 @@ void performDeviceFlash() {
|
||||
infoblock = nullptr;
|
||||
free(flashbuffer);
|
||||
flashbuffer = nullptr;
|
||||
zbs.reset();
|
||||
zbs.set_power(1);
|
||||
zbs->reset();
|
||||
zbs->set_power(1);
|
||||
}
|
||||
270
ESP32_AP-Flasher/src/leds.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#include <Arduino.h>
|
||||
#include <FastLED.h>
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
QueueHandle_t rgbLedQueue;
|
||||
QueueHandle_t ledQueue;
|
||||
|
||||
struct ledInstructionRGB {
|
||||
CRGB ledColor;
|
||||
uint16_t fadeTime;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
struct ledInstruction {
|
||||
uint16_t value;
|
||||
uint16_t fadeTime;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM gamma8[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114,
|
||||
115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142,
|
||||
144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
|
||||
177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213,
|
||||
215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255};
|
||||
|
||||
const uint16_t gamma12[256] = {
|
||||
0, 2, 4, 6, 8, 10, 12, 13, 15, 17,
|
||||
19, 21, 23, 25, 27, 29, 31, 33, 35, 36,
|
||||
38, 37, 39, 41, 43, 45, 47, 49, 52, 54,
|
||||
56, 59, 61, 64, 66, 69, 72, 74, 77, 80,
|
||||
83, 87, 90, 93, 96, 100, 103, 107, 111, 115,
|
||||
118, 122, 126, 131, 135, 139, 143, 148, 153, 157,
|
||||
162, 167, 172, 177, 182, 187, 193, 198, 204, 209,
|
||||
215, 221, 227, 233, 239, 246, 252, 259, 265, 272,
|
||||
279, 286, 293, 300, 307, 315, 322, 330, 338, 346,
|
||||
354, 362, 370, 379, 387, 396, 405, 414, 423, 432,
|
||||
442, 451, 461, 470, 480, 490, 500, 511, 521, 532,
|
||||
542, 553, 564, 575, 587, 598, 610, 622, 633, 645,
|
||||
658, 670, 683, 695, 708, 721, 734, 747, 761, 774,
|
||||
788, 802, 816, 830, 845, 859, 874, 889, 904, 919,
|
||||
935, 950, 966, 982, 998, 1015, 1031, 1048, 1065, 1082,
|
||||
1099, 1116, 1134, 1151, 1169, 1187, 1206, 1224, 1243, 1262,
|
||||
1281, 1300, 1319, 1339, 1359, 1379, 1399, 1419, 1440, 1461,
|
||||
1482, 1503, 1524, 1546, 1568, 1590, 1612, 1634, 1657, 1680,
|
||||
1703, 1726, 1749, 1773, 1797, 1821, 1845, 1870, 1895, 1920,
|
||||
1945, 1970, 1996, 2022, 2048, 2074, 2100, 2127, 2154, 2181,
|
||||
2209, 2236, 2264, 2292, 2321, 2349, 2378, 2407, 2436, 2466,
|
||||
2495, 2525, 2556, 2586, 2617, 2648, 2679, 2710, 2742, 2774,
|
||||
2806, 2838, 2871, 2904, 2937, 2970, 3004, 3038, 3072, 3107,
|
||||
3141, 3176, 3211, 3247, 3283, 3319, 3355, 3391, 3428, 3465,
|
||||
3502, 3540, 3578, 3616, 3654, 3693, 3732, 3771, 3810, 3850,
|
||||
3890, 3930, 3971, 4013, 4054, 4095};
|
||||
|
||||
CRGB leds[1];
|
||||
|
||||
void addToRGBQueue(struct ledInstructionRGB* rgb) {
|
||||
BaseType_t queuestatus = xQueueSend(rgbLedQueue, &rgb, 0);
|
||||
if (queuestatus == pdFALSE) {
|
||||
delete rgb;
|
||||
}
|
||||
}
|
||||
|
||||
void addToMonoQueue(struct ledInstruction* mono) {
|
||||
BaseType_t queuestatus = xQueueSend(ledQueue, &mono, 0);
|
||||
if (queuestatus == pdFALSE) {
|
||||
delete mono;
|
||||
}
|
||||
}
|
||||
|
||||
void addFadeColor(CRGB cname) {
|
||||
struct ledInstructionRGB* rgb = new struct ledInstructionRGB;
|
||||
rgb->ledColor = cname;
|
||||
rgb->fadeTime = 750;
|
||||
rgb->length = 0;
|
||||
addToRGBQueue(rgb);
|
||||
}
|
||||
|
||||
void addFadeMono(uint8_t value) {
|
||||
struct ledInstruction* mono = new struct ledInstruction;
|
||||
mono->value = value;
|
||||
mono->fadeTime = 750;
|
||||
mono->length = 0;
|
||||
addToMonoQueue(mono);
|
||||
}
|
||||
|
||||
void shortBlink(CRGB cname) {
|
||||
struct ledInstructionRGB* rgb = new struct ledInstructionRGB;
|
||||
rgb->ledColor = CRGB::Black;
|
||||
rgb->fadeTime = 0;
|
||||
rgb->length = 3;
|
||||
addToRGBQueue(rgb);
|
||||
rgb = new struct ledInstructionRGB;
|
||||
rgb->ledColor = cname;
|
||||
rgb->ledColor.maximizeBrightness(0x80);
|
||||
rgb->fadeTime = 0;
|
||||
rgb->length = 10;
|
||||
addToRGBQueue(rgb);
|
||||
rgb = new struct ledInstructionRGB;
|
||||
rgb->ledColor = CRGB::Black;
|
||||
rgb->fadeTime = 0;
|
||||
rgb->length = 3;
|
||||
addToRGBQueue(rgb);
|
||||
}
|
||||
|
||||
void showRGB() {
|
||||
FastLED.show();
|
||||
}
|
||||
void showMono(uint8_t brightness) {
|
||||
ledcWrite(7, gamma12[brightness]);
|
||||
}
|
||||
|
||||
volatile uint16_t rgbIdlePeriod = 800;
|
||||
volatile uint16_t monoIdlePeriod = 900;
|
||||
volatile CRGB rgbIdleColor = CRGB::Green;
|
||||
uint8_t monoValue = 0;
|
||||
|
||||
void rgbIdleStep() {
|
||||
static bool dirUp = true;
|
||||
static uint16_t step = 0;
|
||||
|
||||
if (dirUp) {
|
||||
// up
|
||||
step++;
|
||||
if (step == rgbIdlePeriod) {
|
||||
dirUp = false;
|
||||
}
|
||||
} else {
|
||||
// down
|
||||
step--;
|
||||
if (step == 0) {
|
||||
dirUp = true;
|
||||
}
|
||||
}
|
||||
CRGB newvalue = blend(CRGB::Black, (const CRGB&)rgbIdleColor, gamma8[map(step, 0, rgbIdlePeriod, 0, 255)]);
|
||||
if (newvalue != leds[0]) {
|
||||
leds[0] = newvalue;
|
||||
showRGB();
|
||||
}
|
||||
}
|
||||
|
||||
void monoIdleStep() {
|
||||
static bool dirUp = true;
|
||||
static uint16_t step = 0;
|
||||
if (dirUp) {
|
||||
// up
|
||||
step++;
|
||||
if (step == monoIdlePeriod) {
|
||||
dirUp = false;
|
||||
}
|
||||
} else {
|
||||
// down
|
||||
step--;
|
||||
if (step == 0) {
|
||||
dirUp = true;
|
||||
}
|
||||
}
|
||||
uint8_t newvalue = map(step, 0, monoIdlePeriod, 0, 255);
|
||||
if (newvalue != monoValue) {
|
||||
monoValue = newvalue;
|
||||
showMono(newvalue);
|
||||
}
|
||||
}
|
||||
|
||||
void ledTask(void* parameter) {
|
||||
FastLED.addLeds<WS2812B, FLASHER_RGB_LED, GRB>(leds, 1); // GRB ordering is typical
|
||||
leds[0] = CRGB::Blue;
|
||||
showRGB();
|
||||
|
||||
rgbLedQueue = xQueueCreate(30, sizeof(struct ledInstructionRGB*));
|
||||
ledQueue = xQueueCreate(30, sizeof(struct ledInstruction*));
|
||||
|
||||
digitalWrite(FLASHER_LED, HIGH);
|
||||
pinMode(FLASHER_LED, OUTPUT);
|
||||
ledcSetup(7, 9500, 12); // 141251 okay // 101251 okay
|
||||
ledcAttachPin(FLASHER_LED, 7);
|
||||
|
||||
struct ledInstructionRGB* rgb = nullptr;
|
||||
struct ledInstruction* monoled = nullptr;
|
||||
|
||||
// open with a nice RGB crossfade
|
||||
addFadeColor(CRGB::Red);
|
||||
addFadeColor(CRGB::Green);
|
||||
addFadeColor(CRGB::Blue);
|
||||
addFadeColor(CRGB::Red);
|
||||
addFadeColor(CRGB::Green);
|
||||
addFadeColor(CRGB::Blue);
|
||||
|
||||
addFadeMono(255);
|
||||
addFadeMono(127);
|
||||
addFadeMono(255);
|
||||
addFadeMono(0);
|
||||
|
||||
CRGB oldColor = CRGB::Black;
|
||||
|
||||
uint8_t oldBrightness = 0;
|
||||
|
||||
uint16_t rgbInstructionFadeTime = 0;
|
||||
uint16_t monoInstructionFadeTime = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
// handle RGB led instructions
|
||||
if (rgb == nullptr) {
|
||||
// fetch a led instruction
|
||||
BaseType_t q = xQueueReceive(rgbLedQueue, &rgb, 1);
|
||||
if (q == pdTRUE) {
|
||||
rgbInstructionFadeTime = rgb->fadeTime;
|
||||
if (rgb->fadeTime <= 1) {
|
||||
leds[0] = rgb->ledColor;
|
||||
showRGB();
|
||||
}
|
||||
} else {
|
||||
// no commands, run idle led task
|
||||
rgbIdleStep();
|
||||
}
|
||||
} else {
|
||||
// process instruction
|
||||
if (rgb->fadeTime) {
|
||||
rgb->fadeTime--;
|
||||
leds[0] = blend(rgb->ledColor, oldColor, map(rgb->fadeTime, 0, rgbInstructionFadeTime, 0, 255));
|
||||
showRGB();
|
||||
} else if (rgb->length) {
|
||||
rgb->length--;
|
||||
} else {
|
||||
oldColor = rgb->ledColor;
|
||||
delete rgb;
|
||||
rgb = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// handle flasher LED (single color)
|
||||
if (monoled == nullptr) {
|
||||
BaseType_t q = xQueueReceive(ledQueue, &monoled, 1);
|
||||
if (q == pdTRUE) {
|
||||
monoInstructionFadeTime = monoled->fadeTime;
|
||||
if (monoled->fadeTime <= 1) {
|
||||
showMono(gamma12[monoled->value]);
|
||||
}
|
||||
} else {
|
||||
monoIdleStep();
|
||||
}
|
||||
} else {
|
||||
if (monoled->fadeTime) {
|
||||
monoled->fadeTime--;
|
||||
showMono(map(monoled->fadeTime, 0, monoInstructionFadeTime, monoled->value, oldBrightness));
|
||||
} else if (monoled->length) {
|
||||
monoled->length--;
|
||||
} else {
|
||||
oldBrightness = monoled->value;
|
||||
delete monoled;
|
||||
monoled = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
80
ESP32_AP-Flasher/src/main.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiManager.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "contentmanager.h"
|
||||
#include "flasher.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "makeimage.h"
|
||||
#include "pendingdata.h"
|
||||
#include "serial.h"
|
||||
#include "settings.h"
|
||||
#include "tag_db.h"
|
||||
|
||||
#if (HAS_USB == 1)
|
||||
#include "usbflasher.h"
|
||||
#endif
|
||||
|
||||
#include "web.h"
|
||||
|
||||
#include "leds.h"
|
||||
|
||||
void timeTask(void* parameter) {
|
||||
while (1) {
|
||||
time_t now;
|
||||
time(&now);
|
||||
tm tm;
|
||||
if (!getLocalTime(&tm)) {
|
||||
Serial.println("Waiting for valid time from NTP-server");
|
||||
} else {
|
||||
if (now % 10 == 0) wsSendSysteminfo();
|
||||
if (now % 30 == 3) Ping();
|
||||
if (now % 300 == 6) saveDB("/current/tagDB.json");
|
||||
|
||||
contentRunner();
|
||||
}
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.print(">\n");
|
||||
|
||||
psramInit();
|
||||
|
||||
Serial.println("\n\n##################################");
|
||||
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
|
||||
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
|
||||
Serial.printf("ChipRevision %d, Cpu Freq %d, SDK Version %s\n", ESP.getChipRevision(), ESP.getCpuFreqMHz(), ESP.getSdkVersion());
|
||||
Serial.printf("Flash Size %d, Flash Speed %d\n", ESP.getFlashChipSize(), ESP.getFlashChipSpeed());
|
||||
Serial.println("##################################\n\n");
|
||||
|
||||
Serial.println(ESP.getFreeHeap());
|
||||
|
||||
Serial.printf("Total heap: %d", ESP.getHeapSize());
|
||||
Serial.printf("Free heap: %d", ESP.getFreeHeap());
|
||||
Serial.printf("Total PSRAM: %d", ESP.getPsramSize());
|
||||
Serial.printf("Free PSRAM: %d", ESP.getFreePsram());
|
||||
|
||||
#if (HAS_USB == 1)
|
||||
xTaskCreate(usbFlasherTask, "flasher", 10000, NULL, configMAX_PRIORITIES - 10, NULL);
|
||||
#endif
|
||||
|
||||
configTzTime("CET-1CEST,M3.5.0,M10.5.0/3", "0.nl.pool.ntp.org", "europe.pool.ntp.org", "time.nist.gov");
|
||||
// https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
|
||||
|
||||
init_web();
|
||||
loadDB("/current/tagDB.json");
|
||||
|
||||
xTaskCreate(zbsRxTask, "zbsRX Process", 10000, NULL, 2, NULL);
|
||||
xTaskCreate(garbageCollection, "pending-data cleanup", 5000, NULL, 1, NULL);
|
||||
xTaskCreate(webSocketSendProcess, "ws", 5000, NULL, configMAX_PRIORITIES - 10, NULL);
|
||||
xTaskCreate(timeTask, "timed tasks", 10000, NULL, 2, NULL);
|
||||
xTaskCreate(ledTask, "handles leds", 5000, NULL, 10, NULL);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
vTaskDelay(30000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
@@ -287,9 +287,6 @@ void processXferTimeout(struct espXferComplete* xfc) {
|
||||
}
|
||||
|
||||
void processDataReq(struct espAvailDataReq* eadr) {
|
||||
|
||||
digitalWrite(ONBOARD_LED, LOW);
|
||||
|
||||
char buffer[64];
|
||||
uint8_t src[8];
|
||||
*((uint64_t*)src) = swap64(*((uint64_t*)eadr->src));
|
||||
@@ -338,8 +335,6 @@ void processDataReq(struct espAvailDataReq* eadr) {
|
||||
sprintf(buffer, "<ADR %02X%02X%02X%02X%02X%02X\n\0", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
Serial.print(buffer);
|
||||
wsSendTaginfo(mac);
|
||||
|
||||
digitalWrite(ONBOARD_LED, HIGH);
|
||||
}
|
||||
|
||||
void refreshAllPending() {
|
||||
26
ESP32_AP-Flasher/src/powermgt.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <Arduino.h>
|
||||
#include "powermgt.h"
|
||||
#include "settings.h"
|
||||
|
||||
// On the OpenEPaperLink board, there is no in-rush current limiting. The tags that can be connected to the board can have significant capacity, which,
|
||||
// when drained, will cause the 3v3 rail to sag enough to reset the ESP32. This is obviously not great. To prevent this from happening, we ramp up/down the
|
||||
// voltage with PWM. Ramping down really is unnecessary, as the board has a resistor to dump the charge into.
|
||||
void rampTagPower(uint8_t pin, bool up) {
|
||||
if (up) {
|
||||
ledcSetup(0, 152000, 8); // 141251 okay // 101251 okay
|
||||
ledcWrite(0, 254);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
ledcAttachPin(pin, 0);
|
||||
pinMode(pin, OUTPUT);
|
||||
for (uint8_t c = 254; c != 0xFF; c--) {
|
||||
ledcWrite(0, c);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
}
|
||||
digitalWrite(pin, LOW);
|
||||
ledcDetachPin(pin);
|
||||
digitalWrite(pin, LOW);
|
||||
} else {
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, HIGH);
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,6 @@ uint8_t pktindex = 0;
|
||||
char lastchar = 0;
|
||||
uint8_t charindex = 0;
|
||||
uint64_t waitingForVersion = 0;
|
||||
uint8_t crashcounter = 0;
|
||||
uint16_t version;
|
||||
|
||||
void ShortRXWaitLoop() {
|
||||
@@ -201,12 +200,25 @@ void SerialRXLoop() {
|
||||
break;
|
||||
case ZBS_RX_WAIT_VER:
|
||||
waitingForVersion = 0;
|
||||
crashcounter = 0;
|
||||
cmdbuffer[charindex] = lastchar;
|
||||
charindex++;
|
||||
if (charindex == 4) {
|
||||
charindex = 0;
|
||||
version = (uint16_t)strtoul(cmdbuffer, NULL, 16);
|
||||
/*
|
||||
uint16_t fsversion;
|
||||
lookupFirmwareFile(fsversion);
|
||||
if ((fsversion) && (version != fsversion)) {
|
||||
Serial.printf("ZBS/Zigbee FW version: %04X, version on SPIFFS: %04X\n", version, fsversion);
|
||||
Serial.printf("Performing flash update in about 30 seconds");
|
||||
vTaskDelay(30000 / portTICK_PERIOD_MS);
|
||||
performDeviceFlash();
|
||||
} else if (!fsversion) {
|
||||
Serial.println("No ZBS/Zigbee FW binary found on SPIFFS, please upload a zigbeebase000X.bin - format binary to enable flashing");
|
||||
} else {
|
||||
Serial.printf("ZBS/Zigbee FW version: %04X\n", version);
|
||||
}
|
||||
*/
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
@@ -217,14 +229,13 @@ void SerialRXLoop() {
|
||||
extern uint8_t* getDataForFile(File* file);
|
||||
|
||||
void zbsRxTask(void* parameter) {
|
||||
Serial1.begin(228571, SERIAL_8N1, RXD1, TXD1);
|
||||
Serial1.begin(230400, SERIAL_8N1, RXD1, TXD1);
|
||||
|
||||
simplePowerOn();
|
||||
bool firstrun = true;
|
||||
|
||||
Serial1.print("VER?");
|
||||
waitingForVersion = esp_timer_get_time();
|
||||
|
||||
while (1) {
|
||||
SerialRXLoop();
|
||||
|
||||
@@ -234,19 +245,14 @@ void zbsRxTask(void* parameter) {
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
|
||||
if (waitingForVersion) {
|
||||
if (esp_timer_get_time() - waitingForVersion > 5000*1000ULL) {
|
||||
if (esp_timer_get_time() - waitingForVersion > 10000*1000ULL) {
|
||||
waitingForVersion = 0;
|
||||
wsLog("AP doesn't respond... "+String(crashcounter + 1));
|
||||
if (++crashcounter >= 4) {
|
||||
crashcounter = 0;
|
||||
Serial.println("I wasn't able to connect to a ZBS tag, trying to reboot the tag.");
|
||||
Serial.println("If this problem persists, please check wiring and definitions in the settings.h file, and presence of the right firmware");
|
||||
simplePowerOn();
|
||||
wsErr("The AP tag crashed. Restarting tag, regenerating all pending info.");
|
||||
refreshAllPending();
|
||||
} else {
|
||||
Ping();
|
||||
}
|
||||
//performDeviceFlash();
|
||||
Serial.println("I wasn't able to connect to a ZBS tag, trying to reboot the tag.");
|
||||
Serial.println("If this problem persists, please check wiring and definitions in the settings.h file, and presence of the right firmware");
|
||||
simplePowerOn();
|
||||
wsErr("The AP tag crashed. Restarting tag, regenerating all pending info.");
|
||||
refreshAllPending();
|
||||
}
|
||||
}
|
||||
|
||||
347
ESP32_AP-Flasher/src/usbflasher.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "USB.h"
|
||||
#include "powermgt.h"
|
||||
#include "settings.h"
|
||||
#include "zbs_interface.h"
|
||||
|
||||
USBCDC USBSerial;
|
||||
|
||||
QueueHandle_t flasherCmdQueue;
|
||||
|
||||
#define FLASHER_WAIT_A 0
|
||||
#define FLASHER_WAIT_T 1
|
||||
#define FLASHER_WAIT_CMD 2
|
||||
#define FLASHER_WAIT_LEN 3
|
||||
#define FLASHER_WAIT_DATA 4
|
||||
#define FLASHER_WAIT_CRCH 5
|
||||
#define FLASHER_WAIT_CRCL 6
|
||||
|
||||
struct flasherCommand {
|
||||
uint8_t command = 0;
|
||||
uint8_t len = 0;
|
||||
uint8_t* data = nullptr;
|
||||
};
|
||||
|
||||
void sendFlasherAnswer(uint8_t answer_cmd, uint8_t* ans_buff, uint8_t len) {
|
||||
uint8_t* answer_buffer = (uint8_t*)calloc(2 + 2 + len + 2, 1);
|
||||
if (answer_buffer == nullptr) return;
|
||||
uint32_t CRC_value = 0xAB34;
|
||||
answer_buffer[0] = 'A';
|
||||
answer_buffer[1] = 'T';
|
||||
answer_buffer[2] = answer_cmd;
|
||||
CRC_value += answer_cmd;
|
||||
answer_buffer[3] = len;
|
||||
CRC_value += len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
answer_buffer[4 + i] = ans_buff[i];
|
||||
CRC_value += ans_buff[i];
|
||||
}
|
||||
answer_buffer[2 + 2 + len] = CRC_value >> 8;
|
||||
answer_buffer[2 + 2 + len + 1] = CRC_value;
|
||||
USBSerial.write(answer_buffer, 2 + 2 + len + 2);
|
||||
free(answer_buffer);
|
||||
}
|
||||
|
||||
void flasherUartHandler(uint8_t* data, uint8_t len) {
|
||||
static struct flasherCommand* cmd;
|
||||
static uint8_t flasherSerialState = FLASHER_WAIT_A;
|
||||
static uint8_t flasherCmdDataIndex = 0;
|
||||
static uint16_t flasherCRC = 0xAB34;
|
||||
static uint32_t flasherLastCmd = 0;
|
||||
|
||||
if ((flasherSerialState != FLASHER_WAIT_A) && (millis() - flasherLastCmd >= 225)) {
|
||||
flasherSerialState = FLASHER_WAIT_A;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
uint8_t usbbyte = *(data++);
|
||||
switch (flasherSerialState) {
|
||||
case FLASHER_WAIT_A:
|
||||
if (usbbyte == 'A') {
|
||||
flasherSerialState = FLASHER_WAIT_T;
|
||||
flasherLastCmd = millis();
|
||||
}
|
||||
break;
|
||||
case FLASHER_WAIT_T:
|
||||
if (usbbyte == 'T') {
|
||||
flasherSerialState = FLASHER_WAIT_CMD;
|
||||
cmd = new flasherCommand;
|
||||
flasherCRC = 0xAB34;
|
||||
flasherCmdDataIndex = 0;
|
||||
} else {
|
||||
flasherSerialState = FLASHER_WAIT_A;
|
||||
}
|
||||
break;
|
||||
case FLASHER_WAIT_CMD:
|
||||
cmd->command = usbbyte;
|
||||
flasherCRC += usbbyte;
|
||||
flasherSerialState = FLASHER_WAIT_LEN;
|
||||
break;
|
||||
case FLASHER_WAIT_LEN:
|
||||
flasherCRC += usbbyte;
|
||||
if (usbbyte) {
|
||||
cmd->len = usbbyte;
|
||||
cmd->data = (uint8_t*)calloc(usbbyte, 1);
|
||||
flasherSerialState = FLASHER_WAIT_DATA;
|
||||
} else {
|
||||
flasherSerialState = FLASHER_WAIT_CRCH;
|
||||
}
|
||||
break;
|
||||
case FLASHER_WAIT_DATA:
|
||||
flasherCRC += usbbyte;
|
||||
cmd->data[flasherCmdDataIndex++] = usbbyte;
|
||||
if (flasherCmdDataIndex == cmd->len) {
|
||||
flasherSerialState = FLASHER_WAIT_CRCH;
|
||||
}
|
||||
break;
|
||||
case FLASHER_WAIT_CRCH:
|
||||
flasherCRC -= ((uint16_t)usbbyte << 8);
|
||||
flasherSerialState = FLASHER_WAIT_CRCL;
|
||||
break;
|
||||
case FLASHER_WAIT_CRCL:
|
||||
flasherCRC -= ((uint16_t)usbbyte);
|
||||
if (flasherCRC) {
|
||||
Serial.printf("CRC failed for flasher command :( %04X\n", flasherCRC);
|
||||
cmd = nullptr;
|
||||
} else {
|
||||
BaseType_t queuestatus = xQueueSend(flasherCmdQueue, &cmd, 0);
|
||||
if (queuestatus == pdFALSE) {
|
||||
if (cmd->data != nullptr) free(cmd->data);
|
||||
delete cmd;
|
||||
}
|
||||
cmd = nullptr;
|
||||
}
|
||||
flasherSerialState = FLASHER_WAIT_A;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
|
||||
if (event_base == ARDUINO_USB_EVENTS) {
|
||||
arduino_usb_event_data_t* data = (arduino_usb_event_data_t*)event_data;
|
||||
switch (event_id) {
|
||||
case ARDUINO_USB_STARTED_EVENT:
|
||||
Serial.println("USB PLUGGED");
|
||||
break;
|
||||
case ARDUINO_USB_STOPPED_EVENT:
|
||||
Serial.println("USB UNPLUGGED");
|
||||
break;
|
||||
case ARDUINO_USB_SUSPEND_EVENT:
|
||||
Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en);
|
||||
break;
|
||||
case ARDUINO_USB_RESUME_EVENT:
|
||||
Serial.println("USB RESUMED");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (event_base == ARDUINO_USB_CDC_EVENTS) {
|
||||
arduino_usb_cdc_event_data_t* data = (arduino_usb_cdc_event_data_t*)event_data;
|
||||
switch (event_id) {
|
||||
case ARDUINO_USB_CDC_CONNECTED_EVENT:
|
||||
Serial.println("CDC CONNECTED");
|
||||
break;
|
||||
case ARDUINO_USB_CDC_DISCONNECTED_EVENT:
|
||||
Serial.println("CDC DISCONNECTED");
|
||||
break;
|
||||
case ARDUINO_USB_CDC_LINE_STATE_EVENT:
|
||||
Serial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts);
|
||||
break;
|
||||
case ARDUINO_USB_CDC_LINE_CODING_EVENT:
|
||||
Serial.printf("CDC LINE CODING: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity);
|
||||
break;
|
||||
case ARDUINO_USB_CDC_RX_EVENT:
|
||||
// Serial.printf("CDC RX [%u]:", data->rx.len);
|
||||
{
|
||||
uint8_t buf[data->rx.len];
|
||||
size_t len = USBSerial.read(buf, data->rx.len);
|
||||
flasherUartHandler(buf, len);
|
||||
}
|
||||
break;
|
||||
case ARDUINO_USB_CDC_RX_OVERFLOW_EVENT:
|
||||
Serial.printf("CDC RX Overflow of %d bytes", data->rx_overflow.dropped_bytes);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
CMD_GET_VERSION = 1,
|
||||
CMD_RESET_ESP = 2,
|
||||
CMD_ZBS_BEGIN = 10,
|
||||
CMD_RESET_ZBS = 11,
|
||||
CMD_SELECT_PAGE = 12,
|
||||
CMD_SET_POWER = 13,
|
||||
CMD_READ_RAM = 20,
|
||||
CMD_WRITE_RAM = 21,
|
||||
CMD_READ_FLASH = 22,
|
||||
CMD_WRITE_FLASH = 23,
|
||||
CMD_READ_SFR = 24,
|
||||
CMD_WRITE_SFR = 25,
|
||||
CMD_ERASE_FLASH = 26,
|
||||
CMD_ERASE_INFOBLOCK = 27,
|
||||
CMD_SAVE_MAC_FROM_FW = 40,
|
||||
CMD_PASS_THROUGH = 50,
|
||||
} ZBS_UART_PROTO;
|
||||
uint32_t FLASHER_VERSION = 0x0000002F;
|
||||
|
||||
static class ZBS_interface* zbs = nullptr;
|
||||
|
||||
void processFlasherCommand(struct flasherCommand* cmd) {
|
||||
uint8_t* tempbuffer;
|
||||
uint8_t temp_buff[16];
|
||||
uint32_t spi_speed = 0;
|
||||
static uint32_t curspeed = 0;
|
||||
|
||||
switch (cmd->command) {
|
||||
case CMD_GET_VERSION:
|
||||
temp_buff[0] = FLASHER_VERSION >> 24;
|
||||
temp_buff[1] = FLASHER_VERSION >> 16;
|
||||
temp_buff[2] = FLASHER_VERSION >> 8;
|
||||
temp_buff[3] = FLASHER_VERSION;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 4);
|
||||
break;
|
||||
case CMD_RESET_ESP:
|
||||
sendFlasherAnswer(cmd->command, NULL, 0);
|
||||
delay(100);
|
||||
ESP.restart();
|
||||
break;
|
||||
case CMD_ZBS_BEGIN:
|
||||
if (zbs != nullptr) {
|
||||
delete zbs;
|
||||
}
|
||||
zbs = new ZBS_interface;
|
||||
if (cmd->data[0] & 1) {
|
||||
spi_speed = 1000000;
|
||||
} else {
|
||||
spi_speed = 8000000;
|
||||
}
|
||||
curspeed = spi_speed;
|
||||
if (cmd->data[0] & 2) {
|
||||
temp_buff[0] = zbs->begin(FLASHER_AP_SS, FLASHER_AP_CLK, FLASHER_AP_MOSI, FLASHER_AP_MISO, FLASHER_AP_RESET, FLASHER_AP_POWER, spi_speed);
|
||||
} else if (cmd->data[0] & 4) {
|
||||
temp_buff[0] = zbs->begin(FLASHER_ALT_SS, FLASHER_ALT_CLK, FLASHER_ALT_MOSI, FLASHER_ALT_MISO, FLASHER_ALT_RESET, 255, spi_speed);
|
||||
} else {
|
||||
temp_buff[0] = zbs->begin(FLASHER_EXT_SS, FLASHER_EXT_CLK, FLASHER_EXT_MOSI, FLASHER_EXT_MISO, FLASHER_EXT_RESET, FLASHER_EXT_POWER, spi_speed);
|
||||
}
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_RESET_ZBS:
|
||||
zbs->reset();
|
||||
temp_buff[0] = 1;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_SELECT_PAGE:
|
||||
temp_buff[0] = zbs->select_flash(cmd->data[0] ? 1 : 0);
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_SET_POWER:
|
||||
zbs->set_power(cmd->data[0] ? 1 : 0);
|
||||
temp_buff[0] = 1;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_READ_RAM:
|
||||
temp_buff[0] = zbs->read_ram(cmd->data[0]);
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_WRITE_RAM:
|
||||
zbs->write_ram(cmd->data[0], cmd->data[1]);
|
||||
temp_buff[0] = 1;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_READ_FLASH:
|
||||
tempbuffer = (uint8_t*)calloc(cmd->data[0], 1);
|
||||
// cmd_buff[0] = len
|
||||
// cmd_buff[1] << 8 | cmd_buff[2] = position
|
||||
Serial.printf("Loading %d bytes from %04X \n", cmd->data[0], (cmd->data[1] << 8 | cmd->data[2]));
|
||||
for (int i = 0; i < cmd->data[0]; i++) {
|
||||
tempbuffer[i] = zbs->read_flash((cmd->data[1] << 8 | cmd->data[2]) + i);
|
||||
}
|
||||
sendFlasherAnswer(cmd->command, tempbuffer, cmd->data[0]);
|
||||
free(tempbuffer);
|
||||
break;
|
||||
case CMD_WRITE_FLASH:
|
||||
// cmd_buff[0] = len
|
||||
// cmd_buff[1] << 8 | cmd_buff[2] = position
|
||||
// cmd_buff[3+i] = data
|
||||
if (cmd->data[0] >= (0xff - 3)) { // Len too high, only 0xFF - header len possible
|
||||
temp_buff[0] = 0xEE;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
}
|
||||
Serial.printf("Writing %d bytes to %04X \n", cmd->data[0], (cmd->data[1] << 8 | cmd->data[2]));
|
||||
for (int i = 0; i < cmd->data[0]; i++) {
|
||||
if (cmd->data[3 + i] != 0xff) {
|
||||
for (uint8_t attempts = 0; attempts < 10; attempts++) {
|
||||
zbs->write_flash((cmd->data[1] << 8 | cmd->data[2]) + i, cmd->data[3 + i]);
|
||||
if (zbs->read_flash((cmd->data[1] << 8 | cmd->data[2]) + i) == cmd->data[3 + i]) {
|
||||
goto flash_pass;
|
||||
}
|
||||
curspeed -= 100000;
|
||||
zbs->setSpeed(curspeed);
|
||||
}
|
||||
flash_fail:
|
||||
temp_buff[0] = 0;
|
||||
Serial.print("!");
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
flash_pass:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
temp_buff[0] = 1;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
Serial.print("#");
|
||||
break;
|
||||
case CMD_READ_SFR:
|
||||
temp_buff[0] = zbs->read_sfr(cmd->data[0]);
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_WRITE_SFR:
|
||||
zbs->write_sfr(cmd->data[0], cmd->data[1]);
|
||||
temp_buff[0] = 1;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_ERASE_FLASH:
|
||||
zbs->erase_flash();
|
||||
temp_buff[0] = 1;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_ERASE_INFOBLOCK:
|
||||
zbs->erase_infoblock();
|
||||
temp_buff[0] = 1;
|
||||
sendFlasherAnswer(cmd->command, temp_buff, 1);
|
||||
break;
|
||||
case CMD_SAVE_MAC_FROM_FW:
|
||||
case CMD_PASS_THROUGH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbFlasherTask(void* parameter) {
|
||||
flasherCmdQueue = xQueueCreate(10, sizeof(struct flasherCommand*));
|
||||
#if ARDUINO_USB_MODE
|
||||
#warning Wrong USB mode is in use, check settings in platformio.ini
|
||||
#endif
|
||||
USB.onEvent(usbEventCallback);
|
||||
USBSerial.onEvent(usbEventCallback);
|
||||
USBSerial.begin();
|
||||
USB.begin();
|
||||
struct flasherCommand* cmd;
|
||||
while (true) {
|
||||
BaseType_t queuereceive = xQueueReceive(flasherCmdQueue, &cmd, portMAX_DELAY);
|
||||
if (queuereceive == pdTRUE) {
|
||||
processFlasherCommand(cmd);
|
||||
if (cmd->data != nullptr) {
|
||||
free(cmd->data);
|
||||
}
|
||||
delete cmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "newproto.h"
|
||||
#include "settings.h"
|
||||
#include "tag_db.h"
|
||||
#include "leds.h"
|
||||
|
||||
extern uint8_t data_to_send[];
|
||||
|
||||
@@ -51,6 +52,7 @@ void webSocketSendProcess(void *parameter) {
|
||||
}
|
||||
|
||||
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
||||
shortBlink(CRGB::BlueViolet);
|
||||
switch (type) {
|
||||
case WS_EVT_CONNECT:
|
||||
// client connected
|
||||
@@ -1,55 +1,57 @@
|
||||
|
||||
/* Autor: Aaron Christophel ATCnetz.de */
|
||||
|
||||
#include "zbs_interface.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
void simplePowerOn() {
|
||||
pinMode(ZBS_SS, INPUT);
|
||||
pinMode(ZBS_CLK, INPUT);
|
||||
pinMode(ZBS_MoSi, INPUT);
|
||||
pinMode(ZBS_MiSo, INPUT);
|
||||
pinMode(ZBS_Reset, OUTPUT);
|
||||
digitalWrite(ZBS_Reset, HIGH);
|
||||
zbs.set_power(0);
|
||||
delay(500);
|
||||
zbs.set_power(1);
|
||||
}
|
||||
|
||||
uint8_t ZBS_interface::begin() {
|
||||
_SS_PIN = ZBS_SS;
|
||||
_CLK_PIN = ZBS_CLK;
|
||||
_MOSI_PIN = ZBS_MoSi;
|
||||
_MISO_PIN = ZBS_MiSo;
|
||||
_RESET_PIN = ZBS_Reset;
|
||||
#include "powermgt.h"
|
||||
|
||||
uint8_t ZBS_interface::begin(uint8_t SS, uint8_t CLK, uint8_t MOSI, uint8_t MISO, uint8_t RESET, uint8_t POWER, uint32_t spi_speed) {
|
||||
_SS_PIN = SS;
|
||||
_CLK_PIN = CLK;
|
||||
_MOSI_PIN = MOSI;
|
||||
_MISO_PIN = MISO;
|
||||
_RESET_PIN = RESET;
|
||||
_POWER_PIN = POWER;
|
||||
pinMode(_SS_PIN, OUTPUT);
|
||||
pinMode(_RESET_PIN, OUTPUT);
|
||||
digitalWrite(_SS_PIN, HIGH);
|
||||
digitalWrite(_RESET_PIN, HIGH);
|
||||
set_power(ZBS_ON);
|
||||
pinMode(_CLK_PIN, OUTPUT);
|
||||
pinMode(_MOSI_PIN, OUTPUT);
|
||||
pinMode(_MISO_PIN, INPUT);
|
||||
pinMode(_RESET_PIN, OUTPUT);
|
||||
digitalWrite(_SS_PIN, HIGH);
|
||||
digitalWrite(_CLK_PIN, LOW);
|
||||
digitalWrite(_MOSI_PIN, HIGH);
|
||||
digitalWrite(_RESET_PIN, HIGH);
|
||||
set_power(ZBS_ON);
|
||||
|
||||
if (!spi) spi = new SPIClass(HSPI);
|
||||
|
||||
spiSettings = SPISettings(spi_speed, MSBFIRST, SPI_MODE0);
|
||||
spi_ready = 0;
|
||||
|
||||
if (spi_speed != 8000000) {
|
||||
after_byte_delay = 10;
|
||||
} else {
|
||||
after_byte_delay = 10;
|
||||
}
|
||||
enable_debug();
|
||||
return check_connection();
|
||||
}
|
||||
|
||||
void ZBS_interface::setSpeed(uint32_t speed) {
|
||||
spiSettings = SPISettings(speed, MSBFIRST, SPI_MODE0);
|
||||
}
|
||||
|
||||
ZBS_interface::~ZBS_interface() {
|
||||
delete spi;
|
||||
}
|
||||
void ZBS_interface::set_power(uint8_t state) {
|
||||
pinMode(ZBS_POWER1, INPUT);
|
||||
pinMode(ZBS_POWER2, INPUT);
|
||||
digitalWrite(ZBS_POWER1, state);
|
||||
digitalWrite(ZBS_POWER2, state);
|
||||
pinMode(ZBS_POWER1, OUTPUT);
|
||||
pinMode(ZBS_POWER2, OUTPUT);
|
||||
if (_POWER_PIN != 255) {
|
||||
rampTagPower(_POWER_PIN, state);
|
||||
}
|
||||
}
|
||||
|
||||
void ZBS_interface::enable_debug() {
|
||||
@@ -81,6 +83,7 @@ void ZBS_interface::enable_debug() {
|
||||
}
|
||||
|
||||
void ZBS_interface::reset() {
|
||||
spi->end();
|
||||
pinMode(_SS_PIN, INPUT);
|
||||
pinMode(_CLK_PIN, INPUT);
|
||||
pinMode(_MOSI_PIN, INPUT);
|
||||
@@ -96,18 +99,14 @@ void ZBS_interface::reset() {
|
||||
void ZBS_interface::send_byte(uint8_t data) {
|
||||
digitalWrite(_SS_PIN, LOW);
|
||||
delayMicroseconds(5);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (data & 0x80) {
|
||||
digitalWrite(_MOSI_PIN, HIGH);
|
||||
} else {
|
||||
digitalWrite(_MOSI_PIN, LOW);
|
||||
}
|
||||
delayMicroseconds(ZBS_spi_delay);
|
||||
digitalWrite(_CLK_PIN, HIGH);
|
||||
delayMicroseconds(ZBS_spi_delay);
|
||||
digitalWrite(_CLK_PIN, LOW);
|
||||
data <<= 1;
|
||||
if (!spi_ready) {
|
||||
spi_ready = 1;
|
||||
spi->begin(_CLK_PIN, _MISO_PIN, _MOSI_PIN);
|
||||
}
|
||||
spi->beginTransaction(spiSettings);
|
||||
spi->transfer(data);
|
||||
spi->endTransaction();
|
||||
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(_SS_PIN, HIGH);
|
||||
}
|
||||
@@ -116,16 +115,13 @@ uint8_t ZBS_interface::read_byte() {
|
||||
uint8_t data = 0x00;
|
||||
digitalWrite(_SS_PIN, LOW);
|
||||
delayMicroseconds(5);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
data <<= 1;
|
||||
if (digitalRead(_MISO_PIN)) {
|
||||
data |= 1;
|
||||
}
|
||||
delayMicroseconds(ZBS_spi_delay);
|
||||
digitalWrite(_CLK_PIN, HIGH);
|
||||
delayMicroseconds(ZBS_spi_delay);
|
||||
digitalWrite(_CLK_PIN, LOW);
|
||||
if (!spi_ready) {
|
||||
spi_ready = 1;
|
||||
spi->begin(_CLK_PIN, _MISO_PIN, _MOSI_PIN);
|
||||
}
|
||||
spi->beginTransaction(spiSettings);
|
||||
data = spi->transfer(0xff);
|
||||
spi->endTransaction();
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(_SS_PIN, HIGH);
|
||||
return data;
|
||||
@@ -135,7 +131,7 @@ void ZBS_interface::write_byte(uint8_t cmd, uint8_t addr, uint8_t data) {
|
||||
send_byte(cmd);
|
||||
send_byte(addr);
|
||||
send_byte(data);
|
||||
delay(1);
|
||||
delayMicroseconds(after_byte_delay);
|
||||
}
|
||||
|
||||
uint8_t ZBS_interface::read_byte(uint8_t cmd, uint8_t addr) {
|
||||
@@ -143,7 +139,7 @@ uint8_t ZBS_interface::read_byte(uint8_t cmd, uint8_t addr) {
|
||||
send_byte(cmd);
|
||||
send_byte(addr);
|
||||
data = read_byte();
|
||||
delay(1);
|
||||
delayMicroseconds(after_byte_delay);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -152,7 +148,7 @@ void ZBS_interface::write_flash(uint16_t addr, uint8_t data) {
|
||||
send_byte(addr >> 8);
|
||||
send_byte(addr);
|
||||
send_byte(data);
|
||||
delay(1);
|
||||
delayMicroseconds(after_byte_delay);
|
||||
}
|
||||
|
||||
uint8_t ZBS_interface::read_flash(uint16_t addr) {
|
||||
@@ -161,7 +157,7 @@ uint8_t ZBS_interface::read_flash(uint16_t addr) {
|
||||
send_byte(addr >> 8);
|
||||
send_byte(addr);
|
||||
data = read_byte();
|
||||
delay(1);
|
||||
delayMicroseconds(after_byte_delay);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -210,5 +206,3 @@ void ZBS_interface::erase_infoblock() {
|
||||
send_byte(0x00);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
ZBS_interface zbs;
|
||||
BIN
ESP32_AP-Flasher/test.bin2
Normal file
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 121 KiB |