Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

-
- Added support for two named AceSPI instances, `AceSpi_0` and `AceSpi_1`, with matching SPI provider names `_SPI_0` and `_SPI_1`.

### Changed

Expand Down
6 changes: 4 additions & 2 deletions src/SystemGUI/src/components/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class GaTasModules extends El {
// Modules we want to hide because they where never tested, or don't provide any usefull information now
this.hide = [
"Idle",
"AceSpi",
"AceSpi_0",
"AceSpi_1",
"SerialADSB"
];

Expand Down Expand Up @@ -97,7 +98,8 @@ class GaTasModules extends El {
SerialADSB: (html) => html`Receives ADS-B messages from hardware like the GNS5892. Requires an ADSB Decoder to process messages.`,
Dump1090Client: (html) => html`Receives ADS-B messages from Dump1090. Requires an ADSB Decoder to process messages.`,
Bmp280: (html) => html`Reads atmospheric pressure using the Bmp280 hardware.`,
AceSpi: (html) => html`Core module for controlling SPI access between different modules.`,
AceSpi_0: (html) => html`Core module for controlling SPI access between different modules.`,
AceSpi_1: (html) => html`Core module for controlling SPI access between different modules.`,
Config: (html) => html`Core module for receiving and storing configurations.`,
GpsDecoder: (html) => html`Core module for decoding GPS NMEA messages.`,
UbloxM8N: (html) => html`Configures uBlox GPS devices`,
Expand Down
35 changes: 24 additions & 11 deletions src/lib/acespi/ace/acespi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
#include "ace/messages.hpp"
#include "ace/semaphoreguard.hpp"

#ifndef GATAS_SPI_DEFAULT_BUS_FREQUENCY
#define GATAS_SPI_DEFAULT_BUS_FREQUENCY (15)
#endif

/**
* Class that is responsible for managing the Single SPI bus between various devices
* TODO: Add support for two SPI buses
* Class that is responsible for managing an SPI bus between various devices.
*/
class AceSpi : public SpiModule, public etl::message_router<AceSpi>
{
Expand All @@ -40,17 +43,26 @@ class AceSpi : public SpiModule, public etl::message_router<AceSpi>
SemaphoreHandle_t mutex;
public:
static constexpr const etl::string_view NAME = "AceSpi";
AceSpi(etl::imessage_bus &bus, const GATAS::PinTypeMap &pins) : SpiModule(bus),
clk(pins.at(GATAS::PinType::CLK)),
mosi(pins.at(GATAS::PinType::MOSI)),
miso(pins.at(GATAS::PinType::MISO)),
rst(pins.at(GATAS::PinType::RST)),
spi(pins.at(GATAS::PinType::SPI)),
lastBusFrequency(GATAS_SPI_DEFAULT_BUS_FREQUENCY)
static constexpr uint8_t MAX_SPI_MODULES = SpiModule::MAX_SPI_MODULES;
static constexpr etl::array<etl::string_view, MAX_SPI_MODULES> NAMES{"AceSpi_0", "AceSpi_1"};

// Only fallback to AceSpi for AceSpi_0
static const GATAS::PinTypeMap pinMap(const Configuration &config, uint8_t device)
{
return config.pinMap(NAMES[device], device == 0 ? NAME : etl::string_view());
}

AceSpi(etl::imessage_bus &bus, const GATAS::PinTypeMap &pins, uint8_t device) : SpiModule(bus, SpiModule::NAMES[device]),
clk(pins.at(GATAS::PinType::CLK)),
mosi(pins.at(GATAS::PinType::MOSI)),
miso(pins.at(GATAS::PinType::MISO)),
rst(pins.at(GATAS::PinType::RST)),
spi(pins.at(GATAS::PinType::SPI)),
lastBusFrequency(GATAS_SPI_DEFAULT_BUS_FREQUENCY)
{
}

AceSpi(etl::imessage_bus &bus, const Configuration &config) : AceSpi(bus, config.pinMap(NAME))
AceSpi(etl::imessage_bus &bus, const Configuration &config, uint8_t device) : AceSpi(bus, pinMap(config, device), device)
{
}

Expand All @@ -76,7 +88,8 @@ class AceSpi : public SpiModule, public etl::message_router<AceSpi>

virtual SpiGuard getLock(bool &locked) override;

virtual uint8_t spiNum() const {
virtual uint8_t spiNum() const override
{
return spi;
}

Expand Down
15 changes: 11 additions & 4 deletions src/lib/bmp280/ace/bmp280.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "ace/constants.hpp"
#include "ace/basemodule.hpp"
#include "ace/coreutils.hpp"
#include "ace/messages.hpp"

/**
Expand All @@ -24,6 +25,7 @@ class Bmp280 : public BaseModule, public etl::message_router<Bmp280, GATAS::Conf
static constexpr uint8_t READ_BIT = 0x80;

const uint8_t cs;
const uint8_t device;
int16_t compensation;

int32_t t_fine = 0;
Expand All @@ -32,7 +34,7 @@ class Bmp280 : public BaseModule, public etl::message_router<Bmp280, GATAS::Conf
uint16_t dig_P1 = 0;
int16_t dig_P2 = 0, dig_P3 = 0, dig_P4 = 0, dig_P5 = 0, dig_P6 = 0, dig_P7 = 0, dig_P8 = 0, dig_P9 = 0;
SpiModule *aceSpi = nullptr;

private:
/* The following compensation functions are required to convert from the raw ADC
data from the chip to something usable. Each chip has a different set of
Expand All @@ -52,10 +54,15 @@ class Bmp280 : public BaseModule, public etl::message_router<Bmp280, GATAS::Conf

public:
static constexpr const etl::string_view NAME = "Bmp280";
Bmp280(etl::imessage_bus &bus, const Configuration &config) : BaseModule(bus, NAME),
cs(config.pinMap(NAME).at(GATAS::PinType::CS))
Bmp280(etl::imessage_bus &bus, const GATAS::PinTypeMap &pins, int16_t compensation_) : BaseModule(bus, NAME),
cs(pins.at(GATAS::PinType::CS)),
device(CoreUtils::getPin(pins, GATAS::PinType::DEV, 0)),
compensation(compensation_)
{
}

Bmp280(etl::imessage_bus &bus, const Configuration &config) : Bmp280(bus, config.pinMap(NAME), config.valueByPath(0, NAME, "compensation"))
{
compensation = config.valueByPath(0, NAME, "compensation");
}

virtual ~Bmp280() = default;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/bmp280/ace/src/bmp280.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void Bmp280::read_compensation_parameters()

GATAS::PostConstruct Bmp280::postConstruct()
{
aceSpi = static_cast<SpiModule *>(BaseModule::moduleByName(*this, SpiModule::NAME));
aceSpi = static_cast<SpiModule *>(BaseModule::moduleByName(*this, SpiModule::NAMES[device]));
if (aceSpi == nullptr)
{
return GATAS::PostConstruct::DEP_NOT_FOUND;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/config/ace/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class Config : public Configuration, public etl::message_router<Config>
/**
* Retreives the pin mapping for a given module, usually used for hardware configurations
*/
virtual const GATAS::PinTypeMap pinMap(const etl::string_view moduleName) const override;
virtual const GATAS::PinTypeMap pinMap(const etl::string_view moduleName, const etl::string_view fallback = etl::string_view()) const override;

virtual int valueByPath(int defaultValue, const etl::string_view pathToValue, const etl::string_view key) const override;

Expand Down
18 changes: 16 additions & 2 deletions src/lib/config/ace/src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,19 @@ void Config::on_receive_unknown(const etl::imessage &msg)
(void)msg;
}

const GATAS::PinTypeMap Config::pinMap(const etl::string_view moduleName) const
const GATAS::PinTypeMap Config::pinMap(const etl::string_view moduleName, const etl::string_view fallback) const
{
GATAS::PinTypeMap map;
ccharptr hardware = (ccharptr)doc["hardware"]["type"];
if (JsonObjectConst moduleConfig = doc[hardware][moduleName]; !moduleConfig.isNull())

auto loadPinMap = [&](const etl::string_view name) -> bool
{
JsonObjectConst moduleConfig = doc[hardware][name];
if (moduleConfig.isNull())
{
return false;
}

for (JsonPairConst kv : moduleConfig)
{
auto pinType = GATAS::stringToPinType(kv.key().c_str());
Expand All @@ -306,7 +313,14 @@ const GATAS::PinTypeMap Config::pinMap(const etl::string_view moduleName) const
map[pinType] = kv.value().as<uint8_t>();
}
}
return true;
};

if (!loadPinMap(moduleName) && !fallback.empty())
{
loadPinMap(fallback);
}

return map;
}

Expand Down
6 changes: 3 additions & 3 deletions src/lib/config/config_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ set(ALL_EXAMPLE_TARGETS
)

foreach( name ${ALL_EXAMPLE_TARGETS} )
target_link_libraries(
${name}
Catch2WithMain
target_link_libraries(
${name}
Catch2WithMain
etl
ArduinoJson
)
Expand Down
22 changes: 22 additions & 0 deletions src/lib/config/config_tests/config_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ TEST_CASE("Fully Configured", "[single-file]")
REQUIRE(map[GATAS::PinType::SPI] == 0);
}

SECTION("fallback")
{
GATAS::PinTypeMap map = config.pinMap("AceSpi_1", "AceSpi");
REQUIRE(map.size() == 5);
REQUIRE(map[GATAS::PinType::CLK] == 2);
REQUIRE(map[GATAS::PinType::MOSI] == 3);
REQUIRE(map[GATAS::PinType::MISO] == 4);
REQUIRE(map[GATAS::PinType::RST] == 5);
REQUIRE(map[GATAS::PinType::SPI] == 0);
}

SECTION("No fallback")
{
GATAS::PinTypeMap map = config.pinMap("AceSpi_0", "AceSpi");
REQUIRE(map.size() == 5);
REQUIRE(map[GATAS::PinType::CLK] == 12);
REQUIRE(map[GATAS::PinType::MOSI] == 13);
REQUIRE(map[GATAS::PinType::MISO] == 14);
REQUIRE(map[GATAS::PinType::RST] == 15);
REQUIRE(map[GATAS::PinType::SPI] == 10);
}

SECTION("NoPort andInvalidPort")
{
GATAS::PinTypeMap map = config.pinMap("NoPort");
Expand Down
7 changes: 7 additions & 0 deletions src/lib/config/config_tests/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@
"rst": 5,
"spi": 0
},
"AceSpi_0": {
"clk": 12,
"mosi": 13,
"miso": 14,
"rst": 15,
"spi": 10
},
"UbloxM8N": {
"tx": 0,
"rx": 1,
Expand Down
7 changes: 4 additions & 3 deletions src/lib/core/ace/basemodule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,10 @@ class SpiModule : public BaseModule
{
public:
static constexpr uint32_t SPI_BUS_READY = 1 << 30;
static constexpr const etl::string_view NAME = "_SPI";
static constexpr uint8_t MAX_SPI_MODULES = 2;
static constexpr etl::array<etl::string_view, MAX_SPI_MODULES> NAMES{"_SPI_0", "_SPI_1"};

SpiModule(etl::imessage_bus &bus) : BaseModule(bus, NAME)
SpiModule(etl::imessage_bus &bus, const etl::string_view name) : BaseModule(bus, name)
{
}
virtual ~SpiModule() = default;
Expand Down Expand Up @@ -276,7 +277,7 @@ class Configuration : public BaseModule
virtual ~Configuration() = default;

virtual const GATAS::Config::GaTasConfiguration gaTasConfig() const = 0;
virtual const GATAS::PinTypeMap pinMap(const etl::string_view moduleName) const = 0;
virtual const GATAS::PinTypeMap pinMap(const etl::string_view moduleName, const etl::string_view fallback = etl::string_view()) const = 0;

virtual bool deleteData(const etl::string_view fullPath) = 0;
virtual int valueByPath(int defaultValue, const etl::string_view pathToValue, const etl::string_view key) const = 0;
Expand Down
19 changes: 18 additions & 1 deletion src/lib/core/ace/coreutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ namespace CoreUtils
{
float theta = atan2f(east, north);
float deg = theta * 180.f / M_PI;
if (deg < 0.f) {
if (deg < 0.f)
{
deg += 360.f;
}
return deg;
Expand Down Expand Up @@ -656,4 +657,20 @@ namespace CoreUtils
return speedMs > GATAS::GROUNDSPEED_CONSIDERING_AIRBORN; // 10 m/s threshold for others
}
}

/**
* Find a pin number and if not found, return the default
* @param pinMap
* @param pin
* @param defaultNum
*/
inline uint8_t getPin(const GATAS::PinTypeMap &pinMap, GATAS::PinType pin, uint8_t defaultNum)
{
auto it = pinMap.find(pin);
if (it != pinMap.end())
{
return static_cast<uint8_t>(it->second);
}
return defaultNum;
}
}
3 changes: 2 additions & 1 deletion src/lib/core/ace/models.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ namespace GATAS
P0,
P1,
P2,
AD0
AD0,
DEV
};

// PinType alias to uint8_t
Expand Down
2 changes: 1 addition & 1 deletion src/lib/core/ace/src/basemodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ BaseModule *BaseModule::moduleByName(const BaseModule &that, const etl::string_v
// Look for it's provider name eg: _SPI
for (auto it = BaseModule::moduleLoaderMap.cbegin(); it != BaseModule::moduleLoaderMap.cend(); it++)
{
if (it->second.module->name() == requesting)
if ((it->second.module != nullptr) && (it->second.module->name() == requesting))
{
return it->second.module;
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/core/ace/src/models.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ namespace GATAS
{PinType::P1, "P1"},
{PinType::P2, "P2"},
{PinType::AD0, "AD0"},
{PinType::SPI, "SPI"}};
{PinType::SPI, "SPI"},
{PinType::DEV, "DEV"}};

PinType stringToPinType(const char *str)
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib/mocks/mockconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MockConfig : public Configuration
{{GATAS::DataSource::OGN, GATAS::DataSourceMode::RX_TX}}};
}

virtual const GATAS::PinTypeMap pinMap(const etl::string_view moduleName) const override
virtual const GATAS::PinTypeMap pinMap(const etl::string_view moduleName, const etl::string_view fallback = etl::string_view()) const override
{
GATAS::PinTypeMap m;
return m;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/sx1262/ace/src/sx1262.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void Sx1262::start()

GATAS::PostConstruct Sx1262::postConstruct()
{
spiHall = static_cast<SpiModule *>(BaseModule::moduleByName(*this, SpiModule::NAME));
spiHall = static_cast<SpiModule *>(BaseModule::moduleByName(*this, SpiModule::NAMES[device]));

if (spiHall == nullptr)
{
Expand Down Expand Up @@ -648,7 +648,7 @@ void Sx1262::sx1262Trampoline(void *arg)
void Sx1262::sx1262Task(void *arg)
{
(void)arg;
SpiModule *aceSpi = static_cast<SpiModule *>(BaseModule::moduleByName(*this, SpiModule::NAME));
SpiModule *aceSpi = spiHall;
uint32_t keepTransmittingUntill = 0;
bool doListen = false;
while (true)
Expand Down
3 changes: 3 additions & 0 deletions src/lib/sx1262/ace/sx1262.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
/* GaTas Libraries */
#include "ace/constants.hpp"
#include "ace/basemodule.hpp"
#include "ace/coreutils.hpp"
#include "ace/messages.hpp"
#include "rxdataframequeue.hpp"

Expand Down Expand Up @@ -154,6 +155,7 @@ class Sx1262 : public Radio, public etl::message_router<Sx1262, GATAS::RadioTxFr
const uint8_t csPin;
const uint8_t busyPin;
const uint8_t dio1Pin;
const uint8_t device;
const uint8_t radioNo;
bool txEnabled;
// We need to know if the current mode is ground station so the correct package length get's set
Expand All @@ -180,6 +182,7 @@ class Sx1262 : public Radio, public etl::message_router<Sx1262, GATAS::RadioTxFr
csPin(pins.at(GATAS::PinType::CS)),
busyPin(pins.at(GATAS::PinType::BUSY)),
dio1Pin(pins.at(GATAS::PinType::DIO1)),
device(CoreUtils::getPin(pins, GATAS::PinType::DEV, 0)),
radioNo(radioNo_),
txEnabled(txEnabled_),
groundStation(groundStation_),
Expand Down
Loading
Loading