My fork

Dependencies:   BLE_API mbed-dev-bin nRF51822-bluetooth-mdw

Fork of microbit-dal-bluetooth-mdw by Martin Woolley

Committer:
Jonathan Austin
Date:
Thu Apr 07 01:33:22 2016 +0100
Revision:
1:8aa5cdb4ab67
Child:
69:b62f231e51ce
Synchronized with git rev 55cb9199

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 #ifndef MICROBIT_RADIO_H
Jonathan Austin 1:8aa5cdb4ab67 27 #define MICROBIT_RADIO_H
Jonathan Austin 1:8aa5cdb4ab67 28
Jonathan Austin 1:8aa5cdb4ab67 29 class MicroBitRadio;
Jonathan Austin 1:8aa5cdb4ab67 30 struct FrameBuffer;
Jonathan Austin 1:8aa5cdb4ab67 31
Jonathan Austin 1:8aa5cdb4ab67 32 #include "mbed.h"
Jonathan Austin 1:8aa5cdb4ab67 33 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 34 #include "PacketBuffer.h"
Jonathan Austin 1:8aa5cdb4ab67 35 #include "MicroBitRadioDatagram.h"
Jonathan Austin 1:8aa5cdb4ab67 36 #include "MicroBitRadioEvent.h"
Jonathan Austin 1:8aa5cdb4ab67 37
Jonathan Austin 1:8aa5cdb4ab67 38 /**
Jonathan Austin 1:8aa5cdb4ab67 39 * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
Jonathan Austin 1:8aa5cdb4ab67 40 *
Jonathan Austin 1:8aa5cdb4ab67 41 * The nrf51822 RADIO module supports a number of proprietary modes of operation in addition to the typical BLE usage.
Jonathan Austin 1:8aa5cdb4ab67 42 * This class uses one of these modes to enable simple, point to multipoint communication directly between micro:bits.
Jonathan Austin 1:8aa5cdb4ab67 43 *
Jonathan Austin 1:8aa5cdb4ab67 44 * TODO: The protocols implemented here do not currently perform any significant form of energy management,
Jonathan Austin 1:8aa5cdb4ab67 45 * which means that they will consume far more energy than their BLE equivalent. Later versions of the protocol
Jonathan Austin 1:8aa5cdb4ab67 46 * should look to address this through energy efficient broadcast techniques / sleep scheduling. In particular, the GLOSSY
Jonathan Austin 1:8aa5cdb4ab67 47 * approach to efficienct rebroadcast and network synchronisation would likely provide an effective future step.
Jonathan Austin 1:8aa5cdb4ab67 48 *
Jonathan Austin 1:8aa5cdb4ab67 49 * TODO: Meshing should also be considered - again a GLOSSY approach may be effective here, and highly complementary to
Jonathan Austin 1:8aa5cdb4ab67 50 * the master/slave arachitecture of BLE.
Jonathan Austin 1:8aa5cdb4ab67 51 *
Jonathan Austin 1:8aa5cdb4ab67 52 * TODO: This implementation only operates whilst the BLE stack is disabled. The nrf51822 provides a timeslot API to allow
Jonathan Austin 1:8aa5cdb4ab67 53 * 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 54 * creation of wireless BLE bridges.
Jonathan Austin 1:8aa5cdb4ab67 55 *
Jonathan Austin 1:8aa5cdb4ab67 56 * NOTE: This API does not contain any form of encryption, authentication or authorization. It's purpose is solely for use as a
Jonathan Austin 1:8aa5cdb4ab67 57 * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
Jonathan Austin 1:8aa5cdb4ab67 58 * For serious applications, BLE should be considered a substantially more secure alternative.
Jonathan Austin 1:8aa5cdb4ab67 59 */
Jonathan Austin 1:8aa5cdb4ab67 60
Jonathan Austin 1:8aa5cdb4ab67 61 // Status Flags
Jonathan Austin 1:8aa5cdb4ab67 62 #define MICROBIT_RADIO_STATUS_INITIALISED 0x0001
Jonathan Austin 1:8aa5cdb4ab67 63
Jonathan Austin 1:8aa5cdb4ab67 64 // Default configuration values
Jonathan Austin 1:8aa5cdb4ab67 65 #define MICROBIT_RADIO_BASE_ADDRESS 0x75626974
Jonathan Austin 1:8aa5cdb4ab67 66 #define MICROBIT_RADIO_DEFAULT_GROUP 0
Jonathan Austin 1:8aa5cdb4ab67 67 #define MICROBIT_RADIO_DEFAULT_TX_POWER 6
Jonathan Austin 1:8aa5cdb4ab67 68 #define MICROBIT_RADIO_DEFAULT_FREQUENCY 7
Jonathan Austin 1:8aa5cdb4ab67 69 #define MICROBIT_RADIO_MAX_PACKET_SIZE 32
Jonathan Austin 1:8aa5cdb4ab67 70 #define MICROBIT_RADIO_HEADER_SIZE 4
Jonathan Austin 1:8aa5cdb4ab67 71 #define MICROBIT_RADIO_MAXIMUM_RX_BUFFERS 4
Jonathan Austin 1:8aa5cdb4ab67 72
Jonathan Austin 1:8aa5cdb4ab67 73 // Known Protocol Numbers
Jonathan Austin 1:8aa5cdb4ab67 74 #define MICROBIT_RADIO_PROTOCOL_DATAGRAM 1 // A simple, single frame datagram. a little like UDP but with smaller packets. :-)
Jonathan Austin 1:8aa5cdb4ab67 75 #define MICROBIT_RADIO_PROTOCOL_EVENTBUS 2 // Transparent propogation of events from one micro:bit to another.
Jonathan Austin 1:8aa5cdb4ab67 76
Jonathan Austin 1:8aa5cdb4ab67 77 // Events
Jonathan Austin 1:8aa5cdb4ab67 78 #define MICROBIT_RADIO_EVT_DATAGRAM 1 // Event to signal that a new datagram has been received.
Jonathan Austin 1:8aa5cdb4ab67 79
Jonathan Austin 1:8aa5cdb4ab67 80
Jonathan Austin 1:8aa5cdb4ab67 81 struct FrameBuffer
Jonathan Austin 1:8aa5cdb4ab67 82 {
Jonathan Austin 1:8aa5cdb4ab67 83 uint8_t length; // The length of the remaining bytes in the packet. includes protocol/version/group fields, excluding the length field itself.
Jonathan Austin 1:8aa5cdb4ab67 84 uint8_t version; // Protocol version code.
Jonathan Austin 1:8aa5cdb4ab67 85 uint8_t group; // ID of the group to which this packet belongs.
Jonathan Austin 1:8aa5cdb4ab67 86 uint8_t protocol; // Inner protocol number c.f. those issued by IANA for IP protocols
Jonathan Austin 1:8aa5cdb4ab67 87
Jonathan Austin 1:8aa5cdb4ab67 88 uint8_t payload[MICROBIT_RADIO_MAX_PACKET_SIZE]; // User / higher layer protocol data
Jonathan Austin 1:8aa5cdb4ab67 89 FrameBuffer *next; // Linkage, to allow this and other protocols to queue packets pending processing.
Jonathan Austin 1:8aa5cdb4ab67 90 uint8_t rssi; // Received signal strength of this frame.
Jonathan Austin 1:8aa5cdb4ab67 91 };
Jonathan Austin 1:8aa5cdb4ab67 92
Jonathan Austin 1:8aa5cdb4ab67 93
Jonathan Austin 1:8aa5cdb4ab67 94 class MicroBitRadio : MicroBitComponent
Jonathan Austin 1:8aa5cdb4ab67 95 {
Jonathan Austin 1:8aa5cdb4ab67 96 uint8_t group; // The radio group to which this micro:bit belongs.
Jonathan Austin 1:8aa5cdb4ab67 97 uint8_t queueDepth; // The number of packets in the receiver queue.
Jonathan Austin 1:8aa5cdb4ab67 98 uint8_t rssi;
Jonathan Austin 1:8aa5cdb4ab67 99 FrameBuffer *rxQueue; // A linear list of incoming packets, queued awaiting processing.
Jonathan Austin 1:8aa5cdb4ab67 100 FrameBuffer *rxBuf; // A pointer to the buffer being actively used by the RADIO hardware.
Jonathan Austin 1:8aa5cdb4ab67 101
Jonathan Austin 1:8aa5cdb4ab67 102 public:
Jonathan Austin 1:8aa5cdb4ab67 103 MicroBitRadioDatagram datagram; // A simple datagram service.
Jonathan Austin 1:8aa5cdb4ab67 104 MicroBitRadioEvent event; // A simple event handling service.
Jonathan Austin 1:8aa5cdb4ab67 105 static MicroBitRadio *instance; // A singleton reference, used purely by the interrupt service routine.
Jonathan Austin 1:8aa5cdb4ab67 106
Jonathan Austin 1:8aa5cdb4ab67 107 /**
Jonathan Austin 1:8aa5cdb4ab67 108 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 109 *
Jonathan Austin 1:8aa5cdb4ab67 110 * Initialise the MicroBitRadio.
Jonathan Austin 1:8aa5cdb4ab67 111 *
Jonathan Austin 1:8aa5cdb4ab67 112 * @note This class is demand activated, as a result most resources are only
Jonathan Austin 1:8aa5cdb4ab67 113 * committed if send/recv or event registrations calls are made.
Jonathan Austin 1:8aa5cdb4ab67 114 */
Jonathan Austin 1:8aa5cdb4ab67 115 MicroBitRadio(uint16_t id = MICROBIT_ID_RADIO);
Jonathan Austin 1:8aa5cdb4ab67 116
Jonathan Austin 1:8aa5cdb4ab67 117 /**
Jonathan Austin 1:8aa5cdb4ab67 118 * Change the output power level of the transmitter to the given value.
Jonathan Austin 1:8aa5cdb4ab67 119 *
Jonathan Austin 1:8aa5cdb4ab67 120 * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest.
Jonathan Austin 1:8aa5cdb4ab67 121 *
Jonathan Austin 1:8aa5cdb4ab67 122 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range.
Jonathan Austin 1:8aa5cdb4ab67 123 */
Jonathan Austin 1:8aa5cdb4ab67 124 int setTransmitPower(int power);
Jonathan Austin 1:8aa5cdb4ab67 125
Jonathan Austin 1:8aa5cdb4ab67 126 /**
Jonathan Austin 1:8aa5cdb4ab67 127 * Change the transmission and reception band of the radio to the given channel
Jonathan Austin 1:8aa5cdb4ab67 128 *
Jonathan Austin 1:8aa5cdb4ab67 129 * @param band a frequency band in the range 0 - 100. Each step is 1MHz wide, based at 2400MHz.
Jonathan Austin 1:8aa5cdb4ab67 130 *
Jonathan Austin 1:8aa5cdb4ab67 131 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range,
Jonathan Austin 1:8aa5cdb4ab67 132 * or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 133 */
Jonathan Austin 1:8aa5cdb4ab67 134 int setFrequencyBand(int band);
Jonathan Austin 1:8aa5cdb4ab67 135
Jonathan Austin 1:8aa5cdb4ab67 136 /**
Jonathan Austin 1:8aa5cdb4ab67 137 * Retrieve a pointer to the currently allocated receive buffer. This is the area of memory
Jonathan Austin 1:8aa5cdb4ab67 138 * actively being used by the radio hardware to store incoming data.
Jonathan Austin 1:8aa5cdb4ab67 139 *
Jonathan Austin 1:8aa5cdb4ab67 140 * @return a pointer to the current receive buffer.
Jonathan Austin 1:8aa5cdb4ab67 141 */
Jonathan Austin 1:8aa5cdb4ab67 142 FrameBuffer * getRxBuf();
Jonathan Austin 1:8aa5cdb4ab67 143
Jonathan Austin 1:8aa5cdb4ab67 144 /**
Jonathan Austin 1:8aa5cdb4ab67 145 * Attempt to queue a buffer received by the radio hardware, if sufficient space is available.
Jonathan Austin 1:8aa5cdb4ab67 146 *
Jonathan Austin 1:8aa5cdb4ab67 147 * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if a replacement receiver buffer
Jonathan Austin 1:8aa5cdb4ab67 148 * could not be allocated (either by policy or memory exhaustion).
Jonathan Austin 1:8aa5cdb4ab67 149 */
Jonathan Austin 1:8aa5cdb4ab67 150 int queueRxBuf();
Jonathan Austin 1:8aa5cdb4ab67 151
Jonathan Austin 1:8aa5cdb4ab67 152 /**
Jonathan Austin 1:8aa5cdb4ab67 153 * Sets the RSSI for the most recent packet.
Jonathan Austin 1:8aa5cdb4ab67 154 *
Jonathan Austin 1:8aa5cdb4ab67 155 * @param rssi the new rssi value.
Jonathan Austin 1:8aa5cdb4ab67 156 *
Jonathan Austin 1:8aa5cdb4ab67 157 * @note should only be called from RADIO_IRQHandler...
Jonathan Austin 1:8aa5cdb4ab67 158 */
Jonathan Austin 1:8aa5cdb4ab67 159 int setRSSI(uint8_t rssi);
Jonathan Austin 1:8aa5cdb4ab67 160
Jonathan Austin 1:8aa5cdb4ab67 161 /**
Jonathan Austin 1:8aa5cdb4ab67 162 * Retrieves the current RSSI for the most recent packet.
Jonathan Austin 1:8aa5cdb4ab67 163 *
Jonathan Austin 1:8aa5cdb4ab67 164 * @return the most recent RSSI value or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 165 */
Jonathan Austin 1:8aa5cdb4ab67 166 int getRSSI();
Jonathan Austin 1:8aa5cdb4ab67 167
Jonathan Austin 1:8aa5cdb4ab67 168 /**
Jonathan Austin 1:8aa5cdb4ab67 169 * Initialises the radio for use as a multipoint sender/receiver
Jonathan Austin 1:8aa5cdb4ab67 170 *
Jonathan Austin 1:8aa5cdb4ab67 171 * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 172 */
Jonathan Austin 1:8aa5cdb4ab67 173 int enable();
Jonathan Austin 1:8aa5cdb4ab67 174
Jonathan Austin 1:8aa5cdb4ab67 175 /**
Jonathan Austin 1:8aa5cdb4ab67 176 * Disables the radio for use as a multipoint sender/receiver.
Jonathan Austin 1:8aa5cdb4ab67 177 *
Jonathan Austin 1:8aa5cdb4ab67 178 * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 179 */
Jonathan Austin 1:8aa5cdb4ab67 180 int disable();
Jonathan Austin 1:8aa5cdb4ab67 181
Jonathan Austin 1:8aa5cdb4ab67 182 /**
Jonathan Austin 1:8aa5cdb4ab67 183 * Sets the radio to listen to packets sent with the given group id.
Jonathan Austin 1:8aa5cdb4ab67 184 *
Jonathan Austin 1:8aa5cdb4ab67 185 * @param group The group to join. A micro:bit can only listen to one group ID at any time.
Jonathan Austin 1:8aa5cdb4ab67 186 *
Jonathan Austin 1:8aa5cdb4ab67 187 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 188 */
Jonathan Austin 1:8aa5cdb4ab67 189 int setGroup(uint8_t group);
Jonathan Austin 1:8aa5cdb4ab67 190
Jonathan Austin 1:8aa5cdb4ab67 191 /**
Jonathan Austin 1:8aa5cdb4ab67 192 * A background, low priority callback that is triggered whenever the processor is idle.
Jonathan Austin 1:8aa5cdb4ab67 193 * Here, we empty our queue of received packets, and pass them onto higher level protocol handlers.
Jonathan Austin 1:8aa5cdb4ab67 194 */
Jonathan Austin 1:8aa5cdb4ab67 195 virtual void idleTick();
Jonathan Austin 1:8aa5cdb4ab67 196
Jonathan Austin 1:8aa5cdb4ab67 197 /**
Jonathan Austin 1:8aa5cdb4ab67 198 * Determines the number of packets ready to be processed.
Jonathan Austin 1:8aa5cdb4ab67 199 *
Jonathan Austin 1:8aa5cdb4ab67 200 * @return The number of packets in the receive buffer.
Jonathan Austin 1:8aa5cdb4ab67 201 */
Jonathan Austin 1:8aa5cdb4ab67 202 int dataReady();
Jonathan Austin 1:8aa5cdb4ab67 203
Jonathan Austin 1:8aa5cdb4ab67 204 /**
Jonathan Austin 1:8aa5cdb4ab67 205 * Retrieves the next packet from the receive buffer.
Jonathan Austin 1:8aa5cdb4ab67 206 * If a data packet is available, then it will be returned immediately to
Jonathan Austin 1:8aa5cdb4ab67 207 * the caller. This call will also dequeue the buffer.
Jonathan Austin 1:8aa5cdb4ab67 208 *
Jonathan Austin 1:8aa5cdb4ab67 209 * @return The buffer containing the the packet. If no data is available, NULL is returned.
Jonathan Austin 1:8aa5cdb4ab67 210 *
Jonathan Austin 1:8aa5cdb4ab67 211 * @note Once recv() has been called, it is the callers resposibility to
Jonathan Austin 1:8aa5cdb4ab67 212 * delete the buffer when appropriate.
Jonathan Austin 1:8aa5cdb4ab67 213 */
Jonathan Austin 1:8aa5cdb4ab67 214 FrameBuffer* recv();
Jonathan Austin 1:8aa5cdb4ab67 215
Jonathan Austin 1:8aa5cdb4ab67 216 /**
Jonathan Austin 1:8aa5cdb4ab67 217 * Transmits the given buffer onto the broadcast radio.
Jonathan Austin 1:8aa5cdb4ab67 218 * The call will wait until the transmission of the packet has completed before returning.
Jonathan Austin 1:8aa5cdb4ab67 219 *
Jonathan Austin 1:8aa5cdb4ab67 220 * @param data The packet contents to transmit.
Jonathan Austin 1:8aa5cdb4ab67 221 *
Jonathan Austin 1:8aa5cdb4ab67 222 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
Jonathan Austin 1:8aa5cdb4ab67 223 */
Jonathan Austin 1:8aa5cdb4ab67 224 int send(FrameBuffer *buffer);
Jonathan Austin 1:8aa5cdb4ab67 225 };
Jonathan Austin 1:8aa5cdb4ab67 226
Jonathan Austin 1:8aa5cdb4ab67 227 #endif