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

migrate device from TTN V2 to TTN V3 #22

Merged
merged 11 commits into from
Aug 25, 2021
2 changes: 1 addition & 1 deletion examples/Catena4430_Sensor/Catena4430_Sensor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static_assert(
"This sketch requires Catena-Arduino-Platform v0.21.0-5 or later"
);

constexpr std::uint32_t kAppVersion = makeVersion(0,5,0,0);
constexpr std::uint32_t kAppVersion = makeVersion(0,5,1,0);
constexpr std::uint32_t kDoubleResetWaitMs = 500;
constexpr std::uint32_t kSetDoubleResetMagic = 0xCA44301;
constexpr std::uint32_t kClearDoubleResetMagic = 0xCA44300;
Expand Down
15 changes: 13 additions & 2 deletions examples/Catena4430_Sensor/Catena4430_cMeasurementLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ void cMeasurementLoop::begin()
// start (or restart) the FSM.
if (! this->m_running)
{
this->m_fFwUpdate = false;
this->m_exit = false;
this->m_fsm.init(*this, &cMeasurementLoop::fsmDispatch);
}
Expand Down Expand Up @@ -264,7 +265,17 @@ cMeasurementLoop::fsmDispatch(
if (this->handleSdFirmwareUpdate())
newState = State::stRebootForUpdate;
else
newState = State::stSleeping;
newState = State::stTryToMigrate;
this->m_fFwUpdate = false;
break;

// try to migrate to TTN V3
case State::stTryToMigrate:
if (fEntry)
{
this->handleSdTTNv3Migrate();
}
newState = State::stSleeping;
break;

// no SD card....
Expand Down Expand Up @@ -533,7 +544,7 @@ void cMeasurementLoop::poll()
this->m_data.Vbus = gCatena.ReadVbus();
setVbus(this->m_data.Vbus);

if (!(this->m_fUsbPower) && !(os_queryTimeCriticalJobs(ms2osticks(timeOut))))
if (!(this->m_fUsbPower) && !(this->m_fFwUpdate) && !(os_queryTimeCriticalJobs(ms2osticks(timeOut))))
lptimSleep(timeOut);
}

Expand Down
8 changes: 7 additions & 1 deletion examples/Catena4430_Sensor/Catena4430_cMeasurementLoop.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class cMeasurementLoop : public McciCatena::cPollableObject
)
: m_pirSampleSec(2) // PIR sample timer
, m_txCycleSec_Permanent(6 * 60) // default uplink interval
, m_txCycleSec(30) // initial uplink interval
, m_txCycleSec(60) // initial uplink interval
, m_txCycleCount(10) // initial count of fast uplinks
, m_DebugFlags(DebugFlags(kError | kTrace))
, m_ActivityTimerSec(60) // the activity time sample interval
Expand All @@ -262,6 +262,7 @@ class cMeasurementLoop : public McciCatena::cPollableObject
stTransmit, // transmit data
stWriteFile, // write file data
stTryToUpdate, // try to update firmware
stTryToMigrate, // try to migrate device to TTN V3
stAwaitCard, // wait for a card to show up.
stRebootForUpdate, // reboot system to complete firmware update

Expand All @@ -281,6 +282,7 @@ class cMeasurementLoop : public McciCatena::cPollableObject
case State::stTransmit: return "stTransmit";
case State::stWriteFile: return "stWriteFile";
case State::stTryToUpdate: return "stTryToUpdate";
case State::stTryToMigrate: return "stTryToMigrate";
case State::stAwaitCard: return "stAwaitCard";
case State::stRebootForUpdate: return "stRebootForUpdate";
case State::stFinal: return "stFinal";
Expand Down Expand Up @@ -382,6 +384,8 @@ class cMeasurementLoop : public McciCatena::cPollableObject
bool handleSdFirmwareUpdate();
bool handleSdFirmwareUpdateCardUp();
bool updateFromSd(const char *sFile, McciCatena::cDownload::DownloadRq_t rq);
void handleSdTTNv3Migrate();
void rejoinNetwork();
void sdPowerUp(bool fOn);
void sdPrep();

Expand Down Expand Up @@ -448,6 +452,8 @@ class cMeasurementLoop : public McciCatena::cPollableObject
bool m_fPrintedSleeping : 1;
// set true when SPI2 is active
bool m_fSpi2Active: 1;
// set true when we've BIN file in SD card to update
bool m_fFwUpdate : 1;

// PIR sample control
cPIRdigital m_pir;
Expand Down
61 changes: 61 additions & 0 deletions examples/Catena4430_Sensor/Catena4430_cMeasurementLoop_SDcard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Module: Catena4430_cMeasurementLoop_SDcard.cpp

#include <Catena_Download.h>

#include <Catena_Fram.h>

#include <Arduino_LoRaWAN_lmic.h>

#include <SD.h>
#include <mcciadk_baselib.h>

Expand All @@ -33,6 +37,8 @@ using namespace McciCatena;

SDClass gSD;

constexpr char gkMigrateFileName[] = "MIGRATE.V3";

/****************************************************************************\
|
| Some utilities
Expand Down Expand Up @@ -419,6 +425,8 @@ cMeasurementLoop::updateFromSd(
};
context_t context { this, true };

this->m_fFwUpdate = true;

gLog.printf(gLog.kInfo, "Attempting to load firmware from %s\n", sUpdate);

// power management: typically the SPI2 is powered down by a sleep,
Expand Down Expand Up @@ -571,4 +579,57 @@ cMeasurementLoop::updateFromSd(
}
}

void
cMeasurementLoop::handleSdTTNv3Migrate(
void
)
{
bool fMigrate = false;
bool fResult = this->checkSdCard();

if (fResult)
{
if (! gSD.exists(gkMigrateFileName))
fMigrate = false;
else
fMigrate = true;
}

if (fMigrate)
dhineshkumarmcci marked this conversation as resolved.
Show resolved Hide resolved
{
bool fFramUpdate = false;
auto const pFram = gCatena.getFram();
static const uint8_t AppEUI[] = { 1, 0, 0, 0, 0, 0, 0, 0 };

if (pFram == nullptr)
fFramUpdate = false;
else
{
pFram->saveField(cFramStorage::kAppEUI, AppEUI);
fFramUpdate = true;
}

if (fFramUpdate)
{
this->rejoinNetwork();
gSD.remove(gkMigrateFileName);
gLog.printf(gLog.kInfo, "cFramStorage::kAppEUI: update: success\n");
}
else
gLog.printf(gLog.kError, "cFramStorage::kAppEUI: not updated\n");
}
this->sdFinish();
}

void
cMeasurementLoop::rejoinNetwork(
void
)
{
auto const pFram = gCatena.getFram();
pFram->saveField(cFramStorage::kDevAddr, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can return an error. Check return value. As a consequence, rejoinNetwork can return an error.

Copy link
Member Author

@dhineshkumarmcci dhineshkumarmcci Jul 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I have planned to check return value, unfortunately API saveField is of datatype void.

In this case, I believe we can use API getField to read the value written in FRAM, and then compare to check for error.

@terrillmoore Please advice on this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I filed a bug report but didn't make the change. No, don't use getField(); the saveField() API is going to change to be bool, and we'll deal with it then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created a pull-request for changes with McciCatena::cFram::saveField() - Catena-Arduino-Platform PR-317


LMIC_unjoinAndRejoin();
}

#undef FUNCTION