John Rattray / Mbed 2 deprecated Spark

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 
00003 Copyright (c) 2012-2014 RedBearLab
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00006 and associated documentation files (the "Software"), to deal in the Software without restriction, 
00007 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00008 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
00009 subject to the following conditions:
00010 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
00011 
00012 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
00013 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
00014 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
00015 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
00016 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017 
00018 */
00019 
00020 #include "DotStar.h"
00021 #include "BLE.h"
00022 #include "mbed.h"
00023 #include "pstorage.h"
00024 #include "nrf_error.h"
00025 
00026 #define BLE_UUID_TXRX_SERVICE            0x0000 /**< The UUID of the Nordic UART Service. */
00027 #define BLE_UUID_TX_CHARACTERISTIC       0x0002 /**< The UUID of the TX Characteristic. */
00028 #define BLE_UUIDS_RX_CHARACTERISTIC      0x0003 /**< The UUID of the RX Characteristic. */
00029 
00030 #define DATAPIN 0
00031 #define CLOCKPIN 0
00032 
00033 #define TXRX_BUF_LEN                20
00034 
00035 #define NUMPIXELS                   4
00036 #define NAMELENGTH                  8
00037 #define NAMEBLOCK                   0
00038 #define PARAMSBLOCK                 8
00039 #define PARAMSLENGTH                16
00040 #define ELEMSLENGTH                 19
00041 #define ELEMSBLOCK                  24
00042 
00043 #define BLOCKSIZE                   100
00044 
00045 DotStar         strip = DotStar(NUMPIXELS, DATAPIN, CLOCKPIN);
00046 BLE             ble;
00047 Serial          serial(USBTX, USBRX); // tx, rx
00048 
00049 uint8_t DEFAULTNAME[NAMELENGTH] = {'b','e','t','a',0,0,0,0};
00050 uint8_t elements[ELEMSLENGTH] = {0,};
00051 uint8_t parameters[PARAMSLENGTH] = {2,5,'4',1,0,1,0,0,'F','F','F','F',4,0,0,0};
00052 uint8_t masterMode[12];
00053 
00054 Gap::AddressType_t type;
00055 Gap::Address_t address;
00056 uint32_t peerColor1,peerColor2,peerColor3;
00057 int location;
00058 
00059 /*COLORS*/
00060 uint32_t RED = 0x0000FF;
00061 uint32_t LIME = 0x00FF00;
00062 uint32_t YELLOW  = 0x00FFFF;
00063 uint32_t BLUE = 0xFF0000;
00064 uint32_t MAGENTA = 0xFF00FF;
00065 uint32_t CYAN = 0xFFFF00;
00066 uint32_t WHITE = 0xFFFFFF;
00067 uint32_t ORANGE = 0x0055FF;
00068 uint32_t FUSCIA = 0x5500FF;
00069 uint32_t WATER = 0xFF5500;
00070 uint32_t VIOLET = 0xFF0055;
00071 uint32_t LIGHTGREEN = 0x00FF55;
00072 uint32_t SEAFOAM = 0x55FF00;
00073 uint32_t ROSEGOLD = 0x5555FF;
00074 uint32_t LIGHTPURPLE = 0xFF5555;
00075 
00076 uint32_t retval;
00077 pstorage_handle_t handle;
00078 bool readvertise = false;
00079 
00080 int      head, tail; // Index of first 'on' and 'off' pixels
00081 uint32_t color = 0xFFFF00;      // 'On' color (starts white)
00082 uint32_t newColor = 0xFFFF00;
00083 char     mode = '4'; //starts solid
00084 double   brightness = 0, MAX = 10, speed = 640;
00085 double   duration = .06;
00086 int      direction = 1;
00087 double   step = 0, total = 300;
00088 uint32_t c2 = MAGENTA, temp;
00089 uint8_t everything[44];
00090 bool synergy = false;
00091 int tick = 0;
00092 bool resetTick = false;
00093 uint8_t master = 0;
00094 uint8_t showNum = 0;
00095 int waterfallMax = 640, waterfallCounter = 0;
00096 uint8_t threshold = 4;
00097 bool showColor = false;
00098 uint32_t deviceColor;
00099 
00100 uint8_t random = false, advertise = true, length = 5;
00101 
00102 uint8_t input[8] = {0,};
00103 uint8_t eventID = 1;
00104 
00105 uint32_t colors [15] = {WHITE,CYAN,BLUE,LIME,RED,MAGENTA,YELLOW,ORANGE,FUSCIA,WATER,VIOLET,LIGHTGREEN,SEAFOAM,ROSEGOLD,LIGHTPURPLE};
00106 uint8_t  j = 0;
00107 
00108 
00109 // The Nordic UART Service
00110 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
00111 static const uint8_t uart_tx_uuid[]   = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
00112 static const uint8_t uart_rx_uuid[]   = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
00113 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
00114 
00115 
00116 uint8_t txPayload[TXRX_BUF_LEN] = {0,};
00117 uint8_t rxPayload[TXRX_BUF_LEN] = {0,};
00118 
00119 GattCharacteristic  txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
00120                                       
00121 GattCharacteristic  rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
00122                                       
00123 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
00124 
00125 GattService         uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
00126 
00127 
00128 void sendMsg(uint8_t *str, int length){
00129      ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), str, length);    
00130 }
00131 
00132 
00133 /* ==================================================================================================================================================
00134 **
00135 ** CLEAR PROGRAM MEMORY
00136 **
00137    ==================================================================================================================================================*/
00138 
00139 // Request clearing of one block where block size is 16 bytes.
00140 void ClearMemory() 
00141 {
00142     retval = pstorage_clear(&handle, BLOCKSIZE);
00143     if (retval == NRF_SUCCESS)
00144     {
00145         // Clear successfully requested. Wait for operation result.
00146         //serial.printf("Clear successfully performed.\r\n");
00147     }
00148     else
00149     {
00150         // Failed to request clear, take corrective action.
00151         //serial.printf("Clear unsuccessfully performed.\r\n");
00152     }
00153 }
00154 
00155 /* ==================================================================================================================================================
00156 **
00157 ** STORING DATA INTO MEMORY FROM PROGRAM SPACE
00158 **
00159 ** ==================================================================================================================================================*/
00160 
00161 // Store the name, device parameters, and elements 
00162 void StoreEverything(uint8_t *params)
00163 {
00164     retval = pstorage_store(&handle, params, 44, 0); //store new name in block 0 with an offset of 16
00165     if (retval == NRF_SUCCESS)
00166     {
00167        //serial.printf("STORE Everything: %02x:%02x:%02x:%02x - %02x:%02x:%02x:%02x \r\n", params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7]);
00168        //serial.printf("Everything Store successfully requested. Wait for operation result.\r\n");
00169     }
00170     else {//serial.printf("Failed to request store, take corrective action.\r\n");
00171     }
00172 }
00173 
00174 /* ==================================================================================================================================================
00175 **
00176 ** LOADING DATA INTO PROGRAM SPACE FROM MEMORY
00177 **
00178 ** ==================================================================================================================================================*/
00179 
00180 //Load the name from memory into input address
00181 void LoadName(uint8_t *name)
00182 {
00183     retval = pstorage_load(name, &handle, NAMELENGTH, NAMEBLOCK); 
00184     if (retval == NRF_SUCCESS)
00185     {
00186         //serial.printf("Loading Advertising Name\n");         
00187     }
00188     else {
00189        //serial.printf("Failed to load, take corrective action.\r\n"); 
00190     }
00191     //serial.printf("LOAD: %02x:%02x:%02x:%02x - %02x:%02x:%02x:%02x \r\n",name[0],name[1],name[2],name[3], name[4],name[5],name[6],name[7]); 
00192 }
00193 
00194 //Load the name from memory into input address
00195 void LoadParams(uint8_t *params)
00196 {
00197     retval = pstorage_load(params, &handle, PARAMSLENGTH, PARAMSBLOCK); 
00198     if (retval == NRF_SUCCESS)
00199     {
00200         //serial.printf("Loading Parameters\n");         
00201     }
00202     else {
00203        //serial.printf("Failed to load, take corrective action.\r\n"); 
00204     }
00205     //serial.printf("LOAD: %02x:%02x:%02x:%02x - %02x:%02x:%02x:%02x \r\n",params[0],params[1],params[2],params[3], params[4],params[5],params[6],params[7]); 
00206 }
00207 
00208 //Load the name from memory into input address
00209 void LoadElements(uint8_t *params)
00210 {
00211     retval = pstorage_load(params, &handle, 20, ELEMSBLOCK); 
00212     if (retval == NRF_SUCCESS)
00213     {
00214     }
00215     else {  
00216     }
00217 }
00218 
00219 void scanCallback(const Gap::AdvertisementCallbackParams_t *params) {    
00220     /*serial.printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
00221            params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
00222            params->rssi, params->isScanResponse, params->type);
00223            
00224     serial.printf("\n");
00225     for (uint8_t i = 0; i < params->advertisingDataLen; i++) {
00226         serial.printf("%c",params->advertisingData[i]);
00227     }
00228     serial.printf("\n");*/
00229            
00230           /* // MASTER COMMANDS DETECTED
00231            if (!(params->isScanResponse) && params->advertisingData[4] == 0xff && params->advertisingData[5] == 'M' && params->advertisingData[6] == eventID) {
00232                memcpy(masterMode,params->advertisingData+7,12);
00233            }
00234            // OTHER SPARK DETECTED
00235            if (params->isScanResponse && params->advertisingData[1] == 0xff && params->advertisingData[2] == 0xAB && params->advertisingData[3] == eventID) {
00236             if(advertise) {   
00237                uint8_t counter = 0;
00238                for (uint8_t i = 4; i < 4+ELEMSLENGTH; i++) {
00239                     if(params->advertisingData[i] != 0 && params->advertisingData[i] == elements[i-4]){counter++;}
00240                 }
00241                 //serial.printf("There are %d elements in common\n",counter);
00242                 if(counter>=threshold){
00243                     tick = 9600;
00244                     //SHIFT COLORS DOWN IF MULTIPLE SYNERGISTIC SPARKS
00245                     peerColor3=peerColor2;
00246                     peerColor2=peerColor1;
00247                 
00248                     peerColor1 = colors[params->peerAddr[0]%15];              
00249                 }
00250             }
00251            } */                      
00252 }
00253 
00254 
00255 //Handles for Reading and Writing to Flash Memory
00256 static void cb_handler(pstorage_handle_t  * cllbck_handle,
00257                                uint8_t              op_code,
00258                                uint32_t             result,
00259                                uint8_t            * p_data,
00260                                uint32_t             data_len)
00261 {
00262   
00263   //serial.printf("Callback handler successful\r\n");  
00264   
00265   switch(op_code)
00266         {
00267            case PSTORAGE_CLEAR_OP_CODE:
00268                if (result == NRF_SUCCESS)
00269                {
00270                    //serial.printf("Clear operation successful in Callback\r\n");
00271                }
00272                else
00273                {
00274                    //serial.printf("Clear operation failed in Callback\r\n");
00275                }
00276                break;
00277  
00278      
00279           case PSTORAGE_LOAD_OP_CODE:
00280                if (result == NRF_SUCCESS)
00281                {
00282                    //serial.printf("Load operation successful in Callback\r\n");                
00283                }
00284                else
00285                {
00286                    //serial.printf("Load operation failed in Callback\r\n");
00287                }            
00288                break;     
00289           case PSTORAGE_STORE_OP_CODE:            
00290                if (result == NRF_SUCCESS)
00291                {
00292                    //serial.printf("Store operation successful in Callback\r\n");
00293                }
00294                else
00295                {
00296                    //serial.printf("Store operation failed in Callback\r\n");
00297                }     
00298                if (readvertise) {
00299                    readvertise = false;
00300                    ble.gap().clearScanResponse();
00301                    //Load the data here to ensure that the store command is complete 
00302                    uint8_t dest_data[8] = {0,};
00303                     LoadName(dest_data);
00304                     //Start the advertising process with the new name
00305                     ble.clearAdvertisingPayload();
00306                     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00307                     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00308                     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00309                                     dest_data, NAMELENGTH);
00310                     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00311                         (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid)); 
00312                     ble.gap().startAdvertising(); 
00313                     ble.gap().startScan(scanCallback);            
00314                     if (advertise){                        
00315                         uint8_t adv_elements[ELEMSLENGTH+2] = {0xAB,eventID,};
00316                         memcpy(adv_elements+2,elements,ELEMSLENGTH);
00317                         ble.accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA,adv_elements, sizeof(adv_elements)); 
00318                     } else {
00319                         uint8_t adv_elements[ELEMSLENGTH+2] = {0xAB,eventID};
00320                         ble.accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA,adv_elements, sizeof(adv_elements));
00321                     }
00322                 }
00323                break;
00324         }
00325  
00326 }
00327 
00328 
00329 uint8_t char2hex (char nibble1, char nibble2) 
00330 {
00331     uint8_t number = 0;
00332     if (nibble1>=48 && nibble1<=57) //MSN(0-9)
00333         number = (nibble1-48)*16;
00334     else if (nibble1 >= 65 && nibble1 <= 70) //MSN(A-F)
00335         number = (nibble1 - 55)*16;
00336     if(nibble2>=48 && nibble2<=57)//LSN(0-9)
00337         number += (nibble2-48);
00338     else if (nibble2 >= 65 && nibble2 <= 70) //LSN(A-F)
00339         number += (nibble2 - 55);
00340         
00341     return number;
00342     
00343     
00344 }
00345 
00346 bool fade(uint32_t start, uint32_t finish) {
00347         
00348         bool finished = false;
00349         uint8_t b0, b1, g0, g1, r0, r1;
00350         double blue,green,red;
00351         b0 = (start >> 16);
00352         b1 = (finish >> 16);
00353         g0 = start >> 8;
00354         g1 = finish >> 8;
00355         r0 = start;
00356         r1 = finish;
00357         
00358         
00359         blue = (b1 - b0)*(step/total)+ b0;
00360         green = (g1-g0)*(step/total)+g0;
00361         red = (r1-r0)*(step/total)+r0;
00362         
00363         
00364         temp = ((uint32_t) blue<<16)|((uint32_t) green<<8)|(uint32_t) red; 
00365         for (uint8_t i = 0; i < NUMPIXELS; i++) {               
00366                     strip.setPixelColor(i,temp);
00367                   }   
00368         strip.show();     
00369         if (step+1 <= total)
00370         {
00371             step++;
00372             
00373         } else {
00374             //color = newColor;
00375             step = 0;
00376             finished =  true;
00377         }
00378         return finished;
00379 }
00380 
00381 
00382 /**
00383  * Callback triggered upon a connection event. Needs to halt scanning.
00384  */
00385 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
00386 {
00387     ble.gap().stopScan(); 
00388     masterMode[0] = 0;    
00389 }
00390 
00391 /**
00392  * Callback triggered upon a disconnection event. Needs to re-enable advertisements.
00393  */
00394 void disconnectionCallback(Gap::Handle_t gaphandle, Gap::DisconnectionReason_t reason)
00395 {                  
00396     memset(everything, 0, 44);
00397     memcpy(everything, input, NAMELENGTH);
00398     memcpy(everything+PARAMSBLOCK, parameters, PARAMSLENGTH);
00399     memcpy(everything+ELEMSBLOCK,elements,ELEMSLENGTH);
00400     //serial.printf("Everything - %c,%c,%c,%c ... %02x:%02x:%02x:%02x\n",everything[0],everything[1],everything[2],everything[3],everything[8],everything[9],everything[10],everything[11]);
00401     ClearMemory();
00402     readvertise = true;
00403     StoreEverything(everything);
00404 }
00405 
00406 
00407 
00408 uint32_t ble_advdata_parser(uint8_t type, uint8_t advdata_len, uint8_t *p_advdata, uint8_t *len, uint8_t *p_field_data)
00409 {
00410     uint8_t index=0;
00411     uint8_t field_length, field_type;
00412     
00413     while(index<advdata_len)
00414     {
00415         field_length = p_advdata[index];
00416         field_type   = p_advdata[index+1];
00417         if(field_type == type)
00418         {
00419             memcpy(p_field_data, &p_advdata[index+2], (field_length-1));
00420             *len = field_length - 1;
00421             return NRF_SUCCESS;
00422         }
00423         index += field_length + 1;
00424     }
00425     return NRF_ERROR_NOT_FOUND;
00426 }
00427 
00428 
00429 /**
00430  * This Handler controls all information recevied via BT
00431  */
00432 void WrittenHandler(const GattWriteCallbackParams *Handler)
00433 {   
00434     uint8_t buf[TXRX_BUF_LEN];
00435     uint16_t bytesRead;
00436     
00437     if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) 
00438     {
00439         ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead);
00440         memset(txPayload, 0, TXRX_BUF_LEN);
00441         memcpy(txPayload, buf, TXRX_BUF_LEN);       
00442         }  
00443         
00444     char command = buf[0];
00445     serial.printf("The command is %c\n",command);
00446         switch (command) {
00447             case 'i': //initialization
00448                 //serial.printf("Send Data");
00449                 uint8_t packet1[20];
00450                 uint8_t packet2[20];
00451                 memset(packet1,'p', 20);
00452                 memset(packet2,'e', 20);
00453                 memcpy(packet1+1, parameters, 19);
00454                 packet1[13] = threshold;
00455                 memcpy(packet2+1, elements, 19);
00456                 sendMsg(packet1,20);
00457                 sendMsg(packet2,20);
00458             break;
00459             case '1': //fade
00460                 mode = '1';
00461                 parameters[2] = buf[0]; //save this to mode byte
00462             break;
00463             case '2': //pulse
00464                 mode = '2';                
00465                 parameters[2] = buf[0]; //save this to mode byte
00466             break;   
00467             case '3': //rays
00468                 mode = '3';
00469                 parameters[2] = buf[0]; //save this to mode byte
00470             break;
00471             case '4': //solid
00472                 mode = '4';                
00473                 parameters[2] = buf[0]; //save this to mode byte
00474             break;
00475             case '5': //sparks
00476                 mode = '5';
00477                 waterfallCounter = 0;
00478                 parameters[2] = buf[0]; //save this to mode byte
00479             break;
00480             case 'b': //change brightness
00481                 MAX = buf[1]*4;  
00482                 parameters[0] = buf[1]; 
00483             break; 
00484             case 's': //change speed
00485             {
00486                 switch(buf[1]) {
00487                     case 0: //slow
00488                         speed = 960;
00489                         duration = .08;
00490                     break;
00491                     case 1: //medium
00492                         speed = 640;
00493                         duration = .06;                    
00494                     break;
00495                     case 2: //fast
00496                         speed = 320;
00497                         duration = .04;                    
00498                     break;
00499                     default:
00500                 } 
00501                 parameters[3] = buf[1];
00502             }                       
00503             break;
00504             case 'l': //change length
00505                 length = buf[1];   
00506                 parameters[1] = buf[1];  
00507             break;
00508             case 'r': //set random flag
00509                 random = buf[1];    
00510                 parameters[4] = buf[1];
00511             break;
00512             case 'c':
00513                 //serial.printf("Color Code - %c%c:%c%c:%c%c\n",buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]);
00514                 
00515                 uint8_t red = char2hex(buf[1],buf[2]);
00516                 uint8_t green = char2hex(buf[3],buf[4]);
00517                 uint8_t blue = char2hex(buf[5],buf[6]); 
00518                 
00519                 newColor = ((uint32_t) blue<<16)|((uint32_t) green<<8)|(uint32_t) red;
00520                 step = 0;
00521                 
00522                 parameters[6] = buf[1];
00523                 parameters[7] = buf[2];
00524                 parameters[8] = buf[3];
00525                 parameters[9] = buf[4];
00526                 parameters[10] = buf[5];
00527                 parameters[11] = buf[6];
00528             break; 
00529             case '*':        
00530                 memset(input, 0, NAMELENGTH);
00531                 memcpy(input,buf+1,NAMELENGTH);
00532             break;
00533             case 'a': //set advertising flag
00534                 advertise = buf[1];  
00535                 parameters[5] = buf[1];              
00536             break;
00537             case 'e': //elements
00538                 memcpy(elements,buf+1,ELEMSLENGTH);
00539                 //serial.printf("Elements - %d %d %d %d\n",elements[0],elements[1],elements[2],elements[3]);
00540             break;
00541             case '@': //show device color
00542                 deviceColor =  colors[address[0]%15];
00543                 strip.setBrightness(15);
00544                 step = 0;
00545                 total = 1200;
00546                 showColor = true;
00547                 serial.printf("Show Color\n");
00548             break;
00549             case '&': //change threshold
00550                 threshold = buf[1];
00551             default:
00552         } 
00553 }
00554 
00555 
00556 
00557 int main(void)
00558 {       
00559     //Initialize bluetooth module
00560     ble.init();
00561     
00562     /*Initialize Pstorage Module*/
00563     retval = pstorage_init();
00564     if(retval == NRF_SUCCESS)
00565     {
00566         //serial.printf("Module initialization successful\r\n");
00567          
00568         pstorage_module_param_t param;
00569          
00570         param.block_size  = BLOCKSIZE; 
00571         param.block_count = 1; 
00572         
00573         param.cb = cb_handler;
00574 
00575         retval = pstorage_register(&param, &handle); //register our pstorage and store store address in handle
00576         if (retval == NRF_SUCCESS)
00577         {
00578             //serial.printf("Registration successful.\r\n");
00579             //serial.printf("Module id: %u , block: %u \r\n", handle.module_id, handle.block_id);
00580         } else {//serial.printf("Failed to register, take corrective action.\r\n");
00581         }
00582     } else {//serial.printf("Initialization failed, take corrective action.\r\n"); 
00583     }
00584     
00585     LoadElements(elements);
00586     if (elements[0] == 255) {
00587         memset(elements,0,ELEMSLENGTH);
00588     }
00589 
00590     ble.gap().onDisconnection(disconnectionCallback);
00591     ble.gap().onConnection(connectionCallback);
00592     ble.gattServer().onDataWritten(WrittenHandler);  
00593     ble.gattServer().addService(uartService);
00594     // set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4
00595     ble.gap().setTxPower(-12); // tx power to -20
00596     // set adv_interval, 100ms in multiples of 0.625ms.
00597     ble.gap().setAdvertisingInterval(100);
00598     
00599     ble.gap().setScanParams(1000,150,0,true); // (scan interval, scan time,timeout,send scan requests)
00600     
00601     
00602     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00603     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 
00604     
00605     //Load Name
00606     uint8_t dest_data[NAMELENGTH] = {0,};
00607     LoadName(dest_data);            
00608                                 
00609     //Advertise the Loaded Name
00610     if (dest_data[0] != 255)   {        
00611         ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00612                     dest_data, NAMELENGTH);           
00613     } else { //This is first time powered on so initialize default name and advertise
00614         //serial.printf("Factory Condition .... Loading Default Name\n");
00615         ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00616                     DEFAULTNAME, NAMELENGTH);
00617     }
00618     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00619                     (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid)); 
00620    
00621     
00622     
00623     
00624     uint8_t temp_parameters[PARAMSLENGTH];
00625     //Load Parameters
00626     LoadParams(temp_parameters);
00627     if (temp_parameters[0] != 255)
00628     {
00629         memcpy(parameters,temp_parameters,PARAMSLENGTH);
00630         MAX = parameters[0]*4;
00631         length = parameters[1];
00632         mode = parameters[2];
00633         switch(parameters[3]) {
00634             case 0: //slow
00635                 speed = 960;
00636                 duration = .08;
00637             break;
00638             case 1: //medium
00639                 speed = 640;
00640                 duration = .06;
00641             break;
00642             case 2: //fast
00643                 speed = 320;
00644                 duration = .04;
00645             break;
00646             default:
00647         }
00648         random = parameters[4];
00649         advertise = parameters[5];
00650         
00651         uint8_t red = char2hex(parameters[6],parameters[7]);
00652         uint8_t green = char2hex(parameters[8],parameters[9]);
00653         uint8_t blue = char2hex(parameters[10],parameters[11]); 
00654         
00655         newColor = ((uint32_t) blue<<16)|((uint32_t) green<<8)|(uint32_t) red;
00656     }    
00657     
00658     ble.gap().startAdvertising();  
00659     ble.gap().startScan(scanCallback);  
00660     if (advertise){        
00661         uint8_t adv_elements[ELEMSLENGTH+2] = {0xAB,eventID};
00662         memcpy(adv_elements+2,elements,ELEMSLENGTH);
00663         ble.accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA,adv_elements, sizeof(adv_elements)); 
00664     }  
00665 
00666     strip.begin();
00667     
00668     ble.gap().getAddress(&type,address);
00669     
00670     while(1) { 
00671           if (showColor)
00672           {
00673             total = 2400;
00674             strip.setBrightness(15);
00675             if (fade(deviceColor,deviceColor))
00676                 showColor = false;
00677           }
00678           else if (masterMode[0]) {
00679             strip.setBrightness(masterMode[1]);
00680             total = 1200;
00681             if (masterMode[2]) {
00682                 if (elements[masterMode[3]])
00683                     fade(0,colors[elements[masterMode[3]]%15]);
00684                 else
00685                     fade(0,0);
00686             } 
00687             else {
00688                 uint8_t red = char2hex(masterMode[4],masterMode[5]);
00689                 uint8_t green = char2hex(masterMode[6],masterMode[7]);
00690                 uint8_t blue = char2hex(masterMode[8],masterMode[9]);                                 
00691                 uint32_t colour = ((uint32_t) blue<<16)|((uint32_t) green<<8)|(uint32_t) red;
00692                 
00693                 if(masterMode[3]) { //blink -1  or solid - 0
00694                     fade(0,colour);
00695                 }
00696                 else{
00697                     fade(colour,colour); 
00698                 }               
00699             }                 
00700           }
00701           else if(tick>0){            
00702             tick--;
00703             
00704             strip.setPixelColor(0,colors[address[0]%15]);
00705             strip.setPixelColor(1,peerColor3);            
00706             strip.setPixelColor(2,peerColor2);
00707             strip.setPixelColor(3,peerColor1);
00708             
00709             if (tick == 0)
00710             {
00711                peerColor1 = 0;
00712                peerColor2 = 0;
00713                peerColor3 = 0;
00714             }
00715             
00716             strip.setBrightness(15);            
00717             strip.show();                      
00718           } else {
00719           switch(mode) {
00720             case '1': //color fade
00721             {         
00722               brightness = MAX;
00723               total = 1200;      
00724               if(fade(color, c2)){
00725                 j = (j+1)%7;  
00726                 color = c2;               
00727                 c2 = colors[j];
00728                 }                                         
00729             }            
00730             break;
00731             case '2': //pulse
00732               {             
00733                     if (brightness >= MAX){direction = -1;}
00734                     else if(brightness <= 0){
00735                         if (random) {
00736                             j = (j+1)%15;
00737                             color = colors[j];
00738                         } else {
00739                             color = newColor;
00740                         }
00741                         direction = 1;}
00742                   
00743                     if (MAX == 0)
00744                         brightness = 0;
00745                     else
00746                         brightness += (MAX/speed)*direction;                                    
00747                     for (uint8_t i = 0; i < NUMPIXELS; i++) {
00748                         strip.setPixelColor(i, color);
00749                     }                   
00750               }
00751             break;
00752             case '3': //rays setup
00753             {
00754                 tail = -NUMPIXELS*2;
00755                 head = 0;
00756                 mode = '[';
00757             }
00758             break;
00759             case '[': //rays
00760               {    
00761                   brightness = MAX;     
00762                   strip.setPixelColor(head, color); // 'On' pixel at head
00763                   strip.setPixelColor(tail, 0);     // 'Off' pixel at tail            
00764                 
00765                   if(++head >= NUMPIXELS*4) {         // Increment head index.  Off end of strip?
00766                     head = 0;    
00767                     if (random) {
00768                         j = (j+1)%15;
00769                         color = colors[j];
00770                     } else {color = newColor;}
00771                   }
00772                   if(++tail >= NUMPIXELS*4) tail = 0; // Increment, reset tail index
00773                   wait(duration);                  
00774               }
00775               break;            
00776               case '4': //solid
00777               {
00778                   brightness = MAX;
00779                   total = 300;
00780                   if(fade(color, newColor))
00781                     color = newColor;
00782               }
00783               break;
00784               case '5': //waterfall
00785               {
00786                     brightness = MAX;                                    
00787                                         
00788                     if((waterfallCounter)==speed*4) {
00789                         strip.setPixelColor(0,0);
00790                         strip.setPixelColor(1,color);
00791                         strip.setPixelColor(2,color);
00792                         strip.setPixelColor(3,0);
00793                     } else if ((waterfallCounter)==speed*3) {
00794                         strip.setPixelColor(0,color);
00795                         strip.setPixelColor(1,color);
00796                         strip.setPixelColor(2,color);
00797                         strip.setPixelColor(3,color);                           
00798                     } else if ((waterfallCounter)==speed*2) {
00799                         strip.setPixelColor(0,color);
00800                         strip.setPixelColor(1,0);
00801                         strip.setPixelColor(2,0);
00802                         strip.setPixelColor(3,color);
00803                     } else if ((waterfallCounter)==speed) {
00804                         strip.setPixelColor(0,0);
00805                         strip.setPixelColor(1,0);
00806                         strip.setPixelColor(2,0);
00807                         strip.setPixelColor(3,0);
00808                     }
00809                     if (--waterfallCounter<=0) {
00810                         if (random) {
00811                             j = (j+1)%15;
00812                             color = colors[j];
00813                         } else {
00814                             color = newColor;
00815                         }
00816                         waterfallCounter = speed*4;
00817                     }
00818               }
00819               break;              
00820               default:
00821               {
00822                  
00823               }
00824               break;
00825           }
00826           strip.setBrightness(brightness);
00827           strip.show();
00828         } 
00829     }  
00830 }