Skip to content

Commit

Permalink
(Basic) support for Flow3r Badge (c3camp 2023) (#368)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonmicro authored Aug 23, 2024
2 parents 2891297 + fe97034 commit 1b3851c
Show file tree
Hide file tree
Showing 82 changed files with 1,353 additions and 339 deletions.
4 changes: 2 additions & 2 deletions .github/getWorkflowMatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get(info: GettableInfo):
returnArray.add(line.split('=')[1].strip())
break
elif info == GettableInfo.FLAGS:
with open('docs/firmware/osw_os.md') as f:
with open('docs/firmware/flags.md') as f:
for line in f:
# this parses a row with the format: "| `flag` | description | requirements |"
match = re.match(r'^\| `(.+)`\s+\| .+ \| (.+) \|$', line)
Expand Down Expand Up @@ -76,4 +76,4 @@ def get(info: GettableInfo):
ap.add_argument('info', type=GettableInfo)
args = ap.parse_args()

print(json.dumps(list(get(args.info))))
print(json.dumps(list(get(args.info))))
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
path = lib/LUA
url = https://github.com/lua/lua.git
branch = v5.3
[submodule "lib/BMI270-API"]
path = lib/BMI270-API
url = https://github.com/Open-Smartwatch/BMI270-Sensor-API.git
[submodule "emulator/lib/ArduinoJson"]
path = emulator/lib/ArduinoJson
url = https://github.com/bblanchon/ArduinoJson.git
Expand All @@ -42,3 +45,6 @@
[submodule "emulator/lib/ImGUI_TestEngine"]
path = emulator/lib/ImGUI_TestEngine
url = https://github.com/ocornut/imgui_test_engine.git
[submodule "lib/BMP581-API"]
path = lib/BMP581-API
url = https://github.com/boschsensortec/BMP5-Sensor-API.git
19 changes: 10 additions & 9 deletions docs/config.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# This file is similar to the mkdocs.nav configuration option, but it will be mounted under mkdocs.nav.Firmware only!

- 'OSW-OS':
- firmware/getting_started.md
- firmware/osw_os.md
- firmware/troubleshooting.md
- 'Applications':
- 'Watchfaces': 'firmware/apps/watchfaces.md'
- 'Tools': 'firmware/apps/tools.md'
- 'Games': 'firmware/apps/games.md'
- 'OSW Weather': 'firmware/apps/OswWeather.md'
- "OSW-OS":
- firmware/getting_started.md
- firmware/flags.md
- firmware/troubleshooting.md
- firmware/support.md
- "Applications":
- "Watchfaces": "firmware/apps/watchfaces.md"
- "Tools": "firmware/apps/tools.md"
- "Games": "firmware/apps/games.md"
- "OSW Weather": "firmware/apps/OswWeather.md"
23 changes: 12 additions & 11 deletions docs/firmware/osw_os.md → docs/firmware/flags.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# Feature Flags
The table below list all currently available features of the OSW-OS. These features can be manually enabled (or disabled) by modifying the `platformio.ini` and adding (or removing) their `-D`-Define lines.

| Flag | Description | Requirements |
| ------------------------- | ------------------------------------------------------------------- | ---------------------------------- |
| `OSW_FEATURE_STATS_STEPS` | Enable step history (displayed on the watchfaces) | - |
| `OSW_FEATURE_WIFI` | Enable all wifi related functions (services, webinterface) | - |
| `OSW_FEATURE_WIFI_APST` | Allow the watch to enable wifi client and station simultaneously | `OSW_FEATURE_WIFI` |
| `OSW_FEATURE_WIFI_ONBOOT` | Allow the user to enable the wifi on boot | `OSW_FEATURE_WIFI` |
| `OSW_FEATURE_LUA` | Enable LUA scripting support for apps | `LUA_C89_NUMBERS` |
| `DEBUG=1` | Enables debug logging to the console & additional utilities | - |
| `GPS_EDITION` | Configure the build for use with GPS (including apps, api, sensors) | `PROGMEM_TILES`, `BOARD_HAS_PSRAM` |
| `GPS_EDITION_ROTATED` | Replacement for `GPS_EDITION` to work with flipped boards | - |
| Flag | Description | Requirements |
| ---------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------- |
| `OSW_FEATURE_STATS_STEPS` | Enable step history (displayed on the watchfaces) | - |
| `OSW_FEATURE_WIFI` | Enable all wifi related functions (services, webinterface) | - |
| `OSW_FEATURE_WIFI_ONBOOT` | Allow the user to enable the wifi on boot | `OSW_FEATURE_WIFI` |
| `OSW_FEATURE_BLE_MEDIA_CTRL` | Enables media control via BLE | - |
| `OSW_FEATURE_LUA` | Enable LUA scripting support for apps | `LUA_C89_NUMBERS` |
| `SERVICE_BLE_COMPANION=1` | Enables the BLE Companion Service (unstable, requires custom smartphone application) | - |
| `DEBUG=1` | Enables debug logging to the console & additional utilities | - |
| `GPS_EDITION` | Configure the build for use with GPS (including apps, api, sensors) | `PROGMEM_TILES`, `BOARD_HAS_PSRAM` |
| `GPS_EDITION_ROTATED` | Replacement for `GPS_EDITION` to work with flipped boards | - |

## Example Flags

Expand Down Expand Up @@ -42,4 +43,4 @@ The table below lists which features are available in which version of the OS by
| `OSW_FEATURE_WIFI` ||||||
| `OSW_FEATURE_WIFI_APST` ||||||
| `OSW_FEATURE_WIFI_ONBOOT` ||||||
| `OSW_FEATURE_LUA` ||||||
| `OSW_FEATURE_LUA` ||||||
19 changes: 19 additions & 0 deletions docs/firmware/support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Hardware Support
Over time, the operating system gained additional hardware support for non open-smartwatch environments. This page lists the supported hardware and how to use it (as well as unwanted features, so called "bugs"). You can also find all these configurations inside the `platformio.ini` file.

## Official Hardware
...based on hardware schematics released by the OSW team and tested frequently.

| Hardware | Status | Reference |
| -------------------------------------- | ------------ | --------------------------------------------------------- |
| `LIGHT_EDITION_V3_3` | Maintained | See "Hardware"-Documentation section |
| `EXPERIMENTAL_LIGHT_EDITION_V4_0` | Experimental | See "Hardware"-Documentation section |
| `EXPERIMENTAL_LIGHT_EDITION_V3_3_LUA` | Experimental | Same as `LIGHT_EDITION_V3_3`, but with LUA-script-support |
| `EXPERIMENTAL_GPS_EDITION_V3_1` | Experimental | See "Hardware"-Documentation section |
| `EXPERIMENTAL_GPS_EDITION_DEV_ROTATED` | Experimental | See "Hardware"-Documentation section |

## 3rd Party Hardware

| Hardware | Status | Reference | Known Issues |
| ------------------------------ | ------------ | --------------------------------- | ----------------------------------------------------------------------- |
| `3RD_PARTY_FLOW3R_C3CAMP_2023` | Experimental | [website](https://flow3r.garden/) | [PR368](https://github.com/Open-Smartwatch/open-smartwatch-os/pull/368) |
3 changes: 2 additions & 1 deletion emulator/include/Serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ class Serial_t {
int read();

void println();
void flush();
private:
std::list<char> inputBuffer;
int bauds = 0;
bool buffered = false;
bool addBufferNewline = true;
};

extern Serial_t Serial;
extern Serial_t Serial;
29 changes: 26 additions & 3 deletions emulator/src/Emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,32 @@ void OswEmulator::renderGUIFrameEmulator() {
ImGui::InputFloat("Acceleration X", &OswHal::getInstance()->devices()->virtualDevice->values.accelerationX, 0.1f, 10);
ImGui::InputFloat("Acceleration Y", &OswHal::getInstance()->devices()->virtualDevice->values.accelerationY, 0.1f, 10);
ImGui::InputFloat("Acceleration Z", &OswHal::getInstance()->devices()->virtualDevice->values.accelerationZ, 0.1f, 10);
ImGui::InputInt("Magnetometer X", &OswHal::getInstance()->devices()->virtualDevice->values.magnetometerX, 0.1f, 10);
ImGui::InputInt("Magnetometer Y", &OswHal::getInstance()->devices()->virtualDevice->values.magnetometerY, 0.1f, 10);
ImGui::InputInt("Magnetometer Z", &OswHal::getInstance()->devices()->virtualDevice->values.magnetometerZ, 0.1f, 10);
ImGui::InputInt("Magnetometer Azimuth", &OswHal::getInstance()->devices()->virtualDevice->values.magnetometerAzimuth, 1, 10);
ImGui::InputInt("Steps", (int*) &OswHal::getInstance()->devices()->virtualDevice->values.steps, 1, 10); // Warning - negative values will cause an underflow... ImGui has no convenient way of limiting the input range...
// get string to display selected value
const char* str = "unknown";
OswAccelerationProvider::ActivityMode& activityMode = OswHal::getInstance()->devices()->virtualDevice->values.activityMode; // take reference, for easier access
if(activityMode == OswAccelerationProvider::ActivityMode::STILL)
str = "still";
else if(activityMode == OswAccelerationProvider::ActivityMode::WALK)
str = "walk";
else if(activityMode == OswAccelerationProvider::ActivityMode::RUN)
str = "run";
// display activity mode
if (ImGui::BeginCombo("Activity", str)) {
if(ImGui::Selectable("still", activityMode == OswAccelerationProvider::ActivityMode::STILL))
OswHal::getInstance()->devices()->virtualDevice->values.activityMode = OswAccelerationProvider::ActivityMode::STILL;
else if(ImGui::Selectable("walk", activityMode == OswAccelerationProvider::ActivityMode::WALK))
OswHal::getInstance()->devices()->virtualDevice->values.activityMode = OswAccelerationProvider::ActivityMode::WALK;
else if(ImGui::Selectable("run", activityMode == OswAccelerationProvider::ActivityMode::RUN))
OswHal::getInstance()->devices()->virtualDevice->values.activityMode = OswAccelerationProvider::ActivityMode::RUN;
else if(ImGui::Selectable("unknown", activityMode == OswAccelerationProvider::ActivityMode::UNKNOWN))
OswHal::getInstance()->devices()->virtualDevice->values.activityMode = OswAccelerationProvider::ActivityMode::UNKNOWN;
ImGui::EndCombo();
}
} else
ImGui::Text(LANG_IMGUI_VIRTUAL_SENSORS_NOPE);
ImGui::End();
Expand Down Expand Up @@ -491,8 +515,7 @@ void OswEmulator::renderGUIFrameEmulator() {
// Create the combo-box
if (ImGui::BeginCombo(key->label, std::get<std::string>(this->configValuesCache[keyId]).c_str())) {
for (size_t i = 0; i < options.size(); i++) {
bool isSelected = currentOption == i;
if (ImGui::Selectable(options[i].c_str(), &isSelected))
if (ImGui::Selectable(options[i].c_str(), currentOption == i))
this->configValuesCache[keyId] = options[i];
}
ImGui::EndCombo();
Expand Down Expand Up @@ -565,4 +588,4 @@ void OswEmulator::renderGUIFrameEmulator() {

OswEmulator::CPUState OswEmulator::getCpuState() {
return this->cpustate;
}
}
3 changes: 0 additions & 3 deletions emulator/src/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ uint8_t digitalRead(int pin) {
case OSW_DEVICE_TPS2115A_STATPWR:
return OswEmulator::instance->isCharging() ? 1 : 0;
break;
case TFT_LED:
return 255; // The emulator has always full brightness for now...
break;
default:
OSW_EMULATOR_THIS_IS_NOT_IMPLEMENTED;
return LOW;
Expand Down
9 changes: 8 additions & 1 deletion emulator/src/Serial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ void Serial_t::println() {
std::cout << std::endl;
}

void Serial_t::flush() {
if(this->bauds < 1)
return;
if(!this->buffered)
std::cout << std::flush;
}

int Serial_t::available() {
char c;
if(::read(STDIN_FILENO, &c, 1) > 0) {
Expand All @@ -53,4 +60,4 @@ int Serial_t::read() {
char c = this->inputBuffer.front();
this->inputBuffer.pop_front();
return c;
}
}
36 changes: 20 additions & 16 deletions include/OswLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <mutex>
#include <memory>
#include <Arduino.h>
#include <HardwareSerial.h> // For Serial.print(ln)
#include <OswSerial.h>
#include <stdarg.h>

#include <WString.h>
Expand Down Expand Up @@ -58,6 +58,7 @@ class OswLogger {
template<typename... T>
void log(const char* file, const unsigned int line, const severity_t severity, T&& ... message) {
std::lock_guard<std::mutex> guard(this->m_lock);
OswSerial* serial = OswSerial::getInstance();
this->prefix(file, line, severity);

do_in_order([&]() {
Expand All @@ -67,50 +68,53 @@ class OswLogger {
// Iterate over message to find '\n', which trigger new lines...
for(auto& c : message) {
if (c == '\n') {
Serial.println();
serial->println();
this->prefix(file, line, severity);
} else
Serial.print(c);
serial->putc(c);
}
} else if constexpr (std::is_same<T, const char*>::value or std::is_same<T, char*>::value) {
// Iterate over message to find '\n', which trigger new lines...
for(auto& c : std::string_view(message)) {
if (c == '\n') {
Serial.println();
serial->println();
this->prefix(file, line, severity);
} else
Serial.print(c);
serial->putc(c);
}
} else
Serial.print(message);
} else {
serial->print(message);
}
} ...);

Serial.println();
serial->println();
};

void prefix(const char* file, const unsigned int line, const severity_t severity) {
OswSerial* serial = OswSerial::getInstance();

switch(severity) {
case severity_t::D:
Serial.print("D: ");
serial->print("D: ");
break;
case severity_t::I:
Serial.print("I: ");
serial->print("I: ");
break;
case severity_t::W:
Serial.print("W: ");
serial->print("W: ");
break;
case severity_t::E:
Serial.print("E: ");
serial->print("E: ");
break;
default:
throw std::logic_error("Unknown severity level");
}

#ifndef NDEBUG
Serial.print(file);
Serial.print("@");
Serial.print(line);
Serial.print(": ");
serial->print(file);
serial->putc('@');
serial->print(line);
serial->print(": ");
#endif
};
};
Expand Down
92 changes: 92 additions & 0 deletions include/OswSerial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once

#include <cstdint>
#include <WString.h>
#include OSW_TARGET_PLATFORM_HEADER

#if OSW_PLATFORM_HARDWARE_ESP32_USE_JTAG_SERIAL == 1
#include <esp32s3/rom/uart.h> // change this if needed, as this is specifically ESP32s2
#include <esp_rom_caps.h>
#include <esp_rom_uart.h>
#else
#include <HardwareSerial.h>
#endif

/**
* @brief This class is not the fastest (only one byte at a time), but it is the most compatible
*
*/
class OswSerial {
public:
/**
* @brief Start / initialize serial communication (not all platforms may respect the baud rate)
*
* @param baud
*/
void begin(unsigned long baud);

/**
* @brief Put one byte to the serial port (potentially buffered)
*
* If you only want to print a single character, prefer this method over print()
*
* @param c
*/
void putc(uint8_t c);

/**
* @brief FLush out the outgoing buffer, if buffered
*
*/
void flush();

/**
* @brief Get one byte from the serial port
*
* @param c where to store the byte
* @return true if a byte was read
* @return false if no byte was read
*/
bool getc(uint8_t& c);

/**
* @brief Print a string to the serial port and flush it
*
* @tparam T
* @param t
*/
template<typename T>
void print(T t) {
#if OSW_PLATFORM_HARDWARE_ESP32_USE_JTAG_SERIAL == 1
for(auto& c : String(t)) {
this->putc(c);
}
this->flush();
#else
Serial.print(t);
#endif
}

/**
* @brief Print a string to the serial port and flush it
*
* @tparam T
* @param t
*/
template<typename T>
void println(T t) {
this->print(t);
this->println();
}

/**
* @brief Print a newline to the serial port and flush it
*
*/
void println();

static OswSerial* getInstance();
static void resetInstance();
private:
static OswSerial* instance;
};
Loading

0 comments on commit 1b3851c

Please sign in to comment.