My attempts at getting the nRF8001 chip to play with the mbed

Dependencies:   Parallax_X-Band mbed

Committer:
ottaviano3
Date:
Sat Jul 25 17:14:11 2015 +0000
Revision:
0:d75a1797ffd9
Nasty Bluetooth LE code for the nRF8001.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ottaviano3 0:d75a1797ffd9 1 #include "mbed.h"
ottaviano3 0:d75a1797ffd9 2
ottaviano3 0:d75a1797ffd9 3 float version = 0.1;
ottaviano3 0:d75a1797ffd9 4
ottaviano3 0:d75a1797ffd9 5 // Serial to PC for outputs.
ottaviano3 0:d75a1797ffd9 6 Serial pc(USBTX,USBRX);
ottaviano3 0:d75a1797ffd9 7
ottaviano3 0:d75a1797ffd9 8 // SPI Pins
ottaviano3 0:d75a1797ffd9 9 SPI AdaBLE(p11,p12,p13);
ottaviano3 0:d75a1797ffd9 10
ottaviano3 0:d75a1797ffd9 11 // Input, RDYN active low, goes low when the BLE is ready to recieve data, or has data to send
ottaviano3 0:d75a1797ffd9 12 DigitalIn AdaRdyN(p30);
ottaviano3 0:d75a1797ffd9 13 // Output, REQN active low, put low to request right to send data.
ottaviano3 0:d75a1797ffd9 14 DigitalOut AdaReqN(p27);
ottaviano3 0:d75a1797ffd9 15 // Input, goes low when the BLE is busy recieving or sending data.
ottaviano3 0:d75a1797ffd9 16 DigitalIn AdaAct(p29);
ottaviano3 0:d75a1797ffd9 17 // Output, resets the module
ottaviano3 0:d75a1797ffd9 18 DigitalOut AdaRst(p28);
ottaviano3 0:d75a1797ffd9 19
ottaviano3 0:d75a1797ffd9 20 // A function that loads configuration information into the nRF8001
ottaviano3 0:d75a1797ffd9 21 void SetupBLE();
ottaviano3 0:d75a1797ffd9 22 // A function that switches 8 bit MSB to LSB.
ottaviano3 0:d75a1797ffd9 23 unsigned char BOReverse(unsigned char cmd);
ottaviano3 0:d75a1797ffd9 24 // Function that writes setup lines.
ottaviano3 0:d75a1797ffd9 25 bool SetupWriter(char setup[], int length);
ottaviano3 0:d75a1797ffd9 26 // Puts device into connect mode.
ottaviano3 0:d75a1797ffd9 27 void BLEConnectMode();
ottaviano3 0:d75a1797ffd9 28
ottaviano3 0:d75a1797ffd9 29 // Some well used temporary variables.
ottaviano3 0:d75a1797ffd9 30 volatile int counter;
ottaviano3 0:d75a1797ffd9 31 volatile unsigned char temp;
ottaviano3 0:d75a1797ffd9 32
ottaviano3 0:d75a1797ffd9 33 // Timeout for BLE connection
ottaviano3 0:d75a1797ffd9 34 Timer timeout;
ottaviano3 0:d75a1797ffd9 35
ottaviano3 0:d75a1797ffd9 36 // Buffer to store SPI reads.
ottaviano3 0:d75a1797ffd9 37 unsigned char buffer[100];
ottaviano3 0:d75a1797ffd9 38
ottaviano3 0:d75a1797ffd9 39 int main()
ottaviano3 0:d75a1797ffd9 40 {
ottaviano3 0:d75a1797ffd9 41 ////////// Intialization \\\\\\\\\\
ottaviano3 0:d75a1797ffd9 42
ottaviano3 0:d75a1797ffd9 43 // Serial PC Configuration \\
ottaviano3 0:d75a1797ffd9 44 // Set PC baud rate. Default 9600
ottaviano3 0:d75a1797ffd9 45 pc.baud(9600);
ottaviano3 0:d75a1797ffd9 46
ottaviano3 0:d75a1797ffd9 47 // SPI Configuration \\
ottaviano3 0:d75a1797ffd9 48 // Set SPI frequency. nRF maximum is 3 Mhz as per datasheet page 26
ottaviano3 0:d75a1797ffd9 49 AdaBLE.frequency(2000000);
ottaviano3 0:d75a1797ffd9 50 // Set SPI mode 0, 8 bits. nRF uses SPI mode 0, LSB order. mbed uses MSB so a conversion function is nessesary.
ottaviano3 0:d75a1797ffd9 51 AdaBLE.format(8,0);
ottaviano3 0:d75a1797ffd9 52
ottaviano3 0:d75a1797ffd9 53 // Pull Up RDYn line as per nRF8001 datasheet page 23
ottaviano3 0:d75a1797ffd9 54 //AdaRdyN.mode(PullUp); // !! Pin is already pulled up on the Adafruit breakout board by built in hardware. :)
ottaviano3 0:d75a1797ffd9 55
ottaviano3 0:d75a1797ffd9 56 // Hold reset line high to bring device online.
ottaviano3 0:d75a1797ffd9 57 AdaRst = 1;
ottaviano3 0:d75a1797ffd9 58
ottaviano3 0:d75a1797ffd9 59 // Wait 62 miliseconds per nRF8001 datasheet, page 23, for RDYn signal to be valid.
ottaviano3 0:d75a1797ffd9 60 wait_ms(62);
ottaviano3 0:d75a1797ffd9 61
ottaviano3 0:d75a1797ffd9 62 // Print out dat sweet welcome message.
ottaviano3 0:d75a1797ffd9 63 pc.printf("\r====== Shit Where's My Phone Serial Debug Console ======\n\r");
ottaviano3 0:d75a1797ffd9 64 pc.printf("Version: %4.1f\n\r\n\r",version);
ottaviano3 0:d75a1797ffd9 65
ottaviano3 0:d75a1797ffd9 66 // Run Device Setup \\
ottaviano3 0:d75a1797ffd9 67
ottaviano3 0:d75a1797ffd9 68 // Message to serial
ottaviano3 0:d75a1797ffd9 69 pc.printf("Waiting for device to become ready: |");
ottaviano3 0:d75a1797ffd9 70
ottaviano3 0:d75a1797ffd9 71 // Now we wait for the nRF to lower the RDYn signal.
ottaviano3 0:d75a1797ffd9 72 counter = 0;
ottaviano3 0:d75a1797ffd9 73 timeout.stop();
ottaviano3 0:d75a1797ffd9 74 timeout.reset();
ottaviano3 0:d75a1797ffd9 75 timeout.start();
ottaviano3 0:d75a1797ffd9 76 while (AdaRdyN != 0) {
ottaviano3 0:d75a1797ffd9 77 // Do nothing important, i update the display here in terminal.
ottaviano3 0:d75a1797ffd9 78 if (timeout.read() > 2) {
ottaviano3 0:d75a1797ffd9 79 error("\n\rnRF module never came online...");
ottaviano3 0:d75a1797ffd9 80 }
ottaviano3 0:d75a1797ffd9 81 // Wait for device to become ready.
ottaviano3 0:d75a1797ffd9 82 if (counter%3 == 0) {
ottaviano3 0:d75a1797ffd9 83 pc.printf("\b/");
ottaviano3 0:d75a1797ffd9 84 } else if (counter%3 == 1) {
ottaviano3 0:d75a1797ffd9 85 pc.printf("\b-");
ottaviano3 0:d75a1797ffd9 86 } else if (counter%3 == 2) {
ottaviano3 0:d75a1797ffd9 87 pc.printf("\b\\");
ottaviano3 0:d75a1797ffd9 88 } else {
ottaviano3 0:d75a1797ffd9 89 pc.printf("\b|");
ottaviano3 0:d75a1797ffd9 90 }
ottaviano3 0:d75a1797ffd9 91 counter++;
ottaviano3 0:d75a1797ffd9 92 }
ottaviano3 0:d75a1797ffd9 93 // nRF has signaled it has data for me to recieve.
ottaviano3 0:d75a1797ffd9 94
ottaviano3 0:d75a1797ffd9 95 // Set REQn to ground then start clocking in data.
ottaviano3 0:d75a1797ffd9 96 AdaReqN = 0;
ottaviano3 0:d75a1797ffd9 97
ottaviano3 0:d75a1797ffd9 98 BOReverse(AdaBLE.write(0x00)); // Discard this first byte as it is a debug byte.
ottaviano3 0:d75a1797ffd9 99 temp = BOReverse(AdaBLE.write(0x00)); // First byte defines message length. Since this is a bootup message it should always be 4 bytes long.
ottaviano3 0:d75a1797ffd9 100
ottaviano3 0:d75a1797ffd9 101 // Clock in remaining bytes
ottaviano3 0:d75a1797ffd9 102 for (int i = 0; i < temp; i++) {
ottaviano3 0:d75a1797ffd9 103 buffer[i] = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 104 }
ottaviano3 0:d75a1797ffd9 105
ottaviano3 0:d75a1797ffd9 106 // Now set REQn back to high to close this transaction
ottaviano3 0:d75a1797ffd9 107 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 108
ottaviano3 0:d75a1797ffd9 109 // Lets read this message.
ottaviano3 0:d75a1797ffd9 110 switch (buffer[0]) {
ottaviano3 0:d75a1797ffd9 111 case 0x81:
ottaviano3 0:d75a1797ffd9 112 pc.printf("\bDone!\n\r");
ottaviano3 0:d75a1797ffd9 113 break;
ottaviano3 0:d75a1797ffd9 114 default:
ottaviano3 0:d75a1797ffd9 115 error("\n\rStart packet not recieved!");
ottaviano3 0:d75a1797ffd9 116 break;
ottaviano3 0:d75a1797ffd9 117 }
ottaviano3 0:d75a1797ffd9 118
ottaviano3 0:d75a1797ffd9 119 // Get operating mode. 0x01 = test, 0x02 = setup, 0x03 = standby
ottaviano3 0:d75a1797ffd9 120 unsigned char OpMode = buffer[1];
ottaviano3 0:d75a1797ffd9 121 // Check for HW error. 0x00 = no error, 0x01 = fatal error.
ottaviano3 0:d75a1797ffd9 122 unsigned char HWError = buffer[2];
ottaviano3 0:d75a1797ffd9 123 // Get DataCreditAvailiable, number of DataCommand buffers available.
ottaviano3 0:d75a1797ffd9 124 unsigned char DCAvail = buffer[3];
ottaviano3 0:d75a1797ffd9 125
ottaviano3 0:d75a1797ffd9 126 // Print Operational Mode to terminal.
ottaviano3 0:d75a1797ffd9 127 pc.printf("Operational Mode: ");
ottaviano3 0:d75a1797ffd9 128 switch (OpMode) {
ottaviano3 0:d75a1797ffd9 129 case 0x01:
ottaviano3 0:d75a1797ffd9 130 pc.printf("Test\n\r");
ottaviano3 0:d75a1797ffd9 131 break;
ottaviano3 0:d75a1797ffd9 132 case 0x02:
ottaviano3 0:d75a1797ffd9 133 pc.printf("Setup\n\r");
ottaviano3 0:d75a1797ffd9 134 break;
ottaviano3 0:d75a1797ffd9 135 case 0x03:
ottaviano3 0:d75a1797ffd9 136 pc.printf("Standby\n\r");
ottaviano3 0:d75a1797ffd9 137 break;
ottaviano3 0:d75a1797ffd9 138 default:
ottaviano3 0:d75a1797ffd9 139 error("Invalid Operational Mode!");
ottaviano3 0:d75a1797ffd9 140 break;
ottaviano3 0:d75a1797ffd9 141 }
ottaviano3 0:d75a1797ffd9 142
ottaviano3 0:d75a1797ffd9 143 // Warn if HW Error
ottaviano3 0:d75a1797ffd9 144 pc.printf("HW error last boot: ");
ottaviano3 0:d75a1797ffd9 145 switch (HWError) {
ottaviano3 0:d75a1797ffd9 146 case 0x00:
ottaviano3 0:d75a1797ffd9 147 pc.printf("No\n\r");
ottaviano3 0:d75a1797ffd9 148 break;
ottaviano3 0:d75a1797ffd9 149 case 0x01:
ottaviano3 0:d75a1797ffd9 150 pc.printf("Yes\n\r");
ottaviano3 0:d75a1797ffd9 151 break;
ottaviano3 0:d75a1797ffd9 152 default:
ottaviano3 0:d75a1797ffd9 153 error("Invalid Data Recieved");
ottaviano3 0:d75a1797ffd9 154 break;
ottaviano3 0:d75a1797ffd9 155 }
ottaviano3 0:d75a1797ffd9 156
ottaviano3 0:d75a1797ffd9 157 // Print number of datacommand buffers avaliable.
ottaviano3 0:d75a1797ffd9 158 pc.printf("DataCommand buffers avaliable: %i\n\r",DCAvail);
ottaviano3 0:d75a1797ffd9 159
ottaviano3 0:d75a1797ffd9 160 // Call setup routine
ottaviano3 0:d75a1797ffd9 161 SetupBLE();
ottaviano3 0:d75a1797ffd9 162
ottaviano3 0:d75a1797ffd9 163 // Setup complete and device should be in standby mode!
ottaviano3 0:d75a1797ffd9 164
ottaviano3 0:d75a1797ffd9 165 pc.printf("\n\rAbout to start advertising...\n\r");
ottaviano3 0:d75a1797ffd9 166 // Run connect to start pairing
ottaviano3 0:d75a1797ffd9 167 BLEConnectMode();
ottaviano3 0:d75a1797ffd9 168
ottaviano3 0:d75a1797ffd9 169 while(1) {
ottaviano3 0:d75a1797ffd9 170 // Main runloop
ottaviano3 0:d75a1797ffd9 171 if (AdaRdyN == 0) {
ottaviano3 0:d75a1797ffd9 172 pc.printf("\n\r");
ottaviano3 0:d75a1797ffd9 173 AdaReqN = 0;
ottaviano3 0:d75a1797ffd9 174 BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 175 temp = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 176
ottaviano3 0:d75a1797ffd9 177 // Clock in remaining bytes
ottaviano3 0:d75a1797ffd9 178 for (int i = 0; i < temp; i++) {
ottaviano3 0:d75a1797ffd9 179 buffer[i] = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 180 pc.printf("%02x ",buffer[i]);
ottaviano3 0:d75a1797ffd9 181 }
ottaviano3 0:d75a1797ffd9 182 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 183 }
ottaviano3 0:d75a1797ffd9 184 }
ottaviano3 0:d75a1797ffd9 185 }
ottaviano3 0:d75a1797ffd9 186
ottaviano3 0:d75a1797ffd9 187 void BLEConnectMode()
ottaviano3 0:d75a1797ffd9 188 {
ottaviano3 0:d75a1797ffd9 189 // Set REQn to ground
ottaviano3 0:d75a1797ffd9 190 AdaReqN = 0;
ottaviano3 0:d75a1797ffd9 191 timeout.stop();
ottaviano3 0:d75a1797ffd9 192 timeout.reset();
ottaviano3 0:d75a1797ffd9 193 timeout.start();
ottaviano3 0:d75a1797ffd9 194 while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
ottaviano3 0:d75a1797ffd9 195 if (timeout.read() > 2) {
ottaviano3 0:d75a1797ffd9 196 error("\n\rError: No rights to send.");
ottaviano3 0:d75a1797ffd9 197 }
ottaviano3 0:d75a1797ffd9 198 }
ottaviano3 0:d75a1797ffd9 199 // Lenght of packet
ottaviano3 0:d75a1797ffd9 200 AdaBLE.write(BOReverse(0x05));
ottaviano3 0:d75a1797ffd9 201 // Connect packet header
ottaviano3 0:d75a1797ffd9 202 AdaBLE.write(BOReverse(0x0F));
ottaviano3 0:d75a1797ffd9 203 // Set bluetooth announce in seconds.
ottaviano3 0:d75a1797ffd9 204 AdaBLE.write(BOReverse(0x1E)); // !! Reverse order of bits since LSB
ottaviano3 0:d75a1797ffd9 205 AdaBLE.write(BOReverse(0x00)); // 0x1E is 30 seconds
ottaviano3 0:d75a1797ffd9 206 // Set advertisement interval. This setting * 0.625 msec = interval
ottaviano3 0:d75a1797ffd9 207 AdaBLE.write(BOReverse(0x20)); // !! Reverse order of bits since LSB
ottaviano3 0:d75a1797ffd9 208 AdaBLE.write(BOReverse(0x03)); // 0x0620 is 1600, 1 second interval.
ottaviano3 0:d75a1797ffd9 209
ottaviano3 0:d75a1797ffd9 210 // Set REQn high to end transaction
ottaviano3 0:d75a1797ffd9 211 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 212
ottaviano3 0:d75a1797ffd9 213 // Wait for command response event packet
ottaviano3 0:d75a1797ffd9 214
ottaviano3 0:d75a1797ffd9 215 // Now we wait for the response packet to signal a successful transfer.
ottaviano3 0:d75a1797ffd9 216 timeout.stop();
ottaviano3 0:d75a1797ffd9 217 timeout.reset();
ottaviano3 0:d75a1797ffd9 218 timeout.start();
ottaviano3 0:d75a1797ffd9 219 while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
ottaviano3 0:d75a1797ffd9 220 if (timeout.read() > 2) {
ottaviano3 0:d75a1797ffd9 221 error("\n\rError: No response packet recieved.");
ottaviano3 0:d75a1797ffd9 222 }
ottaviano3 0:d75a1797ffd9 223 }
ottaviano3 0:d75a1797ffd9 224
ottaviano3 0:d75a1797ffd9 225 // Now set REQn to ground and clock in data
ottaviano3 0:d75a1797ffd9 226 AdaReqN = 0;
ottaviano3 0:d75a1797ffd9 227
ottaviano3 0:d75a1797ffd9 228 // discard first byte
ottaviano3 0:d75a1797ffd9 229 BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 230 // get length data
ottaviano3 0:d75a1797ffd9 231 temp = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 232
ottaviano3 0:d75a1797ffd9 233 // Clock in remaining bytes
ottaviano3 0:d75a1797ffd9 234 for (int i = 0; i < temp; i++) {
ottaviano3 0:d75a1797ffd9 235 buffer[i] = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 236 }
ottaviano3 0:d75a1797ffd9 237
ottaviano3 0:d75a1797ffd9 238 // Read data
ottaviano3 0:d75a1797ffd9 239 if (buffer[0] != 0x84) {
ottaviano3 0:d75a1797ffd9 240 error("\n\rNot CommandResponseEvent!");
ottaviano3 0:d75a1797ffd9 241 }
ottaviano3 0:d75a1797ffd9 242
ottaviano3 0:d75a1797ffd9 243 if (buffer[1] != 0x0F) {
ottaviano3 0:d75a1797ffd9 244 error("\n\rNot the correct CommandResponseEvent!");
ottaviano3 0:d75a1797ffd9 245 }
ottaviano3 0:d75a1797ffd9 246
ottaviano3 0:d75a1797ffd9 247 switch (buffer[2]) {
ottaviano3 0:d75a1797ffd9 248 case 0x00:
ottaviano3 0:d75a1797ffd9 249 // Sucess lets continue
ottaviano3 0:d75a1797ffd9 250 // Now set REQn high to end transaction
ottaviano3 0:d75a1797ffd9 251 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 252 break;
ottaviano3 0:d75a1797ffd9 253 default:
ottaviano3 0:d75a1797ffd9 254 // Error failled to announce
ottaviano3 0:d75a1797ffd9 255 error("\n\rFailed announce!");
ottaviano3 0:d75a1797ffd9 256 break;
ottaviano3 0:d75a1797ffd9 257 }
ottaviano3 0:d75a1797ffd9 258
ottaviano3 0:d75a1797ffd9 259 pc.printf("Bluetooth announcement successful! Look for it in peer device.\n\r");
ottaviano3 0:d75a1797ffd9 260 return;
ottaviano3 0:d75a1797ffd9 261 }
ottaviano3 0:d75a1797ffd9 262
ottaviano3 0:d75a1797ffd9 263 unsigned char BOReverse(unsigned char cmd)
ottaviano3 0:d75a1797ffd9 264 {
ottaviano3 0:d75a1797ffd9 265 return (((cmd * 0x0802LU & 0x22110LU) | (cmd * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16);
ottaviano3 0:d75a1797ffd9 266 }
ottaviano3 0:d75a1797ffd9 267
ottaviano3 0:d75a1797ffd9 268 bool SetupWriter(unsigned char setup[], int length)
ottaviano3 0:d75a1797ffd9 269 {
ottaviano3 0:d75a1797ffd9 270 // Set REQn line to groud to request right to send.
ottaviano3 0:d75a1797ffd9 271 AdaReqN = 0;
ottaviano3 0:d75a1797ffd9 272 // reset timeout timer
ottaviano3 0:d75a1797ffd9 273 timeout.stop();
ottaviano3 0:d75a1797ffd9 274 timeout.reset();
ottaviano3 0:d75a1797ffd9 275 timeout.start();
ottaviano3 0:d75a1797ffd9 276 while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
ottaviano3 0:d75a1797ffd9 277 if (timeout.read() > 2) {
ottaviano3 0:d75a1797ffd9 278 error("\n\rError: No rights to send.");
ottaviano3 0:d75a1797ffd9 279 }
ottaviano3 0:d75a1797ffd9 280 }
ottaviano3 0:d75a1797ffd9 281 // Right to send recieved, Write setup strings
ottaviano3 0:d75a1797ffd9 282 for (int i = 0; i < (length); i++) {
ottaviano3 0:d75a1797ffd9 283 AdaBLE.write(BOReverse(setup[i]));
ottaviano3 0:d75a1797ffd9 284 }
ottaviano3 0:d75a1797ffd9 285
ottaviano3 0:d75a1797ffd9 286 // Set REQn high to finish this transaction
ottaviano3 0:d75a1797ffd9 287 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 288
ottaviano3 0:d75a1797ffd9 289 // Reset Timer
ottaviano3 0:d75a1797ffd9 290 timeout.stop();
ottaviano3 0:d75a1797ffd9 291 timeout.reset();
ottaviano3 0:d75a1797ffd9 292 timeout.start();
ottaviano3 0:d75a1797ffd9 293 temp = 0x00;
ottaviano3 0:d75a1797ffd9 294
ottaviano3 0:d75a1797ffd9 295 // Now we wait for the response packet to signal a successful transfer.
ottaviano3 0:d75a1797ffd9 296 while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
ottaviano3 0:d75a1797ffd9 297 if (timeout.read() > 2) {
ottaviano3 0:d75a1797ffd9 298 error("\n\rError: No response packet recieved.");
ottaviano3 0:d75a1797ffd9 299 }
ottaviano3 0:d75a1797ffd9 300 }
ottaviano3 0:d75a1797ffd9 301
ottaviano3 0:d75a1797ffd9 302 // Now set REQn to ground and clock in data
ottaviano3 0:d75a1797ffd9 303 AdaReqN = 0;
ottaviano3 0:d75a1797ffd9 304
ottaviano3 0:d75a1797ffd9 305 // discard first byte
ottaviano3 0:d75a1797ffd9 306 BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 307 // get length data
ottaviano3 0:d75a1797ffd9 308 temp = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 309
ottaviano3 0:d75a1797ffd9 310 // Clock in remaining bytes
ottaviano3 0:d75a1797ffd9 311 for (int i = 0; i < temp; i++) {
ottaviano3 0:d75a1797ffd9 312 buffer[i] = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 313 }
ottaviano3 0:d75a1797ffd9 314
ottaviano3 0:d75a1797ffd9 315 if (buffer[0] != 0x84) {
ottaviano3 0:d75a1797ffd9 316 error("\n\rNot CommandResponseEvent!");
ottaviano3 0:d75a1797ffd9 317 }
ottaviano3 0:d75a1797ffd9 318
ottaviano3 0:d75a1797ffd9 319 if (buffer[1] != 0x06) {
ottaviano3 0:d75a1797ffd9 320 error("\n\rNot the correct CommandResponseEvent!");
ottaviano3 0:d75a1797ffd9 321 }
ottaviano3 0:d75a1797ffd9 322
ottaviano3 0:d75a1797ffd9 323 switch (buffer[2]) {
ottaviano3 0:d75a1797ffd9 324 case 0x01:
ottaviano3 0:d75a1797ffd9 325 // Sucess lets continue
ottaviano3 0:d75a1797ffd9 326 // Now set REQn high to end transaction
ottaviano3 0:d75a1797ffd9 327 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 328 return true;
ottaviano3 0:d75a1797ffd9 329 case 0x02:
ottaviano3 0:d75a1797ffd9 330 // We finished writing settings!
ottaviano3 0:d75a1797ffd9 331 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 332 return true;
ottaviano3 0:d75a1797ffd9 333 case 0x88:
ottaviano3 0:d75a1797ffd9 334 // CRC mismatch
ottaviano3 0:d75a1797ffd9 335 error("\n\r\n\rACI_STATUS_ERROR_CRC_MISMATCH - CRC Mismatch Error\n\rThis is caused by not accurately entering the strings from nRFgo Studio.");
ottaviano3 0:d75a1797ffd9 336 default:
ottaviano3 0:d75a1797ffd9 337 // Error not expected
ottaviano3 0:d75a1797ffd9 338 error("\n\rUnexpected Response!");
ottaviano3 0:d75a1797ffd9 339 break;
ottaviano3 0:d75a1797ffd9 340 }
ottaviano3 0:d75a1797ffd9 341
ottaviano3 0:d75a1797ffd9 342 // Should never be reached but just in case.
ottaviano3 0:d75a1797ffd9 343 return false;
ottaviano3 0:d75a1797ffd9 344 }
ottaviano3 0:d75a1797ffd9 345
ottaviano3 0:d75a1797ffd9 346 void SetupBLE()
ottaviano3 0:d75a1797ffd9 347 {
ottaviano3 0:d75a1797ffd9 348 // Write setup data arrays (Generated in nRFgo Studio)
ottaviano3 0:d75a1797ffd9 349 unsigned char setup1[] = {0x07,0x06,0x00,0x00,0x03,0x02,0x42,0x07};
ottaviano3 0:d75a1797ffd9 350 unsigned char setup2[] = {0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x06,0x00,0x00,
ottaviano3 0:d75a1797ffd9 351 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
ottaviano3 0:d75a1797ffd9 352 };
ottaviano3 0:d75a1797ffd9 353 unsigned char setup3[] = {0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
ottaviano3 0:d75a1797ffd9 354 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x03,0x90,0x01,0xff
ottaviano3 0:d75a1797ffd9 355 };
ottaviano3 0:d75a1797ffd9 356 unsigned char setup4[] = {0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
ottaviano3 0:d75a1797ffd9 357 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
ottaviano3 0:d75a1797ffd9 358 };
ottaviano3 0:d75a1797ffd9 359 unsigned char setup5[] = {0x05,0x06,0x10,0x54,0x00,0x00};
ottaviano3 0:d75a1797ffd9 360 unsigned char setup6[] = {0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,
ottaviano3 0:d75a1797ffd9 361 0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14
ottaviano3 0:d75a1797ffd9 362 };
ottaviano3 0:d75a1797ffd9 363 unsigned char setup7[] = {0x1f,0x06,0x20,0x1c,0x04,0x00,0x03,0x2a,0x00,0x01,0x53,0x57,0x4d,0x46,0x69,0x63,0x73,0x65,0x6d,0x69,
ottaviano3 0:d75a1797ffd9 364 0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04
ottaviano3 0:d75a1797ffd9 365 };
ottaviano3 0:d75a1797ffd9 366 unsigned char setup8[] = {0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,
ottaviano3 0:d75a1797ffd9 367 0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00
ottaviano3 0:d75a1797ffd9 368 };
ottaviano3 0:d75a1797ffd9 369 unsigned char setup9[] = {0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,
ottaviano3 0:d75a1797ffd9 370 0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x04,0x04
ottaviano3 0:d75a1797ffd9 371 };
ottaviano3 0:d75a1797ffd9 372 unsigned char setup10[] = {0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,
ottaviano3 0:d75a1797ffd9 373 0x00,0x01,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48
ottaviano3 0:d75a1797ffd9 374 };
ottaviano3 0:d75a1797ffd9 375 unsigned char setup11[] = {0x1f,0x06,0x20,0x8c,0x6e,0xec,0x0f,0x18,0xfd,0x5a,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x02,
ottaviano3 0:d75a1797ffd9 376 0x0b,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48
ottaviano3 0:d75a1797ffd9 377 };
ottaviano3 0:d75a1797ffd9 378 unsigned char setup12[] = {0x1f,0x06,0x20,0xa8,0x6e,0xec,0x19,0x2a,0xfd,0x5a,0x06,0x04,0x02,0x01,0x00,0x0b,0x2a,0x19,0x02,0x10,
ottaviano3 0:d75a1797ffd9 379 0x04,0x04,0x13,0x13,0x00,0x0c,0x28,0x03,0x01,0x02,0x0d,0x00
ottaviano3 0:d75a1797ffd9 380 };
ottaviano3 0:d75a1797ffd9 381 unsigned char setup13[] = {0x1f,0x06,0x20,0xc4,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48,0x6e,0xec,0x1a,0x2a,0xfd,0x5a,
ottaviano3 0:d75a1797ffd9 382 0x06,0x04,0x02,0x01,0x00,0x0d,0x2a,0x1a,0x02,0x00,0x04,0x04
ottaviano3 0:d75a1797ffd9 383 };
ottaviano3 0:d75a1797ffd9 384 unsigned char setup14[] = {0x1f,0x06,0x20,0xe0,0x13,0x13,0x00,0x0e,0x28,0x03,0x01,0x02,0x0f,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,
ottaviano3 0:d75a1797ffd9 385 0x27,0xb0,0x1b,0x48,0x6e,0xec,0x1b,0x2a,0xfd,0x5a,0x06,0x04
ottaviano3 0:d75a1797ffd9 386 };
ottaviano3 0:d75a1797ffd9 387 unsigned char setup15[] = {0x0d,0x06,0x20,0xfc,0x03,0x02,0x00,0x0f,0x2a,0x1b,0x02,0x00,0x00,0x00};
ottaviano3 0:d75a1797ffd9 388 unsigned char setup16[] = {0x13,0x06,0x50,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48,0x6e,0xec,0x00,0x00,0xfd,0x5a};
ottaviano3 0:d75a1797ffd9 389 unsigned char setup17[] = {0x06,0x06,0xf0,0x00,0x03,0x7f,0xc3};
ottaviano3 0:d75a1797ffd9 390
ottaviano3 0:d75a1797ffd9 391 pc.printf("Starting to write settings...");
ottaviano3 0:d75a1797ffd9 392 // Setup 1
ottaviano3 0:d75a1797ffd9 393 if (!SetupWriter(setup1,sizeof(setup1)/sizeof(setup1[1]))) {
ottaviano3 0:d75a1797ffd9 394 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 395 }
ottaviano3 0:d75a1797ffd9 396 pc.printf("1,");
ottaviano3 0:d75a1797ffd9 397
ottaviano3 0:d75a1797ffd9 398 // Setup 2
ottaviano3 0:d75a1797ffd9 399 if (!SetupWriter(setup2,sizeof(setup2)/sizeof(setup2[1]))) {
ottaviano3 0:d75a1797ffd9 400 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 401 }
ottaviano3 0:d75a1797ffd9 402 pc.printf("2,");
ottaviano3 0:d75a1797ffd9 403
ottaviano3 0:d75a1797ffd9 404 // Setup 3
ottaviano3 0:d75a1797ffd9 405 if (!SetupWriter(setup3,sizeof(setup3)/sizeof(setup3[1]))) {
ottaviano3 0:d75a1797ffd9 406 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 407 }
ottaviano3 0:d75a1797ffd9 408 pc.printf("3,");
ottaviano3 0:d75a1797ffd9 409
ottaviano3 0:d75a1797ffd9 410 // Setup 4
ottaviano3 0:d75a1797ffd9 411 if (!SetupWriter(setup4,sizeof(setup4)/sizeof(setup4[1]))) {
ottaviano3 0:d75a1797ffd9 412 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 413 }
ottaviano3 0:d75a1797ffd9 414 pc.printf("4,");
ottaviano3 0:d75a1797ffd9 415
ottaviano3 0:d75a1797ffd9 416 // Setup 5
ottaviano3 0:d75a1797ffd9 417 if (!SetupWriter(setup5,sizeof(setup5)/sizeof(setup5[1]))) {
ottaviano3 0:d75a1797ffd9 418 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 419 }
ottaviano3 0:d75a1797ffd9 420 pc.printf("5,");
ottaviano3 0:d75a1797ffd9 421
ottaviano3 0:d75a1797ffd9 422 // Setup 6
ottaviano3 0:d75a1797ffd9 423 if (!SetupWriter(setup6,sizeof(setup6)/sizeof(setup6[1]))) {
ottaviano3 0:d75a1797ffd9 424 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 425 }
ottaviano3 0:d75a1797ffd9 426 pc.printf("6,");
ottaviano3 0:d75a1797ffd9 427
ottaviano3 0:d75a1797ffd9 428 // Setup 7
ottaviano3 0:d75a1797ffd9 429 if (!SetupWriter(setup7,sizeof(setup7)/sizeof(setup7[1]))) {
ottaviano3 0:d75a1797ffd9 430 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 431 }
ottaviano3 0:d75a1797ffd9 432 pc.printf("7,");
ottaviano3 0:d75a1797ffd9 433
ottaviano3 0:d75a1797ffd9 434 // Setup 8
ottaviano3 0:d75a1797ffd9 435 if (!SetupWriter(setup8,sizeof(setup8)/sizeof(setup8[1]))) {
ottaviano3 0:d75a1797ffd9 436 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 437 }
ottaviano3 0:d75a1797ffd9 438 pc.printf("8,");
ottaviano3 0:d75a1797ffd9 439
ottaviano3 0:d75a1797ffd9 440 // Setup 9
ottaviano3 0:d75a1797ffd9 441 if (!SetupWriter(setup9,sizeof(setup9)/sizeof(setup9[1]))) {
ottaviano3 0:d75a1797ffd9 442 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 443 }
ottaviano3 0:d75a1797ffd9 444 pc.printf("9,");
ottaviano3 0:d75a1797ffd9 445
ottaviano3 0:d75a1797ffd9 446 // Setup 10
ottaviano3 0:d75a1797ffd9 447 if (!SetupWriter(setup10,sizeof(setup10)/sizeof(setup10[1]))) {
ottaviano3 0:d75a1797ffd9 448 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 449 }
ottaviano3 0:d75a1797ffd9 450 pc.printf("10,");
ottaviano3 0:d75a1797ffd9 451
ottaviano3 0:d75a1797ffd9 452 // Setup 11
ottaviano3 0:d75a1797ffd9 453 if (!SetupWriter(setup11,sizeof(setup11)/sizeof(setup11[1]))) {
ottaviano3 0:d75a1797ffd9 454 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 455 }
ottaviano3 0:d75a1797ffd9 456 pc.printf("11,");
ottaviano3 0:d75a1797ffd9 457
ottaviano3 0:d75a1797ffd9 458 // Setup 12
ottaviano3 0:d75a1797ffd9 459 if (!SetupWriter(setup12,sizeof(setup12)/sizeof(setup12[1]))) {
ottaviano3 0:d75a1797ffd9 460 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 461 }
ottaviano3 0:d75a1797ffd9 462 pc.printf("12,");
ottaviano3 0:d75a1797ffd9 463
ottaviano3 0:d75a1797ffd9 464 // Setup 13
ottaviano3 0:d75a1797ffd9 465 if (!SetupWriter(setup13,sizeof(setup13)/sizeof(setup13[1]))) {
ottaviano3 0:d75a1797ffd9 466 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 467 }
ottaviano3 0:d75a1797ffd9 468 pc.printf("13,");
ottaviano3 0:d75a1797ffd9 469
ottaviano3 0:d75a1797ffd9 470 // Setup 14
ottaviano3 0:d75a1797ffd9 471 if (!SetupWriter(setup14,sizeof(setup14)/sizeof(setup14[1]))) {
ottaviano3 0:d75a1797ffd9 472 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 473 }
ottaviano3 0:d75a1797ffd9 474 pc.printf("14,");
ottaviano3 0:d75a1797ffd9 475
ottaviano3 0:d75a1797ffd9 476 // Setup 15
ottaviano3 0:d75a1797ffd9 477 if (!SetupWriter(setup15,sizeof(setup15)/sizeof(setup15[1]))) {
ottaviano3 0:d75a1797ffd9 478 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 479 }
ottaviano3 0:d75a1797ffd9 480 pc.printf("15,");
ottaviano3 0:d75a1797ffd9 481
ottaviano3 0:d75a1797ffd9 482 // Setup 16
ottaviano3 0:d75a1797ffd9 483 if (!SetupWriter(setup16,sizeof(setup16)/sizeof(setup16[1]))) {
ottaviano3 0:d75a1797ffd9 484 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 485 }
ottaviano3 0:d75a1797ffd9 486 pc.printf("16,");
ottaviano3 0:d75a1797ffd9 487
ottaviano3 0:d75a1797ffd9 488 // Setup 17
ottaviano3 0:d75a1797ffd9 489 if (!SetupWriter(setup17,sizeof(setup17)/sizeof(setup17[1]))) {
ottaviano3 0:d75a1797ffd9 490 error("\n\rWrite Failed!");
ottaviano3 0:d75a1797ffd9 491 }
ottaviano3 0:d75a1797ffd9 492 pc.printf("17");
ottaviano3 0:d75a1797ffd9 493 // Done writing setup strings phew!
ottaviano3 0:d75a1797ffd9 494
ottaviano3 0:d75a1797ffd9 495 // Wait for DeviceStartedEvent
ottaviano3 0:d75a1797ffd9 496 pc.printf("\n\rWaiting for device to accept settings: |");
ottaviano3 0:d75a1797ffd9 497
ottaviano3 0:d75a1797ffd9 498 // Now we wait for the nRF to lower the RDYn signal.
ottaviano3 0:d75a1797ffd9 499 counter = 0;
ottaviano3 0:d75a1797ffd9 500 timeout.stop();
ottaviano3 0:d75a1797ffd9 501 timeout.reset();
ottaviano3 0:d75a1797ffd9 502 timeout.start();
ottaviano3 0:d75a1797ffd9 503 while (AdaRdyN != 0) {
ottaviano3 0:d75a1797ffd9 504 // Do nothing important, i update the display here in terminal.
ottaviano3 0:d75a1797ffd9 505 if (timeout.read() > 2) {
ottaviano3 0:d75a1797ffd9 506 error("\n\rnRF module never came back after settings where written...");
ottaviano3 0:d75a1797ffd9 507 }
ottaviano3 0:d75a1797ffd9 508 // Wait for device to become ready.
ottaviano3 0:d75a1797ffd9 509 if (counter%3 == 0) {
ottaviano3 0:d75a1797ffd9 510 pc.printf("\b/");
ottaviano3 0:d75a1797ffd9 511 } else if (counter%3 == 1) {
ottaviano3 0:d75a1797ffd9 512 pc.printf("\b-");
ottaviano3 0:d75a1797ffd9 513 } else if (counter%3 == 2) {
ottaviano3 0:d75a1797ffd9 514 pc.printf("\b\\");
ottaviano3 0:d75a1797ffd9 515 } else {
ottaviano3 0:d75a1797ffd9 516 pc.printf("\b|");
ottaviano3 0:d75a1797ffd9 517 }
ottaviano3 0:d75a1797ffd9 518 counter++;
ottaviano3 0:d75a1797ffd9 519 }
ottaviano3 0:d75a1797ffd9 520 // nRF has signaled it has data for me to recieve.
ottaviano3 0:d75a1797ffd9 521
ottaviano3 0:d75a1797ffd9 522 // Set REQn to ground then start clocking in data.
ottaviano3 0:d75a1797ffd9 523 AdaReqN = 0;
ottaviano3 0:d75a1797ffd9 524
ottaviano3 0:d75a1797ffd9 525 BOReverse(AdaBLE.write(0x00)); // Discard this first byte as it is a debug byte.
ottaviano3 0:d75a1797ffd9 526 temp = BOReverse(AdaBLE.write(0x00)); // First byte defines message length. Since this is a bootup message it should always be 4 bytes long.
ottaviano3 0:d75a1797ffd9 527
ottaviano3 0:d75a1797ffd9 528 // Clock in remaining bytes
ottaviano3 0:d75a1797ffd9 529 for (int i = 0; i < temp; i++) {
ottaviano3 0:d75a1797ffd9 530 buffer[i] = BOReverse(AdaBLE.write(0x00));
ottaviano3 0:d75a1797ffd9 531 }
ottaviano3 0:d75a1797ffd9 532
ottaviano3 0:d75a1797ffd9 533 // Now set REQn back to high to close this transaction
ottaviano3 0:d75a1797ffd9 534 AdaReqN = 1;
ottaviano3 0:d75a1797ffd9 535
ottaviano3 0:d75a1797ffd9 536 // Lets read this message.
ottaviano3 0:d75a1797ffd9 537 switch (buffer[0]) {
ottaviano3 0:d75a1797ffd9 538 case 0x81:
ottaviano3 0:d75a1797ffd9 539 pc.printf("\bDone!\n\r");
ottaviano3 0:d75a1797ffd9 540 break;
ottaviano3 0:d75a1797ffd9 541 default:
ottaviano3 0:d75a1797ffd9 542 error("\n\rStart packet not recieved!");
ottaviano3 0:d75a1797ffd9 543 break;
ottaviano3 0:d75a1797ffd9 544 }
ottaviano3 0:d75a1797ffd9 545
ottaviano3 0:d75a1797ffd9 546 // Get operating mode. 0x01 = test, 0x02 = setup, 0x03 = standby
ottaviano3 0:d75a1797ffd9 547 unsigned char OpMode = buffer[1];
ottaviano3 0:d75a1797ffd9 548
ottaviano3 0:d75a1797ffd9 549 // Print Operational Mode to terminal.
ottaviano3 0:d75a1797ffd9 550 pc.printf("Operational Mode: ");
ottaviano3 0:d75a1797ffd9 551 switch (OpMode) {
ottaviano3 0:d75a1797ffd9 552 case 0x01:
ottaviano3 0:d75a1797ffd9 553 pc.printf("Test\n\r");
ottaviano3 0:d75a1797ffd9 554 break;
ottaviano3 0:d75a1797ffd9 555 case 0x02:
ottaviano3 0:d75a1797ffd9 556 pc.printf("Setup\n\r");
ottaviano3 0:d75a1797ffd9 557 break;
ottaviano3 0:d75a1797ffd9 558 case 0x03:
ottaviano3 0:d75a1797ffd9 559 pc.printf("Standby\n\r");
ottaviano3 0:d75a1797ffd9 560 break;
ottaviano3 0:d75a1797ffd9 561 default:
ottaviano3 0:d75a1797ffd9 562 error("Invalid Operational Mode!");
ottaviano3 0:d75a1797ffd9 563 break;
ottaviano3 0:d75a1797ffd9 564 }
ottaviano3 0:d75a1797ffd9 565
ottaviano3 0:d75a1797ffd9 566 // Wait for Dev
ottaviano3 0:d75a1797ffd9 567 pc.printf("Settings written!\n\r");
ottaviano3 0:d75a1797ffd9 568
ottaviano3 0:d75a1797ffd9 569 return;
ottaviano3 0:d75a1797ffd9 570 }