Dominic Ottaviano / Mbed 2 deprecated Adafruit_BLE_Test

Dependencies:   Parallax_X-Band mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 float version = 0.1;
00004 
00005 // Serial to PC for outputs.
00006 Serial pc(USBTX,USBRX);
00007 
00008 // SPI Pins
00009 SPI AdaBLE(p11,p12,p13);
00010 
00011 // Input, RDYN active low, goes low when the BLE is ready to recieve data, or has data to send
00012 DigitalIn AdaRdyN(p30);
00013 // Output, REQN active low, put low to request right to send data.
00014 DigitalOut AdaReqN(p27);
00015 // Input, goes low when the BLE is busy recieving or sending data.
00016 DigitalIn AdaAct(p29);
00017 // Output, resets the module
00018 DigitalOut AdaRst(p28);
00019 
00020 // A function that loads configuration information into the nRF8001
00021 void SetupBLE();
00022 // A function that switches 8 bit MSB to LSB.
00023 unsigned char BOReverse(unsigned char cmd);
00024 // Function that writes setup lines.
00025 bool SetupWriter(char setup[], int length);
00026 // Puts device into connect mode.
00027 void BLEConnectMode();
00028 
00029 // Some well used temporary variables.
00030 volatile int counter;
00031 volatile unsigned char temp;
00032 
00033 // Timeout for BLE connection
00034 Timer timeout;
00035 
00036 // Buffer to store SPI reads.
00037 unsigned char buffer[100];
00038 
00039 int main()
00040 {
00041     ////////// Intialization \\\\\\\\\\
00042 
00043     // Serial PC Configuration \\
00044     // Set PC baud rate. Default 9600
00045     pc.baud(9600);
00046 
00047     // SPI Configuration \\
00048     // Set SPI frequency. nRF maximum is 3 Mhz as per datasheet page 26
00049     AdaBLE.frequency(2000000);
00050     // Set SPI mode 0, 8 bits. nRF uses SPI mode 0, LSB order. mbed uses MSB so a conversion function is nessesary.
00051     AdaBLE.format(8,0);
00052 
00053     // Pull Up RDYn line as per nRF8001 datasheet page 23
00054     //AdaRdyN.mode(PullUp); // !! Pin is already pulled up on the Adafruit breakout board by built in hardware. :)
00055 
00056     // Hold reset line high to bring device online.
00057     AdaRst = 1;
00058 
00059     // Wait 62 miliseconds per nRF8001 datasheet, page 23, for RDYn signal to be valid.
00060     wait_ms(62);
00061 
00062     // Print out dat sweet welcome message.
00063     pc.printf("\r====== Shit Where's My Phone Serial Debug Console ======\n\r");
00064     pc.printf("Version: %4.1f\n\r\n\r",version);
00065 
00066     // Run Device Setup \\
00067 
00068     // Message to serial
00069     pc.printf("Waiting for device to become ready: |");
00070 
00071     // Now we wait for the nRF to lower the RDYn signal.
00072     counter = 0;
00073     timeout.stop();
00074     timeout.reset();
00075     timeout.start();
00076     while (AdaRdyN != 0) {
00077         // Do nothing important, i update the display here in terminal.
00078         if (timeout.read() > 2) {
00079             error("\n\rnRF module never came online...");
00080         }
00081         // Wait for device to become ready.
00082         if (counter%3 == 0) {
00083             pc.printf("\b/");
00084         } else if (counter%3 == 1) {
00085             pc.printf("\b-");
00086         } else if (counter%3 == 2) {
00087             pc.printf("\b\\");
00088         } else {
00089             pc.printf("\b|");
00090         }
00091         counter++;
00092     }
00093     // nRF has signaled it has data for me to recieve.
00094 
00095     // Set REQn to ground then start clocking in data.
00096     AdaReqN = 0;
00097 
00098     BOReverse(AdaBLE.write(0x00)); // Discard this first byte as it is a debug byte.
00099     temp = BOReverse(AdaBLE.write(0x00)); // First byte defines message length. Since this is a bootup message it should always be 4 bytes long.
00100 
00101     // Clock in remaining bytes
00102     for (int i = 0; i < temp; i++) {
00103         buffer[i] = BOReverse(AdaBLE.write(0x00));
00104     }
00105 
00106     // Now set REQn back to high to close this transaction
00107     AdaReqN = 1;
00108 
00109     // Lets read this message.
00110     switch (buffer[0]) {
00111         case 0x81:
00112             pc.printf("\bDone!\n\r");
00113             break;
00114         default:
00115             error("\n\rStart packet not recieved!");
00116             break;
00117     }
00118 
00119     // Get operating mode. 0x01 = test, 0x02 = setup, 0x03 = standby
00120     unsigned char OpMode = buffer[1];
00121     // Check for HW error. 0x00 = no error, 0x01 = fatal error.
00122     unsigned char HWError = buffer[2];
00123     // Get DataCreditAvailiable, number of DataCommand buffers available.
00124     unsigned char DCAvail = buffer[3];
00125 
00126     // Print Operational Mode to terminal.
00127     pc.printf("Operational Mode: ");
00128     switch (OpMode) {
00129         case 0x01:
00130             pc.printf("Test\n\r");
00131             break;
00132         case 0x02:
00133             pc.printf("Setup\n\r");
00134             break;
00135         case 0x03:
00136             pc.printf("Standby\n\r");
00137             break;
00138         default:
00139             error("Invalid Operational Mode!");
00140             break;
00141     }
00142 
00143     // Warn if HW Error
00144     pc.printf("HW error last boot: ");
00145     switch (HWError) {
00146         case 0x00:
00147             pc.printf("No\n\r");
00148             break;
00149         case 0x01:
00150             pc.printf("Yes\n\r");
00151             break;
00152         default:
00153             error("Invalid Data Recieved");
00154             break;
00155     }
00156 
00157     // Print number of datacommand buffers avaliable.
00158     pc.printf("DataCommand buffers avaliable: %i\n\r",DCAvail);
00159 
00160     // Call setup routine
00161     SetupBLE();
00162 
00163     // Setup complete and device should be in standby mode!
00164 
00165     pc.printf("\n\rAbout to start advertising...\n\r");
00166     // Run connect to start pairing
00167     BLEConnectMode();
00168 
00169     while(1) {
00170         // Main runloop
00171         if (AdaRdyN == 0) {
00172             pc.printf("\n\r");
00173             AdaReqN = 0;
00174             BOReverse(AdaBLE.write(0x00));
00175             temp = BOReverse(AdaBLE.write(0x00));
00176 
00177             // Clock in remaining bytes
00178             for (int i = 0; i < temp; i++) {
00179                 buffer[i] = BOReverse(AdaBLE.write(0x00));
00180                 pc.printf("%02x ",buffer[i]);
00181             }
00182             AdaReqN = 1;
00183         }
00184     }
00185 }
00186 
00187 void BLEConnectMode()
00188 {
00189     // Set REQn to ground
00190     AdaReqN = 0;
00191     timeout.stop();
00192     timeout.reset();
00193     timeout.start();
00194     while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
00195         if (timeout.read() > 2) {
00196             error("\n\rError: No rights to send.");
00197         }
00198     }
00199     // Lenght of packet
00200     AdaBLE.write(BOReverse(0x05));
00201     // Connect packet header
00202     AdaBLE.write(BOReverse(0x0F));
00203     // Set bluetooth announce in seconds.
00204     AdaBLE.write(BOReverse(0x1E)); // !! Reverse order of bits since LSB
00205     AdaBLE.write(BOReverse(0x00)); // 0x1E is 30 seconds
00206     // Set advertisement interval. This setting * 0.625 msec = interval
00207     AdaBLE.write(BOReverse(0x20)); // !! Reverse order of bits since LSB
00208     AdaBLE.write(BOReverse(0x03)); // 0x0620 is 1600, 1 second interval.
00209 
00210     // Set REQn high to end transaction
00211     AdaReqN = 1;
00212 
00213     // Wait for command response event packet
00214 
00215     // Now we wait for the response packet to signal a successful transfer.
00216     timeout.stop();
00217     timeout.reset();
00218     timeout.start();
00219     while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
00220         if (timeout.read() > 2) {
00221             error("\n\rError: No response packet recieved.");
00222         }
00223     }
00224 
00225     // Now set REQn to ground and clock in data
00226     AdaReqN = 0;
00227 
00228     // discard first byte
00229     BOReverse(AdaBLE.write(0x00));
00230     // get length data
00231     temp = BOReverse(AdaBLE.write(0x00));
00232 
00233     // Clock in remaining bytes
00234     for (int i = 0; i < temp; i++) {
00235         buffer[i] = BOReverse(AdaBLE.write(0x00));
00236     }
00237 
00238     // Read data
00239     if (buffer[0] != 0x84) {
00240         error("\n\rNot CommandResponseEvent!");
00241     }
00242 
00243     if (buffer[1] != 0x0F) {
00244         error("\n\rNot the correct CommandResponseEvent!");
00245     }
00246 
00247     switch (buffer[2]) {
00248         case 0x00:
00249             // Sucess lets continue
00250             // Now set REQn high to end transaction
00251             AdaReqN = 1;
00252             break;
00253         default:
00254             // Error failled to announce
00255             error("\n\rFailed announce!");
00256             break;
00257     }
00258 
00259     pc.printf("Bluetooth announcement successful! Look for it in peer device.\n\r");
00260     return;
00261 }
00262 
00263 unsigned char BOReverse(unsigned char cmd)
00264 {
00265     return (((cmd * 0x0802LU & 0x22110LU) | (cmd * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16);
00266 }
00267 
00268 bool SetupWriter(unsigned char setup[], int length)
00269 {
00270     // Set REQn line to groud to request right to send.
00271     AdaReqN = 0;
00272     // reset timeout timer
00273     timeout.stop();
00274     timeout.reset();
00275     timeout.start();
00276     while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
00277         if (timeout.read() > 2) {
00278             error("\n\rError: No rights to send.");
00279         }
00280     }
00281     // Right to send recieved, Write setup strings
00282     for (int i = 0; i < (length); i++) {
00283         AdaBLE.write(BOReverse(setup[i]));
00284     }
00285 
00286     // Set REQn high to finish this transaction
00287     AdaReqN = 1;
00288 
00289     // Reset Timer
00290     timeout.stop();
00291     timeout.reset();
00292     timeout.start();
00293     temp = 0x00;
00294 
00295     // Now we wait for the response packet to signal a successful transfer.
00296     while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */
00297         if (timeout.read() > 2) {
00298             error("\n\rError: No response packet recieved.");
00299         }
00300     }
00301 
00302     // Now set REQn to ground and clock in data
00303     AdaReqN = 0;
00304 
00305     // discard first byte
00306     BOReverse(AdaBLE.write(0x00));
00307     // get length data
00308     temp = BOReverse(AdaBLE.write(0x00));
00309 
00310     // Clock in remaining bytes
00311     for (int i = 0; i < temp; i++) {
00312         buffer[i] = BOReverse(AdaBLE.write(0x00));
00313     }
00314 
00315     if (buffer[0] != 0x84) {
00316         error("\n\rNot CommandResponseEvent!");
00317     }
00318 
00319     if (buffer[1] != 0x06) {
00320         error("\n\rNot the correct CommandResponseEvent!");
00321     }
00322 
00323     switch (buffer[2]) {
00324         case 0x01:
00325             // Sucess lets continue
00326             // Now set REQn high to end transaction
00327             AdaReqN = 1;
00328             return true;
00329         case 0x02:
00330             // We finished writing settings!
00331             AdaReqN = 1;
00332             return true;
00333         case 0x88:
00334             // CRC mismatch
00335             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.");
00336         default:
00337             // Error not expected
00338             error("\n\rUnexpected Response!");
00339             break;
00340     }
00341 
00342     // Should never be reached but just in case.
00343     return false;
00344 }
00345 
00346 void SetupBLE()
00347 {
00348     // Write setup data arrays (Generated in nRFgo Studio)
00349     unsigned char setup1[] = {0x07,0x06,0x00,0x00,0x03,0x02,0x42,0x07};
00350     unsigned char setup2[] = {0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x06,0x00,0x00,
00351                               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
00352                              };
00353     unsigned char setup3[] = {0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00354                               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x03,0x90,0x01,0xff
00355                              };
00356     unsigned char setup4[] = {0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00357                               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
00358                              };
00359     unsigned char setup5[] = {0x05,0x06,0x10,0x54,0x00,0x00};
00360     unsigned char setup6[] = {0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,
00361                               0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14
00362                              };
00363     unsigned char setup7[] = {0x1f,0x06,0x20,0x1c,0x04,0x00,0x03,0x2a,0x00,0x01,0x53,0x57,0x4d,0x46,0x69,0x63,0x73,0x65,0x6d,0x69,
00364                               0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04
00365                              };
00366     unsigned char setup8[] = {0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,
00367                               0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00
00368                              };
00369     unsigned char setup9[] = {0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,
00370                               0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x04,0x04
00371                              };
00372     unsigned char setup10[] = {0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,
00373                                0x00,0x01,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48
00374                               };
00375     unsigned char setup11[] = {0x1f,0x06,0x20,0x8c,0x6e,0xec,0x0f,0x18,0xfd,0x5a,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x02,
00376                                0x0b,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48
00377                               };
00378     unsigned char setup12[] = {0x1f,0x06,0x20,0xa8,0x6e,0xec,0x19,0x2a,0xfd,0x5a,0x06,0x04,0x02,0x01,0x00,0x0b,0x2a,0x19,0x02,0x10,
00379                                0x04,0x04,0x13,0x13,0x00,0x0c,0x28,0x03,0x01,0x02,0x0d,0x00
00380                               };
00381     unsigned char setup13[] = {0x1f,0x06,0x20,0xc4,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48,0x6e,0xec,0x1a,0x2a,0xfd,0x5a,
00382                                0x06,0x04,0x02,0x01,0x00,0x0d,0x2a,0x1a,0x02,0x00,0x04,0x04
00383                               };
00384     unsigned char setup14[] = {0x1f,0x06,0x20,0xe0,0x13,0x13,0x00,0x0e,0x28,0x03,0x01,0x02,0x0f,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,
00385                                0x27,0xb0,0x1b,0x48,0x6e,0xec,0x1b,0x2a,0xfd,0x5a,0x06,0x04
00386                               };
00387     unsigned char setup15[] = {0x0d,0x06,0x20,0xfc,0x03,0x02,0x00,0x0f,0x2a,0x1b,0x02,0x00,0x00,0x00};
00388     unsigned char setup16[] = {0x13,0x06,0x50,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48,0x6e,0xec,0x00,0x00,0xfd,0x5a};
00389     unsigned char setup17[] = {0x06,0x06,0xf0,0x00,0x03,0x7f,0xc3};
00390 
00391     pc.printf("Starting to write settings...");
00392     // Setup 1
00393     if (!SetupWriter(setup1,sizeof(setup1)/sizeof(setup1[1]))) {
00394         error("\n\rWrite Failed!");
00395     }
00396     pc.printf("1,");
00397 
00398     // Setup 2
00399     if (!SetupWriter(setup2,sizeof(setup2)/sizeof(setup2[1]))) {
00400         error("\n\rWrite Failed!");
00401     }
00402     pc.printf("2,");
00403 
00404     // Setup 3
00405     if (!SetupWriter(setup3,sizeof(setup3)/sizeof(setup3[1]))) {
00406         error("\n\rWrite Failed!");
00407     }
00408     pc.printf("3,");
00409 
00410     // Setup 4
00411     if (!SetupWriter(setup4,sizeof(setup4)/sizeof(setup4[1]))) {
00412         error("\n\rWrite Failed!");
00413     }
00414     pc.printf("4,");
00415 
00416     // Setup 5
00417     if (!SetupWriter(setup5,sizeof(setup5)/sizeof(setup5[1]))) {
00418         error("\n\rWrite Failed!");
00419     }
00420     pc.printf("5,");
00421 
00422     // Setup 6
00423     if (!SetupWriter(setup6,sizeof(setup6)/sizeof(setup6[1]))) {
00424         error("\n\rWrite Failed!");
00425     }
00426     pc.printf("6,");
00427 
00428     // Setup 7
00429     if (!SetupWriter(setup7,sizeof(setup7)/sizeof(setup7[1]))) {
00430         error("\n\rWrite Failed!");
00431     }
00432     pc.printf("7,");
00433 
00434     // Setup 8
00435     if (!SetupWriter(setup8,sizeof(setup8)/sizeof(setup8[1]))) {
00436         error("\n\rWrite Failed!");
00437     }
00438     pc.printf("8,");
00439 
00440     // Setup 9
00441     if (!SetupWriter(setup9,sizeof(setup9)/sizeof(setup9[1]))) {
00442         error("\n\rWrite Failed!");
00443     }
00444     pc.printf("9,");
00445 
00446     // Setup 10
00447     if (!SetupWriter(setup10,sizeof(setup10)/sizeof(setup10[1]))) {
00448         error("\n\rWrite Failed!");
00449     }
00450     pc.printf("10,");
00451 
00452     // Setup 11
00453     if (!SetupWriter(setup11,sizeof(setup11)/sizeof(setup11[1]))) {
00454         error("\n\rWrite Failed!");
00455     }
00456     pc.printf("11,");
00457     
00458     // Setup 12
00459     if (!SetupWriter(setup12,sizeof(setup12)/sizeof(setup12[1]))) {
00460         error("\n\rWrite Failed!");
00461     }
00462     pc.printf("12,");
00463     
00464     // Setup 13
00465     if (!SetupWriter(setup13,sizeof(setup13)/sizeof(setup13[1]))) {
00466         error("\n\rWrite Failed!");
00467     }
00468     pc.printf("13,");
00469     
00470     // Setup 14
00471     if (!SetupWriter(setup14,sizeof(setup14)/sizeof(setup14[1]))) {
00472         error("\n\rWrite Failed!");
00473     }
00474     pc.printf("14,");
00475     
00476     // Setup 15
00477     if (!SetupWriter(setup15,sizeof(setup15)/sizeof(setup15[1]))) {
00478         error("\n\rWrite Failed!");
00479     }
00480     pc.printf("15,");
00481     
00482     // Setup 16
00483     if (!SetupWriter(setup16,sizeof(setup16)/sizeof(setup16[1]))) {
00484         error("\n\rWrite Failed!");
00485     }
00486     pc.printf("16,");
00487     
00488     // Setup 17
00489     if (!SetupWriter(setup17,sizeof(setup17)/sizeof(setup17[1]))) {
00490         error("\n\rWrite Failed!");
00491     }
00492     pc.printf("17");
00493     // Done writing setup strings phew!
00494 
00495     // Wait for DeviceStartedEvent
00496     pc.printf("\n\rWaiting for device to accept settings: |");
00497 
00498     // Now we wait for the nRF to lower the RDYn signal.
00499     counter = 0;
00500     timeout.stop();
00501     timeout.reset();
00502     timeout.start();
00503     while (AdaRdyN != 0) {
00504         // Do nothing important, i update the display here in terminal.
00505         if (timeout.read() > 2) {
00506             error("\n\rnRF module never came back after settings where written...");
00507         }
00508         // Wait for device to become ready.
00509         if (counter%3 == 0) {
00510             pc.printf("\b/");
00511         } else if (counter%3 == 1) {
00512             pc.printf("\b-");
00513         } else if (counter%3 == 2) {
00514             pc.printf("\b\\");
00515         } else {
00516             pc.printf("\b|");
00517         }
00518         counter++;
00519     }
00520     // nRF has signaled it has data for me to recieve.
00521 
00522     // Set REQn to ground then start clocking in data.
00523     AdaReqN = 0;
00524 
00525     BOReverse(AdaBLE.write(0x00)); // Discard this first byte as it is a debug byte.
00526     temp = BOReverse(AdaBLE.write(0x00)); // First byte defines message length. Since this is a bootup message it should always be 4 bytes long.
00527 
00528     // Clock in remaining bytes
00529     for (int i = 0; i < temp; i++) {
00530         buffer[i] = BOReverse(AdaBLE.write(0x00));
00531     }
00532 
00533     // Now set REQn back to high to close this transaction
00534     AdaReqN = 1;
00535 
00536     // Lets read this message.
00537     switch (buffer[0]) {
00538         case 0x81:
00539             pc.printf("\bDone!\n\r");
00540             break;
00541         default:
00542             error("\n\rStart packet not recieved!");
00543             break;
00544     }
00545 
00546     // Get operating mode. 0x01 = test, 0x02 = setup, 0x03 = standby
00547     unsigned char OpMode = buffer[1];
00548 
00549     // Print Operational Mode to terminal.
00550     pc.printf("Operational Mode: ");
00551     switch (OpMode) {
00552         case 0x01:
00553             pc.printf("Test\n\r");
00554             break;
00555         case 0x02:
00556             pc.printf("Setup\n\r");
00557             break;
00558         case 0x03:
00559             pc.printf("Standby\n\r");
00560             break;
00561         default:
00562             error("Invalid Operational Mode!");
00563             break;
00564     }
00565 
00566     // Wait for Dev
00567     pc.printf("Settings written!\n\r");
00568 
00569     return;
00570 }