Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RadioHead-148 by
RH_NRF51.cpp
00001 // NRF51.cpp 00002 // 00003 // Per: nRF51_Series_Reference_manual v3.0.pdf 00004 // Copyright (C) 2012 Mike McCauley 00005 // $Id: RH_NRF51.cpp,v 1.1 2015/07/01 00:46:05 mikem Exp $ 00006 00007 // Set by Arduino IDE when compiling for nRF51 chips: 00008 #ifdef NRF51 00009 00010 #include <RH_NRF51.h> 00011 00012 RH_NRF51::RH_NRF51() 00013 : _rxBufValid(false) 00014 { 00015 } 00016 00017 bool RH_NRF51::init() 00018 { 00019 // Enable the High Frequency clock to the system as a whole 00020 NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; 00021 NRF_CLOCK->TASKS_HFCLKSTART = 1; 00022 /* Wait for the external oscillator to start up */ 00023 while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { } 00024 00025 // Enables the DC/DC converter when the radio is enabled. Need this! 00026 NRF_POWER->DCDCEN = 0x00000001; 00027 00028 // Disable and reset the radio 00029 NRF_RADIO->POWER = RADIO_POWER_POWER_Disabled; 00030 NRF_RADIO->POWER = RADIO_POWER_POWER_Enabled; 00031 NRF_RADIO->EVENTS_DISABLED = 0; 00032 NRF_RADIO->TASKS_DISABLE = 1; 00033 // Wait until we are in DISABLE state 00034 while (NRF_RADIO->EVENTS_DISABLED == 0) {} 00035 00036 // Physical on-air address is set in PREFIX0 + BASE0 by setNetworkAddress 00037 NRF_RADIO->TXADDRESS = 0x00; // Use logical address 0 (PREFIX0 + BASE0) 00038 NRF_RADIO->RXADDRESSES = 0x01; // Enable reception on logical address 0 (PREFIX0 + BASE0) 00039 00040 // Configure the CRC 00041 NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits 00042 NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value 00043 NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1 00044 00045 // These shorts will make the radio transition from Ready to Start to Disable automatically 00046 // for both TX and RX, which makes for much shorter on-air times 00047 NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos) 00048 | (RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos); 00049 00050 NRF_RADIO->PCNF0 = ((8 << RADIO_PCNF0_LFLEN_Pos) & RADIO_PCNF0_LFLEN_Msk); // Payload length in bits 00051 00052 // Make sure we are powered down 00053 setModeIdle(); 00054 00055 // Set a default network address 00056 uint8_t default_network_address[] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7}; 00057 setNetworkAddress(default_network_address, sizeof(default_network_address)); 00058 00059 setChannel(2); // The default, in case it was set by another app without powering down 00060 setRF(RH_NRF51::DataRate2Mbps, RH_NRF51::TransmitPower0dBm); 00061 00062 return true; 00063 } 00064 00065 bool RH_NRF51::setChannel(uint8_t channel) 00066 { 00067 NRF_RADIO->FREQUENCY = ((channel << RADIO_FREQUENCY_FREQUENCY_Pos) & RADIO_FREQUENCY_FREQUENCY_Msk); 00068 return true; 00069 } 00070 00071 bool RH_NRF51::setNetworkAddress(uint8_t* address, uint8_t len) 00072 { 00073 if (len < 3 || len > 5) 00074 return false; 00075 00076 // First byte is the prefix, remainder are base 00077 NRF_RADIO->PREFIX0 = ((address[0] << RADIO_PREFIX0_AP0_Pos) & RADIO_PREFIX0_AP0_Msk); 00078 uint32_t base; 00079 memcpy(&base, address+1, len-1); 00080 NRF_RADIO->BASE0 = base; 00081 00082 NRF_RADIO->PCNF1 = ( 00083 (((sizeof(_buf)) << RADIO_PCNF1_MAXLEN_Pos) & RADIO_PCNF1_MAXLEN_Msk) // maximum length of payload 00084 | (((0UL) << RADIO_PCNF1_STATLEN_Pos) & RADIO_PCNF1_STATLEN_Msk) // expand the payload with 0 bytes 00085 | (((len-1) << RADIO_PCNF1_BALEN_Pos) & RADIO_PCNF1_BALEN_Msk)); // base address length in number of bytes. 00086 00087 return true; 00088 } 00089 00090 bool RH_NRF51::setRF(DataRate data_rate, TransmitPower power) 00091 { 00092 uint8_t mode; 00093 uint8_t p; 00094 00095 if (data_rate == DataRate2Mbps) 00096 mode = RADIO_MODE_MODE_Nrf_2Mbit; 00097 else if (data_rate == DataRate1Mbps) 00098 mode = RADIO_MODE_MODE_Nrf_1Mbit; 00099 else if (data_rate == DataRate250kbps) 00100 mode = RADIO_MODE_MODE_Nrf_250Kbit; 00101 else 00102 return false;// Invalid 00103 00104 if (power == TransmitPower4dBm) 00105 p = RADIO_TXPOWER_TXPOWER_Pos4dBm; 00106 else if (power == TransmitPower0dBm) 00107 p = RADIO_TXPOWER_TXPOWER_0dBm; 00108 else if (power == TransmitPowerm4dBm) 00109 p = RADIO_TXPOWER_TXPOWER_Neg4dBm; 00110 else if (power == TransmitPowerm8dBm) 00111 p = RADIO_TXPOWER_TXPOWER_Neg8dBm; 00112 else if (power == TransmitPowerm12dBm) 00113 p = RADIO_TXPOWER_TXPOWER_Neg12dBm; 00114 else if (power == TransmitPowerm16dBm) 00115 p = RADIO_TXPOWER_TXPOWER_Neg16dBm; 00116 else if (power == TransmitPowerm20dBm) 00117 p = RADIO_TXPOWER_TXPOWER_Neg20dBm; 00118 else if (power == TransmitPowerm30dBm) 00119 p = RADIO_TXPOWER_TXPOWER_Neg30dBm; 00120 else 00121 return false; // Invalid 00122 00123 00124 NRF_RADIO->TXPOWER = ((p << RADIO_TXPOWER_TXPOWER_Pos) & RADIO_TXPOWER_TXPOWER_Msk); 00125 NRF_RADIO->MODE = ((mode << RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk); 00126 00127 return true; 00128 } 00129 00130 void RH_NRF51::setModeIdle() 00131 { 00132 if (_mode != RHModeIdle) 00133 { 00134 NRF_RADIO->TASKS_DISABLE = 1; 00135 _mode = RHModeIdle; 00136 } 00137 } 00138 00139 void RH_NRF51::setModeRx() 00140 { 00141 if (_mode != RHModeRx) 00142 { 00143 setModeIdle(); // Can only start RX from DISABLE state 00144 // Radio will transition automatically to Disable state when a messageis received 00145 NRF_RADIO->PACKETPTR = (uint32_t)_buf; 00146 NRF_RADIO->EVENTS_DISABLED = 0U; // So we can detect end of transmission 00147 NRF_RADIO->TASKS_RXEN = 1; 00148 _mode = RHModeRx; 00149 } 00150 } 00151 00152 void RH_NRF51::setModeTx() 00153 { 00154 if (_mode != RHModeTx) 00155 { 00156 setModeIdle(); // Can only start RX from DISABLE state 00157 // Radio will transition automatically to Disable state at the end of transmission 00158 NRF_RADIO->PACKETPTR = (uint32_t)_buf; 00159 NRF_RADIO->EVENTS_DISABLED = 0U; // So we can detect end of transmission 00160 NRF_RADIO->TASKS_TXEN = 1; 00161 _mode = RHModeTx; 00162 } 00163 } 00164 00165 bool RH_NRF51::send(const uint8_t* data, uint8_t len) 00166 { 00167 if (len > RH_NRF51_MAX_MESSAGE_LEN) 00168 return false; 00169 // Set up the headers 00170 _buf[0] = len + RH_NRF51_HEADER_LEN; 00171 _buf[1] = _txHeaderTo; 00172 _buf[2] = _txHeaderFrom; 00173 _buf[3] = _txHeaderId; 00174 _buf[4] = _txHeaderFlags; 00175 memcpy(_buf+RH_NRF51_HEADER_LEN+1, data, len); 00176 00177 _rxBufValid = false; 00178 setModeTx(); 00179 // Radio will return to Disabled state after transmission is complete 00180 _txGood++; 00181 return true; 00182 } 00183 00184 bool RH_NRF51::waitPacketSent() 00185 { 00186 // If we are not currently in transmit mode, there is no packet to wait for 00187 if (_mode != RHModeTx) 00188 return false; 00189 00190 // When the Disabled event occurs we know the transmission has completed 00191 while (NRF_RADIO->EVENTS_DISABLED == 0U) 00192 { 00193 YIELD; 00194 } 00195 setModeIdle(); 00196 00197 return true; 00198 } 00199 00200 bool RH_NRF51::isSending() 00201 { 00202 return (NRF_RADIO->STATE == RADIO_STATE_STATE_Tx) ? true : false; 00203 } 00204 00205 bool RH_NRF51::printRegisters() 00206 { 00207 #ifdef RH_HAVE_SERIAL 00208 uint16_t i; 00209 uint32_t* p = (uint32_t*)NRF_RADIO; 00210 for (i = 0; (p + i) < (uint32_t*) (((NRF_RADIO_Type*)NRF_RADIO) + 1); i++) 00211 { 00212 Serial.print("Offset: "); 00213 Serial.print(i, DEC); 00214 Serial.print(" "); 00215 Serial.println(*(p+i), HEX); 00216 } 00217 #endif 00218 00219 return true; 00220 } 00221 00222 // Check whether the latest received message is complete and uncorrupted 00223 void RH_NRF51::validateRxBuf() 00224 { 00225 if (_buf[0] < 4) 00226 return; // Too short to be a real message 00227 // Extract the 4 headers 00228 _rxHeaderTo = _buf[1]; 00229 _rxHeaderFrom = _buf[2]; 00230 _rxHeaderId = _buf[3]; 00231 _rxHeaderFlags = _buf[4]; 00232 if (_promiscuous || 00233 _rxHeaderTo == _thisAddress || 00234 _rxHeaderTo == RH_BROADCAST_ADDRESS) 00235 { 00236 _rxGood++; 00237 _rxBufValid = true; 00238 } 00239 } 00240 00241 bool RH_NRF51::available() 00242 { 00243 if (!_rxBufValid) 00244 { 00245 if (_mode == RHModeTx) 00246 return false; 00247 setModeRx(); 00248 if (NRF_RADIO->EVENTS_DISABLED == 0U) 00249 return false; // No message yet 00250 if (NRF_RADIO->CRCSTATUS == ((RADIO_CRCSTATUS_CRCSTATUS_CRCError << RADIO_CRCSTATUS_CRCSTATUS_Pos) & RADIO_CRCSTATUS_CRCSTATUS_Msk)) 00251 { 00252 // Bad CRC, restart the radio 00253 _rxBad++; 00254 setModeRx(); 00255 return false; 00256 } 00257 validateRxBuf(); 00258 if (_rxBufValid) 00259 setModeIdle(); // Got one 00260 } 00261 return _rxBufValid; 00262 } 00263 00264 void RH_NRF51::clearRxBuf() 00265 { 00266 _rxBufValid = false; 00267 _buf[0] = 0; 00268 } 00269 00270 bool RH_NRF51::recv(uint8_t* buf, uint8_t* len) 00271 { 00272 if (!available()) 00273 return false; 00274 if (buf && len) 00275 { 00276 // Skip the 4 headers that are at the beginning of the rxBuf 00277 // the payload length is the first octet in _buf 00278 if (*len > _buf[0]-RH_NRF51_HEADER_LEN) 00279 *len = _buf[0]-RH_NRF51_HEADER_LEN; 00280 memcpy(buf, _buf+RH_NRF51_HEADER_LEN+1, *len); 00281 } 00282 clearRxBuf(); // This message accepted and cleared 00283 return true; 00284 } 00285 00286 uint8_t RH_NRF51::maxMessageLength() 00287 { 00288 return RH_NRF51_MAX_MESSAGE_LEN; 00289 } 00290 00291 #endif // NRF51
Generated on Tue Jul 12 2022 20:15:57 by
1.7.2
