mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-30 09:39:49 +02:00
Fixed bugs, added convert-all.py
This commit is contained in:
114
libraries/EpoxyEepromEsp/EEPROM.h
Normal file
114
libraries/EpoxyEepromEsp/EEPROM.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
Copyright (c) 2021 Brian T. Park.
|
||||
|
||||
API derived from:
|
||||
EEPROM.cpp - esp8266 EEPROM emulation
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef EPOXY_EEPROM_ESP_H
|
||||
#define EPOXY_EEPROM_ESP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h> // memcpy()
|
||||
|
||||
/** Use this macro to distinguish between EpoxyEepromEsp or EpoxyEepromAvr. */
|
||||
#define EPOXY_DUINO_EPOXY_EEPROM_ESP 1
|
||||
|
||||
/**
|
||||
* A EEPROM library that works on POSIX-like systems using EpoxyDuino. This
|
||||
* version implements the EEPROM API found on ESP8266 and ESP32 Arduino Cores.
|
||||
*/
|
||||
class EpoxyEepromEsp {
|
||||
public:
|
||||
EpoxyEepromEsp() = default;
|
||||
|
||||
void begin(size_t size);
|
||||
|
||||
uint8_t read(int address) {
|
||||
return data_[address];
|
||||
}
|
||||
|
||||
void write(int address, uint8_t val) {
|
||||
uint8_t prev = data_[address];
|
||||
if (val != prev) {
|
||||
data_[address] = val;
|
||||
dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool commit();
|
||||
|
||||
void end() {
|
||||
commit();
|
||||
if (data_) {
|
||||
delete[] data_;
|
||||
data_ = nullptr;
|
||||
}
|
||||
size_ = 0;
|
||||
dirty_ = false;
|
||||
}
|
||||
|
||||
size_t length() { return size_; }
|
||||
|
||||
uint8_t& operator[](int address) { return data_[address]; }
|
||||
|
||||
uint8_t const & operator[](int address) const { return data_[address]; }
|
||||
|
||||
/**
|
||||
* Unlike the version on ESP8266 or ESP32, this implementation does not
|
||||
* perform bounds checking. It didn't seem to make sense since operator[]
|
||||
* does not do bounds checking either, and it seems better to catch out of
|
||||
* bounds problem on desktop systems with a Segmentation Fault.
|
||||
*/
|
||||
template<typename T>
|
||||
T &get(int address, T &t) {
|
||||
memcpy((uint8_t*) &t, data_ + address, sizeof(T));
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike the version on ESP8266 or ESP32, this implementation does not
|
||||
* perform bounds checking. It didn't seem to make sense since operator[]
|
||||
* does not do bounds checking either, and it seems better to catch out of
|
||||
* bounds problem on desktop systems with a Segmentation Fault.
|
||||
*/
|
||||
template<typename T>
|
||||
const T &put(int address, const T &t) {
|
||||
if (memcmp(data_ + address, (const uint8_t*)&t, sizeof(T)) != 0) {
|
||||
dirty_ = true;
|
||||
memcpy(data_ + address, (const uint8_t*)&t, sizeof(T));
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
private:
|
||||
static const char* getDataPath();
|
||||
|
||||
uint8_t* data_ = nullptr;
|
||||
size_t size_ = 0;
|
||||
bool dirty_ = false;
|
||||
};
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)
|
||||
extern EpoxyEepromEsp EpoxyEepromEspInstance;
|
||||
#endif
|
||||
|
||||
#endif
|
70
libraries/EpoxyEepromEsp/EpoxyEepromEsp.cpp
Normal file
70
libraries/EpoxyEepromEsp/EpoxyEepromEsp.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright (c) 2021 Brian T. Park.
|
||||
|
||||
API derived from:
|
||||
EEPROM.cpp - esp8266 EEPROM emulation
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h> // getenv()
|
||||
#include <stdio.h> // FILE, fopen(), fwrite(), fread()
|
||||
#include "EpoxyEepromEsp.h"
|
||||
|
||||
void EpoxyEepromEsp::begin(size_t size) {
|
||||
// round up to nearest 4-byte alignment
|
||||
size = (size + 3) & (~3);
|
||||
|
||||
if (size == size_) return;
|
||||
size_ = size;
|
||||
|
||||
if (data_) {
|
||||
delete[] data_;
|
||||
}
|
||||
data_ = new uint8_t[size_];
|
||||
dirty_ = false;
|
||||
|
||||
const char* dataPath = getDataPath();
|
||||
FILE* fp = fopen(dataPath, "rb");
|
||||
if (fp) {
|
||||
fread(data_, 1, size_, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
bool EpoxyEepromEsp::commit() {
|
||||
if (!size_ || !dirty_ || !data_) return true;
|
||||
const char* dataPath = getDataPath();
|
||||
FILE* fp = fopen(dataPath, "wb");
|
||||
if (!fp) return false;
|
||||
fwrite(data_, 1, size_, fp);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* EpoxyEepromEsp::getDataPath() {
|
||||
const char* dataPath = getenv("EPOXY_EEPROM_DATA");
|
||||
if (!dataPath) {
|
||||
dataPath = "epoxyeepromdata";
|
||||
}
|
||||
return dataPath;
|
||||
}
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)
|
||||
EpoxyEepromEsp EpoxyEepromEspInstance;
|
||||
#endif
|
142
libraries/EpoxyEepromEsp/README.md
Normal file
142
libraries/EpoxyEepromEsp/README.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# EpoxyEepromEsp
|
||||
|
||||
An implementation of `EEPROM` that runs on Linux (or other POSIX-like system)
|
||||
using EpoxyDuino (https://github.com/bxparks/EpoxyDuino). There are at least two
|
||||
versions of the `EEPROM` API:
|
||||
|
||||
* AVR flavor: AVR, STM32, Teensy, and potentially others
|
||||
* https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/EEPROM/src/EEPROM.h
|
||||
* ESP flavor: ESP8266 and ESP32,
|
||||
* https://github.com/esp8266/Arduino/blob/master/libraries/EEPROM/EEPROM.h
|
||||
|
||||
This library implements the **ESP** flavor of the EEPROM API. The EEPROM
|
||||
contents are buffered in memory, then saved to a file called `epoxyeepromdata`
|
||||
in the current directory upon the `EEPROM.commit()` or `EEPROM.end()` methods.
|
||||
|
||||
See [EpoxyEepromAvr](../EpoxyEepromAvr/) for the AVR version.
|
||||
|
||||
## Usage
|
||||
|
||||
### EEPROM API
|
||||
|
||||
This library provides most of the functions listed in
|
||||
[EEPROM.h](https://github.com/esp8266/Arduino/blob/master/libraries/EEPROM/EEPROM.h)
|
||||
in the Arduino ESP8226 Core.
|
||||
|
||||
### Makefile
|
||||
|
||||
When using the EpoxyDuino Makefile, the `EpoxyEepromEsp` library must be added to
|
||||
the `ARDUINO_LIBS` parameter, like this:
|
||||
|
||||
```
|
||||
APP_NAME := EpoxyEepromEspTest
|
||||
ARDUINO_LIBS := EpoxyEepromEsp ...
|
||||
MORE_CLEAN := more_clean
|
||||
include ../../../../EpoxyDuino.mk
|
||||
```
|
||||
|
||||
### Sample Code
|
||||
|
||||
```C++
|
||||
#include <EpoxyEepromEsp.h>
|
||||
#define EEPROM EpoxyEepromEspInstance
|
||||
|
||||
void write() {
|
||||
int address = 0;
|
||||
uint8_t value = 10;
|
||||
|
||||
// write() method
|
||||
EEPROM.write(address, value);
|
||||
|
||||
// operator[]
|
||||
EEPROM[address+1] = value+1;
|
||||
|
||||
// commit() or end() required to persist to disk
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void read() {
|
||||
int address = 0;
|
||||
|
||||
// read()
|
||||
uint8_t value = EEPROM.read(address);
|
||||
|
||||
// operator[]
|
||||
value = EEPROM[address];
|
||||
}
|
||||
|
||||
void detectAPI() {
|
||||
#if EPOXY_DUINO_EPOXY_EEPROM_ESP
|
||||
#warning Using EpoxyEepromEsp version of EEPROM
|
||||
EEPROM.begin(...);
|
||||
EEPROM.write(...);
|
||||
EEPROM.commit(...);
|
||||
EEPROM.read(...);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup() {
|
||||
const int SIZE = 1024;
|
||||
|
||||
// begin() required
|
||||
EEPROM.begin(SIZE);
|
||||
...
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
```
|
||||
|
||||
## Difference between ESP and AVR APIs
|
||||
|
||||
### AVR Flavor
|
||||
|
||||
The AVR version of `EEPROM` provides 2 write functions:
|
||||
```C++
|
||||
EEPROM.write(address, value);
|
||||
EEPROM.update(address, value);
|
||||
```
|
||||
where the `update()` only writes to the EEPROM if the new value is different
|
||||
than the old value stored in the EEPROM. This saves wear on the EEPROM.
|
||||
|
||||
The `EEPROM.begin()` and `EEPROM.end()` methods return iterators, which allows
|
||||
looping for the content of the EEPROM like this:
|
||||
|
||||
```C++
|
||||
for (EEPtr p = EEPROM.begin(); p != EEPROM.end(); p++) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### ESP Flavor
|
||||
|
||||
The ESP8266 and ESP32 versions provide only the `write()` function:
|
||||
|
||||
```C++
|
||||
EEPROM.write(address, value)
|
||||
```
|
||||
|
||||
The `begin()` and `end()` methods mean completely different things on the ESP
|
||||
processors:
|
||||
|
||||
```C++
|
||||
EEPROM.begin(size);
|
||||
```
|
||||
initializes the EEPROM storage space. The data written to the EEPROM using
|
||||
the `write()` method is buffered in memory until one of:
|
||||
|
||||
```C++
|
||||
EEPROM.commit();
|
||||
EEPROM.end();
|
||||
```
|
||||
is executed.
|
||||
|
||||
## Environment Variable
|
||||
|
||||
By default, the content of the `EEPROM` is saved to a file named
|
||||
`epoxyeepromdata` in the current directory. You can change this by setting the
|
||||
`EPOXY_EEPROM_DATA` environment variable:
|
||||
|
||||
```
|
||||
$ export EPOXY_EEPROM_DATA=/tmp/epoxyeepromdata
|
||||
```
|
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Test the EEPROM implementation provided by EpoxyEepromEsp. This program
|
||||
* should compile and run under EpoxyDuino and produce the following output:
|
||||
*
|
||||
* write1: 0 1 2 3 252 253 254 255
|
||||
* write2: 3 2 1 0 255 254 253 252
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <EpoxyEepromEsp.h>
|
||||
|
||||
#ifndef SERIAL_PORT_MONITOR
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
#endif
|
||||
|
||||
#define EEPROM EpoxyEepromEspInstance
|
||||
|
||||
void writeToEeprom1() {
|
||||
// Write at address=0
|
||||
uint32_t value = 0x03020100;
|
||||
EEPROM.put(0, value);
|
||||
|
||||
// Write at the end of the EEPROM.
|
||||
EEPROM.write(1020, 252);
|
||||
EEPROM.write(1021, 253);
|
||||
EEPROM.write(1022, 254);
|
||||
EEPROM.write(1023, 255);
|
||||
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void writeToEeprom2() {
|
||||
// Write at address=0
|
||||
uint32_t value = 0x00010203;
|
||||
EEPROM.put(0, value);
|
||||
|
||||
// Write at the end of the EEPROM.
|
||||
EEPROM.write(1020, 255);
|
||||
EEPROM.write(1021, 254);
|
||||
EEPROM.write(1022, 253);
|
||||
EEPROM.write(1023, 252);
|
||||
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void readFromEeprom(const char* label) {
|
||||
SERIAL_PORT_MONITOR.print(label);
|
||||
SERIAL_PORT_MONITOR.print(": ");
|
||||
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(0));
|
||||
SERIAL_PORT_MONITOR.print(' ');
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(1));
|
||||
SERIAL_PORT_MONITOR.print(' ');
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(2));
|
||||
SERIAL_PORT_MONITOR.print(' ');
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(3));
|
||||
SERIAL_PORT_MONITOR.print(' ');
|
||||
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(1020));
|
||||
SERIAL_PORT_MONITOR.print(' ');
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(1021));
|
||||
SERIAL_PORT_MONITOR.print(' ');
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(1022));
|
||||
SERIAL_PORT_MONITOR.print(' ');
|
||||
SERIAL_PORT_MONITOR.print(EEPROM.read(1023));
|
||||
|
||||
SERIAL_PORT_MONITOR.println();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
#if ! defined(EPOXY_DUINO)
|
||||
delay(1000); // some boards reboot twice
|
||||
#endif
|
||||
SERIAL_PORT_MONITOR.begin(115200);
|
||||
while (!SERIAL_PORT_MONITOR); // For Leonardo/Micro
|
||||
|
||||
EEPROM.begin(1024);
|
||||
|
||||
writeToEeprom1();
|
||||
readFromEeprom("write1");
|
||||
writeToEeprom2();
|
||||
readFromEeprom("write2");
|
||||
|
||||
#if defined(EPOXY_DUINO)
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
# See https://github.com/bxparks/EpoxyDuino for documentation about this
|
||||
# Makefile to compile and run Arduino programs natively on Linux or MacOS.
|
||||
|
||||
APP_NAME := HelloEpoxyEepromEsp
|
||||
ARDUINO_LIBS := EpoxyEepromEsp AceUtils AceCRC AceRoutine AceCommon
|
||||
MORE_CLEAN := more_clean
|
||||
include ../../../../EpoxyDuino.mk
|
||||
|
||||
more_clean:
|
||||
rm -f epoxyeepromdata
|
13
libraries/EpoxyEepromEsp/examples/Makefile
Normal file
13
libraries/EpoxyEepromEsp/examples/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
all:
|
||||
set -e; \
|
||||
for i in */Makefile; do \
|
||||
echo '==== Making:' $$(dirname $$i); \
|
||||
$(MAKE) -C $$(dirname $$i) -j; \
|
||||
done
|
||||
|
||||
clean:
|
||||
set -e; \
|
||||
for i in */Makefile; do \
|
||||
echo '==== Cleaning:' $$(dirname $$i); \
|
||||
$(MAKE) -C $$(dirname $$i) clean; \
|
||||
done
|
10
libraries/EpoxyEepromEsp/library.properties
Normal file
10
libraries/EpoxyEepromEsp/library.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
name=EpoxyEepromEsp
|
||||
version=1.0
|
||||
author=bxparks
|
||||
maintainer=bxparks
|
||||
sentence=ESP32 EEPROM emulation for EpoxyDuino
|
||||
paragraph=
|
||||
category=
|
||||
url=https://github.com/bxparks/EpoxyDuino
|
||||
architectures=esp32 windows_amd64
|
||||
|
@@ -0,0 +1,60 @@
|
||||
#line 2 "EpoxyEepromEspTest.ino"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <AUnit.h>
|
||||
#include <EpoxyEepromEsp.h>
|
||||
|
||||
using aunit::TestRunner;
|
||||
|
||||
#define EEPROM EpoxyEepromEspInstance
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
test(writeAndReadTest) {
|
||||
EEPROM.begin(1024);
|
||||
assertEqual((size_t) 1024, EEPROM.length());
|
||||
|
||||
// Write using put()
|
||||
uint32_t output = 0x04030201;
|
||||
EEPROM.put(0, output);
|
||||
|
||||
// Write at the end of the EEPROM space, using write() and operator[].
|
||||
EEPROM.write(1020, 1);
|
||||
EEPROM.write(1021, 2);
|
||||
EEPROM[1022] = 3;
|
||||
EEPROM[1023] = 4;
|
||||
|
||||
// Save to disk
|
||||
EEPROM.commit();
|
||||
EEPROM.end();
|
||||
|
||||
// Read back again.
|
||||
EEPROM.begin(1024);
|
||||
|
||||
// Read using get()
|
||||
uint32_t input = 0;
|
||||
EEPROM.get(0, input);
|
||||
assertEqual(output, input);
|
||||
|
||||
// Read using read() and operator[].
|
||||
assertEqual(1, EEPROM.read(1020));
|
||||
assertEqual(2, EEPROM.read(1021));
|
||||
assertEqual(3, EEPROM[1022]);
|
||||
assertEqual(4, EEPROM[1023]);
|
||||
|
||||
EEPROM.end();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void setup() {
|
||||
#if ! defined(EPOXY_DUINO)
|
||||
delay(1000); // wait to prevent garbage on SERIAL_PORT_MONITOR
|
||||
#endif
|
||||
SERIAL_PORT_MONITOR.begin(115200);
|
||||
while (!SERIAL_PORT_MONITOR); // needed for Leonardo/Micro
|
||||
}
|
||||
|
||||
void loop() {
|
||||
TestRunner::run();
|
||||
}
|
10
libraries/EpoxyEepromEsp/tests/EpoxyEepromEspTest/Makefile
Normal file
10
libraries/EpoxyEepromEsp/tests/EpoxyEepromEspTest/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
# See https://github.com/bxparks/EpoxyDuino for documentation about this
|
||||
# Makefile to compile and run Arduino programs natively on Linux or MacOS.
|
||||
|
||||
APP_NAME := EpoxyEepromEspTest
|
||||
ARDUINO_LIBS := EpoxyEepromEsp AUnit
|
||||
MORE_CLEAN := more_clean
|
||||
include ../../../../EpoxyDuino.mk
|
||||
|
||||
more_clean:
|
||||
rm -f epoxyeepromdata
|
20
libraries/EpoxyEepromEsp/tests/Makefile
Normal file
20
libraries/EpoxyEepromEsp/tests/Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
tests:
|
||||
set -e; \
|
||||
for i in *Test/Makefile; do \
|
||||
echo '==== Making:' $$(dirname $$i); \
|
||||
$(MAKE) -C $$(dirname $$i) -j; \
|
||||
done
|
||||
|
||||
runtests:
|
||||
set -e; \
|
||||
for i in *Test/Makefile; do \
|
||||
echo '==== Running:' $$(dirname $$i); \
|
||||
$$(dirname $$i)/$$(dirname $$i).out; \
|
||||
done
|
||||
|
||||
clean:
|
||||
set -e; \
|
||||
for i in *Test/Makefile; do \
|
||||
echo '==== Cleaning:' $$(dirname $$i); \
|
||||
$(MAKE) -C $$(dirname $$i) clean; \
|
||||
done
|
Reference in New Issue
Block a user