Skip to content

Commit dbda6d2

Browse files
committed
[driver] radio: dw3110 Add STS capabilities
1 parent 303cfc7 commit dbda6d2

File tree

3 files changed

+163
-3
lines changed

3 files changed

+163
-3
lines changed

src/modm/driver/radio/dw3110/dw3110_definitions.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ struct Dw3110
115115
Code_64Mhz_12 = 12,
116116
};
117117

118+
enum class STSMode : uint8_t
119+
{
120+
SP0 = 0b00, // No STS
121+
SP1 = 0b01, // STS between SDF and PHR
122+
SP2 = 0b10, // STS at the end (vulnerable to attack!)
123+
SP3 = 0b11 // STS after SDF but no PHR or data
124+
};
125+
118126
enum class StartFrameDelimiter : uint8_t
119127
{
120128
IEEE802_15_4_8 = 0,

src/modm/driver/radio/dw3110/dw3110_phy.hpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace modm
3030
* Hardware abstraction layer for DW3110 \n
3131
* Unsupported Features: AES encryption, Double buffering, GPIO, Temperature and
3232
* Voltage, Pulse Generator calibration, RX antenna delay temp compensation,
33-
* Soft reset, Sleep, Sniff mode, Delayed transmission, STS
33+
* Soft reset, Sleep, Sniff mode
3434
* @ingroup modm_driver_dw3110
3535
* @author Elias H.
3636
* @author Raphael Lehmann
@@ -305,6 +305,57 @@ class Dw3110Phy : public modm::SpiDevice<SpiMaster>, protected modm::NestedResum
305305
modm::ResumableResult<void>
306306
setIRQPolarity(bool high);
307307

308+
/// Set the length of the generated Secure timestamp
309+
///@param len Length in units of 8 chips (~1µs), minimum supported is 32 chips(e.g a value of 3)
310+
modm::ResumableResult<bool>
311+
setSTSLength(uint8_t len);
312+
313+
/// Set the STS mode \n
314+
/// @param mode Defines where to place the STS inside the packet
315+
/// @param sdc If true IV and Key are ignored and a deterministic code is used
316+
modm::ResumableResult<void>
317+
setSTSMode(Dw3110::STSMode mode, bool sdc);
318+
319+
/// Return the 12-bit quality assessment of the last received STS
320+
modm::ResumableResult<uint16_t>
321+
getSTSQuality();
322+
323+
/// Return whether or not the STS quality is in an acceptable range
324+
modm::ResumableResult<bool>
325+
getSTSGood();
326+
327+
/// Set the Key to use for AES generation of the STS \n
328+
/// Ignored if SDC is set in \ref setSTSMode()
329+
modm::ResumableResult<void>
330+
setSTSKey(std::span<const uint8_t, 16> key);
331+
332+
/// Set the IV to use for AES generation of the STS \n
333+
/// Ignored if SDC is set in \ref setSTSMode()
334+
modm::ResumableResult<void>
335+
setSTSIV(std::span<const uint8_t, 16> iv);
336+
337+
/// Get the Key to use for AES generation of the STS
338+
modm::ResumableResult<void>
339+
getSTSKey(std::span<uint8_t, 16> key);
340+
341+
/// Get the IV to use for AES generation of the STS
342+
/// @warning Will only return the programmed IV, to get the incremented value use \ref
343+
/// getCurrentCounter()
344+
modm::ResumableResult<void>
345+
getSTSIV(std::span<uint8_t, 16> iv);
346+
347+
/// Get lower 32 bits of the currently used STS IV
348+
modm::ResumableResult<uint32_t>
349+
getCurrentCounter();
350+
351+
/// Reload the STS IV from the STSIV registers
352+
modm::ResumableResult<void>
353+
reloadSTSIV();
354+
355+
/// Don't increment the STS IV for the next RX/TX
356+
modm::ResumableResult<void>
357+
reuseLastSTSIV();
358+
308359
protected:
309360
/// Transmit a given package using the current configuration and a specific command
310361
/// @param payload Span to the desired payload

src/modm/driver/radio/dw3110/dw3110_phy_impl.hpp

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ modm::Dw3110Phy<SpiMaster, Cs>::initialize(Dw3110::Channel channel, Dw3110::Prea
107107
RF_CALL(setEnableLongFrames(false));
108108
RF_CALL(setSendHeaderFast(false));
109109
RF_CALL(setCCATimeout(256));
110+
RF_CALL(reloadSTSIV());
110111
RF_END_RETURN(true);
111112
}
112113

@@ -1044,9 +1045,11 @@ modm::Dw3110Phy<SpiMaster, Cs>::fetchPacket(std::span<uint8_t> payload, size_t &
10441045
if (payload.size() < payload_len) { RF_RETURN(false); }
10451046
RF_CALL(readRegisterBank<Dw3110::RX_BUFFER_0_BANK>(payload, payload_len));
10461047

1047-
// Clear RXFR RXPHE RXFCG and RXFCE flag
1048+
// Clear most rx flags
10481049
RF_CALL(clearStatusBits(Dw3110::SystemStatus::RXFR | Dw3110::SystemStatus::RXPHE |
1049-
Dw3110::SystemStatus::RXFCG | Dw3110::SystemStatus::RXFCE));
1050+
Dw3110::SystemStatus::RXFCG | Dw3110::SystemStatus::RXFCE |
1051+
Dw3110::SystemStatus::RXSFDD | Dw3110::SystemStatus::RXPRD |
1052+
Dw3110::SystemStatus::RXPHD | Dw3110::SystemStatus::RXFSL));
10501053
RF_END_RETURN(true);
10511054
}
10521055

