Official Sheffield ARMBand micro:bit program
microbit/microbit-dal/inc/drivers/MicroBitRadio.h@0:b9164b348919, 2016-10-17 (annotated)
- Committer:
- MrBedfordVan
- Date:
- Mon Oct 17 12:41:20 2016 +0000
- Revision:
- 0:b9164b348919
Official Sheffield ARMBand Micro:bit program
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MrBedfordVan | 0:b9164b348919 | 1 | /* |
MrBedfordVan | 0:b9164b348919 | 2 | The MIT License (MIT) |
MrBedfordVan | 0:b9164b348919 | 3 | |
MrBedfordVan | 0:b9164b348919 | 4 | Copyright (c) 2016 British Broadcasting Corporation. |
MrBedfordVan | 0:b9164b348919 | 5 | This software is provided by Lancaster University by arrangement with the BBC. |
MrBedfordVan | 0:b9164b348919 | 6 | |
MrBedfordVan | 0:b9164b348919 | 7 | Permission is hereby granted, free of charge, to any person obtaining a |
MrBedfordVan | 0:b9164b348919 | 8 | copy of this software and associated documentation files (the "Software"), |
MrBedfordVan | 0:b9164b348919 | 9 | to deal in the Software without restriction, including without limitation |
MrBedfordVan | 0:b9164b348919 | 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
MrBedfordVan | 0:b9164b348919 | 11 | and/or sell copies of the Software, and to permit persons to whom the |
MrBedfordVan | 0:b9164b348919 | 12 | Software is furnished to do so, subject to the following conditions: |
MrBedfordVan | 0:b9164b348919 | 13 | |
MrBedfordVan | 0:b9164b348919 | 14 | The above copyright notice and this permission notice shall be included in |
MrBedfordVan | 0:b9164b348919 | 15 | all copies or substantial portions of the Software. |
MrBedfordVan | 0:b9164b348919 | 16 | |
MrBedfordVan | 0:b9164b348919 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
MrBedfordVan | 0:b9164b348919 | 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
MrBedfordVan | 0:b9164b348919 | 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
MrBedfordVan | 0:b9164b348919 | 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
MrBedfordVan | 0:b9164b348919 | 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
MrBedfordVan | 0:b9164b348919 | 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
MrBedfordVan | 0:b9164b348919 | 23 | DEALINGS IN THE SOFTWARE. |
MrBedfordVan | 0:b9164b348919 | 24 | */ |
MrBedfordVan | 0:b9164b348919 | 25 | |
MrBedfordVan | 0:b9164b348919 | 26 | #ifndef MICROBIT_RADIO_H |
MrBedfordVan | 0:b9164b348919 | 27 | #define MICROBIT_RADIO_H |
MrBedfordVan | 0:b9164b348919 | 28 | |
MrBedfordVan | 0:b9164b348919 | 29 | class MicroBitRadio; |
MrBedfordVan | 0:b9164b348919 | 30 | struct FrameBuffer; |
MrBedfordVan | 0:b9164b348919 | 31 | |
MrBedfordVan | 0:b9164b348919 | 32 | #include "mbed.h" |
MrBedfordVan | 0:b9164b348919 | 33 | #include "MicroBitConfig.h" |
MrBedfordVan | 0:b9164b348919 | 34 | #include "PacketBuffer.h" |
MrBedfordVan | 0:b9164b348919 | 35 | #include "MicroBitRadioDatagram.h" |
MrBedfordVan | 0:b9164b348919 | 36 | #include "MicroBitRadioEvent.h" |
MrBedfordVan | 0:b9164b348919 | 37 | |
MrBedfordVan | 0:b9164b348919 | 38 | /** |
MrBedfordVan | 0:b9164b348919 | 39 | * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module. |
MrBedfordVan | 0:b9164b348919 | 40 | * |
MrBedfordVan | 0:b9164b348919 | 41 | * The nrf51822 RADIO module supports a number of proprietary modes of operation in addition to the typical BLE usage. |
MrBedfordVan | 0:b9164b348919 | 42 | * This class uses one of these modes to enable simple, point to multipoint communication directly between micro:bits. |
MrBedfordVan | 0:b9164b348919 | 43 | * |
MrBedfordVan | 0:b9164b348919 | 44 | * TODO: The protocols implemented here do not currently perform any significant form of energy management, |
MrBedfordVan | 0:b9164b348919 | 45 | * which means that they will consume far more energy than their BLE equivalent. Later versions of the protocol |
MrBedfordVan | 0:b9164b348919 | 46 | * should look to address this through energy efficient broadcast techniques / sleep scheduling. In particular, the GLOSSY |
MrBedfordVan | 0:b9164b348919 | 47 | * approach to efficienct rebroadcast and network synchronisation would likely provide an effective future step. |
MrBedfordVan | 0:b9164b348919 | 48 | * |
MrBedfordVan | 0:b9164b348919 | 49 | * TODO: Meshing should also be considered - again a GLOSSY approach may be effective here, and highly complementary to |
MrBedfordVan | 0:b9164b348919 | 50 | * the master/slave arachitecture of BLE. |
MrBedfordVan | 0:b9164b348919 | 51 | * |
MrBedfordVan | 0:b9164b348919 | 52 | * TODO: This implementation only operates whilst the BLE stack is disabled. The nrf51822 provides a timeslot API to allow |
MrBedfordVan | 0:b9164b348919 | 53 | * BLE to cohabit with other protocols. Future work to allow this colocation would be benefical, and would also allow for the |
MrBedfordVan | 0:b9164b348919 | 54 | * creation of wireless BLE bridges. |
MrBedfordVan | 0:b9164b348919 | 55 | * |
MrBedfordVan | 0:b9164b348919 | 56 | * NOTE: This API does not contain any form of encryption, authentication or authorization. It's purpose is solely for use as a |
MrBedfordVan | 0:b9164b348919 | 57 | * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place. |
MrBedfordVan | 0:b9164b348919 | 58 | * For serious applications, BLE should be considered a substantially more secure alternative. |
MrBedfordVan | 0:b9164b348919 | 59 | */ |
MrBedfordVan | 0:b9164b348919 | 60 | |
MrBedfordVan | 0:b9164b348919 | 61 | // Status Flags |
MrBedfordVan | 0:b9164b348919 | 62 | #define MICROBIT_RADIO_STATUS_INITIALISED 0x0001 |
MrBedfordVan | 0:b9164b348919 | 63 | |
MrBedfordVan | 0:b9164b348919 | 64 | // Default configuration values |
MrBedfordVan | 0:b9164b348919 | 65 | #define MICROBIT_RADIO_BASE_ADDRESS 0x75626974 |
MrBedfordVan | 0:b9164b348919 | 66 | #define MICROBIT_RADIO_DEFAULT_GROUP 0 |
MrBedfordVan | 0:b9164b348919 | 67 | #define MICROBIT_RADIO_DEFAULT_TX_POWER 6 |
MrBedfordVan | 0:b9164b348919 | 68 | #define MICROBIT_RADIO_DEFAULT_FREQUENCY 7 |
MrBedfordVan | 0:b9164b348919 | 69 | #define MICROBIT_RADIO_MAX_PACKET_SIZE 32 |
MrBedfordVan | 0:b9164b348919 | 70 | #define MICROBIT_RADIO_HEADER_SIZE 4 |
MrBedfordVan | 0:b9164b348919 | 71 | #define MICROBIT_RADIO_MAXIMUM_RX_BUFFERS 4 |
MrBedfordVan | 0:b9164b348919 | 72 | |
MrBedfordVan | 0:b9164b348919 | 73 | // Known Protocol Numbers |
MrBedfordVan | 0:b9164b348919 | 74 | #define MICROBIT_RADIO_PROTOCOL_DATAGRAM 1 // A simple, single frame datagram. a little like UDP but with smaller packets. :-) |
MrBedfordVan | 0:b9164b348919 | 75 | #define MICROBIT_RADIO_PROTOCOL_EVENTBUS 2 // Transparent propogation of events from one micro:bit to another. |
MrBedfordVan | 0:b9164b348919 | 76 | |
MrBedfordVan | 0:b9164b348919 | 77 | // Events |
MrBedfordVan | 0:b9164b348919 | 78 | #define MICROBIT_RADIO_EVT_DATAGRAM 1 // Event to signal that a new datagram has been received. |
MrBedfordVan | 0:b9164b348919 | 79 | |
MrBedfordVan | 0:b9164b348919 | 80 | |
MrBedfordVan | 0:b9164b348919 | 81 | struct FrameBuffer |
MrBedfordVan | 0:b9164b348919 | 82 | { |
MrBedfordVan | 0:b9164b348919 | 83 | uint8_t length; // The length of the remaining bytes in the packet. includes protocol/version/group fields, excluding the length field itself. |
MrBedfordVan | 0:b9164b348919 | 84 | uint8_t version; // Protocol version code. |
MrBedfordVan | 0:b9164b348919 | 85 | uint8_t group; // ID of the group to which this packet belongs. |
MrBedfordVan | 0:b9164b348919 | 86 | uint8_t protocol; // Inner protocol number c.f. those issued by IANA for IP protocols |
MrBedfordVan | 0:b9164b348919 | 87 | |
MrBedfordVan | 0:b9164b348919 | 88 | uint8_t payload[MICROBIT_RADIO_MAX_PACKET_SIZE]; // User / higher layer protocol data |
MrBedfordVan | 0:b9164b348919 | 89 | FrameBuffer *next; // Linkage, to allow this and other protocols to queue packets pending processing. |
MrBedfordVan | 0:b9164b348919 | 90 | uint8_t rssi; // Received signal strength of this frame. |
MrBedfordVan | 0:b9164b348919 | 91 | }; |
MrBedfordVan | 0:b9164b348919 | 92 | |
MrBedfordVan | 0:b9164b348919 | 93 | |
MrBedfordVan | 0:b9164b348919 | 94 | class MicroBitRadio : MicroBitComponent |
MrBedfordVan | 0:b9164b348919 | 95 | { |
MrBedfordVan | 0:b9164b348919 | 96 | uint8_t group; // The radio group to which this micro:bit belongs. |
MrBedfordVan | 0:b9164b348919 | 97 | uint8_t queueDepth; // The number of packets in the receiver queue. |
MrBedfordVan | 0:b9164b348919 | 98 | uint8_t rssi; |
MrBedfordVan | 0:b9164b348919 | 99 | FrameBuffer *rxQueue; // A linear list of incoming packets, queued awaiting processing. |
MrBedfordVan | 0:b9164b348919 | 100 | FrameBuffer *rxBuf; // A pointer to the buffer being actively used by the RADIO hardware. |
MrBedfordVan | 0:b9164b348919 | 101 | |
MrBedfordVan | 0:b9164b348919 | 102 | public: |
MrBedfordVan | 0:b9164b348919 | 103 | MicroBitRadioDatagram datagram; // A simple datagram service. |
MrBedfordVan | 0:b9164b348919 | 104 | MicroBitRadioEvent event; // A simple event handling service. |
MrBedfordVan | 0:b9164b348919 | 105 | static MicroBitRadio *instance; // A singleton reference, used purely by the interrupt service routine. |
MrBedfordVan | 0:b9164b348919 | 106 | |
MrBedfordVan | 0:b9164b348919 | 107 | /** |
MrBedfordVan | 0:b9164b348919 | 108 | * Constructor. |
MrBedfordVan | 0:b9164b348919 | 109 | * |
MrBedfordVan | 0:b9164b348919 | 110 | * Initialise the MicroBitRadio. |
MrBedfordVan | 0:b9164b348919 | 111 | * |
MrBedfordVan | 0:b9164b348919 | 112 | * @note This class is demand activated, as a result most resources are only |
MrBedfordVan | 0:b9164b348919 | 113 | * committed if send/recv or event registrations calls are made. |
MrBedfordVan | 0:b9164b348919 | 114 | */ |
MrBedfordVan | 0:b9164b348919 | 115 | MicroBitRadio(uint16_t id = MICROBIT_ID_RADIO); |
MrBedfordVan | 0:b9164b348919 | 116 | |
MrBedfordVan | 0:b9164b348919 | 117 | /** |
MrBedfordVan | 0:b9164b348919 | 118 | * Change the output power level of the transmitter to the given value. |
MrBedfordVan | 0:b9164b348919 | 119 | * |
MrBedfordVan | 0:b9164b348919 | 120 | * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. |
MrBedfordVan | 0:b9164b348919 | 121 | * |
MrBedfordVan | 0:b9164b348919 | 122 | * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range. |
MrBedfordVan | 0:b9164b348919 | 123 | */ |
MrBedfordVan | 0:b9164b348919 | 124 | int setTransmitPower(int power); |
MrBedfordVan | 0:b9164b348919 | 125 | |
MrBedfordVan | 0:b9164b348919 | 126 | /** |
MrBedfordVan | 0:b9164b348919 | 127 | * Change the transmission and reception band of the radio to the given channel |
MrBedfordVan | 0:b9164b348919 | 128 | * |
MrBedfordVan | 0:b9164b348919 | 129 | * @param band a frequency band in the range 0 - 100. Each step is 1MHz wide, based at 2400MHz. |
MrBedfordVan | 0:b9164b348919 | 130 | * |
MrBedfordVan | 0:b9164b348919 | 131 | * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range, |
MrBedfordVan | 0:b9164b348919 | 132 | * or MICROBIT_NOT_SUPPORTED if the BLE stack is running. |
MrBedfordVan | 0:b9164b348919 | 133 | */ |
MrBedfordVan | 0:b9164b348919 | 134 | int setFrequencyBand(int band); |
MrBedfordVan | 0:b9164b348919 | 135 | |
MrBedfordVan | 0:b9164b348919 | 136 | /** |
MrBedfordVan | 0:b9164b348919 | 137 | * Retrieve a pointer to the currently allocated receive buffer. This is the area of memory |
MrBedfordVan | 0:b9164b348919 | 138 | * actively being used by the radio hardware to store incoming data. |
MrBedfordVan | 0:b9164b348919 | 139 | * |
MrBedfordVan | 0:b9164b348919 | 140 | * @return a pointer to the current receive buffer. |
MrBedfordVan | 0:b9164b348919 | 141 | */ |
MrBedfordVan | 0:b9164b348919 | 142 | FrameBuffer * getRxBuf(); |
MrBedfordVan | 0:b9164b348919 | 143 | |
MrBedfordVan | 0:b9164b348919 | 144 | /** |
MrBedfordVan | 0:b9164b348919 | 145 | * Attempt to queue a buffer received by the radio hardware, if sufficient space is available. |
MrBedfordVan | 0:b9164b348919 | 146 | * |
MrBedfordVan | 0:b9164b348919 | 147 | * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if a replacement receiver buffer |
MrBedfordVan | 0:b9164b348919 | 148 | * could not be allocated (either by policy or memory exhaustion). |
MrBedfordVan | 0:b9164b348919 | 149 | */ |
MrBedfordVan | 0:b9164b348919 | 150 | int queueRxBuf(); |
MrBedfordVan | 0:b9164b348919 | 151 | |
MrBedfordVan | 0:b9164b348919 | 152 | /** |
MrBedfordVan | 0:b9164b348919 | 153 | * Sets the RSSI for the most recent packet. |
MrBedfordVan | 0:b9164b348919 | 154 | * |
MrBedfordVan | 0:b9164b348919 | 155 | * @param rssi the new rssi value. |
MrBedfordVan | 0:b9164b348919 | 156 | * |
MrBedfordVan | 0:b9164b348919 | 157 | * @note should only be called from RADIO_IRQHandler... |
MrBedfordVan | 0:b9164b348919 | 158 | */ |
MrBedfordVan | 0:b9164b348919 | 159 | int setRSSI(uint8_t rssi); |
MrBedfordVan | 0:b9164b348919 | 160 | |
MrBedfordVan | 0:b9164b348919 | 161 | /** |
MrBedfordVan | 0:b9164b348919 | 162 | * Retrieves the current RSSI for the most recent packet. |
MrBedfordVan | 0:b9164b348919 | 163 | * |
MrBedfordVan | 0:b9164b348919 | 164 | * @return the most recent RSSI value or MICROBIT_NOT_SUPPORTED if the BLE stack is running. |
MrBedfordVan | 0:b9164b348919 | 165 | */ |
MrBedfordVan | 0:b9164b348919 | 166 | int getRSSI(); |
MrBedfordVan | 0:b9164b348919 | 167 | |
MrBedfordVan | 0:b9164b348919 | 168 | /** |
MrBedfordVan | 0:b9164b348919 | 169 | * Initialises the radio for use as a multipoint sender/receiver |
MrBedfordVan | 0:b9164b348919 | 170 | * |
MrBedfordVan | 0:b9164b348919 | 171 | * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running. |
MrBedfordVan | 0:b9164b348919 | 172 | */ |
MrBedfordVan | 0:b9164b348919 | 173 | int enable(); |
MrBedfordVan | 0:b9164b348919 | 174 | |
MrBedfordVan | 0:b9164b348919 | 175 | /** |
MrBedfordVan | 0:b9164b348919 | 176 | * Disables the radio for use as a multipoint sender/receiver. |
MrBedfordVan | 0:b9164b348919 | 177 | * |
MrBedfordVan | 0:b9164b348919 | 178 | * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running. |
MrBedfordVan | 0:b9164b348919 | 179 | */ |
MrBedfordVan | 0:b9164b348919 | 180 | int disable(); |
MrBedfordVan | 0:b9164b348919 | 181 | |
MrBedfordVan | 0:b9164b348919 | 182 | /** |
MrBedfordVan | 0:b9164b348919 | 183 | * Sets the radio to listen to packets sent with the given group id. |
MrBedfordVan | 0:b9164b348919 | 184 | * |
MrBedfordVan | 0:b9164b348919 | 185 | * @param group The group to join. A micro:bit can only listen to one group ID at any time. |
MrBedfordVan | 0:b9164b348919 | 186 | * |
MrBedfordVan | 0:b9164b348919 | 187 | * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running. |
MrBedfordVan | 0:b9164b348919 | 188 | */ |
MrBedfordVan | 0:b9164b348919 | 189 | int setGroup(uint8_t group); |
MrBedfordVan | 0:b9164b348919 | 190 | |
MrBedfordVan | 0:b9164b348919 | 191 | /** |
MrBedfordVan | 0:b9164b348919 | 192 | * A background, low priority callback that is triggered whenever the processor is idle. |
MrBedfordVan | 0:b9164b348919 | 193 | * Here, we empty our queue of received packets, and pass them onto higher level protocol handlers. |
MrBedfordVan | 0:b9164b348919 | 194 | */ |
MrBedfordVan | 0:b9164b348919 | 195 | virtual void idleTick(); |
MrBedfordVan | 0:b9164b348919 | 196 | |
MrBedfordVan | 0:b9164b348919 | 197 | /** |
MrBedfordVan | 0:b9164b348919 | 198 | * Determines the number of packets ready to be processed. |
MrBedfordVan | 0:b9164b348919 | 199 | * |
MrBedfordVan | 0:b9164b348919 | 200 | * @return The number of packets in the receive buffer. |
MrBedfordVan | 0:b9164b348919 | 201 | */ |
MrBedfordVan | 0:b9164b348919 | 202 | int dataReady(); |
MrBedfordVan | 0:b9164b348919 | 203 | |
MrBedfordVan | 0:b9164b348919 | 204 | /** |
MrBedfordVan | 0:b9164b348919 | 205 | * Retrieves the next packet from the receive buffer. |
MrBedfordVan | 0:b9164b348919 | 206 | * If a data packet is available, then it will be returned immediately to |
MrBedfordVan | 0:b9164b348919 | 207 | * the caller. This call will also dequeue the buffer. |
MrBedfordVan | 0:b9164b348919 | 208 | * |
MrBedfordVan | 0:b9164b348919 | 209 | * @return The buffer containing the the packet. If no data is available, NULL is returned. |
MrBedfordVan | 0:b9164b348919 | 210 | * |
MrBedfordVan | 0:b9164b348919 | 211 | * @note Once recv() has been called, it is the callers responsibility to |
MrBedfordVan | 0:b9164b348919 | 212 | * delete the buffer when appropriate. |
MrBedfordVan | 0:b9164b348919 | 213 | */ |
MrBedfordVan | 0:b9164b348919 | 214 | FrameBuffer* recv(); |
MrBedfordVan | 0:b9164b348919 | 215 | |
MrBedfordVan | 0:b9164b348919 | 216 | /** |
MrBedfordVan | 0:b9164b348919 | 217 | * Transmits the given buffer onto the broadcast radio. |
MrBedfordVan | 0:b9164b348919 | 218 | * The call will wait until the transmission of the packet has completed before returning. |
MrBedfordVan | 0:b9164b348919 | 219 | * |
MrBedfordVan | 0:b9164b348919 | 220 | * @param data The packet contents to transmit. |
MrBedfordVan | 0:b9164b348919 | 221 | * |
MrBedfordVan | 0:b9164b348919 | 222 | * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running. |
MrBedfordVan | 0:b9164b348919 | 223 | */ |
MrBedfordVan | 0:b9164b348919 | 224 | int send(FrameBuffer *buffer); |
MrBedfordVan | 0:b9164b348919 | 225 | }; |
MrBedfordVan | 0:b9164b348919 | 226 | |
MrBedfordVan | 0:b9164b348919 | 227 | #endif |