My attempts at getting the nRF8001 chip to play with the mbed
Dependencies: Parallax_X-Band mbed
main.cpp
- Committer:
- ottaviano3
- Date:
- 2015-07-25
- Revision:
- 0:d75a1797ffd9
File content as of revision 0:d75a1797ffd9:
#include "mbed.h" float version = 0.1; // Serial to PC for outputs. Serial pc(USBTX,USBRX); // SPI Pins SPI AdaBLE(p11,p12,p13); // Input, RDYN active low, goes low when the BLE is ready to recieve data, or has data to send DigitalIn AdaRdyN(p30); // Output, REQN active low, put low to request right to send data. DigitalOut AdaReqN(p27); // Input, goes low when the BLE is busy recieving or sending data. DigitalIn AdaAct(p29); // Output, resets the module DigitalOut AdaRst(p28); // A function that loads configuration information into the nRF8001 void SetupBLE(); // A function that switches 8 bit MSB to LSB. unsigned char BOReverse(unsigned char cmd); // Function that writes setup lines. bool SetupWriter(char setup[], int length); // Puts device into connect mode. void BLEConnectMode(); // Some well used temporary variables. volatile int counter; volatile unsigned char temp; // Timeout for BLE connection Timer timeout; // Buffer to store SPI reads. unsigned char buffer[100]; int main() { ////////// Intialization \\\\\\\\\\ // Serial PC Configuration \\ // Set PC baud rate. Default 9600 pc.baud(9600); // SPI Configuration \\ // Set SPI frequency. nRF maximum is 3 Mhz as per datasheet page 26 AdaBLE.frequency(2000000); // Set SPI mode 0, 8 bits. nRF uses SPI mode 0, LSB order. mbed uses MSB so a conversion function is nessesary. AdaBLE.format(8,0); // Pull Up RDYn line as per nRF8001 datasheet page 23 //AdaRdyN.mode(PullUp); // !! Pin is already pulled up on the Adafruit breakout board by built in hardware. :) // Hold reset line high to bring device online. AdaRst = 1; // Wait 62 miliseconds per nRF8001 datasheet, page 23, for RDYn signal to be valid. wait_ms(62); // Print out dat sweet welcome message. pc.printf("\r====== Shit Where's My Phone Serial Debug Console ======\n\r"); pc.printf("Version: %4.1f\n\r\n\r",version); // Run Device Setup \\ // Message to serial pc.printf("Waiting for device to become ready: |"); // Now we wait for the nRF to lower the RDYn signal. counter = 0; timeout.stop(); timeout.reset(); timeout.start(); while (AdaRdyN != 0) { // Do nothing important, i update the display here in terminal. if (timeout.read() > 2) { error("\n\rnRF module never came online..."); } // Wait for device to become ready. if (counter%3 == 0) { pc.printf("\b/"); } else if (counter%3 == 1) { pc.printf("\b-"); } else if (counter%3 == 2) { pc.printf("\b\\"); } else { pc.printf("\b|"); } counter++; } // nRF has signaled it has data for me to recieve. // Set REQn to ground then start clocking in data. AdaReqN = 0; BOReverse(AdaBLE.write(0x00)); // Discard this first byte as it is a debug byte. temp = BOReverse(AdaBLE.write(0x00)); // First byte defines message length. Since this is a bootup message it should always be 4 bytes long. // Clock in remaining bytes for (int i = 0; i < temp; i++) { buffer[i] = BOReverse(AdaBLE.write(0x00)); } // Now set REQn back to high to close this transaction AdaReqN = 1; // Lets read this message. switch (buffer[0]) { case 0x81: pc.printf("\bDone!\n\r"); break; default: error("\n\rStart packet not recieved!"); break; } // Get operating mode. 0x01 = test, 0x02 = setup, 0x03 = standby unsigned char OpMode = buffer[1]; // Check for HW error. 0x00 = no error, 0x01 = fatal error. unsigned char HWError = buffer[2]; // Get DataCreditAvailiable, number of DataCommand buffers available. unsigned char DCAvail = buffer[3]; // Print Operational Mode to terminal. pc.printf("Operational Mode: "); switch (OpMode) { case 0x01: pc.printf("Test\n\r"); break; case 0x02: pc.printf("Setup\n\r"); break; case 0x03: pc.printf("Standby\n\r"); break; default: error("Invalid Operational Mode!"); break; } // Warn if HW Error pc.printf("HW error last boot: "); switch (HWError) { case 0x00: pc.printf("No\n\r"); break; case 0x01: pc.printf("Yes\n\r"); break; default: error("Invalid Data Recieved"); break; } // Print number of datacommand buffers avaliable. pc.printf("DataCommand buffers avaliable: %i\n\r",DCAvail); // Call setup routine SetupBLE(); // Setup complete and device should be in standby mode! pc.printf("\n\rAbout to start advertising...\n\r"); // Run connect to start pairing BLEConnectMode(); while(1) { // Main runloop if (AdaRdyN == 0) { pc.printf("\n\r"); AdaReqN = 0; BOReverse(AdaBLE.write(0x00)); temp = BOReverse(AdaBLE.write(0x00)); // Clock in remaining bytes for (int i = 0; i < temp; i++) { buffer[i] = BOReverse(AdaBLE.write(0x00)); pc.printf("%02x ",buffer[i]); } AdaReqN = 1; } } } void BLEConnectMode() { // Set REQn to ground AdaReqN = 0; timeout.stop(); timeout.reset(); timeout.start(); while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */ if (timeout.read() > 2) { error("\n\rError: No rights to send."); } } // Lenght of packet AdaBLE.write(BOReverse(0x05)); // Connect packet header AdaBLE.write(BOReverse(0x0F)); // Set bluetooth announce in seconds. AdaBLE.write(BOReverse(0x1E)); // !! Reverse order of bits since LSB AdaBLE.write(BOReverse(0x00)); // 0x1E is 30 seconds // Set advertisement interval. This setting * 0.625 msec = interval AdaBLE.write(BOReverse(0x20)); // !! Reverse order of bits since LSB AdaBLE.write(BOReverse(0x03)); // 0x0620 is 1600, 1 second interval. // Set REQn high to end transaction AdaReqN = 1; // Wait for command response event packet // Now we wait for the response packet to signal a successful transfer. timeout.stop(); timeout.reset(); timeout.start(); while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */ if (timeout.read() > 2) { error("\n\rError: No response packet recieved."); } } // Now set REQn to ground and clock in data AdaReqN = 0; // discard first byte BOReverse(AdaBLE.write(0x00)); // get length data temp = BOReverse(AdaBLE.write(0x00)); // Clock in remaining bytes for (int i = 0; i < temp; i++) { buffer[i] = BOReverse(AdaBLE.write(0x00)); } // Read data if (buffer[0] != 0x84) { error("\n\rNot CommandResponseEvent!"); } if (buffer[1] != 0x0F) { error("\n\rNot the correct CommandResponseEvent!"); } switch (buffer[2]) { case 0x00: // Sucess lets continue // Now set REQn high to end transaction AdaReqN = 1; break; default: // Error failled to announce error("\n\rFailed announce!"); break; } pc.printf("Bluetooth announcement successful! Look for it in peer device.\n\r"); return; } unsigned char BOReverse(unsigned char cmd) { return (((cmd * 0x0802LU & 0x22110LU) | (cmd * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); } bool SetupWriter(unsigned char setup[], int length) { // Set REQn line to groud to request right to send. AdaReqN = 0; // reset timeout timer timeout.stop(); timeout.reset(); timeout.start(); while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */ if (timeout.read() > 2) { error("\n\rError: No rights to send."); } } // Right to send recieved, Write setup strings for (int i = 0; i < (length); i++) { AdaBLE.write(BOReverse(setup[i])); } // Set REQn high to finish this transaction AdaReqN = 1; // Reset Timer timeout.stop(); timeout.reset(); timeout.start(); temp = 0x00; // Now we wait for the response packet to signal a successful transfer. while (AdaRdyN == 1) { /* wait until nRF sets RDYn line low */ if (timeout.read() > 2) { error("\n\rError: No response packet recieved."); } } // Now set REQn to ground and clock in data AdaReqN = 0; // discard first byte BOReverse(AdaBLE.write(0x00)); // get length data temp = BOReverse(AdaBLE.write(0x00)); // Clock in remaining bytes for (int i = 0; i < temp; i++) { buffer[i] = BOReverse(AdaBLE.write(0x00)); } if (buffer[0] != 0x84) { error("\n\rNot CommandResponseEvent!"); } if (buffer[1] != 0x06) { error("\n\rNot the correct CommandResponseEvent!"); } switch (buffer[2]) { case 0x01: // Sucess lets continue // Now set REQn high to end transaction AdaReqN = 1; return true; case 0x02: // We finished writing settings! AdaReqN = 1; return true; case 0x88: // CRC mismatch 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."); default: // Error not expected error("\n\rUnexpected Response!"); break; } // Should never be reached but just in case. return false; } void SetupBLE() { // Write setup data arrays (Generated in nRFgo Studio) unsigned char setup1[] = {0x07,0x06,0x00,0x00,0x03,0x02,0x42,0x07}; unsigned char setup2[] = {0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x06,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; unsigned char setup3[] = {0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x03,0x90,0x01,0xff }; unsigned char setup4[] = {0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; unsigned char setup5[] = {0x05,0x06,0x10,0x54,0x00,0x00}; unsigned char setup6[] = {0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00, 0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14 }; unsigned char setup7[] = {0x1f,0x06,0x20,0x1c,0x04,0x00,0x03,0x2a,0x00,0x01,0x53,0x57,0x4d,0x46,0x69,0x63,0x73,0x65,0x6d,0x69, 0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04 }; unsigned char setup8[] = {0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02, 0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00 }; unsigned char setup9[] = {0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a, 0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x04,0x04 }; unsigned char setup10[] = {0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28, 0x00,0x01,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48 }; unsigned char setup11[] = {0x1f,0x06,0x20,0x8c,0x6e,0xec,0x0f,0x18,0xfd,0x5a,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x02, 0x0b,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48 }; unsigned char setup12[] = {0x1f,0x06,0x20,0xa8,0x6e,0xec,0x19,0x2a,0xfd,0x5a,0x06,0x04,0x02,0x01,0x00,0x0b,0x2a,0x19,0x02,0x10, 0x04,0x04,0x13,0x13,0x00,0x0c,0x28,0x03,0x01,0x02,0x0d,0x00 }; unsigned char setup13[] = {0x1f,0x06,0x20,0xc4,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48,0x6e,0xec,0x1a,0x2a,0xfd,0x5a, 0x06,0x04,0x02,0x01,0x00,0x0d,0x2a,0x1a,0x02,0x00,0x04,0x04 }; unsigned char setup14[] = {0x1f,0x06,0x20,0xe0,0x13,0x13,0x00,0x0e,0x28,0x03,0x01,0x02,0x0f,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8, 0x27,0xb0,0x1b,0x48,0x6e,0xec,0x1b,0x2a,0xfd,0x5a,0x06,0x04 }; unsigned char setup15[] = {0x0d,0x06,0x20,0xfc,0x03,0x02,0x00,0x0f,0x2a,0x1b,0x02,0x00,0x00,0x00}; unsigned char setup16[] = {0x13,0x06,0x50,0x00,0x84,0xb1,0x91,0xcc,0x05,0xd8,0x27,0xb0,0x1b,0x48,0x6e,0xec,0x00,0x00,0xfd,0x5a}; unsigned char setup17[] = {0x06,0x06,0xf0,0x00,0x03,0x7f,0xc3}; pc.printf("Starting to write settings..."); // Setup 1 if (!SetupWriter(setup1,sizeof(setup1)/sizeof(setup1[1]))) { error("\n\rWrite Failed!"); } pc.printf("1,"); // Setup 2 if (!SetupWriter(setup2,sizeof(setup2)/sizeof(setup2[1]))) { error("\n\rWrite Failed!"); } pc.printf("2,"); // Setup 3 if (!SetupWriter(setup3,sizeof(setup3)/sizeof(setup3[1]))) { error("\n\rWrite Failed!"); } pc.printf("3,"); // Setup 4 if (!SetupWriter(setup4,sizeof(setup4)/sizeof(setup4[1]))) { error("\n\rWrite Failed!"); } pc.printf("4,"); // Setup 5 if (!SetupWriter(setup5,sizeof(setup5)/sizeof(setup5[1]))) { error("\n\rWrite Failed!"); } pc.printf("5,"); // Setup 6 if (!SetupWriter(setup6,sizeof(setup6)/sizeof(setup6[1]))) { error("\n\rWrite Failed!"); } pc.printf("6,"); // Setup 7 if (!SetupWriter(setup7,sizeof(setup7)/sizeof(setup7[1]))) { error("\n\rWrite Failed!"); } pc.printf("7,"); // Setup 8 if (!SetupWriter(setup8,sizeof(setup8)/sizeof(setup8[1]))) { error("\n\rWrite Failed!"); } pc.printf("8,"); // Setup 9 if (!SetupWriter(setup9,sizeof(setup9)/sizeof(setup9[1]))) { error("\n\rWrite Failed!"); } pc.printf("9,"); // Setup 10 if (!SetupWriter(setup10,sizeof(setup10)/sizeof(setup10[1]))) { error("\n\rWrite Failed!"); } pc.printf("10,"); // Setup 11 if (!SetupWriter(setup11,sizeof(setup11)/sizeof(setup11[1]))) { error("\n\rWrite Failed!"); } pc.printf("11,"); // Setup 12 if (!SetupWriter(setup12,sizeof(setup12)/sizeof(setup12[1]))) { error("\n\rWrite Failed!"); } pc.printf("12,"); // Setup 13 if (!SetupWriter(setup13,sizeof(setup13)/sizeof(setup13[1]))) { error("\n\rWrite Failed!"); } pc.printf("13,"); // Setup 14 if (!SetupWriter(setup14,sizeof(setup14)/sizeof(setup14[1]))) { error("\n\rWrite Failed!"); } pc.printf("14,"); // Setup 15 if (!SetupWriter(setup15,sizeof(setup15)/sizeof(setup15[1]))) { error("\n\rWrite Failed!"); } pc.printf("15,"); // Setup 16 if (!SetupWriter(setup16,sizeof(setup16)/sizeof(setup16[1]))) { error("\n\rWrite Failed!"); } pc.printf("16,"); // Setup 17 if (!SetupWriter(setup17,sizeof(setup17)/sizeof(setup17[1]))) { error("\n\rWrite Failed!"); } pc.printf("17"); // Done writing setup strings phew! // Wait for DeviceStartedEvent pc.printf("\n\rWaiting for device to accept settings: |"); // Now we wait for the nRF to lower the RDYn signal. counter = 0; timeout.stop(); timeout.reset(); timeout.start(); while (AdaRdyN != 0) { // Do nothing important, i update the display here in terminal. if (timeout.read() > 2) { error("\n\rnRF module never came back after settings where written..."); } // Wait for device to become ready. if (counter%3 == 0) { pc.printf("\b/"); } else if (counter%3 == 1) { pc.printf("\b-"); } else if (counter%3 == 2) { pc.printf("\b\\"); } else { pc.printf("\b|"); } counter++; } // nRF has signaled it has data for me to recieve. // Set REQn to ground then start clocking in data. AdaReqN = 0; BOReverse(AdaBLE.write(0x00)); // Discard this first byte as it is a debug byte. temp = BOReverse(AdaBLE.write(0x00)); // First byte defines message length. Since this is a bootup message it should always be 4 bytes long. // Clock in remaining bytes for (int i = 0; i < temp; i++) { buffer[i] = BOReverse(AdaBLE.write(0x00)); } // Now set REQn back to high to close this transaction AdaReqN = 1; // Lets read this message. switch (buffer[0]) { case 0x81: pc.printf("\bDone!\n\r"); break; default: error("\n\rStart packet not recieved!"); break; } // Get operating mode. 0x01 = test, 0x02 = setup, 0x03 = standby unsigned char OpMode = buffer[1]; // Print Operational Mode to terminal. pc.printf("Operational Mode: "); switch (OpMode) { case 0x01: pc.printf("Test\n\r"); break; case 0x02: pc.printf("Setup\n\r"); break; case 0x03: pc.printf("Standby\n\r"); break; default: error("Invalid Operational Mode!"); break; } // Wait for Dev pc.printf("Settings written!\n\r"); return; }