Added WiFi AP console mode

This commit is contained in:
Mark Qvist 2023-01-07 16:35:07 +01:00
parent da1d9e732b
commit 910d50f11e
9 changed files with 313 additions and 27 deletions

View File

@ -109,7 +109,7 @@ char bt_devname[11];
bool bt_init() {
bt_state = BT_STATE_OFF;
if (bt_setup_hw()) {
if (bt_enabled) bt_start();
if (bt_enabled && !console_active) bt_start();
return true;
} else {
return false;

View File

@ -42,6 +42,11 @@
bool bt_enabled = false;
bool bt_allow_pairing = false;
#define M_FRQ_S 27388122
#define M_FRQ_R 27388061
bool console_active = false;
bool sx1276_installed = false;
#if defined(__AVR_ATmega1284P__)
#define PLATFORM PLATFORM_AVR
#define MCU_VARIANT MCU_1284P

178
Console.h Normal file
View File

@ -0,0 +1,178 @@
#include <FS.h>
#include <SPIFFS.h>
#include <WiFi.h>
#include <WebServer.h>
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/rtc.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
// Replace with your network credentials
const char* ssid = "RNode Test";
const char* password = "somepass";
WebServer server(80);
void console_dbg(String msg) {
Serial.print("[Webserver] ");
Serial.println(msg);
}
bool exists(String path){
bool yes = false;
File file = SPIFFS.open(path, "r");
if(!file.isDirectory()){
yes = true;
}
file.close();
return yes;
}
String console_get_content_type(String filename) {
if (server.hasArg("download")) {
return "application/octet-stream";
} else if (filename.endsWith(".htm")) {
return "text/html";
} else if (filename.endsWith(".html")) {
return "text/html";
} else if (filename.endsWith(".css")) {
return "text/css";
} else if (filename.endsWith(".js")) {
return "application/javascript";
} else if (filename.endsWith(".png")) {
return "image/png";
} else if (filename.endsWith(".gif")) {
return "image/gif";
} else if (filename.endsWith(".jpg")) {
return "image/jpeg";
} else if (filename.endsWith(".ico")) {
return "image/x-icon";
} else if (filename.endsWith(".xml")) {
return "text/xml";
} else if (filename.endsWith(".pdf")) {
return "application/x-pdf";
} else if (filename.endsWith(".zip")) {
return "application/x-zip";
} else if (filename.endsWith(".gz")) {
return "application/x-gzip";
}
return "text/plain";
}
bool console_serve_file(String path) {
console_dbg("Request for: "+path);
if (path.endsWith("/")) {
path += "index.html";
}
String content_type = console_get_content_type(path);
String pathWithGz = path + ".gz";
if (exists(pathWithGz) || exists(path)) {
if (exists(pathWithGz)) {
path += ".gz";
}
File file = SPIFFS.open(path, "r");
console_dbg("Serving file to client");
server.streamFile(file, content_type);
file.close();
console_dbg("File serving done");
return true;
}
console_dbg("Error: Could not open file for serving");
return false;
}
void console_register_pages() {
server.onNotFound([]() {
if (!console_serve_file(server.uri())) {
server.send(404, "text/plain", "Not Found");
}
});
}
void console_start() {
Serial.println("");
console_dbg("Starting Access Point...");
// WiFi.softAP(ssid, password);
WiFi.softAP(bt_devname, password);
delay(150);
IPAddress ip(10, 0, 0, 1);
IPAddress nm(255, 255, 255, 0);
WiFi.softAPConfig(ip, ip, nm);
if(!SPIFFS.begin(true)){
console_dbg("Error: Could not mount SPIFFS");
return;
} else {
console_dbg("SPIFFS Ready");
}
console_register_pages();
server.begin();
led_indicate_console();
}
void console_loop(){
server.handleClient();
// Internally, this yields the thread and allows
// other tasks to run.
delay(5);
}
// void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
// Serial.printf("Listing directory: %s\r\n", dirname);
// File root = fs.open(dirname);
// if(!root){
// Serial.println("- failed to open directory");
// return;
// }
// if(!root.isDirectory()){
// Serial.println(" - not a directory");
// return;
// }
// File file = root.openNextFile();
// while(file){
// if(file.isDirectory()){
// Serial.print(" DIR : ");
// Serial.println(file.name());
// if(levels){
// listDir(fs, file.path(), levels -1);
// }
// } else {
// Serial.print(" FILE: ");
// Serial.print(file.name());
// Serial.print("\tSIZE: ");
// Serial.println(file.size());
// }
// file = root.openNextFile();
// }
// }
// void readFile(fs::FS &fs, const char * path){
// Serial.printf("Reading file: %s\r\n", path);
// File file = fs.open(path);
// if(!file || file.isDirectory()){
// Serial.println(" failed to open file for reading");
// return;
// }
// Serial.println(" read from file:");
// while(file.available()){
// Serial.write(file.read());
// }
// }

14
Console/index.html Normal file

File diff suppressed because one or more lines are too long

View File

@ -85,6 +85,8 @@
#define MAX_PKT_LENGTH 255
bool lora_preinit_done = false;
LoRaClass::LoRaClass() :
_spiSettings(8E6, MSBFIRST, SPI_MODE0),
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN),
@ -97,13 +99,26 @@ LoRaClass::LoRaClass() :
setTimeout(0);
}
int LoRaClass::begin(long frequency)
{
bool LoRaClass::preInit() {
// setup pins
pinMode(_ss, OUTPUT);
// set SS high
digitalWrite(_ss, HIGH);
SPI.begin();
// check version
uint8_t version = readRegister(REG_VERSION);
if (version != 0x12) {
return false;
}
lora_preinit_done = true;
return true;
}
int LoRaClass::begin(long frequency)
{
if (_reset != -1) {
pinMode(_reset, OUTPUT);
@ -114,13 +129,10 @@ int LoRaClass::begin(long frequency)
delay(10);
}
// start SPI
SPI.begin();
// check version
uint8_t version = readRegister(REG_VERSION);
if (version != 0x12) {
return 0;
if (!lora_preinit_done) {
if (!preInit()) {
return false;
}
}
// put in sleep mode
@ -433,6 +445,11 @@ void LoRaClass::setTxPower(int level, int outputPin) {
}
}
uint8_t LoRaClass::getTxPower() {
byte txp = readRegister(REG_PA_CONFIG);
return txp;
}
void LoRaClass::setFrequency(long frequency) {
_frequency = frequency;

2
LoRa.h
View File

@ -54,6 +54,8 @@ public:
void idle();
void sleep();
bool preInit();
uint8_t getTxPower();
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
uint32_t getFrequency();
void setFrequency(long frequency);

View File

@ -32,9 +32,6 @@ char sbuf[128];
bool packet_ready = false;
#endif
// TODO: Implement
bool console_active = true;
void setup() {
#if MCU_VARIANT == MCU_ESP32
boot_seq();
@ -76,6 +73,26 @@ void setup() {
// pins for the LoRa module
LoRa.setPins(pin_cs, pin_reset, pin_dio);
if (LoRa.preInit()) {
sx1276_installed = true;
uint32_t lfr = LoRa.getFrequency();
if (lfr == 0) {
// Normal boot
} else if (lfr == M_FRQ_R) {
// Quick reboot
#if HAS_CONSOLE
if (rtc_get_reset_reason(0) == POWERON_RESET) {
console_active = true;
}
#endif
} else {
// Unknown boot
}
LoRa.setFrequency(M_FRQ_S);
} else {
sx1276_installed = false;
}
#if HAS_DISPLAY
disp_ready = display_init();
update_display();
@ -91,15 +108,17 @@ void setup() {
bt_init_ran = true;
#endif
kiss_indicate_reset();
if (console_active) {
console_start();
} else {
kiss_indicate_reset();
}
#endif
// Validate board health, EEPROM and config
validate_status();
LoRa.setFrequency(0);
}
void lora_receive() {
@ -864,6 +883,7 @@ void validate_status() {
if (eeprom_product_valid() && eeprom_model_valid() && eeprom_hwrev_valid()) {
if (eeprom_checksum_valid()) {
eeprom_ok = true;
if (sx1276_installed) {
#if PLATFORM == PLATFORM_ESP32
if (device_init()) {
hw_ready = true;
@ -873,6 +893,16 @@ void validate_status() {
#else
hw_ready = true;
#endif
} else {
hw_ready = false;
Serial.write("No SX1276/SX1278 radio module found\r\n");
#if HAS_DISPLAY
if (disp_ready) {
device_init_done = true;
update_display();
}
#endif
}
if (hw_ready && eeprom_have_conf()) {
eeprom_conf_load();
@ -969,8 +999,10 @@ void loop() {
}
#if MCU_VARIANT == MCU_ESP32
// if (!console_active) {
buffer_serial();
if (!fifo_isempty(&serialFIFO)) serial_poll();
// }
#else
if (!fifo_isempty_locked(&serialFIFO)) serial_poll();
#endif
@ -984,7 +1016,7 @@ void loop() {
#endif
#if HAS_BLUETOOTH
if (bt_ready) update_bt();
if (!console_active && bt_ready) update_bt();
#endif
}

BIN
Release/spiffs.bin Normal file

Binary file not shown.

View File

@ -326,6 +326,7 @@ unsigned long led_standby_ticks = 0;
int8_t led_notready_direction = 0;
unsigned long led_notready_ticks = 0;
unsigned long led_standby_wait = 350;
unsigned long led_console_wait = 1;
unsigned long led_notready_wait = 200;
#else
@ -389,6 +390,34 @@ int8_t led_standby_direction = 0;
}
}
void led_indicate_console() {
npset(0x60, 0x00, 0x60);
// led_standby_ticks++;
// if (led_standby_ticks > led_console_wait) {
// led_standby_ticks = 0;
// if (led_standby_value <= led_standby_min) {
// led_standby_direction = 1;
// } else if (led_standby_value >= led_standby_max) {
// led_standby_direction = -1;
// }
// uint8_t led_standby_intensity;
// led_standby_value += led_standby_direction;
// int led_standby_ti = led_standby_value - led_standby_lng;
// if (led_standby_ti < 0) {
// led_standby_intensity = 0;
// } else if (led_standby_ti > led_standby_cut) {
// led_standby_intensity = led_standby_cut;
// } else {
// led_standby_intensity = led_standby_ti;
// }
// npset(led_standby_intensity, 0x00, led_standby_intensity);
// }
}
#else
void led_indicate_standby() {
led_standby_ticks++;
@ -418,6 +447,10 @@ int8_t led_standby_direction = 0;
#endif
}
}
void led_indicate_console() {
led_indicate_standby();
}
#endif
#endif
@ -804,6 +837,11 @@ void set_implicit_length(uint8_t len) {
}
}
int getTxPower() {
uint8_t txp = LoRa.getTxPower();
return (int)txp;
}
void setTXPower() {
if (radio_online) {
if (model == MODEL_A2) LoRa.setTxPower(lora_txp, PA_OUTPUT_PA_BOOST_PIN);