Revised to disable BLE for radio communication as needed.

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit

Committer:
tsfarber
Date:
Tue Nov 26 04:12:46 2019 +0000
Revision:
74:26717338739d
Parent:
70:ce33cdf741b5
This program combines samples programs radio TX and radio RX so that both units can send or receive depending on which unit's buttons are pressed. Tested successfully. MicroBitConfig.h has been edited to disable BLE.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 27 #include "MicroBitRadio.h"
Jonathan Austin 1:8aa5cdb4ab67 28 #include "MicroBitComponent.h"
Jonathan Austin 1:8aa5cdb4ab67 29 #include "EventModel.h"
Jonathan Austin 1:8aa5cdb4ab67 30 #include "MicroBitDevice.h"
Jonathan Austin 1:8aa5cdb4ab67 31 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 32 #include "MicroBitFiber.h"
Jonathan Austin 1:8aa5cdb4ab67 33 #include "MicroBitBLEManager.h"
Jonathan Austin 1:8aa5cdb4ab67 34
Jonathan Austin 1:8aa5cdb4ab67 35 /**
Jonathan Austin 1:8aa5cdb4ab67 36 * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
Jonathan Austin 1:8aa5cdb4ab67 37 *
Jonathan Austin 1:8aa5cdb4ab67 38 * The nrf51822 RADIO module supports a number of proprietary modes of operation oher than the typical BLE usage.
Jonathan Austin 1:8aa5cdb4ab67 39 * This class uses one of these modes to enable simple, point to multipoint communication directly between micro:bits.
Jonathan Austin 1:8aa5cdb4ab67 40 *
Jonathan Austin 1:8aa5cdb4ab67 41 * TODO: The protocols implemented here do not currently perform any significant form of energy management,
Jonathan Austin 1:8aa5cdb4ab67 42 * which means that they will consume far more energy than their BLE equivalent. Later versions of the protocol
Jonathan Austin 1:8aa5cdb4ab67 43 * should look to address this through energy efficient broadcast techbiques / sleep scheduling. In particular, the GLOSSY
Jonathan Austin 1:8aa5cdb4ab67 44 * approach to efficient rebroadcast and network synchronisation would likely provide an effective future step.
Jonathan Austin 1:8aa5cdb4ab67 45 *
Jonathan Austin 1:8aa5cdb4ab67 46 * TODO: Meshing should also be considered - again a GLOSSY approach may be effective here, and highly complementary to
Jonathan Austin 1:8aa5cdb4ab67 47 * the master/slave arachitecture of BLE.
Jonathan Austin 1:8aa5cdb4ab67 48 *
Jonathan Austin 1:8aa5cdb4ab67 49 * TODO: This implementation may only operated whilst the BLE stack is disabled. The nrf51822 provides a timeslot API to allow
Jonathan Austin 1:8aa5cdb4ab67 50 * BLE to cohabit with other protocols. Future work to allow this colocation would be benefical, and would also allow for the
Jonathan Austin 1:8aa5cdb4ab67 51 * creation of wireless BLE bridges.
Jonathan Austin 1:8aa5cdb4ab67 52 *
Jonathan Austin 1:8aa5cdb4ab67 53 * NOTE: This API does not contain any form of encryption, authentication or authorisation. Its purpose is solely for use as a
Jonathan Austin 1:8aa5cdb4ab67 54 * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
Jonathan Austin 1:8aa5cdb4ab67 55 * For serious applications, BLE should be considered a substantially more secure alternative.
Jonathan Austin 1:8aa5cdb4ab67 56 */
Jonathan Austin 1:8aa5cdb4ab67 57
Jonathan Austin 1:8aa5cdb4ab67 58 MicroBitRadio* MicroBitRadio::instance = NULL;
Jonathan Austin 1:8aa5cdb4ab67 59
Jonathan Austin 1:8aa5cdb4ab67 60 extern "C" void RADIO_IRQHandler(void)
Jonathan Austin 1:8aa5cdb4ab67 61 {
Jonathan Austin 1:8aa5cdb4ab67 62 if(NRF_RADIO->EVENTS_READY)
Jonathan Austin 1:8aa5cdb4ab67 63 {
Jonathan Austin 1:8aa5cdb4ab67 64 NRF_RADIO->EVENTS_READY = 0;
Jonathan Austin 1:8aa5cdb4ab67 65
Jonathan Austin 1:8aa5cdb4ab67 66 // Start listening and wait for the END event
Jonathan Austin 1:8aa5cdb4ab67 67 NRF_RADIO->TASKS_START = 1;
Jonathan Austin 1:8aa5cdb4ab67 68 }
Jonathan Austin 1:8aa5cdb4ab67 69
Jonathan Austin 1:8aa5cdb4ab67 70 if(NRF_RADIO->EVENTS_END)
Jonathan Austin 1:8aa5cdb4ab67 71 {
Jonathan Austin 1:8aa5cdb4ab67 72 NRF_RADIO->EVENTS_END = 0;
Jonathan Austin 1:8aa5cdb4ab67 73 if(NRF_RADIO->CRCSTATUS == 1)
Jonathan Austin 1:8aa5cdb4ab67 74 {
Jonathan Austin 1:8aa5cdb4ab67 75 uint8_t sample = NRF_RADIO->RSSISAMPLE;
Jonathan Austin 1:8aa5cdb4ab67 76
LancasterUniversity 69:b62f231e51ce 77 // Associate this packet's rssi value with the data just
LancasterUniversity 66:2fc7d7c2fffc 78 // transferred by DMA receive
Jonathan Austin 1:8aa5cdb4ab67 79 MicroBitRadio::instance->setRSSI(sample);
LancasterUniversity 66:2fc7d7c2fffc 80
LancasterUniversity 66:2fc7d7c2fffc 81 // Now move on to the next buffer, if possible.
LancasterUniversity 66:2fc7d7c2fffc 82 // The queued packet will get the rssi value set above.
LancasterUniversity 66:2fc7d7c2fffc 83 MicroBitRadio::instance->queueRxBuf();
LancasterUniversity 66:2fc7d7c2fffc 84
LancasterUniversity 66:2fc7d7c2fffc 85 // Set the new buffer for DMA
LancasterUniversity 66:2fc7d7c2fffc 86 NRF_RADIO->PACKETPTR = (uint32_t) MicroBitRadio::instance->getRxBuf();
LancasterUniversity 66:2fc7d7c2fffc 87 }
LancasterUniversity 66:2fc7d7c2fffc 88 else
LancasterUniversity 66:2fc7d7c2fffc 89 {
LancasterUniversity 66:2fc7d7c2fffc 90 MicroBitRadio::instance->setRSSI(0);
Jonathan Austin 1:8aa5cdb4ab67 91 }
Jonathan Austin 1:8aa5cdb4ab67 92
Jonathan Austin 1:8aa5cdb4ab67 93 // Start listening and wait for the END event
Jonathan Austin 1:8aa5cdb4ab67 94 NRF_RADIO->TASKS_START = 1;
Jonathan Austin 1:8aa5cdb4ab67 95 }
Jonathan Austin 1:8aa5cdb4ab67 96 }
Jonathan Austin 1:8aa5cdb4ab67 97
Jonathan Austin 1:8aa5cdb4ab67 98 /**
Jonathan Austin 1:8aa5cdb4ab67 99 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 100 *
Jonathan Austin 1:8aa5cdb4ab67 101 * Initialise the MicroBitRadio.
Jonathan Austin 1:8aa5cdb4ab67 102 *
Jonathan Austin 1:8aa5cdb4ab67 103 * @note This class is demand activated, as a result most resources are only
Jonathan Austin 1:8aa5cdb4ab67 104 * committed if send/recv or event registrations calls are made.
Jonathan Austin 1:8aa5cdb4ab67 105 */
Jonathan Austin 1:8aa5cdb4ab67 106 MicroBitRadio::MicroBitRadio(uint16_t id) : datagram(*this), event (*this)
Jonathan Austin 1:8aa5cdb4ab67 107 {
Jonathan Austin 1:8aa5cdb4ab67 108 this->id = id;
Jonathan Austin 1:8aa5cdb4ab67 109 this->status = 0;
LancasterUniversity 25:27299423d813 110 this->group = MICROBIT_RADIO_DEFAULT_GROUP;
Jonathan Austin 1:8aa5cdb4ab67 111 this->queueDepth = 0;
Jonathan Austin 1:8aa5cdb4ab67 112 this->rssi = 0;
Jonathan Austin 1:8aa5cdb4ab67 113 this->rxQueue = NULL;
Jonathan Austin 1:8aa5cdb4ab67 114 this->rxBuf = NULL;
Jonathan Austin 1:8aa5cdb4ab67 115
Jonathan Austin 1:8aa5cdb4ab67 116 instance = this;
Jonathan Austin 1:8aa5cdb4ab67 117 }
Jonathan Austin 1:8aa5cdb4ab67 118
Jonathan Austin 1:8aa5cdb4ab67 119 /**
Jonathan Austin 1:8aa5cdb4ab67 120 * Change the output power level of the transmitter to the given value.
Jonathan Austin 1:8aa5cdb4ab67 121 *
Jonathan Austin 1:8aa5cdb4ab67 122 * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest.
Jonathan Austin 1:8aa5cdb4ab67 123 *
Jonathan Austin 1:8aa5cdb4ab67 124 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range.
Jonathan Austin 1:8aa5cdb4ab67 125 */
Jonathan Austin 1:8aa5cdb4ab67 126 int MicroBitRadio::setTransmitPower(int power)
Jonathan Austin 1:8aa5cdb4ab67 127 {
Jonathan Austin 1:8aa5cdb4ab67 128 if (power < 0 || power >= MICROBIT_BLE_POWER_LEVELS)
Jonathan Austin 1:8aa5cdb4ab67 129 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 130
Jonathan Austin 1:8aa5cdb4ab67 131 NRF_RADIO->TXPOWER = (uint32_t)MICROBIT_BLE_POWER_LEVEL[power];
Jonathan Austin 1:8aa5cdb4ab67 132
Jonathan Austin 1:8aa5cdb4ab67 133 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 134 }
Jonathan Austin 1:8aa5cdb4ab67 135
Jonathan Austin 1:8aa5cdb4ab67 136 /**
Jonathan Austin 1:8aa5cdb4ab67 137 * Change the transmission and reception band of the radio to the given channel
Jonathan Austin 1:8aa5cdb4ab67 138 *
Jonathan Austin 1:8aa5cdb4ab67 139 * @param band a frequency band in the range 0 - 100. Each step is 1MHz wide, based at 2400MHz.
Jonathan Austin 1:8aa5cdb4ab67 140 *
Jonathan Austin 1:8aa5cdb4ab67 141 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range,
Jonathan Austin 1:8aa5cdb4ab67 142 * or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 143 */
Jonathan Austin 1:8aa5cdb4ab67 144 int MicroBitRadio::setFrequencyBand(int band)
Jonathan Austin 1:8aa5cdb4ab67 145 {
Jonathan Austin 1:8aa5cdb4ab67 146 if (ble_running())
Jonathan Austin 1:8aa5cdb4ab67 147 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 148
Jonathan Austin 1:8aa5cdb4ab67 149 if (band < 0 || band > 100)
Jonathan Austin 1:8aa5cdb4ab67 150 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 151
Jonathan Austin 1:8aa5cdb4ab67 152 NRF_RADIO->FREQUENCY = (uint32_t)band;
Jonathan Austin 1:8aa5cdb4ab67 153
Jonathan Austin 1:8aa5cdb4ab67 154 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 155 }
Jonathan Austin 1:8aa5cdb4ab67 156
Jonathan Austin 1:8aa5cdb4ab67 157 /**
Jonathan Austin 1:8aa5cdb4ab67 158 * Retrieve a pointer to the currently allocated receive buffer. This is the area of memory
Jonathan Austin 1:8aa5cdb4ab67 159 * actively being used by the radio hardware to store incoming data.
Jonathan Austin 1:8aa5cdb4ab67 160 *
Jonathan Austin 1:8aa5cdb4ab67 161 * @return a pointer to the current receive buffer.
Jonathan Austin 1:8aa5cdb4ab67 162 */
Jonathan Austin 1:8aa5cdb4ab67 163 FrameBuffer* MicroBitRadio::getRxBuf()
Jonathan Austin 1:8aa5cdb4ab67 164 {
Jonathan Austin 1:8aa5cdb4ab67 165 return rxBuf;
Jonathan Austin 1:8aa5cdb4ab67 166 }
Jonathan Austin 1:8aa5cdb4ab67 167
Jonathan Austin 1:8aa5cdb4ab67 168 /**
Jonathan Austin 1:8aa5cdb4ab67 169 * Attempt to queue a buffer received by the radio hardware, if sufficient space is available.
Jonathan Austin 1:8aa5cdb4ab67 170 *
Jonathan Austin 1:8aa5cdb4ab67 171 * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if a replacement receiver buffer
Jonathan Austin 1:8aa5cdb4ab67 172 * could not be allocated (either by policy or memory exhaustion).
Jonathan Austin 1:8aa5cdb4ab67 173 */
Jonathan Austin 1:8aa5cdb4ab67 174 int MicroBitRadio::queueRxBuf()
Jonathan Austin 1:8aa5cdb4ab67 175 {
Jonathan Austin 1:8aa5cdb4ab67 176 if (rxBuf == NULL)
Jonathan Austin 1:8aa5cdb4ab67 177 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 178
Jonathan Austin 1:8aa5cdb4ab67 179 if (queueDepth >= MICROBIT_RADIO_MAXIMUM_RX_BUFFERS)
Jonathan Austin 1:8aa5cdb4ab67 180 return MICROBIT_NO_RESOURCES;
Jonathan Austin 1:8aa5cdb4ab67 181
Jonathan Austin 1:8aa5cdb4ab67 182 // Store the received RSSI value in the frame
Jonathan Austin 1:8aa5cdb4ab67 183 rxBuf->rssi = getRSSI();
Jonathan Austin 1:8aa5cdb4ab67 184
Jonathan Austin 1:8aa5cdb4ab67 185 // Ensure that a replacement buffer is available before queuing.
Jonathan Austin 1:8aa5cdb4ab67 186 FrameBuffer *newRxBuf = new FrameBuffer();
Jonathan Austin 1:8aa5cdb4ab67 187
Jonathan Austin 1:8aa5cdb4ab67 188 if (newRxBuf == NULL)
Jonathan Austin 1:8aa5cdb4ab67 189 return MICROBIT_NO_RESOURCES;
Jonathan Austin 1:8aa5cdb4ab67 190
Jonathan Austin 1:8aa5cdb4ab67 191 // We add to the tail of the queue to preserve causal ordering.
Jonathan Austin 1:8aa5cdb4ab67 192 rxBuf->next = NULL;
Jonathan Austin 1:8aa5cdb4ab67 193
Jonathan Austin 1:8aa5cdb4ab67 194 if (rxQueue == NULL)
Jonathan Austin 1:8aa5cdb4ab67 195 {
Jonathan Austin 1:8aa5cdb4ab67 196 rxQueue = rxBuf;
Jonathan Austin 1:8aa5cdb4ab67 197 }
Jonathan Austin 1:8aa5cdb4ab67 198 else
Jonathan Austin 1:8aa5cdb4ab67 199 {
Jonathan Austin 1:8aa5cdb4ab67 200 FrameBuffer *p = rxQueue;
Jonathan Austin 1:8aa5cdb4ab67 201 while (p->next != NULL)
Jonathan Austin 1:8aa5cdb4ab67 202 p = p->next;
Jonathan Austin 1:8aa5cdb4ab67 203
Jonathan Austin 1:8aa5cdb4ab67 204 p->next = rxBuf;
Jonathan Austin 1:8aa5cdb4ab67 205 }
Jonathan Austin 1:8aa5cdb4ab67 206
Jonathan Austin 1:8aa5cdb4ab67 207 // Increase our received packet count
Jonathan Austin 1:8aa5cdb4ab67 208 queueDepth++;
Jonathan Austin 1:8aa5cdb4ab67 209
Jonathan Austin 1:8aa5cdb4ab67 210 // Allocate a new buffer for the receiver hardware to use. the old on will be passed on to higher layer protocols/apps.
Jonathan Austin 1:8aa5cdb4ab67 211 rxBuf = newRxBuf;
Jonathan Austin 1:8aa5cdb4ab67 212
Jonathan Austin 1:8aa5cdb4ab67 213 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 214 }
Jonathan Austin 1:8aa5cdb4ab67 215
Jonathan Austin 1:8aa5cdb4ab67 216 /**
Jonathan Austin 1:8aa5cdb4ab67 217 * Sets the RSSI for the most recent packet.
Jonathan Austin 1:8aa5cdb4ab67 218 *
Jonathan Austin 1:8aa5cdb4ab67 219 * @param rssi the new rssi value.
Jonathan Austin 1:8aa5cdb4ab67 220 *
Jonathan Austin 1:8aa5cdb4ab67 221 * @note should only be called from RADIO_IRQHandler...
Jonathan Austin 1:8aa5cdb4ab67 222 */
Jonathan Austin 1:8aa5cdb4ab67 223 int MicroBitRadio::setRSSI(uint8_t rssi)
Jonathan Austin 1:8aa5cdb4ab67 224 {
Jonathan Austin 1:8aa5cdb4ab67 225 if (!(status & MICROBIT_RADIO_STATUS_INITIALISED))
Jonathan Austin 1:8aa5cdb4ab67 226 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 227
Jonathan Austin 1:8aa5cdb4ab67 228 this->rssi = rssi;
Jonathan Austin 1:8aa5cdb4ab67 229
Jonathan Austin 1:8aa5cdb4ab67 230 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 231 }
Jonathan Austin 1:8aa5cdb4ab67 232
Jonathan Austin 1:8aa5cdb4ab67 233 /**
Jonathan Austin 1:8aa5cdb4ab67 234 * Retrieves the current RSSI for the most recent packet.
Jonathan Austin 1:8aa5cdb4ab67 235 *
Jonathan Austin 1:8aa5cdb4ab67 236 * @return the most recent RSSI value or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 237 */
Jonathan Austin 1:8aa5cdb4ab67 238 int MicroBitRadio::getRSSI()
Jonathan Austin 1:8aa5cdb4ab67 239 {
Jonathan Austin 1:8aa5cdb4ab67 240 if (!(status & MICROBIT_RADIO_STATUS_INITIALISED))
Jonathan Austin 1:8aa5cdb4ab67 241 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 242
Jonathan Austin 1:8aa5cdb4ab67 243 return this->rssi;
Jonathan Austin 1:8aa5cdb4ab67 244 }
Jonathan Austin 1:8aa5cdb4ab67 245
Jonathan Austin 1:8aa5cdb4ab67 246 /**
Jonathan Austin 1:8aa5cdb4ab67 247 * Initialises the radio for use as a multipoint sender/receiver
Jonathan Austin 1:8aa5cdb4ab67 248 *
Jonathan Austin 1:8aa5cdb4ab67 249 * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 250 */
Jonathan Austin 1:8aa5cdb4ab67 251 int MicroBitRadio::enable()
Jonathan Austin 1:8aa5cdb4ab67 252 {
Jonathan Austin 1:8aa5cdb4ab67 253 // If the device is already initialised, then there's nothing to do.
Jonathan Austin 1:8aa5cdb4ab67 254 if (status & MICROBIT_RADIO_STATUS_INITIALISED)
Jonathan Austin 1:8aa5cdb4ab67 255 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 256
Jonathan Austin 1:8aa5cdb4ab67 257 // Only attempt to enable this radio mode if BLE is disabled.
Jonathan Austin 1:8aa5cdb4ab67 258 if (ble_running())
Jonathan Austin 1:8aa5cdb4ab67 259 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 260
Jonathan Austin 1:8aa5cdb4ab67 261 // If this is the first time we've been enable, allocate out receive buffers.
Jonathan Austin 1:8aa5cdb4ab67 262 if (rxBuf == NULL)
Jonathan Austin 1:8aa5cdb4ab67 263 rxBuf = new FrameBuffer();
Jonathan Austin 1:8aa5cdb4ab67 264
Jonathan Austin 1:8aa5cdb4ab67 265 if (rxBuf == NULL)
Jonathan Austin 1:8aa5cdb4ab67 266 return MICROBIT_NO_RESOURCES;
Jonathan Austin 1:8aa5cdb4ab67 267
Jonathan Austin 1:8aa5cdb4ab67 268 // Enable the High Frequency clock on the processor. This is a pre-requisite for
Jonathan Austin 1:8aa5cdb4ab67 269 // the RADIO module. Without this clock, no communication is possible.
Jonathan Austin 1:8aa5cdb4ab67 270 NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
Jonathan Austin 1:8aa5cdb4ab67 271 NRF_CLOCK->TASKS_HFCLKSTART = 1;
Jonathan Austin 1:8aa5cdb4ab67 272 while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
Jonathan Austin 1:8aa5cdb4ab67 273
Jonathan Austin 1:8aa5cdb4ab67 274 // Bring up the nrf51822 RADIO module in Nordic's proprietary 1MBps packet radio mode.
Jonathan Austin 1:8aa5cdb4ab67 275 setTransmitPower(MICROBIT_RADIO_DEFAULT_TX_POWER);
Jonathan Austin 1:8aa5cdb4ab67 276 setFrequencyBand(MICROBIT_RADIO_DEFAULT_FREQUENCY);
Jonathan Austin 1:8aa5cdb4ab67 277
Jonathan Austin 1:8aa5cdb4ab67 278 // Configure for 1Mbps throughput.
Jonathan Austin 1:8aa5cdb4ab67 279 // This may sound excessive, but running a high data rates reduces the chances of collisions...
Jonathan Austin 1:8aa5cdb4ab67 280 NRF_RADIO->MODE = RADIO_MODE_MODE_Nrf_1Mbit;
Jonathan Austin 1:8aa5cdb4ab67 281
Jonathan Austin 1:8aa5cdb4ab67 282 // Configure the addresses we use for this protocol. We run ANONYMOUSLY at the core.
Jonathan Austin 1:8aa5cdb4ab67 283 // A 40 bit addresses is used. The first 32 bits match the ASCII character code for "uBit".
Jonathan Austin 1:8aa5cdb4ab67 284 // Statistically, this provides assurance to avoid other similar 2.4GHz protocols that may be in the vicinity.
Jonathan Austin 1:8aa5cdb4ab67 285 // We also map the assigned 8-bit GROUP id into the PREFIX field. This allows the RADIO hardware to perform
Jonathan Austin 1:8aa5cdb4ab67 286 // address matching for us, and only generate an interrupt when a packet matching our group is received.
Jonathan Austin 1:8aa5cdb4ab67 287 NRF_RADIO->BASE0 = MICROBIT_RADIO_BASE_ADDRESS;
Jonathan Austin 1:8aa5cdb4ab67 288
Jonathan Austin 1:8aa5cdb4ab67 289 // Join the default group. This will configure the remaining byte in the RADIO hardware module.
LancasterUniversity 25:27299423d813 290 setGroup(this->group);
Jonathan Austin 1:8aa5cdb4ab67 291
Jonathan Austin 1:8aa5cdb4ab67 292 // The RADIO hardware module supports the use of multiple addresses, but as we're running anonymously, we only need one.
Jonathan Austin 1:8aa5cdb4ab67 293 // Configure the RADIO module to use the default address (address 0) for both send and receive operations.
Jonathan Austin 1:8aa5cdb4ab67 294 NRF_RADIO->TXADDRESS = 0;
Jonathan Austin 1:8aa5cdb4ab67 295 NRF_RADIO->RXADDRESSES = 1;
Jonathan Austin 1:8aa5cdb4ab67 296
Jonathan Austin 1:8aa5cdb4ab67 297 // Packet layout configuration. The nrf51822 has a highly capable and flexible RADIO module that, in addition to transmission
Jonathan Austin 1:8aa5cdb4ab67 298 // and reception of data, also contains a LENGTH field, two optional additional 1 byte fields (S0 and S1) and a CRC calculation.
Jonathan Austin 1:8aa5cdb4ab67 299 // Configure the packet format for a simple 8 bit length field and no additional fields.
Jonathan Austin 1:8aa5cdb4ab67 300 NRF_RADIO->PCNF0 = 0x00000008;
Jonathan Austin 1:8aa5cdb4ab67 301 NRF_RADIO->PCNF1 = 0x02040000 | MICROBIT_RADIO_MAX_PACKET_SIZE;
Jonathan Austin 1:8aa5cdb4ab67 302
Jonathan Austin 1:8aa5cdb4ab67 303 // Most communication channels contain some form of checksum - a mathematical calculation taken based on all the data
Jonathan Austin 1:8aa5cdb4ab67 304 // in a packet, that is also sent as part of the packet. When received, this calculation can be repeated, and the results
Jonathan Austin 1:8aa5cdb4ab67 305 // from the sender and receiver compared. If they are different, then some corruption of the data ahas happened in transit,
Jonathan Austin 1:8aa5cdb4ab67 306 // and we know we can't trust it. The nrf51822 RADIO uses a CRC for this - a very effective checksum calculation.
Jonathan Austin 1:8aa5cdb4ab67 307 //
Jonathan Austin 1:8aa5cdb4ab67 308 // Enable automatic 16bit CRC generation and checking, and configure how the CRC is calculated.
Jonathan Austin 1:8aa5cdb4ab67 309 NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_Two;
Jonathan Austin 1:8aa5cdb4ab67 310 NRF_RADIO->CRCINIT = 0xFFFF;
Jonathan Austin 1:8aa5cdb4ab67 311 NRF_RADIO->CRCPOLY = 0x11021;
Jonathan Austin 1:8aa5cdb4ab67 312
Jonathan Austin 1:8aa5cdb4ab67 313 // Set the start random value of the data whitening algorithm. This can be any non zero number.
Jonathan Austin 1:8aa5cdb4ab67 314 NRF_RADIO->DATAWHITEIV = 0x18;
Jonathan Austin 1:8aa5cdb4ab67 315
Jonathan Austin 1:8aa5cdb4ab67 316 // Set up the RADIO module to read and write from our internal buffer.
Jonathan Austin 1:8aa5cdb4ab67 317 NRF_RADIO->PACKETPTR = (uint32_t)rxBuf;
Jonathan Austin 1:8aa5cdb4ab67 318
Jonathan Austin 1:8aa5cdb4ab67 319 // Configure the hardware to issue an interrupt whenever a task is complete (e.g. send/receive).
Jonathan Austin 1:8aa5cdb4ab67 320 NRF_RADIO->INTENSET = 0x00000008;
Jonathan Austin 1:8aa5cdb4ab67 321 NVIC_ClearPendingIRQ(RADIO_IRQn);
Jonathan Austin 1:8aa5cdb4ab67 322 NVIC_EnableIRQ(RADIO_IRQn);
Jonathan Austin 1:8aa5cdb4ab67 323
Jonathan Austin 1:8aa5cdb4ab67 324 NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_RSSISTART_Msk;
Jonathan Austin 1:8aa5cdb4ab67 325
Jonathan Austin 1:8aa5cdb4ab67 326 // Start listening for the next packet
Jonathan Austin 1:8aa5cdb4ab67 327 NRF_RADIO->EVENTS_READY = 0;
Jonathan Austin 1:8aa5cdb4ab67 328 NRF_RADIO->TASKS_RXEN = 1;
Jonathan Austin 1:8aa5cdb4ab67 329 while(NRF_RADIO->EVENTS_READY == 0);
Jonathan Austin 1:8aa5cdb4ab67 330
Jonathan Austin 1:8aa5cdb4ab67 331 NRF_RADIO->EVENTS_END = 0;
Jonathan Austin 1:8aa5cdb4ab67 332 NRF_RADIO->TASKS_START = 1;
Jonathan Austin 1:8aa5cdb4ab67 333
Jonathan Austin 1:8aa5cdb4ab67 334 // register ourselves for a callback event, in order to empty the receive queue.
Jonathan Austin 1:8aa5cdb4ab67 335 fiber_add_idle_component(this);
Jonathan Austin 1:8aa5cdb4ab67 336
Jonathan Austin 1:8aa5cdb4ab67 337 // Done. Record that our RADIO is configured.
Jonathan Austin 1:8aa5cdb4ab67 338 status |= MICROBIT_RADIO_STATUS_INITIALISED;
Jonathan Austin 1:8aa5cdb4ab67 339
Jonathan Austin 1:8aa5cdb4ab67 340 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 341 }
Jonathan Austin 1:8aa5cdb4ab67 342
Jonathan Austin 1:8aa5cdb4ab67 343 /**
Jonathan Austin 1:8aa5cdb4ab67 344 * Disables the radio for use as a multipoint sender/receiver.
Jonathan Austin 1:8aa5cdb4ab67 345 *
Jonathan Austin 1:8aa5cdb4ab67 346 * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 347 */
Jonathan Austin 1:8aa5cdb4ab67 348 int MicroBitRadio::disable()
Jonathan Austin 1:8aa5cdb4ab67 349 {
Jonathan Austin 1:8aa5cdb4ab67 350 // Only attempt to enable.disable the radio if the protocol is alreayd running.
Jonathan Austin 1:8aa5cdb4ab67 351 if (ble_running())
Jonathan Austin 1:8aa5cdb4ab67 352 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 353
Jonathan Austin 1:8aa5cdb4ab67 354 if (!(status & MICROBIT_RADIO_STATUS_INITIALISED))
Jonathan Austin 1:8aa5cdb4ab67 355 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 356
Jonathan Austin 1:8aa5cdb4ab67 357 // Disable interrupts and STOP any ongoing packet reception.
Jonathan Austin 1:8aa5cdb4ab67 358 NVIC_DisableIRQ(RADIO_IRQn);
Jonathan Austin 1:8aa5cdb4ab67 359
Jonathan Austin 1:8aa5cdb4ab67 360 NRF_RADIO->EVENTS_DISABLED = 0;
Jonathan Austin 1:8aa5cdb4ab67 361 NRF_RADIO->TASKS_DISABLE = 1;
Jonathan Austin 1:8aa5cdb4ab67 362 while(NRF_RADIO->EVENTS_DISABLED == 0);
Jonathan Austin 1:8aa5cdb4ab67 363
Jonathan Austin 1:8aa5cdb4ab67 364 // deregister ourselves from the callback event used to empty the receive queue.
Jonathan Austin 1:8aa5cdb4ab67 365 fiber_remove_idle_component(this);
Jonathan Austin 1:8aa5cdb4ab67 366
LancasterUniversity 25:27299423d813 367 // record that the radio is now disabled
LancasterUniversity 25:27299423d813 368 status &= ~MICROBIT_RADIO_STATUS_INITIALISED;
LancasterUniversity 25:27299423d813 369
Jonathan Austin 1:8aa5cdb4ab67 370 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 371 }
Jonathan Austin 1:8aa5cdb4ab67 372
Jonathan Austin 1:8aa5cdb4ab67 373 /**
Jonathan Austin 1:8aa5cdb4ab67 374 * Sets the radio to listen to packets sent with the given group id.
Jonathan Austin 1:8aa5cdb4ab67 375 *
Jonathan Austin 1:8aa5cdb4ab67 376 * @param group The group to join. A micro:bit can only listen to one group ID at any time.
Jonathan Austin 1:8aa5cdb4ab67 377 *
Jonathan Austin 1:8aa5cdb4ab67 378 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 379 */
Jonathan Austin 1:8aa5cdb4ab67 380 int MicroBitRadio::setGroup(uint8_t group)
Jonathan Austin 1:8aa5cdb4ab67 381 {
Jonathan Austin 1:8aa5cdb4ab67 382 if (ble_running())
Jonathan Austin 1:8aa5cdb4ab67 383 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 384
Jonathan Austin 1:8aa5cdb4ab67 385 // Record our group id locally
Jonathan Austin 1:8aa5cdb4ab67 386 this->group = group;
Jonathan Austin 1:8aa5cdb4ab67 387
Jonathan Austin 1:8aa5cdb4ab67 388 // Also append it to the address of this device, to allow the RADIO module to filter for us.
Jonathan Austin 1:8aa5cdb4ab67 389 NRF_RADIO->PREFIX0 = (uint32_t)group;
Jonathan Austin 1:8aa5cdb4ab67 390
Jonathan Austin 1:8aa5cdb4ab67 391 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 392 }
Jonathan Austin 1:8aa5cdb4ab67 393
Jonathan Austin 1:8aa5cdb4ab67 394 /**
Jonathan Austin 1:8aa5cdb4ab67 395 * A background, low priority callback that is triggered whenever the processor is idle.
Jonathan Austin 1:8aa5cdb4ab67 396 * Here, we empty our queue of received packets, and pass them onto higher level protocol handlers.
Jonathan Austin 1:8aa5cdb4ab67 397 */
Jonathan Austin 1:8aa5cdb4ab67 398 void MicroBitRadio::idleTick()
Jonathan Austin 1:8aa5cdb4ab67 399 {
Jonathan Austin 1:8aa5cdb4ab67 400 // Walk the list of packets and process each one.
Jonathan Austin 1:8aa5cdb4ab67 401 while(rxQueue)
Jonathan Austin 1:8aa5cdb4ab67 402 {
Jonathan Austin 1:8aa5cdb4ab67 403 FrameBuffer *p = rxQueue;
Jonathan Austin 1:8aa5cdb4ab67 404
Jonathan Austin 1:8aa5cdb4ab67 405 switch (p->protocol)
Jonathan Austin 1:8aa5cdb4ab67 406 {
Jonathan Austin 1:8aa5cdb4ab67 407 case MICROBIT_RADIO_PROTOCOL_DATAGRAM:
Jonathan Austin 1:8aa5cdb4ab67 408 datagram.packetReceived();
Jonathan Austin 1:8aa5cdb4ab67 409 break;
Jonathan Austin 1:8aa5cdb4ab67 410
Jonathan Austin 1:8aa5cdb4ab67 411 case MICROBIT_RADIO_PROTOCOL_EVENTBUS:
Jonathan Austin 1:8aa5cdb4ab67 412 event.packetReceived();
Jonathan Austin 1:8aa5cdb4ab67 413 break;
Jonathan Austin 1:8aa5cdb4ab67 414
Jonathan Austin 1:8aa5cdb4ab67 415 default:
Jonathan Austin 1:8aa5cdb4ab67 416 MicroBitEvent(MICROBIT_ID_RADIO_DATA_READY, p->protocol);
Jonathan Austin 1:8aa5cdb4ab67 417 }
Jonathan Austin 1:8aa5cdb4ab67 418
Jonathan Austin 1:8aa5cdb4ab67 419 // If the packet was processed, it will have been recv'd, and taken from the queue.
Jonathan Austin 1:8aa5cdb4ab67 420 // If this was a packet for an unknown protocol, it will still be there, so simply free it.
Jonathan Austin 1:8aa5cdb4ab67 421 if (p == rxQueue)
Jonathan Austin 1:8aa5cdb4ab67 422 {
Jonathan Austin 1:8aa5cdb4ab67 423 recv();
Jonathan Austin 1:8aa5cdb4ab67 424 delete p;
Jonathan Austin 1:8aa5cdb4ab67 425 }
Jonathan Austin 1:8aa5cdb4ab67 426 }
Jonathan Austin 1:8aa5cdb4ab67 427 }
Jonathan Austin 1:8aa5cdb4ab67 428
Jonathan Austin 1:8aa5cdb4ab67 429 /**
Jonathan Austin 1:8aa5cdb4ab67 430 * Determines the number of packets ready to be processed.
Jonathan Austin 1:8aa5cdb4ab67 431 *
Jonathan Austin 1:8aa5cdb4ab67 432 * @return The number of packets in the receive buffer.
Jonathan Austin 1:8aa5cdb4ab67 433 */
Jonathan Austin 1:8aa5cdb4ab67 434 int MicroBitRadio::dataReady()
Jonathan Austin 1:8aa5cdb4ab67 435 {
Jonathan Austin 1:8aa5cdb4ab67 436 return queueDepth;
Jonathan Austin 1:8aa5cdb4ab67 437 }
Jonathan Austin 1:8aa5cdb4ab67 438
Jonathan Austin 1:8aa5cdb4ab67 439 /**
Jonathan Austin 1:8aa5cdb4ab67 440 * Retrieves the next packet from the receive buffer.
Jonathan Austin 1:8aa5cdb4ab67 441 * If a data packet is available, then it will be returned immediately to
Jonathan Austin 1:8aa5cdb4ab67 442 * the caller. This call will also dequeue the buffer.
Jonathan Austin 1:8aa5cdb4ab67 443 *
Jonathan Austin 1:8aa5cdb4ab67 444 * @return The buffer containing the the packet. If no data is available, NULL is returned.
Jonathan Austin 1:8aa5cdb4ab67 445 *
LancasterUniversity 69:b62f231e51ce 446 * @note Once recv() has been called, it is the callers responsibility to
Jonathan Austin 1:8aa5cdb4ab67 447 * delete the buffer when appropriate.
Jonathan Austin 1:8aa5cdb4ab67 448 */
Jonathan Austin 1:8aa5cdb4ab67 449 FrameBuffer* MicroBitRadio::recv()
Jonathan Austin 1:8aa5cdb4ab67 450 {
Jonathan Austin 1:8aa5cdb4ab67 451 FrameBuffer *p = rxQueue;
Jonathan Austin 1:8aa5cdb4ab67 452
Jonathan Austin 1:8aa5cdb4ab67 453 if (p)
Jonathan Austin 1:8aa5cdb4ab67 454 {
LancasterUniversity 70:ce33cdf741b5 455 // Protect shared resource from ISR activity
LancasterUniversity 70:ce33cdf741b5 456 NVIC_DisableIRQ(RADIO_IRQn);
LancasterUniversity 70:ce33cdf741b5 457
Jonathan Austin 1:8aa5cdb4ab67 458 rxQueue = rxQueue->next;
Jonathan Austin 1:8aa5cdb4ab67 459 queueDepth--;
LancasterUniversity 70:ce33cdf741b5 460
LancasterUniversity 70:ce33cdf741b5 461 // Allow ISR access to shared resource
LancasterUniversity 70:ce33cdf741b5 462 NVIC_EnableIRQ(RADIO_IRQn);
Jonathan Austin 1:8aa5cdb4ab67 463 }
Jonathan Austin 1:8aa5cdb4ab67 464
Jonathan Austin 1:8aa5cdb4ab67 465 return p;
Jonathan Austin 1:8aa5cdb4ab67 466 }
Jonathan Austin 1:8aa5cdb4ab67 467
Jonathan Austin 1:8aa5cdb4ab67 468 /**
Jonathan Austin 1:8aa5cdb4ab67 469 * Transmits the given buffer onto the broadcast radio.
Jonathan Austin 1:8aa5cdb4ab67 470 * The call will wait until the transmission of the packet has completed before returning.
Jonathan Austin 1:8aa5cdb4ab67 471 *
Jonathan Austin 1:8aa5cdb4ab67 472 * @param data The packet contents to transmit.
Jonathan Austin 1:8aa5cdb4ab67 473 *
Jonathan Austin 1:8aa5cdb4ab67 474 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 475 */
Jonathan Austin 1:8aa5cdb4ab67 476 int MicroBitRadio::send(FrameBuffer *buffer)
Jonathan Austin 1:8aa5cdb4ab67 477 {
Jonathan Austin 1:8aa5cdb4ab67 478 if (ble_running())
Jonathan Austin 1:8aa5cdb4ab67 479 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 480
Jonathan Austin 1:8aa5cdb4ab67 481 if (buffer == NULL)
Jonathan Austin 1:8aa5cdb4ab67 482 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 483
Jonathan Austin 1:8aa5cdb4ab67 484 if (buffer->length > MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE - 1)
Jonathan Austin 1:8aa5cdb4ab67 485 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 486
Jonathan Austin 1:8aa5cdb4ab67 487 // Firstly, disable the Radio interrupt. We want to wait until the trasmission completes.
Jonathan Austin 1:8aa5cdb4ab67 488 NVIC_DisableIRQ(RADIO_IRQn);
Jonathan Austin 1:8aa5cdb4ab67 489
Jonathan Austin 1:8aa5cdb4ab67 490 // Turn off the transceiver.
Jonathan Austin 1:8aa5cdb4ab67 491 NRF_RADIO->EVENTS_DISABLED = 0;
Jonathan Austin 1:8aa5cdb4ab67 492 NRF_RADIO->TASKS_DISABLE = 1;
Jonathan Austin 1:8aa5cdb4ab67 493 while(NRF_RADIO->EVENTS_DISABLED == 0);
Jonathan Austin 1:8aa5cdb4ab67 494
Jonathan Austin 1:8aa5cdb4ab67 495 // Configure the radio to send the buffer provided.
Jonathan Austin 1:8aa5cdb4ab67 496 NRF_RADIO->PACKETPTR = (uint32_t) buffer;
Jonathan Austin 1:8aa5cdb4ab67 497
Jonathan Austin 1:8aa5cdb4ab67 498 // Turn on the transmitter, and wait for it to signal that it's ready to use.
Jonathan Austin 1:8aa5cdb4ab67 499 NRF_RADIO->EVENTS_READY = 0;
Jonathan Austin 1:8aa5cdb4ab67 500 NRF_RADIO->TASKS_TXEN = 1;
Jonathan Austin 1:8aa5cdb4ab67 501 while (NRF_RADIO->EVENTS_READY == 0);
Jonathan Austin 1:8aa5cdb4ab67 502
Jonathan Austin 1:8aa5cdb4ab67 503 // Start transmission and wait for end of packet.
Jonathan Austin 1:8aa5cdb4ab67 504 NRF_RADIO->TASKS_START = 1;
Jonathan Austin 1:8aa5cdb4ab67 505 NRF_RADIO->EVENTS_END = 0;
Jonathan Austin 1:8aa5cdb4ab67 506 while(NRF_RADIO->EVENTS_END == 0);
Jonathan Austin 1:8aa5cdb4ab67 507
Jonathan Austin 1:8aa5cdb4ab67 508 // Return the radio to using the default receive buffer
Jonathan Austin 1:8aa5cdb4ab67 509 NRF_RADIO->PACKETPTR = (uint32_t) rxBuf;
Jonathan Austin 1:8aa5cdb4ab67 510
Jonathan Austin 1:8aa5cdb4ab67 511 // Turn off the transmitter.
Jonathan Austin 1:8aa5cdb4ab67 512 NRF_RADIO->EVENTS_DISABLED = 0;
Jonathan Austin 1:8aa5cdb4ab67 513 NRF_RADIO->TASKS_DISABLE = 1;
Jonathan Austin 1:8aa5cdb4ab67 514 while(NRF_RADIO->EVENTS_DISABLED == 0);
Jonathan Austin 1:8aa5cdb4ab67 515
Jonathan Austin 1:8aa5cdb4ab67 516 // Start listening for the next packet
Jonathan Austin 1:8aa5cdb4ab67 517 NRF_RADIO->EVENTS_READY = 0;
Jonathan Austin 1:8aa5cdb4ab67 518 NRF_RADIO->TASKS_RXEN = 1;
Jonathan Austin 1:8aa5cdb4ab67 519 while(NRF_RADIO->EVENTS_READY == 0);
Jonathan Austin 1:8aa5cdb4ab67 520
Jonathan Austin 1:8aa5cdb4ab67 521 NRF_RADIO->EVENTS_END = 0;
Jonathan Austin 1:8aa5cdb4ab67 522 NRF_RADIO->TASKS_START = 1;
Jonathan Austin 1:8aa5cdb4ab67 523
Jonathan Austin 1:8aa5cdb4ab67 524 // Re-enable the Radio interrupt.
Jonathan Austin 1:8aa5cdb4ab67 525 NVIC_ClearPendingIRQ(RADIO_IRQn);
Jonathan Austin 1:8aa5cdb4ab67 526 NVIC_EnableIRQ(RADIO_IRQn);
Jonathan Austin 1:8aa5cdb4ab67 527
Jonathan Austin 1:8aa5cdb4ab67 528 return MICROBIT_OK;
LancasterUniversity 18:e2f92ac26450 529 }