Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for Model 4917 #354

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
214 changes: 214 additions & 0 deletions doc/LOGGING.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/Catena.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ Copyright notice:
#elif defined(ARDUINO_MCCI_CATENA_4802)
# include "Catena4802.h"
# define CATENA_H_SUPER_ McciCatena::Catena4802
#elif defined(ARDUINO_MCCI_MODEL_4917)
# include "Catena4917.h"
# define CATENA_H_SUPER_ McciCatena::Catena4917
/* fallback in case it's SAMD but not what we expect */
#elif defined(ARDUINO_ARCH_SAMD)
# include "CatenaSamd21.h"
Expand Down
63 changes: 63 additions & 0 deletions src/Catena4917.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*

Module: Catena4917.h

Function:
class Catena4917: CatenaBase Platform to represent a Catena 4917

Copyright notice:
See accompanying LICENSE file.

Author:
Pranau R, MCCI Corporation November 2022

*/

#ifndef _Catena4917_H_ /* prevent multiple includes */
#define _Catena4917_H_

#pragma once

#ifndef _CATENA491x_H_
# include "Catena491x.h"
#endif

namespace McciCatena {

class Catena4917 : public Catena491x
{
public:
using Super = Catena4917;

// no specific constructor.
Catena4917() {};

// uses default destructor

// neither copyable nor movable
Catena4917(const Catena4917&) = delete;
Catena4917& operator=(const Catena4917&) = delete;
Catena4917(const Catena4917&&) = delete;
Catena4917& operator=(const Catena4917&&) = delete;

virtual const char *CatenaName() const override { return "Catena 4917"; };
virtual float ReadVbat(void) const override;
virtual float ReadVbus(void) const override;

protected:
// we are required to provide a table of platforms
virtual void getPlatformTable(
const CATENA_PLATFORM * const * &vPlatforms,
size_t &nvPlatforms
) override;

private:
// the known platforms
static const CATENA_PLATFORM(* const vPlatforms[]);
static const size_t nvPlatforms;
};

} // namespace McciCatena

/**** end of Catena4917.h ****/
#endif /* _Catena4917_H_ */
106 changes: 106 additions & 0 deletions src/Catena491x.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*

Module: Catena491x.h

Function:
class Catena491x: CatenaBase Platform to represent a Catena 491x
(such as the 4917).

Copyright notice:
See accompanying LICENSE file.

Author:
Pranau R, MCCI Corporation November 2022

*/

#ifndef _CATENA491X_H_ /* prevent multiple includes */
#define _CATENA491X_H_

#pragma once

#ifndef _CATENASTM32L0_H_
# include "CatenaStm32L0.h"
#endif

namespace McciCatena {

class Catena491x : public CatenaStm32L0
{
public:
using Super = CatenaStm32L0;

// no specific constructor.
Catena491x() {};

// uses default destructor

// neither copyable nor movable
Catena491x(const Catena491x&) = delete;
Catena491x& operator=(const Catena491x&) = delete;
Catena491x(const Catena491x&&) = delete;
Catena491x& operator=(const Catena491x&&) = delete;

// LoRaWAN binding
class LoRaWAN /* forward */;

enum ANALOG_PINS
{
APIN_VBAT_SENSE = A3,
APIN_VBUS_SENSE = A4,
};

enum ANALOG_CHANNELS
{
ANALOG_CHANNEL_A0 = 0,
ANALOG_CHANNEL_A1 = 5,
ANALOG_CHANNEL_A2 = 4,
ANALOG_CHANNEL_A3 = 3,
ANALOG_CHANNEL_A4 = 2,
ANALOG_CHANNEL_VBAT = ANALOG_CHANNEL_A3,
ANALOG_CHANNEL_VBUS = ANALOG_CHANNEL_A4,
ANALOG_CHANNEL_VREF = 17,
};

enum DIGITAL_PINS
{
PIN_STATUS_LED = D13,
PIN_SPI2_FLASH_SS = D19,
PIN_SPI2_MOSI = D23,
PIN_SPI2_MISO = D22,
PIN_SPI2_SCK = D24,
};

// methods
virtual bool begin() override;

protected:

private:
};

/*
|| The LoRaWAN class for the Catena 455x. Assumes The Things Network
*/
class Catena491x::LoRaWAN : public CatenaStm32L0::LoRaWAN
{
public:
using Super = CatenaStm32L0::LoRaWAN;

/*
|| the constructor. We don't do anything at this level, the
|| Super constructor does most of the work.
*/
LoRaWAN() {};

bool begin(Catena491x *pParent);

protected:

private:
};

} // namespace McciCatena

/**** end of Catena491x.h ****/
#endif /* _CATENA491X_H_ */
2 changes: 2 additions & 0 deletions src/CatenaBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ class CatenaBase
fHasI2cLevelShifter = 1 << 21,
//platform has LTR329 Lux sensor
fHasLuxLtr329 = 1 << 22,
//platform has LIS2HH12 Accelerometer
fHasLIS2HH12 = 1 << 23,

// special wiring variants all are offsets from M100...
// we support up to 127 variants, becuase we have 7
Expand Down
51 changes: 50 additions & 1 deletion src/Catena_Fram.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ class cFram::Cursor
// take a located cursor and create an object if needed
bool create(void);

// test whether a cursro is bound to an object
// test whether a cursor is bound to an object
bool isbound() const
{
return this->m_uKey != cFramStorage::StandardKeys::kMAX;
Expand All @@ -211,6 +211,35 @@ class cFram::Cursor
return this->m_offset != cFramStorage::kInvalidOffset;
}

