Revised to disable BLE for radio communication as needed.
Dependencies: BLE_API nRF51822 mbed-dev-bin
source/drivers/MicroBitRadioDatagram.cpp@74:26717338739d, 2019-11-26 (annotated)
- Committer:
- tsfarber
- Date:
- Tue Nov 26 04:12:46 2019 +0000
- Revision:
- 74:26717338739d
- Parent:
- 1:8aa5cdb4ab67
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?
User | Revision | Line number | New 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 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 29 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 30 | * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module. |
Jonathan Austin |
1:8aa5cdb4ab67 | 31 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 32 | * This class provides the ability to broadcast simple text or binary messages to other micro:bits in the vicinity |
Jonathan Austin |
1:8aa5cdb4ab67 | 33 | * It is envisaged that this would provide the basis for children to experiment with building their own, simple, |
Jonathan Austin |
1:8aa5cdb4ab67 | 34 | * custom protocols. |
Jonathan Austin |
1:8aa5cdb4ab67 | 35 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 36 | * @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 | 37 | * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place. |
Jonathan Austin |
1:8aa5cdb4ab67 | 38 | * For serious applications, BLE should be considered a substantially more secure alternative. |
Jonathan Austin |
1:8aa5cdb4ab67 | 39 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 40 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 41 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 42 | * Constructor. |
Jonathan Austin |
1:8aa5cdb4ab67 | 43 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 44 | * Creates an instance of a MicroBitRadioDatagram which offers the ability |
Jonathan Austin |
1:8aa5cdb4ab67 | 45 | * to broadcast simple text or binary messages to other micro:bits in the vicinity |
Jonathan Austin |
1:8aa5cdb4ab67 | 46 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 47 | * @param r The underlying radio module used to send and receive data. |
Jonathan Austin |
1:8aa5cdb4ab67 | 48 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 49 | MicroBitRadioDatagram::MicroBitRadioDatagram(MicroBitRadio &r) : radio(r) |
Jonathan Austin |
1:8aa5cdb4ab67 | 50 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 51 | this->rxQueue = NULL; |
Jonathan Austin |
1:8aa5cdb4ab67 | 52 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 53 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 54 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 55 | * Retrieves packet payload data into the given buffer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 56 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 57 | * If a data packet is already available, then it will be returned immediately to the caller. |
Jonathan Austin |
1:8aa5cdb4ab67 | 58 | * If no data is available then MICROBIT_INVALID_PARAMETER is returned. |
Jonathan Austin |
1:8aa5cdb4ab67 | 59 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 60 | * @param buf A pointer to a valid memory location where the received data is to be stored |
Jonathan Austin |
1:8aa5cdb4ab67 | 61 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 62 | * @param len The maximum amount of data that can safely be stored in 'buf' |
Jonathan Austin |
1:8aa5cdb4ab67 | 63 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 64 | * @return The length of the data stored, or MICROBIT_INVALID_PARAMETER if no data is available, or the memory regions provided are invalid. |
Jonathan Austin |
1:8aa5cdb4ab67 | 65 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 66 | int MicroBitRadioDatagram::recv(uint8_t *buf, int len) |
Jonathan Austin |
1:8aa5cdb4ab67 | 67 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 68 | if (buf == NULL || rxQueue == NULL || len < 0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 69 | return MICROBIT_INVALID_PARAMETER; |
Jonathan Austin |
1:8aa5cdb4ab67 | 70 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 71 | // Take the first buffer from the queue. |
Jonathan Austin |
1:8aa5cdb4ab67 | 72 | FrameBuffer *p = rxQueue; |
Jonathan Austin |
1:8aa5cdb4ab67 | 73 | rxQueue = rxQueue->next; |
Jonathan Austin |
1:8aa5cdb4ab67 | 74 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 75 | int l = min(len, p->length - (MICROBIT_RADIO_HEADER_SIZE - 1)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 76 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 77 | // Fill in the buffer provided, if possible. |
Jonathan Austin |
1:8aa5cdb4ab67 | 78 | memcpy(buf, p->payload, l); |
Jonathan Austin |
1:8aa5cdb4ab67 | 79 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 80 | delete p; |
Jonathan Austin |
1:8aa5cdb4ab67 | 81 | return l; |
Jonathan Austin |
1:8aa5cdb4ab67 | 82 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 83 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 84 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 85 | * Retreives packet payload data into the given buffer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 86 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 87 | * If a data packet is already available, then it will be returned immediately to the caller |
Jonathan Austin |
1:8aa5cdb4ab67 | 88 | * in the form of a PacketBuffer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 89 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 90 | * @return the data received, or an empty PacketBuffer if no data is available. |
Jonathan Austin |
1:8aa5cdb4ab67 | 91 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 92 | PacketBuffer MicroBitRadioDatagram::recv() |
Jonathan Austin |
1:8aa5cdb4ab67 | 93 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 94 | if (rxQueue == NULL) |
Jonathan Austin |
1:8aa5cdb4ab67 | 95 | return PacketBuffer::EmptyPacket; |
Jonathan Austin |
1:8aa5cdb4ab67 | 96 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 97 | FrameBuffer *p = rxQueue; |
Jonathan Austin |
1:8aa5cdb4ab67 | 98 | rxQueue = rxQueue->next; |
Jonathan Austin |
1:8aa5cdb4ab67 | 99 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 100 | PacketBuffer packet(p->payload, p->length - (MICROBIT_RADIO_HEADER_SIZE - 1), p->rssi); |
Jonathan Austin |
1:8aa5cdb4ab67 | 101 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 102 | delete p; |
Jonathan Austin |
1:8aa5cdb4ab67 | 103 | return packet; |
Jonathan Austin |
1:8aa5cdb4ab67 | 104 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 105 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 106 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 107 | * Transmits the given buffer onto the broadcast radio. |
Jonathan Austin |
1:8aa5cdb4ab67 | 108 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 109 | * This is a synchronous call that will wait until the transmission of the packet |
Jonathan Austin |
1:8aa5cdb4ab67 | 110 | * has completed before returning. |
Jonathan Austin |
1:8aa5cdb4ab67 | 111 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 112 | * @param buffer The packet contents to transmit. |
Jonathan Austin |
1:8aa5cdb4ab67 | 113 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 114 | * @param len The number of bytes to transmit. |
Jonathan Austin |
1:8aa5cdb4ab67 | 115 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 116 | * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid, |
Jonathan Austin |
1:8aa5cdb4ab67 | 117 | * or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`. |
Jonathan Austin |
1:8aa5cdb4ab67 | 118 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 119 | int MicroBitRadioDatagram::send(uint8_t *buffer, int len) |
Jonathan Austin |
1:8aa5cdb4ab67 | 120 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 121 | if (buffer == NULL || len < 0 || len > MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE - 1) |
Jonathan Austin |
1:8aa5cdb4ab67 | 122 | return MICROBIT_INVALID_PARAMETER; |
Jonathan Austin |
1:8aa5cdb4ab67 | 123 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 124 | FrameBuffer buf; |
Jonathan Austin |
1:8aa5cdb4ab67 | 125 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 126 | buf.length = len + MICROBIT_RADIO_HEADER_SIZE - 1; |
Jonathan Austin |
1:8aa5cdb4ab67 | 127 | buf.version = 1; |
Jonathan Austin |
1:8aa5cdb4ab67 | 128 | buf.group = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 129 | buf.protocol = MICROBIT_RADIO_PROTOCOL_DATAGRAM; |
Jonathan Austin |
1:8aa5cdb4ab67 | 130 | memcpy(buf.payload, buffer, len); |
Jonathan Austin |
1:8aa5cdb4ab67 | 131 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 132 | return radio.send(&buf); |
Jonathan Austin |
1:8aa5cdb4ab67 | 133 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 134 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 135 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 136 | * Transmits the given string onto the broadcast radio. |
Jonathan Austin |
1:8aa5cdb4ab67 | 137 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 138 | * This is a synchronous call that will wait until the transmission of the packet |
Jonathan Austin |
1:8aa5cdb4ab67 | 139 | * has completed before returning. |
Jonathan Austin |
1:8aa5cdb4ab67 | 140 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 141 | * @param data The packet contents to transmit. |
Jonathan Austin |
1:8aa5cdb4ab67 | 142 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 143 | * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid, |
Jonathan Austin |
1:8aa5cdb4ab67 | 144 | * or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`. |
Jonathan Austin |
1:8aa5cdb4ab67 | 145 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 146 | int MicroBitRadioDatagram::send(PacketBuffer data) |
Jonathan Austin |
1:8aa5cdb4ab67 | 147 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 148 | return send((uint8_t *)data.getBytes(), data.length()); |
Jonathan Austin |
1:8aa5cdb4ab67 | 149 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 150 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 151 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 152 | * Transmits the given string onto the broadcast radio. |
Jonathan Austin |
1:8aa5cdb4ab67 | 153 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 154 | * This is a synchronous call that will wait until the transmission of the packet |
Jonathan Austin |
1:8aa5cdb4ab67 | 155 | * has completed before returning. |
Jonathan Austin |
1:8aa5cdb4ab67 | 156 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 157 | * @param data The packet contents to transmit. |
Jonathan Austin |
1:8aa5cdb4ab67 | 158 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 159 | * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid, |
Jonathan Austin |
1:8aa5cdb4ab67 | 160 | * or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`. |
Jonathan Austin |
1:8aa5cdb4ab67 | 161 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 162 | int MicroBitRadioDatagram::send(ManagedString data) |
Jonathan Austin |
1:8aa5cdb4ab67 | 163 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 164 | return send((uint8_t *)data.toCharArray(), data.length()); |
Jonathan Austin |
1:8aa5cdb4ab67 | 165 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 166 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 167 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 168 | * Protocol handler callback. This is called when the radio receives a packet marked as a datagram. |
Jonathan Austin |
1:8aa5cdb4ab67 | 169 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 170 | * This function process this packet, and queues it for user reception. |
Jonathan Austin |
1:8aa5cdb4ab67 | 171 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 172 | void MicroBitRadioDatagram::packetReceived() |
Jonathan Austin |
1:8aa5cdb4ab67 | 173 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 174 | FrameBuffer *packet = radio.recv(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 175 | int queueDepth = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 176 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 177 | // We add to the tail of the queue to preserve causal ordering. |
Jonathan Austin |
1:8aa5cdb4ab67 | 178 | packet->next = NULL; |
Jonathan Austin |
1:8aa5cdb4ab67 | 179 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 180 | if (rxQueue == NULL) |
Jonathan Austin |
1:8aa5cdb4ab67 | 181 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 182 | rxQueue = packet; |
Jonathan Austin |
1:8aa5cdb4ab67 | 183 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 184 | else |
Jonathan Austin |
1:8aa5cdb4ab67 | 185 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 186 | FrameBuffer *p = rxQueue; |
Jonathan Austin |
1:8aa5cdb4ab67 | 187 | while (p->next != NULL) |
Jonathan Austin |
1:8aa5cdb4ab67 | 188 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 189 | p = p->next; |
Jonathan Austin |
1:8aa5cdb4ab67 | 190 | queueDepth++; |
Jonathan Austin |
1:8aa5cdb4ab67 | 191 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 192 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 193 | if (queueDepth >= MICROBIT_RADIO_MAXIMUM_RX_BUFFERS) |
Jonathan Austin |
1:8aa5cdb4ab67 | 194 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 195 | delete packet; |
Jonathan Austin |
1:8aa5cdb4ab67 | 196 | return; |
Jonathan Austin |
1:8aa5cdb4ab67 | 197 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 198 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 199 | p->next = packet; |
Jonathan Austin |
1:8aa5cdb4ab67 | 200 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 201 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 202 | MicroBitEvent(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM); |
Jonathan Austin |
1:8aa5cdb4ab67 | 203 | } |