Skip to content

Commit

Permalink
Massive refactor of code (#76)
Browse files Browse the repository at this point in the history
* Refactor and strengthen the abstractions between UI and furble.

Abstract all knowledge of the NimBLE library into the furble library.
Rename Furble::Device to Furble::Camera.
Abstract the device connection list into Furble::CameraList.
Delete redundant Canon connect() implementations.
Break the furble library dependency on M5ez, only UI includes it now.
Try to autoconfig M5Unified in M5ez.begin().

* Bump M5Unified to 0.1.13.

* Tweak M5Core font and UI.

On M5Core the screen flickers during lightSleep(), so just delay
instead.
This needs further investigation and a proper fix.

* Move ino to cpp.

Arduino does strange things, avoid by just using cpp extensions.

* Appease clang-format.

* Refactor GPS handling code.
  • Loading branch information
gkoh authored Mar 10, 2024
1 parent 0b24397 commit d80aee1
Show file tree
Hide file tree
Showing 25 changed files with 485 additions and 342 deletions.
14 changes: 14 additions & 0 deletions include/furble_gps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef FURBLE_GPS_H
#define FURBLE_GPS_H

#include <Camera.h>
#include <TinyGPS++.h>

extern TinyGPSPlus furble_gps;

extern bool furble_gps_enable;

void furble_gps_init(void);
void furble_gps_update_geodata(Furble::Camera *camera);

#endif
4 changes: 2 additions & 2 deletions include/furble_ui.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#ifndef FURBLE_UI_H
#define FURBLE_UI_H

#include <Furble.h>
#include <Camera.h>

struct FurbleCtx {
Furble::Device *device;
Furble::Camera *camera;
bool reconnected;
};

Expand Down
3 changes: 3 additions & 0 deletions include/settings.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SETTINGS_H
#define SETTINGS_H

#include <M5ez.h>
#include <esp_bt.h>

#include "interval.h"
Expand All @@ -9,6 +10,8 @@ extern interval_t interval;

void settings_menu_tx_power(void);
esp_power_level_t settings_load_esp_tx_power(void);

bool settings_load_gps(void);
void settings_menu_gps(void);

void settings_load_interval(interval_t *interval);
Expand Down
12 changes: 7 additions & 5 deletions lib/M5ez/src/M5ez.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,8 +901,11 @@ uint16_t ezBacklight::loop(void *private_data) {
if (M5.BtnA.wasClicked() || M5.BtnB.wasClicked())
break;
ez.yield();
// delay(100);
#if M5STACK_CORE2
delay(100);
#else
M5.Power.lightSleep(100000);
#endif
}
ez.buttons.releaseWait(); // Make sure the key pressed to wake display gets ignored
M5.Display.setBrightness(_brightness);
Expand Down Expand Up @@ -2225,7 +2228,8 @@ bool M5ez::_text_cursor_state;
long M5ez::_text_cursor_millis;

void M5ez::begin() {
M5.begin();
auto cfg = M5.config();
M5.begin(cfg);
M5.Lcd.setRotation(3);
ezTheme::begin();
ez.screen.begin();
Expand Down Expand Up @@ -2858,10 +2862,8 @@ void M5ez::setFont(const GFXfont *font) {
}

int16_t M5ez::fontHeight() {
#if M5STICKC_PLUS
#if M5STICKC_PLUS || M5STACK_CORE2
return M5.Lcd.fontHeight(M5.Lcd.getFont());
#elif M5STACK_CORE2
return 26;
#else
return 11;
#endif
Expand Down
4 changes: 2 additions & 2 deletions lib/M5ez/src/M5ez.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@
#ifdef M5STACK_CORE2
#define TFT_W 320
#define TFT_H 240
#define TFT_FONT sans16
#define TFT_FONT (&FreeMono12pt7b)
#define TFT_HEADER_HEIGHT 23
#define TFT_BUTTON_HEIGHT 19
#define TFT_BUTTON_HEIGHT 24
#define TFT_RADIUS 8
#endif

Expand Down
44 changes: 44 additions & 0 deletions lib/furble/Camera.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <NimBLEAdvertisedDevice.h>

#include "Camera.h"

namespace Furble {

const char *Camera::getName(void) {
return m_Name.c_str();
}

void Camera::fillSaveName(char *name) {
snprintf(name, 16, "%08llX", (uint64_t)m_Address);
}

void Camera::updateProgress(progressFunc pFunc, void *ctx, float value) {
if (pFunc != nullptr) {
(pFunc)(ctx, value);
}
}

/**
* Generate a 32-bit PRNG.
*/
static uint32_t xorshift(uint32_t x) {
/* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
x ^= x << 13;
x ^= x << 17;
x ^= x << 5;
return x;
}

void Camera::getUUID128(uuid128_t *uuid) {
uint32_t chip_id = (uint32_t)ESP.getEfuseMac();
for (size_t i = 0; i < UUID128_AS_32_LEN; i++) {
chip_id = xorshift(chip_id);
uuid->uint32[i] = chip_id;
}
}

bool Camera::isConnected(void) {
return m_Client->isConnected();
}

} // namespace Furble
42 changes: 23 additions & 19 deletions lib/furble/Device.h → lib/furble/Camera.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
#ifndef DEVICE_H
#define DEVICE_H
#ifndef CAMERA_H
#define CAMERA_H

#include <NimBLEAddress.h>
#include <NimBLEClient.h>
#include <NimBLEDevice.h>

#include "FurbleTypes.h"

#define MAX_NAME (64)

#define UUID128_LEN (16)
#define UUID128_AS_32_LEN (UUID128_LEN / sizeof(uint32_t))

// Progress update function
typedef void(progressFunc(void *, float));

namespace Furble {

/**
* Represents a single target camera.
*/
class Device {
class Camera {
public:
/**
* UUID type.
Expand Down Expand Up @@ -51,7 +61,7 @@ class Device {
*
* @return true if the client is now ready for shutter control
*/
virtual bool connect(NimBLEClient *pClient, ezProgressBar &progress_bar) = 0;
virtual bool connect(progressFunc pFunc = nullptr, void *pCtx = nullptr) = 0;

/**
* Disconnect from the target.
Expand Down Expand Up @@ -83,38 +93,32 @@ class Device {
*/
virtual void updateGeoData(gps_t &gps, timesync_t &timesync) = 0;

virtual device_type_t getDeviceType(void) = 0;
virtual size_t getSerialisedBytes(void) = 0;
virtual bool serialise(void *buffer, size_t bytes) = 0;

/**
* Checks if the client is still connected.
*/
bool isConnected(void);

const char *getName(void);
void save(void);
void remove(void);

static void loadDevices(std::vector<Furble::Device *> &device_list);

/**
* Add matching devices to the list.
*/
static void match(NimBLEAdvertisedDevice *pDevice, std::vector<Furble::Device *> &list);

/**
* Generate a device consistent 128-bit UUID.
*/
static void getUUID128(uuid128_t *uuid);

void fillSaveName(char *name);

protected:
NimBLEAddress m_Address = NimBLEAddress("");
NimBLEClient *m_Client;
NimBLEClient *m_Client = NimBLEDevice::createClient();
std::string m_Name;

private:
virtual device_type_t getDeviceType(void) = 0;
virtual size_t getSerialisedBytes(void) = 0;
virtual bool serialise(void *buffer, size_t bytes) = 0;
void updateProgress(progressFunc pFunc, void *ctx, float value);

void fillSaveName(char *name);
private:
};
} // namespace Furble

Expand Down
71 changes: 23 additions & 48 deletions lib/furble/Device.cpp → lib/furble/CameraList.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#include <NimBLEAdvertisedDevice.h>
#include <Preferences.h>

#include "Furble.h"
#include "CanonEOSM6.h"
#include "CanonEOSRP.h"
#include "Fujifilm.h"

#include "CameraList.h"

#define FURBLE_PREF_INDEX "index"

namespace Furble {

std::vector<Furble::Camera *> CameraList::m_ConnectList;
static Preferences m_Prefs;

/**
Expand Down Expand Up @@ -62,23 +67,19 @@ static void add_index(std::vector<index_entry_t> &index, index_entry_t &entry) {
}
}

const char *Device::getName(void) {
return m_Name.c_str();
}

void Device::save(void) {
void CameraList::save(Camera *pCamera) {
m_Prefs.begin(FURBLE_STR, false);
std::vector<index_entry_t> index = load_index();

index_entry_t entry = {0};
fillSaveName(entry.name);
entry.type = getDeviceType();
pCamera->fillSaveName(entry.name);
entry.type = pCamera->getDeviceType();

add_index(index, entry);

size_t dbytes = getSerialisedBytes();
size_t dbytes = pCamera->getSerialisedBytes();
uint8_t dbuffer[dbytes] = {0};
serialise(dbuffer, dbytes);
pCamera->serialise(dbuffer, dbytes);

// Store the entry and the index
m_Prefs.putBytes(entry.name, dbuffer, dbytes);
Expand All @@ -90,12 +91,12 @@ void Device::save(void) {
m_Prefs.end();
}

void Device::remove(void) {
void CameraList::remove(Camera *pCamera) {
m_Prefs.begin(FURBLE_STR, false);
std::vector<index_entry_t> index = load_index();

index_entry_t entry = {0};
fillSaveName(entry.name);
pCamera->fillSaveName(entry.name);

size_t i = 0;
for (i = 0; i < index.size(); i++) {
Expand All @@ -115,14 +116,15 @@ void Device::remove(void) {
}

/**
* Load the list of saved devices.
* Load the list of saved cameras.
*
* The Arduino-ESP32 NVS library does not expose an entry iterator even though
* the underlying library supports it. We work around this by managing a simple
* index with a known name and storing target devices in separate entries.
*/
void Device::loadDevices(std::vector<Furble::Device *> &device_list) {
void CameraList::load(void) {
m_Prefs.begin(FURBLE_STR, true);
m_ConnectList.clear();
std::vector<index_entry_t> index = load_index();
for (size_t i = 0; i < index.size(); i++) {
size_t dbytes = m_Prefs.getBytesLength(index[i].name);
Expand All @@ -134,54 +136,27 @@ void Device::loadDevices(std::vector<Furble::Device *> &device_list) {

switch (index[i].type) {
case FURBLE_FUJIFILM:
device_list.push_back(new Fujifilm(dbuffer, dbytes));
m_ConnectList.push_back(new Fujifilm(dbuffer, dbytes));
break;
case FURBLE_CANON_EOS_M6:
device_list.push_back(new CanonEOSM6(dbuffer, dbytes));
m_ConnectList.push_back(new CanonEOSM6(dbuffer, dbytes));
break;
case FURBLE_CANON_EOS_RP:
device_list.push_back(new CanonEOSRP(dbuffer, dbytes));
m_ConnectList.push_back(new CanonEOSRP(dbuffer, dbytes));
break;
}
}
m_Prefs.end();
}

void Device::fillSaveName(char *name) {
snprintf(name, 16, "%08llX", (uint64_t)m_Address);
}

void Device::match(NimBLEAdvertisedDevice *pDevice, std::vector<Furble::Device *> &list) {
void CameraList::match(NimBLEAdvertisedDevice *pDevice) {
if (Fujifilm::matches(pDevice)) {
list.push_back(new Furble::Fujifilm(pDevice));
m_ConnectList.push_back(new Furble::Fujifilm(pDevice));
} else if (CanonEOSM6::matches(pDevice)) {
list.push_back(new Furble::CanonEOSM6(pDevice));
m_ConnectList.push_back(new Furble::CanonEOSM6(pDevice));
} else if (CanonEOSRP::matches(pDevice)) {
list.push_back(new Furble::CanonEOSRP(pDevice));
}
}

/**
* Generate a 32-bit PRNG.
*/
static uint32_t xorshift(uint32_t x) {
/* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
x ^= x << 13;
x ^= x << 17;
x ^= x << 5;
return x;
}

void Device::getUUID128(uuid128_t *uuid) {
uint32_t chip_id = (uint32_t)ESP.getEfuseMac();
for (size_t i = 0; i < UUID128_AS_32_LEN; i++) {
chip_id = xorshift(chip_id);
uuid->uint32[i] = chip_id;
m_ConnectList.push_back(new Furble::CanonEOSRP(pDevice));
}
}

bool Device::isConnected(void) {
return m_Client->isConnected();
}

} // namespace Furble
Loading

0 comments on commit d80aee1

Please sign in to comment.