bool isinitialized() const
{
return this->m_pFram != nullptr;
}

bool initialize(cFram *pFram)
{
if (pFram == nullptr)
{
// invalid paramter
return false;
}

else if (this->m_pFram == nullptr)
{
// not set
this->m_pFram = pFram;
return true;
}
else if (this->m_pFram == pFram)
{
// not changing.
return true;
}
else
// already set and trying to chagne.
return false;
}

// set up a cursor to match a standard item
bool locate(const cFramStorage::StandardItem);

Expand All @@ -234,6 +263,16 @@ class cFram::Cursor
return this->get((uint8_t *)&v, sizeof(v));
}

// get an object.
template <class T>
bool get(T &v)
{
return this->get((uint8_t *)&v, sizeof(v));
}

// get a part of a value
bool getPartialValue(uint8_t *pBuffer, size_t nBuffer, size_t offset);

// put a buffer
bool put(const uint8_t *pBuffer, size_t nBuffer);

Expand All @@ -243,6 +282,16 @@ class cFram::Cursor
return this->put((const uint8_t *)&v, sizeof(v));
}

// put an object
template <class T>
bool put(const T &v)
{
return this->put((const uint8_t *)&v, sizeof(v));
}

// put a part of a value
bool putPartialValue(size_t offset, const uint8_t *pBuffer, size_t nBuffer);

// parse a value
bool parsevalue(
const char *pValue,
Expand Down
117 changes: 117 additions & 0 deletions src/Catena_FramRingBuf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*

Module: Catena_FramRingBuf.h

Function:
FRAM-based non-volatile ring buffer templates

Copyright and License:
This file copyright (C) 2024 by

MCCI Corporation
3520 Krums Corners Road
Ithaca, NY 14850

See accompanying LICENSE file for copyright and license information.

Author:
Terry Moore, MCCI Corporation August 2024

*/

#ifndef _Catena_FramRingBuf_h_
#define _Catena_FramRingBuf_h_ /* prevent multiple includes */

#pragma once

#ifndef _Catena_FramStorage_h_
# include "Catena_FramStorage.h"
#endif

#ifndef _Catena_Fram_h_
# include "Catena_Fram.h"
#endif


namespace McciCatena {

class FramRingBuffer_t;

class FramRingBuffer_t
{
public:
using OverflowPolicy_t = cFramStorage::DataLogHeader_t::OverflowPolicy_t;
using size_type = cFramStorage::DataLogHeader_t::size_type;
using sequence_type = cFramStorage::DataLogHeader_t::sequence_type;

// neither copyable nor movable
FramRingBuffer_t(const FramRingBuffer_t&) = delete;
FramRingBuffer_t& operator=(const FramRingBuffer_t&) = delete;
FramRingBuffer_t(const FramRingBuffer_t&&) = delete;
FramRingBuffer_t& operator=(const FramRingBuffer_t&&) = delete;

// constructor
FramRingBuffer_t(uint8_t version, size_type itemsize, OverflowPolicy_t policy)
: m_logheader(version, this->getBufferSize(), itemsize + sizeof(sequence_type), policy)
{}

protected:
bool initializeFromFram(uint8_t version, size_type itemsize, OverflowPolicy_t policy);
bool put_tail(sequence_type seqnum, const uint8_t *pBuffer, size_type nBuffer);
bool peek_front(sequence_type &seqnum, uint8_t *pBuffer, size_type nBuffer, size_type iEntry = 0);
bool pop_front();

public:
size_type size() const
{
return this->m_logheader.size() - sizeof(sequence_type);
}

size_type getBufferSize() const
{
return cFramStorage::kDataLogBufferSize;
}

bool newSequenceNumber(sequence_type &sequenceNumber);

bool clear();

private:
cFramStorage::DataLogHeader_t m_logheader;
cFram::Cursor m_logBufferCursor {nullptr};
cFram::Cursor m_logHeaderCursor {nullptr};
};

template <class cDataItem>
class RecoverableUplinkQueue_t : public FramRingBuffer_t
{
public:
// neither copyable nor movable
RecoverableUplinkQueue_t(const RecoverableUplinkQueue_t&) = delete;
RecoverableUplinkQueue_t& operator=(const RecoverableUplinkQueue_t&) = delete;
RecoverableUplinkQueue_t(const RecoverableUplinkQueue_t&&) = delete;
RecoverableUplinkQueue_t& operator=(const RecoverableUplinkQueue_t&&) = delete;

RecoverableUplinkQueue_t(uint8_t version, OverflowPolicy_t policy)
: FramRingBuffer_t(version, sizeof(cDataItem), policy)
{}

bool put_tail(sequence_type sequenceNumber, cDataItem &refItem)
{
return this->FramRingBuffer_t::put_tail(sequenceNumber, (const uint8_t *)&refItem, sizeof(refItem));
}

bool peek_front(sequence_type &sequenceNumber, cDataItem &refItem, size_type iEntry = 0)
{
return this->FramRingBuffer_t::peek_front(sequenceNumber, (uint8_t *)&refItem, sizeof(refItem), iEntry);
}

bool initializeFromFram(uint8_t version)
{
return this->FramRingBuffer_t::initializeFromFram(version, sizeof(cDataItem), OverflowPolicy_t::kDropOldest);
};
};

} // namespace McciCatena

#endif /* _Catena_FramRingBuf_h_ */
Loading