fram support for digital output

This commit is contained in:
Siwat Sirichai 2023-12-28 19:35:53 +07:00
parent 1e2eb1b0cf
commit c1d598ab20
5 changed files with 104 additions and 4 deletions

View File

@ -32,6 +32,10 @@ void DigitalOutputCard::digitalWrite(uint8_t pin, bool state) {
this->pwm.setPin(virtualPinMap[pin], state ? 4095 : 0);
this->state_buffer[pin] = state;
this->value_buffer[pin] = state ? 4095 : 0;
if (this->framAutoSave) {
this->saveStateToFRAM();
this->savePinValueToFRAM(pin);
}
if(change_callback != NULL) {
change_callback(pin, state, state ? 4095 : 0);
}
@ -42,6 +46,10 @@ void DigitalOutputCard::analogWrite(uint8_t pin, uint16_t value) {
if (value > 4095) value = 4095;
// Set the pwm value
this->pwm.setPin(virtualPinMap[pin], value);
if (this->framAutoSave) {
this->saveStateToFRAM();
this->savePinValueToFRAM(pin);
}
this->state_buffer[pin] = value > 0;
this->value_buffer[pin] = value;
if(change_callback != NULL) {
@ -71,6 +79,9 @@ uint8_t DigitalOutputCard::getType() {
void DigitalOutputCard::setState(uint8_t pin, bool state) {
this-> state_buffer[pin] = state;
this->pwm.setPin(pin, state*value_buffer[pin]);
if(this->framAutoSave) {
this->saveStateToFRAM();
}
if (change_callback != NULL) {
change_callback(pin, state, value_buffer[pin]);
}
@ -81,6 +92,9 @@ void DigitalOutputCard::setValue(uint8_t pin, uint16_t value) {
if (value > 4095) value = 4095;
this-> value_buffer[pin] = value;
this->pwm.setPin(pin, state_buffer[pin]*value);
if (this->framAutoSave) {
this->savePinValueToFRAM(pin);
}
if (change_callback != NULL) {
change_callback(pin, state_buffer[pin], value);
}
@ -99,4 +113,61 @@ void DigitalOutputCard::loadPinMap(uint8_t pinMap[16]) {
this->pinMap[i] = pinMap[i];
this->virtualPinMap[pinMap[i]] = i;
}
}
void DigitalOutputCard::bindFRAM(FRAM *fram, uint16_t address) {
this->fram = fram;
this->framBinded = true;
this->framAddress = address;
}
uint16_t DigitalOutputCard::packStates() {
uint16_t packed = 0;
for(int i = 0; i < 16; i++) {
packed |= (state_buffer[i] << i);
}
return packed;
}
void DigitalOutputCard::unpackStates(uint16_t states) {
for(int i = 0; i < 16; i++) {
this->setState(i, (states >> i) & 1);
}
}
void DigitalOutputCard::saveToFRAM() {
if(!framBinded) return;
// Save the state
uint16_t packed = packStates();
this->fram->write16(framAddress, packed);
// Save the value
this->fram->write(framAddress+2, (uint8_t*)value_buffer, 32);
}
void DigitalOutputCard::loadFromFRAM() {
if(!framBinded) return;
// Load the state
uint16_t packed = this->fram->read16(framAddress);
unpackStates(packed);
// Load the value
uint16_t value[16];
this->fram->read(framAddress+2, (uint8_t*)value, 32);
for(int i = 0; i < 16; i++) {
this->setValue(i, value[i]);
}
}
void DigitalOutputCard::setAutoSaveToFRAM(bool autoSave) {
this->framAutoSave = autoSave;
}
void DigitalOutputCard::savePinValueToFRAM(uint8_t pin) {
if(!framBinded) return;
this->fram->write(framAddress+2+pin*2, (uint8_t*)&value_buffer[pin], 2);
}
void DigitalOutputCard::saveStateToFRAM() {
if(!framBinded) return;
uint16_t packed = packStates();
this->fram->write16(framAddress, packed);
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <ExpansionCard.hpp>
#include <Adafruit_PWMServoDriver.h>
#include <FRAM.h>
// Protocol for digital output card
// Note that pin is always 2 characters long and padded with 0 if necessary
@ -50,10 +51,35 @@ public:
// Deregister the callback function
void deregisterChangeCallback();
// Load a new pin map
void loadPinMap(uint8_t pinMap[16]);
void loadPinMap(uint8_t pinMap[16]);
// Bind the fram object to the card
// The Output card use the fram in this layout:
// [2 bytes] 0-1 : state
// [32 bytes] 2-33 : value
void bindFRAM(FRAM *fram, uint16_t address);
// Save the state and value to the fram
void saveToFRAM();
// Load the state and value from the fram
void loadFromFRAM();
// Set the auto save to fram flag
void setAutoSaveToFRAM(bool autoSave);
// Save a single pin value to fram
void savePinValueToFRAM(uint8_t pin);
// Save state to fram
void saveStateToFRAM();
// Save value to fram
void saveValueToFRAM();
// Get type of card
uint8_t getType();
private:
// FRAM address
uint16_t framAddress;
// FRAM is binded
bool framBinded = false;
// Auto save to fram
bool framAutoSave = false;
// The fram object pointer
FRAM *fram;
// The pwm driver
Adafruit_PWMServoDriver pwm;
// The address of the card
@ -66,6 +92,10 @@ private:
std::function<void(uint8_t, bool, uint16_t)> change_callback;
// Physical pin to virtual pin map
uint8_t pinMap[16];
// Return 16 bit value representing all 16 channels
uint16_t packStates();
// Unpack the 16 bit value to the state buffer
void unpackStates(uint16_t states);
// Virtual pin to physical pin map
uint8_t virtualPinMap[16];
};

View File

@ -1 +0,0 @@
#include <ESPMegaTouch.hpp>

View File

@ -1 +0,0 @@
#include <EasyNextion.h>

View File

@ -24,5 +24,6 @@ lib_deps = adafruit/Adafruit PWM Servo Driver Library@^2.4.1
paulstoffregen/Time@^1.6.1
paulstoffregen/DS1307RTC@0.0.0-alpha+sha.c2590c0033
knolleary/pubsubclient@^2.8.0
seithan/Easy Nextion Library@^1.0.6
monitor_speed = 115200