Associate driver with address, writeback to file
This commit is contained in:
parent
b7784dfe49
commit
f13a706d93
6 changed files with 189 additions and 88 deletions
19
src/Wippersnapper_demo.ino.cpp
Normal file
19
src/Wippersnapper_demo.ino.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# 1 "/var/folders/ff/dmzflvf52tq9kzvt6g8jglxw0000gn/T/tmpjqartfsv"
|
||||
#include <Arduino.h>
|
||||
# 1 "/Users/brentrubell/Documents/Arduino/libraries/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino"
|
||||
# 11 "/Users/brentrubell/Documents/Arduino/libraries/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino"
|
||||
#include "ws_adapters.h"
|
||||
|
||||
|
||||
ws_adapter_offline wipper;
|
||||
#define WS_DEBUG
|
||||
void setup();
|
||||
void loop();
|
||||
#line 17 "/Users/brentrubell/Documents/Arduino/libraries/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino"
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
wipper.provision();
|
||||
wipper.connect();
|
||||
}
|
||||
|
||||
void loop() { wipper.run(); }
|
||||
|
|
@ -626,53 +626,36 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
|
|||
|
||||
drvBase *drv = nullptr;
|
||||
if (strcmp(device_name, SCAN_DEVICE) == 0) {
|
||||
WS_DEBUG_PRINTLN("Attempting to autoconfig device found in scan...");
|
||||
// Get all possible driver candidates for this address
|
||||
WS_DEBUG_PRINT("Getting drivers for address: ");
|
||||
WS_DEBUG_PRINTLN(device_descriptor.i2c_device_address);
|
||||
std::vector<const char *> candidate_drivers =
|
||||
getDriversForAddress(device_descriptor.i2c_device_address);
|
||||
|
||||
// Print out all the candidates
|
||||
// Probe each candidate to see if it communicates
|
||||
for (const char *driverName : candidate_drivers) {
|
||||
WS_DEBUG_PRINT("[i2c] Found a candidate driver: ");
|
||||
WS_DEBUG_PRINT("[i2c] Attempting to initialize driver: ");
|
||||
WS_DEBUG_PRINTLN(driverName);
|
||||
}
|
||||
|
||||
// Check/probe each candidate to see if it communicates
|
||||
for (const char *driverName : candidate_drivers) {
|
||||
drv = CreateI2CDriverByName(
|
||||
driverName, bus, device_descriptor.i2c_device_address,
|
||||
device_descriptor.i2c_mux_channel, device_status);
|
||||
// Probe the driver to check if it communicates its init. sequence
|
||||
// properly
|
||||
if (!drv->begin()) {
|
||||
delete drv;
|
||||
drv = nullptr;
|
||||
} else {
|
||||
WS_DEBUG_PRINT("[i2c] Device initialized: ");
|
||||
WS_DEBUG_PRINT("[i2c] Driver successfully initialized: ");
|
||||
WS_DEBUG_PRINTLN(driverName);
|
||||
// TOdO: NOTE THAT WE MAY DOUBLE_INIT BELOW!!! AND CRASH
|
||||
drv->SetSensorTypes(true);
|
||||
drv->SetPeriod(0);
|
||||
// TODO: Add driver information to FS
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WS_DEBUG_PRINTLN("Device was defined in config file, initializing...");
|
||||
// TODO: Add more debug window here
|
||||
drv = CreateI2CDriverByName(
|
||||
device_name, bus, device_descriptor.i2c_device_address,
|
||||
device_descriptor.i2c_mux_channel, device_status);
|
||||
if (drv == nullptr) {
|
||||
WS_DEBUG_PRINTLN(
|
||||
"[i2c] ERROR: I2C driver type not found or unsupported!");
|
||||
if (WsV2._sdCardV2->isModeOffline()) {
|
||||
WsV2.haltErrorV2("[i2c] Driver failed to initialize!\n\tDid you set "
|
||||
"the correct value for i2cDeviceName?\n\tDid you set "
|
||||
"the correct value for"
|
||||
"i2cDeviceAddress?",
|
||||
WS_LED_STATUS_ERROR_RUNTIME, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to initialize the driver
|
||||
if (did_set_mux_ch) {
|
||||
drv->SetMuxAddress(device_descriptor.i2c_mux_address);
|
||||
WS_DEBUG_PRINTLN("[i2c] Set driver to use MUX");
|
||||
|
|
@ -685,10 +668,12 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
|
|||
WS_DEBUG_PRINTLN("[i2c] Set driver to use Alt I2C bus");
|
||||
}
|
||||
// Configure the driver
|
||||
drv->EnableSensorReads(
|
||||
drv->SetSensorTypes(
|
||||
false,
|
||||
_i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_sensor_types,
|
||||
_i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_sensor_types_count);
|
||||
drv->SetSensorPeriod(
|
||||
_i2c_model->GetI2cDeviceAddOrReplaceMsg()
|
||||
->i2c_device_sensor_types_count);
|
||||
drv->SetPeriod(
|
||||
_i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_period);
|
||||
if (!drv->begin()) {
|
||||
if (WsV2._sdCardV2->isModeOffline()) {
|
||||
|
|
@ -699,7 +684,7 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
|
|||
WS_LED_STATUS_ERROR_RUNTIME, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
_i2c_drivers.push_back(drv);
|
||||
WS_DEBUG_PRINTLN("[i2c] Driver initialized and added to controller: ");
|
||||
WS_DEBUG_PRINTLN(device_name);
|
||||
|
|
|
|||
|
|
@ -112,6 +112,12 @@ protected:
|
|||
NULL; ///< Holds data for the AHTX0's temperature sensor
|
||||
Adafruit_Sensor *_aht_humidity =
|
||||
NULL; ///< Holds data for the AHTX0's humidity sensor
|
||||
wippersnapper_sensor_SensorType _default_sensor_types[3] = {
|
||||
wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE,
|
||||
wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT,
|
||||
wippersnapper_sensor_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY}; ///< Default
|
||||
///< sensor
|
||||
///< types
|
||||
};
|
||||
|
||||
#endif // drvAhtx0
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#include <protos/i2c.pb.h>
|
||||
|
||||
#define NO_MUX_CH 0xFFFF; ///< No MUX channel specified
|
||||
#define DEFAULT_SENSOR_PERIOD 30.0 ///< Default sensor period, in seconds
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
|
@ -161,8 +162,15 @@ public:
|
|||
The number of active sensors to read from the device.
|
||||
*/
|
||||
/*******************************************************************************/
|
||||
void EnableSensorReads(wippersnapper_sensor_SensorType *sensor_types,
|
||||
size_t sensor_types_count) {
|
||||
void SetSensorTypes(bool use_default_types = false,
|
||||
wippersnapper_sensor_SensorType *sensor_types = nullptr,
|
||||
size_t sensor_types_count = 0) {
|
||||
if (use_default_types) {
|
||||
sensor_types = _default_sensor_types;
|
||||
// set sensor_types_count to # of elements within _default_sensor_types
|
||||
sensor_types_count =
|
||||
sizeof(_default_sensor_types) / sizeof(_default_sensor_types[0]);
|
||||
}
|
||||
_sensors_count = sensor_types_count;
|
||||
for (size_t i = 0; i < _sensors_count; i++) {
|
||||
_sensors[i] = sensor_types[i];
|
||||
|
|
@ -193,11 +201,10 @@ public:
|
|||
seconds.
|
||||
*/
|
||||
/*******************************************************************************/
|
||||
void SetSensorPeriod(float period) {
|
||||
if (period < 0) {
|
||||
_sensor_period = 0;
|
||||
return;
|
||||
}
|
||||
void SetPeriod(float period = DEFAULT_SENSOR_PERIOD) {
|
||||
if (period < 0)
|
||||
_sensor_period = DEFAULT_SENSOR_PERIOD;
|
||||
|
||||
_sensor_period = (unsigned long)(period * 1000.0f);
|
||||
}
|
||||
|
||||
|
|
@ -219,6 +226,14 @@ public:
|
|||
/*******************************************************************************/
|
||||
ulong GetSensorPeriod() { return _sensor_period; }
|
||||
|
||||
/*******************************************************************************/
|
||||
/*!
|
||||
@brief Gets the sensor's types
|
||||
@returns A pointer to an array of SensorTypes.
|
||||
*/
|
||||
/*******************************************************************************/
|
||||
wippersnapper_sensor_SensorType *GetSensorTypes() { return _sensors; }
|
||||
|
||||
/*******************************************************************************/
|
||||
/*!
|
||||
@brief Gets the sensor's previous period.
|
||||
|
|
@ -591,26 +606,6 @@ public:
|
|||
return it->second(sensors_event);
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/*!
|
||||
@brief Checks if an address found during an i2c scan belongs to the
|
||||
sensor.
|
||||
@param scan_address
|
||||
The desired address to check, from an i2c scan
|
||||
@returns True if the address belongs to the sensor, False otherwise
|
||||
*/
|
||||
/*******************************************************************************/
|
||||
bool IsPotentialAddress(uint16_t scan_address) {
|
||||
for (uint8_t i = 0;
|
||||
i < sizeof(_potential_addresses) / sizeof(_potential_addresses[0]);
|
||||
i++) {
|
||||
if (scan_address == _potential_addresses[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // nothing found
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/*!
|
||||
@brief Function type for sensor event handlers
|
||||
|
|
@ -735,8 +730,6 @@ protected:
|
|||
TwoWire *_i2c; ///< Pointer to the I2C bus
|
||||
bool _has_alt_i2c_bus; ///< True if the device is on an alternate I2C bus
|
||||
uint16_t _address; ///< The device's I2C address.
|
||||
uint16_t _potential_addresses[2]; ///< Potential I2C addresses for the device,
|
||||
///< stored on the device driver
|
||||
uint32_t _i2c_mux_addr; ///< The I2C MUX address, if applicable.
|
||||
uint32_t _i2c_mux_channel; ///< The I2C MUX channel, if applicable.
|
||||
char _name[15]; ///< The device's name.
|
||||
|
|
@ -745,5 +738,7 @@ protected:
|
|||
ulong _sensor_period; ///< The sensor's period, in milliseconds.
|
||||
ulong _sensor_period_prv; ///< The sensor's previous period, in milliseconds.
|
||||
size_t _sensors_count; ///< Number of sensors on the device.
|
||||
wippersnapper_sensor_SensorType
|
||||
_default_sensor_types[1]; ///< Default sensor types
|
||||
};
|
||||
#endif // DRV_BASE_H
|
||||
|
|
@ -473,8 +473,104 @@ bool Wippersnapper_FS::AddSDCSPinToFileConfig(uint8_t pin) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Wippersnapper_FS::AddI2CDeviceToConfig(uint32_t address) { return true; }
|
||||
// TODO: Add an inclusion for "i2cDeviceSensorTypes"
|
||||
/********************************************************************************/
|
||||
/*!
|
||||
@brief Adds an I2C device to the `config.json` file.
|
||||
@param address
|
||||
The I2C device's address.
|
||||
@param period
|
||||
The period at which the device should be polled.
|
||||
@param driver_name
|
||||
The name of the driver.
|
||||
@returns True if the device was successfully added, False otherwise.
|
||||
*/
|
||||
/********************************************************************************/
|
||||
bool Wippersnapper_FS::AddI2cDeviceToFileConfig(uint32_t address, float period,
|
||||
char *driver_name) {
|
||||
if (!wipperFatFs_v2.exists("/config.json")) {
|
||||
HaltFilesystem("ERROR: Could not find expected config.json file on the "
|
||||
"WIPPER volume!");
|
||||
return false;
|
||||
}
|
||||
|
||||
File32 file_cfg = wipperFatFs_v2.open("/config.json", FILE_READ);
|
||||
if (!file_cfg) {
|
||||
WS_DEBUG_PRINTLN("ERROR: Could not open the config.json file for reading!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the JSON document
|
||||
JsonDocument doc;
|
||||
DeserializationError error = deserializeJson(doc, file_cfg);
|
||||
file_cfg.close();
|
||||
if (error) {
|
||||
WS_DEBUG_PRINT("JSON parse error: ");
|
||||
WS_DEBUG_PRINTLN(error.c_str());
|
||||
WS_DEBUG_PRINTLN(
|
||||
"ERROR: Unable to parse config.json file - deserializeJson() failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonObject new_component = doc["components"].add<JsonObject>();
|
||||
new_component["name"] = driver_name;
|
||||
new_component["componentAPI"] = "i2c";
|
||||
new_component["i2cdevicei2cDeviceName"] = driver_name;
|
||||
new_component["period"] = period;
|
||||
// convert address to string
|
||||
char address_str[10];
|
||||
sprintf(address_str, "0x%02X", address);
|
||||
new_component["i2cDeviceAddress"] = address_str;
|
||||
|
||||
// Handle the sensor types
|
||||
// TODO: This is un-implemented because I'm unsure how to go from type->string
|
||||
// representation without adding significant overhead...
|
||||
/*
|
||||
JsonArray new_component_types =
|
||||
new_component["i2cDeviceSensorTypes"].to<JsonArray>();
|
||||
new_component_types[0]["type"] = "relative-humidity";
|
||||
new_component_types[1]["type"] = "ambient-temp";
|
||||
new_component_types[2]["type"] = "ambient-temp-fahrenheit";
|
||||
new_component_types[3]["type"] = "pressure";
|
||||
new_component_types[4]["type"] = "altitude";
|
||||
*/
|
||||
|
||||
doc.shrinkToFit();
|
||||
|
||||
// Remove the existing config.json file
|
||||
wipperFatFs_v2.remove("/config.json");
|
||||
flash_v2.syncBlocks();
|
||||
wipperFatFs_v2.cacheClear();
|
||||
|
||||
// Write the updated doc back to new config.json file
|
||||
file_cfg = wipperFatFs_v2.open("/config.json", FILE_WRITE);
|
||||
if (!file_cfg) {
|
||||
HaltFilesystem("ERROR: Could not open the config.json file for writing!");
|
||||
return false;
|
||||
}
|
||||
serializeJsonPretty(doc, file_cfg);
|
||||
|
||||
// Flush and sync file
|
||||
// TODO: Not sure if this is actually doing anything on RP2040, need to test
|
||||
// in isolation
|
||||
file_cfg.flush();
|
||||
flash_v2.syncBlocks();
|
||||
file_cfg.close();
|
||||
|
||||
// Force cache clear and sync
|
||||
// TODO: Not sure if this is actually doing anything on RP2040, need to test
|
||||
// in isolation
|
||||
flash_v2.syncBlocks();
|
||||
wipperFatFs_v2.cacheClear();
|
||||
refreshMassStorage();
|
||||
|
||||
TinyUSBDevice.detach();
|
||||
delay(150);
|
||||
TinyUSBDevice.attach();
|
||||
delay(1500);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Checks if secrets.json file exists on the flash filesystem.
|
||||
|
|
|
|||
|
|
@ -64,9 +64,9 @@ public:
|
|||
#endif
|
||||
// config.json
|
||||
void CreateFileConfig();
|
||||
bool AddSDCSPinToFileConfig(uint8_t pin);
|
||||
void GetPinSDCS();
|
||||
bool AddI2CDeviceToConfig(uint32_t address);
|
||||
bool AddSDCSPinToFileConfig(uint8_t pin);
|
||||
bool AddI2cDeviceToFileConfig(uint32_t address, float period, char *driver_name);
|
||||
|
||||
private:
|
||||
bool _is_secrets_file_empty = false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue