mirror of
https://github.com/espressif/openthread.git
synced 2026-07-26 22:09:05 +00:00
@@ -69,6 +69,7 @@
|
||||
#define RFCORE_XREG_RSSISTAT 0x40088664 // RSSI valid status register
|
||||
#define RFCORE_XREG_AGCCTRL1 0x400886C8 // AGC reference level
|
||||
#define RFCORE_XREG_TXFILTCFG 0x400887E8 // TX filter configuration
|
||||
#define RFCORE_XREG_RFRND 0x4008869C // Random data
|
||||
#define RFCORE_SFR_RFDATA 0x40088828 // The TX FIFO and RX FIFO
|
||||
#define RFCORE_SFR_RFERRF 0x4008882C // RF error interrupt flags
|
||||
#define RFCORE_SFR_RFIRQF0 0x40088834 // RF interrupt flags
|
||||
@@ -78,9 +79,12 @@
|
||||
|
||||
#define RFCORE_XREG_FRMCTRL0_AUTOACK 0x00000020
|
||||
#define RFCORE_XREG_FRMCTRL0_AUTOCRC 0x00000040
|
||||
#define RFCORE_XREG_FRMCTRL0_INFINITY_RX 0x00000008
|
||||
|
||||
#define RFCORE_XREG_FRMCTRL1_PENDING_OR 0x00000004
|
||||
|
||||
#define RFCORE_XREG_RFRND_IRND 0x00000001
|
||||
|
||||
#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE 0x00000002
|
||||
#define RFCORE_XREG_FSMSTAT1_CCA 0x00000010 // Clear channel assessment
|
||||
#define RFCORE_XREG_FSMSTAT1_SFD 0x00000020
|
||||
@@ -91,6 +95,12 @@
|
||||
|
||||
#define RFCORE_SFR_RFERRF_RXOVERF 0x00000004 // RX FIFO overflowed.
|
||||
|
||||
#define RFCORE_SFR_RFST_INSTR_RXON 0xE3 // Instruction set RX on
|
||||
#define RFCORE_SFR_RFST_INSTR_TXON 0xE9 // Instruction set TX on
|
||||
#define RFCORE_SFR_RFST_INSTR_RFOFF 0xEF // Instruction set RF off
|
||||
#define RFCORE_SFR_RFST_INSTR_FLUSHRX 0xED // Instruction set flush rx buffer
|
||||
#define RFCORE_SFR_RFST_INSTR_FLUSHTX 0xEE // Instruction set flush tx buffer
|
||||
|
||||
#define ANA_REGS_BASE 0x400D6000 // ANA_REGS
|
||||
#define ANA_REGS_O_IVCTRL 0x00000004 // Analog control register
|
||||
|
||||
@@ -167,4 +177,11 @@
|
||||
#define UART_IM_RXIM 0x00000010 // UART receive interrupt mask
|
||||
#define UART_IM_RTIM 0x00000040 // UART receive time-out interrupt
|
||||
|
||||
#define SOC_ADC_ADCCON1 0x400D7000 // ADC Control
|
||||
#define SOC_ADC_RNDL 0x400D7014 // RNG low data
|
||||
#define SOC_ADC_RNDH 0x400D7018 // RNG high data
|
||||
|
||||
#define SOC_ADC_ADCCON1_RCTRL0 0x00000004 // ADCCON1 RCTRL bit 0
|
||||
#define SOC_ADC_ADCCON1_RCTRL1 0x00000008 // ADCCON1 RCTRL bit 1
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
void PlatformInit(int argc, char *argv[])
|
||||
{
|
||||
cc2538AlarmInit();
|
||||
cc2538RadioInit();
|
||||
cc2538RandomInit();
|
||||
cc2538RadioInit();
|
||||
otPlatUartEnable();
|
||||
|
||||
(void)argc;
|
||||
|
||||
@@ -52,15 +52,6 @@ enum
|
||||
IEEE802154_DSN_OFFSET = 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CC2538_RF_CSP_OP_ISRXON = 0xE3,
|
||||
CC2538_RF_CSP_OP_ISTXON = 0xE9,
|
||||
CC2538_RF_CSP_OP_ISRFOFF = 0xEF,
|
||||
CC2538_RF_CSP_OP_ISFLUSHRX = 0xED,
|
||||
CC2538_RF_CSP_OP_ISFLUSHTX = 0xEE,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CC2538_RSSI_OFFSET = 73,
|
||||
@@ -84,11 +75,11 @@ void enableReceiver(void)
|
||||
if (!sIsReceiverEnabled)
|
||||
{
|
||||
// flush rxfifo
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHRX;
|
||||
|
||||
// enable receiver
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRXON;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_RXON;
|
||||
sIsReceiverEnabled = true;
|
||||
}
|
||||
}
|
||||
@@ -100,13 +91,13 @@ void disableReceiver(void)
|
||||
while (HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
|
||||
|
||||
// flush rxfifo
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHRX;
|
||||
|
||||
if (HWREG(RFCORE_XREG_RXENABLE) != 0)
|
||||
{
|
||||
// disable receiver
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRFOFF;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_RFOFF;
|
||||
}
|
||||
|
||||
sIsReceiverEnabled = false;
|
||||
@@ -218,6 +209,11 @@ ThreadError otPlatRadioDisable(void)
|
||||
return error;
|
||||
}
|
||||
|
||||
bool otPlatRadioIsEnabled(void)
|
||||
{
|
||||
return (sState != kStateDisabled) ? true : false;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioSleep(void)
|
||||
{
|
||||
ThreadError error = kThreadError_Busy;
|
||||
@@ -263,8 +259,8 @@ ThreadError otPlatRadioTransmit(void)
|
||||
while (HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
|
||||
|
||||
// flush txfifo
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX;
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHTX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHTX;
|
||||
|
||||
// frame length
|
||||
HWREG(RFCORE_SFR_RFDATA) = sTransmitFrame.mLength;
|
||||
@@ -286,7 +282,7 @@ ThreadError otPlatRadioTransmit(void)
|
||||
sTransmitError = kThreadError_ChannelAccessFailure);
|
||||
|
||||
// begin transmit
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_TXON;
|
||||
|
||||
while (HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
|
||||
}
|
||||
@@ -359,8 +355,8 @@ void readFrame(void)
|
||||
if ((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) != 0 &&
|
||||
(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFO) == 0)
|
||||
{
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHRX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHRX;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -28,60 +28,96 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements a pseudo-random number generator.
|
||||
* This file implements a random number generator.
|
||||
*
|
||||
* @warning
|
||||
* This implementation is not a true random number generator and does @em satisfy the Thread requirements.
|
||||
*/
|
||||
|
||||
#include <openthread-types.h>
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <platform/radio.h>
|
||||
#include <platform/random.h>
|
||||
#include "platform-cc2538.h"
|
||||
|
||||
static uint32_t s_state = 1;
|
||||
static void generateRandom(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength)
|
||||
{
|
||||
HWREG(SOC_ADC_ADCCON1) &= ~(SOC_ADC_ADCCON1_RCTRL1 | SOC_ADC_ADCCON1_RCTRL0);
|
||||
HWREG(SYS_CTRL_RCGCRFC) = SYS_CTRL_RCGCRFC_RFC0;
|
||||
|
||||
while (HWREG(SYS_CTRL_RCGCRFC) != SYS_CTRL_RCGCRFC_RFC0);
|
||||
|
||||
HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_INFINITY_RX;
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_RXON;
|
||||
|
||||
while (!HWREG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID);
|
||||
|
||||
for (uint16_t index = 0; index < aInputLength; index++)
|
||||
{
|
||||
aOutput[index] = 0;
|
||||
|
||||
for (uint8_t offset = 0; offset < 8 * sizeof(uint8_t); offset++)
|
||||
{
|
||||
aOutput[index] <<= 1;
|
||||
aOutput[index] |= (HWREG(RFCORE_XREG_RFRND) & RFCORE_XREG_RFRND_IRND);
|
||||
}
|
||||
}
|
||||
|
||||
HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_RFOFF;
|
||||
|
||||
if (aOutputLength)
|
||||
{
|
||||
*aOutputLength = aInputLength;
|
||||
}
|
||||
}
|
||||
|
||||
void cc2538RandomInit(void)
|
||||
{
|
||||
// use Extended Identifier portion of IEEE EUI-64 as the seed
|
||||
s_state = HWREG(IEEE_EUI64 + 4);
|
||||
uint16_t seed = 0;
|
||||
|
||||
while (seed == 0x0000 || seed == 0x8003)
|
||||
{
|
||||
generateRandom(sizeof(seed), (uint8_t *)&seed, 0);
|
||||
}
|
||||
|
||||
HWREG(SOC_ADC_RNDL) = (seed >> 8) & 0xff;
|
||||
HWREG(SOC_ADC_RNDL) = seed & 0xff;
|
||||
}
|
||||
|
||||
uint32_t otPlatRandomGet(void)
|
||||
{
|
||||
uint32_t mlcg, p, q;
|
||||
uint64_t tmpstate;
|
||||
uint32_t random = 0;
|
||||
|
||||
tmpstate = (uint64_t)33614 * (uint64_t)s_state;
|
||||
q = tmpstate & 0xffffffff;
|
||||
q = q >> 1;
|
||||
p = tmpstate >> 32;
|
||||
mlcg = p + q;
|
||||
HWREG(SOC_ADC_ADCCON1) |= SOC_ADC_ADCCON1_RCTRL0;
|
||||
random = HWREG(SOC_ADC_RNDL) | (HWREG(SOC_ADC_RNDH) << 8);
|
||||
|
||||
if (mlcg & 0x80000000)
|
||||
{
|
||||
mlcg &= 0x7fffffff;
|
||||
mlcg++;
|
||||
}
|
||||
HWREG(SOC_ADC_ADCCON1) |= SOC_ADC_ADCCON1_RCTRL0;
|
||||
random |= ((HWREG(SOC_ADC_RNDL) | (HWREG(SOC_ADC_RNDH) << 8)) << 16);
|
||||
|
||||
s_state = mlcg;
|
||||
|
||||
return mlcg;
|
||||
return random;
|
||||
}
|
||||
|
||||
ThreadError otPlatSecureRandomGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength)
|
||||
ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uint8_t channel = 0;
|
||||
|
||||
VerifyOrExit(aOutput && aOutputLength, error = kThreadError_InvalidArgs);
|
||||
|
||||
for (uint16_t length = 0; length < aInputLength; length++)
|
||||
if (otPlatRadioIsEnabled())
|
||||
{
|
||||
aOutput[length] = (uint8_t)otPlatRandomGet();
|
||||
channel = 11 + (HWREG(RFCORE_XREG_FREQCTRL) - 11) / 5;
|
||||
otPlatRadioSleep();
|
||||
otPlatRadioDisable();
|
||||
}
|
||||
|
||||
*aOutputLength = aInputLength;
|
||||
generateRandom(aInputLength, aOutput, aOutputLength);
|
||||
|
||||
if (channel)
|
||||
{
|
||||
cc2538RadioInit();
|
||||
otPlatRadioEnable();
|
||||
otPlatRadioReceive(channel);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -377,6 +377,11 @@ ThreadError otPlatRadioDisable(void)
|
||||
return error;
|
||||
}
|
||||
|
||||
bool otPlatRadioIsEnabled(void)
|
||||
{
|
||||
return (sState != kStateDisabled) ? true : false;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioSleep(void)
|
||||
{
|
||||
ThreadError error = kThreadError_Busy;
|
||||
|
||||
@@ -201,6 +201,14 @@ ThreadError otPlatRadioEnable(void);
|
||||
*/
|
||||
ThreadError otPlatRadioDisable(void);
|
||||
|
||||
/**
|
||||
* Check whether radio is enabled or not.
|
||||
*
|
||||
* @retval ::true radio is enabled.
|
||||
* @retval ::false radio is disabled.
|
||||
*/
|
||||
bool otPlatRadioIsEnabled(void);
|
||||
|
||||
/**
|
||||
* Transition the radio from Receive to Sleep.
|
||||
* Turn off the radio.
|
||||
|
||||
+10
-10
@@ -55,7 +55,15 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get random stream.
|
||||
* Get a 32-bit random value.
|
||||
*
|
||||
* @returns A 32-bit random value.
|
||||
*
|
||||
*/
|
||||
uint32_t otPlatRandomGet(void);
|
||||
|
||||
/**
|
||||
* Get true random stream.
|
||||
*
|
||||
* @param[in] aInputLength The expected size of random values.
|
||||
* @param[out] aOutput A pointer to the buffer for the generated random stream. The pointer should never be NULL.
|
||||
@@ -67,15 +75,7 @@ extern "C" {
|
||||
* @retval kThreadError_Fail Generate random fail.
|
||||
* @retval kThreadError_InvalidArgs Invalid args.
|
||||
*/
|
||||
ThreadError otPlatSecureRandomGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength);
|
||||
|
||||
/**
|
||||
* Get a 32-bit true random value.
|
||||
*
|
||||
* @returns A 32-bit true random value.
|
||||
*
|
||||
*/
|
||||
uint32_t otPlatRandomGet(void);
|
||||
ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
Reference in New Issue
Block a user