@@ -1312,3 +1315,101 @@ modm::Dw3110Phy<SpiMaster, Cs>::setIRQPolarity(bool high)
13121315
}
13131316
RF_END();
13141317
}
1318+
1319+
template<typename SpiMaster, typename Cs>
1320+
modm::ResumableResult<bool>
1321+
modm::Dw3110Phy<SpiMaster, Cs>::setSTSLength(uint8_t len)
1322+
{
1323+
RF_BEGIN();
1324+
if (len < 3) { RF_RETURN(false); }
1325+
scratch[0] = len;
1326+
RF_CALL(writeRegister<Dw3110::STS_CFG, 1>(std::span<const uint8_t>(scratch).first<1>()));
1327+
RF_END_RETURN(true);
1328+
}
1329+
1330+
template<typename SpiMaster, typename Cs>
1331+
modm::ResumableResult<void>
1332+
modm::Dw3110Phy<SpiMaster, Cs>::setSTSMode(Dw3110::STSMode mode, bool sdc)
1333+
{
1334+
RF_BEGIN();
1335+
scratch[0] = ((uint8_t)mode << 4) | (sdc ? 0x80 : 0x00);
1336+
scratch[1] = 0x4F | scratch[0];
1337+
RF_CALL(writeRegisterMasked<Dw3110::SYS_CFG, 1, 1>(
1338+
std::span<const uint8_t>(scratch).first<1>(),
1339+
std::span<const uint8_t>(scratch).subspan<1, 1>()));
1340+
RF_END();
1341+
}
1342+
1343+
template<typename SpiMaster, typename Cs>
1344+
modm::ResumableResult<uint16_t>
1345+
modm::Dw3110Phy<SpiMaster, Cs>::getSTSQuality()
1346+
{
1347+
RF_BEGIN();
1348+
RF_CALL(readRegister<Dw3110::STS_STS, 2>(std::span<uint8_t>(scratch).first<2>()));
1349+
RF_END_RETURN((uint16_t)(scratch[0] << 0 | (scratch[1] & 0x0F) << 8));
1350+
}
1351+
1352+
template<typename SpiMaster, typename Cs>
1353+
modm::ResumableResult<bool>
1354+
modm::Dw3110Phy<SpiMaster, Cs>::getSTSGood()
1355+
{
1356+
RF_BEGIN();
1357+
RF_CALL(readRegister<Dw3110::STS_CFG, 1>(std::span<uint8_t>(scratch).first<1>()));
1358+
RF_CALL(readRegister<Dw3110::STS_STS, 2>(std::span<uint8_t>(scratch).subspan<1, 2>()));
1359+
RF_END_RETURN((scratch[0] + 1) * 8.0f * 0.6f < (scratch[1] | (scratch[2] << 8)));
1360+
}
1361+
1362+
template<typename SpiMaster, typename Cs>
1363+
modm::ResumableResult<void>
1364+
modm::Dw3110Phy<SpiMaster, Cs>::setSTSKey(std::span<const uint8_t, 16> key)
1365+
{
1366+
return writeRegister<Dw3110::STS_KEY, 16, 0>(key);
1367+
}
1368+
1369+
template<typename SpiMaster, typename Cs>
1370+
modm::ResumableResult<void>
1371+
modm::Dw3110Phy<SpiMaster, Cs>::setSTSIV(std::span<const uint8_t, 16> iv)
1372+
{
1373+
return writeRegister<Dw3110::STS_IV, 16, 0>(iv);
1374+
}
1375+
1376+
template<typename SpiMaster, typename Cs>
1377+
modm::ResumableResult<void>
1378+
modm::Dw3110Phy<SpiMaster, Cs>::getSTSKey(std::span<uint8_t, 16> key)
1379+
{
1380+
return readRegister<Dw3110::STS_KEY, 16, 0>(key);
1381+
}
1382+
1383+
template<typename SpiMaster, typename Cs>
1384+
modm::ResumableResult<void>
1385+
modm::Dw3110Phy<SpiMaster, Cs>::getSTSIV(std::span<uint8_t, 16> iv)
1386+
{
1387+
return readRegister<Dw3110::STS_IV, 16, 0>(iv);
1388+
}
1389+
1390+
template<typename SpiMaster, typename Cs>
1391+
modm::ResumableResult<uint32_t>
1392+
modm::Dw3110Phy<SpiMaster, Cs>::getCurrentCounter()
1393+
{
1394+
RF_BEGIN();
1395+
RF_CALL(readRegister<Dw3110::CTR_DBG, 4, 0>(std::span<uint8_t>(scratch).first<4>()));
1396+
RF_END_RETURN((uint32_t)scratch[0] | (uint32_t)scratch[1] << 8 | (uint32_t)scratch[2] << 16 |
1397+
(uint32_t)scratch[3] << 24);
1398+
}
1399+
1400+
template<typename SpiMaster, typename Cs>
1401+
modm::ResumableResult<void>
1402+
modm::Dw3110Phy<SpiMaster, Cs>::reloadSTSIV()
1403+
{
1404+
constexpr static uint8_t sts_ctrl[] = {0x01};
1405+
return writeRegister<Dw3110::STS_CTRL, 1>(sts_ctrl);
1406+
}
1407+
1408+
template<typename SpiMaster, typename Cs>
1409+
modm::ResumableResult<void>
1410+
modm::Dw3110Phy<SpiMaster, Cs>::reuseLastSTSIV()
1411+
{
1412+
1413+
constexpr static uint8_t sts_ctrl[] = {0x02};
1414+
return writeRegister<Dw3110::STS_CTRL, 1>(sts_ctrl);
1415+
}

0 commit comments

Comments
 (0)