mbed.org local branch of microbit-dal. The real version lives in git at https://github.com/lancaster-university/microbit-dal

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit Microbit IoTChallenge1 microbit ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitRadio.h Source File

MicroBitRadio.h

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 #ifndef MICROBIT_RADIO_H
00027 #define MICROBIT_RADIO_H
00028 
00029 class MicroBitRadio;
00030 struct FrameBuffer;
00031 
00032 #include "mbed.h"
00033 #include "MicroBitConfig.h"
00034 #include "PacketBuffer.h"
00035 #include "MicroBitRadioDatagram.h"
00036 #include "MicroBitRadioEvent.h"
00037 
00038 /**
00039  * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
00040  *
00041  * The nrf51822 RADIO module supports a number of proprietary modes of operation in addition to the typical BLE usage.
00042  * This class uses one of these modes to enable simple, point to multipoint communication directly between micro:bits.
00043  *
00044  * TODO: The protocols implemented here do not currently perform any significant form of energy management,
00045  * which means that they will consume far more energy than their BLE equivalent. Later versions of the protocol
00046  * should look to address this through energy efficient broadcast techniques / sleep scheduling. In particular, the GLOSSY
00047  * approach to efficienct rebroadcast and network synchronisation would likely provide an effective future step.
00048  *
00049  * TODO: Meshing should also be considered - again a GLOSSY approach may be effective here, and highly complementary to
00050  * the master/slave arachitecture of BLE.
00051  *
00052  * TODO: This implementation only operates whilst the BLE stack is disabled. The nrf51822 provides a timeslot API to allow
00053  * BLE to cohabit with other protocols. Future work to allow this colocation would be benefical, and would also allow for the
00054  * creation of wireless BLE bridges.
00055  *
00056  * NOTE: This API does not contain any form of encryption, authentication or authorization. It's purpose is solely for use as a
00057  * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
00058  * For serious applications, BLE should be considered a substantially more secure alternative.
00059  */
00060 
00061 // Status Flags
00062 #define MICROBIT_RADIO_STATUS_INITIALISED       0x0001
00063 
00064 // Default configuration values
00065 #define MICROBIT_RADIO_BASE_ADDRESS             0x75626974
00066 #define MICROBIT_RADIO_DEFAULT_GROUP            0
00067 #define MICROBIT_RADIO_DEFAULT_TX_POWER         6
00068 #define MICROBIT_RADIO_DEFAULT_FREQUENCY        7
00069 #define MICROBIT_RADIO_MAX_PACKET_SIZE          32
00070 #define MICROBIT_RADIO_HEADER_SIZE              4
00071 #define MICROBIT_RADIO_MAXIMUM_RX_BUFFERS       4
00072 
00073 // Known Protocol Numbers
00074 #define MICROBIT_RADIO_PROTOCOL_DATAGRAM        1       // A simple, single frame datagram. a little like UDP but with smaller packets. :-)
00075 #define MICROBIT_RADIO_PROTOCOL_EVENTBUS        2       // Transparent propogation of events from one micro:bit to another.
00076 
00077 // Events
00078 #define MICROBIT_RADIO_EVT_DATAGRAM             1       // Event to signal that a new datagram has been received.
00079 
00080 
00081 struct FrameBuffer
00082 {
00083     uint8_t         length;                             // The length of the remaining bytes in the packet. includes protocol/version/group fields, excluding the length field itself.
00084     uint8_t         version;                            // Protocol version code.
00085     uint8_t         group;                              // ID of the group to which this packet belongs.
00086     uint8_t         protocol;                           // Inner protocol number c.f. those issued by IANA for IP protocols
00087 
00088     uint8_t         payload[MICROBIT_RADIO_MAX_PACKET_SIZE];    // User / higher layer protocol data
00089     FrameBuffer     *next;                              // Linkage, to allow this and other protocols to queue packets pending processing.
00090     uint8_t         rssi;                               // Received signal strength of this frame.
00091 };
00092 
00093 
00094 class MicroBitRadio : MicroBitComponent
00095 {
00096     uint8_t                 group;      // The radio group to which this micro:bit belongs.
00097     uint8_t                 queueDepth; // The number of packets in the receiver queue.
00098     uint8_t                 rssi;
00099     FrameBuffer             *rxQueue;   // A linear list of incoming packets, queued awaiting processing.
00100     FrameBuffer             *rxBuf;     // A pointer to the buffer being actively used by the RADIO hardware.
00101 
00102     public:
00103     MicroBitRadioDatagram   datagram;   // A simple datagram service.
00104     MicroBitRadioEvent      event;      // A simple event handling service.
00105     static MicroBitRadio    *instance;  // A singleton reference, used purely by the interrupt service routine.
00106 
00107     /**
00108       * Constructor.
00109       *
00110       * Initialise the MicroBitRadio.
00111       *
00112       * @note This class is demand activated, as a result most resources are only
00113       *       committed if send/recv or event registrations calls are made.
00114       */
00115     MicroBitRadio(uint16_t id = MICROBIT_ID_RADIO);
00116 
00117     /**
00118       * Change the output power level of the transmitter to the given value.
00119       *
00120       * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest.
00121       *
00122       * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range.
00123       */
00124     int setTransmitPower(int power);
00125 
00126     /**
00127       * Change the transmission and reception band of the radio to the given channel
00128       *
00129       * @param band a frequency band in the range 0 - 100. Each step is 1MHz wide, based at 2400MHz.
00130       *
00131       * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range,
00132       *         or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
00133       */
00134     int setFrequencyBand(int band);
00135 
00136     /**
00137       * Retrieve a pointer to the currently allocated receive buffer. This is the area of memory
00138       * actively being used by the radio hardware to store incoming data.
00139       *
00140       * @return a pointer to the current receive buffer.
00141       */
00142     FrameBuffer * getRxBuf();
00143 
00144     /**
00145       * Attempt to queue a buffer received by the radio hardware, if sufficient space is available.
00146       *
00147       * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if a replacement receiver buffer
00148       *         could not be allocated (either by policy or memory exhaustion).
00149       */
00150     int queueRxBuf();
00151 
00152     /**
00153       * Sets the RSSI for the most recent packet.
00154       *
00155       * @param rssi the new rssi value.
00156       *
00157       * @note should only be called from RADIO_IRQHandler...
00158       */
00159     int setRSSI(uint8_t rssi);
00160 
00161     /**
00162       * Retrieves the current RSSI for the most recent packet.
00163       *
00164       * @return the most recent RSSI value or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
00165       */
00166     int getRSSI();
00167 
00168     /**
00169       * Initialises the radio for use as a multipoint sender/receiver
00170       *
00171       * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
00172       */
00173     int enable();
00174 
00175     /**
00176       * Disables the radio for use as a multipoint sender/receiver.
00177       *
00178       * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
00179       */
00180     int disable();
00181 
00182     /**
00183       * Sets the radio to listen to packets sent with the given group id.
00184       *
00185       * @param group The group to join. A micro:bit can only listen to one group ID at any time.
00186       *
00187       * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
00188       */
00189     int setGroup(uint8_t group);
00190 
00191     /**
00192       * A background, low priority callback that is triggered whenever the processor is idle.
00193       * Here, we empty our queue of received packets, and pass them onto higher level protocol handlers.
00194       */
00195     virtual void idleTick();
00196 
00197     /**
00198       * Determines the number of packets ready to be processed.
00199       *
00200       * @return The number of packets in the receive buffer.
00201       */
00202     int dataReady();
00203 
00204     /**
00205       * Retrieves the next packet from the receive buffer.
00206       * If a data packet is available, then it will be returned immediately to
00207       * the caller. This call will also dequeue the buffer.
00208       *
00209       * @return The buffer containing the the packet. If no data is available, NULL is returned.
00210       *
00211       * @note Once recv() has been called, it is the callers responsibility to
00212       *       delete the buffer when appropriate.
00213       */
00214     FrameBuffer* recv();
00215 
00216     /**
00217       * Transmits the given buffer onto the broadcast radio.
00218       * The call will wait until the transmission of the packet has completed before returning.
00219       *
00220       * @param data The packet contents to transmit.
00221       *
00222       * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
00223       */
00224     int send(FrameBuffer *buffer);
00225 };
00226 
00227 #endif