App for BLE Nano to monitor the power consumption for a specific location, by intercepting the led flashes of a standard power meter. It counts and log the flashes for each second. It works with RedBear App for smart phone (Simple Chat App).

Dependencies:   BLE_API lib_mma8451q mbed nRF51822

Fork of nRF51822_DataLogger_with_Chat by Valentin Tanasa

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 /*
00021  *    The application works with the BLEController iOS/Android App.
00022  *    Type something from the Terminal to send
00023  *    to the BLEController App or vice verse.
00024  *    Characteristics received from App will print on Terminal.
00025  *      Read read_me.md file for more informations about the extended feature
00026  */
00027 
00028 
00029 #include "ble/BLE.h"
00030 //#include "LowPowerTicker.h"
00031 #include <myData.h>
00032 #include <Gap.h>
00033 //#include "ble_flash.h"
00034 #include "ble_flash.c"
00035 #include "BatteryService.h"
00036 //#include "DFUService.h"
00037 
00038 BLE ble;
00039 //DFUService dfu(ble);
00040 
00041 #define BLE_UUID_TXRX_SERVICE            0x0000 /**< The UUID of the Nordic UART Service. */
00042 #define BLE_UUID_TX_CHARACTERISTIC       0x0002 /**< The UUID of the TX Characteristic. */
00043 #define BLE_UUIDS_RX_CHARACTERISTIC      0x0003 /**< The UUID of the RX Characteristic. */
00044 
00045 #define TXRX_BUF_LEN                     20  /** For radio message transmission*/
00046 
00047 #define MyASSERT(cond , serialpc, errVal) assert_error_app((bool)cond, serialpc, (uint16_t)errVal, __LINE__, __FILE__)
00048 
00049 
00050 Serial pc(USBTX, USBRX);
00051 
00052 //uint8_t batteryLevel=100;
00053 uint16_t nr_of_hits = 0;
00054 uint32_t g_nrOfHits=0;
00055 float gmaxV=0,gminV=3,gmedianV=0.18; // Voltage of the PhotoResistorstatic float measure: max, min, median;
00056 
00057 bool bTimeReady = false;
00058 // The Nordic UART Service
00059 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
00060 static const uint8_t uart_tx_uuid[]   = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
00061 static const uint8_t uart_rx_uuid[]   = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
00062 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
00063 
00064 static const int8_t txPower = 0xCD;
00065 //BatteryService *batteryService = NULL;
00066 
00067 //uint8_t txPayload[TXRX_BUF_LEN] = {0, p28};
00068 uint8_t txPayload[TXRX_BUF_LEN] = {0,};
00069 uint8_t rxPayload[TXRX_BUF_LEN] = {0,};
00070 
00071 static uint8_t rx_buf[TXRX_BUF_LEN];
00072 static uint8_t rx_len=0;
00073 
00074 static uint32_t gTimeInstant = 1; // TimerTick Resolution, in seconds
00075 
00076 
00077 bool g_bIsConnected = false;
00078 bool g_bIsAdvertising = false;
00079 bool g_bConnDisabled = false;
00080 bool g_LogActive = false;// g_bAccEnabled=false, g_bCalib = false;
00081 static myDataLog_t g_MyData;
00082 uint8_t g_MyDataIdx=0;
00083 
00084 
00085 // pins connected for measuring
00086 DigitalOut led(LED1), //redLed(D4);//, accBuzzAlarm(D3), accLEDAlarm(D5);
00087 
00088 //uint8_t tempAlarm, accAlarm;
00089 
00090 //PwmOut buzzer(D1); // changed from P15
00091 AnalogIn photoVoltage(A5); // photo voltaga measurement 
00092 
00093 myPayload_t g_currMeasures2; // last measurements
00094 
00095 //Timeout timeout_err; // timeout for buzz on error
00096 Ticker periodicActions, doMeasures;
00097 mdatetime_manager_t g_myDateTimeVar;
00098 //uint8_t gBatteryValue=0;
00099 GattCharacteristic  txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
00100 
00101 GattCharacteristic  rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
00102 
00103 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
00104 
00105 GattService         uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
00106 
00107 void decode(uint8_t * buffer, uint16_t length);
00108 
00109 void alarm(){
00110     
00111     //accBuzzAlarm = 1;
00112     //accLEDAlarm = 0;
00113     //timeout_err.attach(&at_timeout_err, 2);
00114 }
00115 
00116 void sendRadioMsg(const uint8_t* buf, uint16_t length)
00117 {
00118     uint8_t retVal;
00119     retVal = ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, length);
00120     //pc.printf("Err=%d\r\n",retVal);
00121     MyASSERT((retVal!=0),&pc, retVal);
00122 }
00123 
00124 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00125 {
00126     pc.printf("Disconnected \r\n");
00127     g_bIsConnected = false;
00128     g_bIsAdvertising = false;
00129     pc.printf("R: %d\r",reason);
00130     if (reason != 0x16) {
00131         ble.startAdvertising();
00132         g_bIsAdvertising = true;
00133     }    
00134 }
00135 
00136 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
00137 {
00138     pc.printf("Connected \r\n");
00139     g_bIsConnected = true;
00140     g_bIsAdvertising = false;
00141 }
00142 
00143 void connectionUpdate(connection_update_t option)
00144 {
00145     if (g_bConnDisabled == false) {
00146         switch (option) {
00147             case eStartAdvertising: {
00148                 if ((g_bIsConnected == false)&&(g_bIsAdvertising == false)) {
00149                     pc.printf("Start Advertising\r");
00150                     ble.startAdvertising();
00151                     g_bIsAdvertising = true;
00152                 }
00153                 break;
00154             }
00155             case eStopAdvertising: {
00156                 if (g_bIsAdvertising == true) {
00157                     pc.printf("Stop Advertising\r");
00158                     ble.stopAdvertising();
00159                     g_bIsAdvertising = false;
00160                 }
00161                 break;
00162             }
00163             case eDisconnect: {
00164                 if (g_bIsConnected == true) {
00165                     pc.printf("Close connection\r");
00166                     ble.disconnect((Gap::DisconnectionReason_t)0x12);                    
00167                 } else if (g_bIsAdvertising == true) {
00168                     pc.printf("Stop Advertising\r");
00169                     ble.stopAdvertising();
00170                     g_bIsAdvertising = false;
00171                 }
00172                 break;
00173             }
00174         }
00175     }
00176 }
00177 void write_data_to_flash(uint32_t *tick, myPayload_t * currMeasures)
00178 {
00179     uint8_t page_num=0;
00180 
00181     if (g_MyDataIdx==0) {
00182         //initiate connection
00183         connectionUpdate(eStartAdvertising);
00184         // time and date used to initialize the g_MyData variable
00185         memcpy(&g_MyData.startData.datetime,&g_myDateTimeVar.currentDateTime, sizeof(mdate_time_t));        
00186         memcpy(&g_MyData.startData.data,currMeasures, sizeof(myPayload_t));
00187     } else {
00188         // it should be logged here the time difference from last record...
00189         g_MyData.myData[g_MyDataIdx-1].minutes = (uint16_t)(*tick*gTimeInstant / 60);
00190         g_MyData.myData[g_MyDataIdx-1].seconds = (*tick*gTimeInstant% 60);
00191         memcpy(&g_MyData.myData[g_MyDataIdx-1].data,currMeasures, sizeof(myPayload_t));
00192     }
00193     *tick = 0;
00194 
00195     if (g_MyDataIdx==(MAXBUFFER-3)) {
00196         //initiate disconnection
00197         connectionUpdate(eDisconnect);
00198     }
00199 
00200     if (g_MyDataIdx == MAXBUFFER) {
00201         // write2Flash the current page num
00202         //connectionUpdate(eDisconnect);
00203         
00204         page_num=flash_currPage();
00205         // write2Flash the current page data
00206         ble_flash_page_write(page_num, (uint32_t*)&(g_MyData), 253);
00207         memset(&g_MyData,0,sizeof(myDataLog_t));
00208         //pc.printf("retValWr: %d, Pg:%d, Min: %d \r\n",retVal, page_num,g_myDateTimeVar.currentDateTime.minutes);
00209         flash_go_nextPage();
00210     }
00211     g_MyDataIdx = (g_MyDataIdx+1)%(MAXBUFFER+1);
00212 }
00213 
00214 
00215 void on_error_radioMsg()
00216 {
00217     char myBuf[TXRX_BUF_LEN];
00218     sprintf(myBuf,"%s","WrongSyntax");
00219     //buzz_int(&buzzer,5,3);
00220     //timeout_err.attach(&at_timeout_err, 2);
00221     sendRadioMsg((uint8_t*)&myBuf[0], 12);
00222 }
00223 
00224 void flash_page_serial_dump(uint32_t* p_curr_addr)
00225 {
00226     myDataLogShort_t initialData;
00227     mdate_time_t * pdate;
00228     myDataL_t dataOut[2];
00229     uint8_t i;
00230 
00231     p_curr_addr += 2; // skip the magic number and the word count
00232     memcpy((uint32_t*)&initialData, p_curr_addr, 3*sizeof(uint32_t));
00233     pdate = &initialData.startData.datetime;
00234     pc.printf("20%2d_%2d_%2d H:%2d P:%4x\r",pdate->year, pdate->month, pdate->day, pdate->hours, p_curr_addr);
00235     pc.printf("%2d:%2d;%3d;%2d:%2d;%3d;\r",pdate->minutes, pdate->seconds, initialData.startData.data.hits,initialData.myData.minutes, initialData.myData.seconds, initialData.myData.data.hits);    
00236     p_curr_addr += 3;
00237 
00238     for (i=0; i<125; i++) {
00239         memcpy((uint32_t*)&dataOut, p_curr_addr, 2*sizeof(uint32_t));
00240         pc.printf("%2d:%2d;%3d;%2d:%2d;%3d;\r",dataOut[0].minutes, dataOut[0].seconds, dataOut[0].data.hits,dataOut[1].minutes, dataOut[1].seconds, dataOut[1].data.hits);        
00241         p_curr_addr += 2;
00242     }
00243 }
00244 
00245 int sign(int nr){
00246     int retVal=0;
00247     if (nr>0) retVal=1;
00248     else if (nr<0) retVal=-1;
00249     
00250     return retVal;    
00251 }
00252 
00253 float read_real_value(void){
00254     uint32_t wrk,reg0,reg1,reg2;
00255     reg0 = NRF_ADC->ENABLE;     // save register value
00256     reg1 = NRF_ADC->CONFIG;     // save register value
00257     reg2 = NRF_ADC->RESULT;     // save register value
00258     NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
00259     NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
00260                       (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
00261                       (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
00262                       (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
00263                       (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
00264     NRF_ADC->EVENTS_END  = 0;
00265     NRF_ADC->TASKS_START = 1;
00266     while (!NRF_ADC->EVENTS_END) {;}
00267     wrk = NRF_ADC->RESULT;      // 10 bit result
00268     NRF_ADC->ENABLE = reg0;     // recover register value
00269     NRF_ADC->CONFIG = reg1;     // recover register value
00270     NRF_ADC->RESULT = reg2;     // recover register value
00271     NRF_ADC->EVENTS_END  = 0;
00272     return ((float)wrk / 1024 * 1.2 * 3.0);            
00273 }
00274 
00275 uint8_t read100(void)
00276 { 
00277     float wrk_vdd, v0p= 2.7 ,v100p= 3.3;
00278     wrk_vdd = read_real_value();
00279     if (wrk_vdd <= v0p){
00280         return 0;
00281     } else if (wrk_vdd >= v100p){
00282         led = 0;
00283         return 100;
00284         
00285     }
00286     led = 1;
00287     wrk_vdd = (wrk_vdd - v0p) / (v100p - v0p);
00288     return (uint8_t)(wrk_vdd * 100); 
00289 }
00290 
00291 
00292 void at_eachInstant()
00293 {
00294     static uint32_t tick=0;
00295     static uint8_t ltick=0;
00296     uint8_t rcBuff[2]={'r','0'};
00297     //static myPayload_t prevMeasures2=(myPayload_t) { 0, 0, 0, 0};
00298 
00299     // update time
00300     update_time(&g_myDateTimeVar, gTimeInstant);
00301    
00302     //batteryService->updateBatteryLevel(gBatteryValue );
00303     //update measurements
00304     if (g_LogActive==true){       
00305     // if there are changes in data save
00306         if (0!=g_currMeasures2.hits){            
00307             write_data_to_flash(&tick, &g_currMeasures2);                                   
00308     }
00309     if (g_bIsConnected == true){
00310     // print info           
00311         rcBuff[1]='0'+ltick;
00312         decode(rcBuff,2);
00313         ltick =(ltick+1)%4;
00314     }
00315     tick++;
00316     
00317     }
00318 }
00319 
00320 void update_measurements()
00321 {
00322     nr_of_hits ++; 
00323     g_nrOfHits ++;
00324     /*if (bNewSample==false){ 
00325         //g_currMeasures2.hits =nr_of_hits; 
00326         nr_of_hits = 1;
00327         bNewSample = true; 
00328     } */   
00329     
00330     //gBatteryValue = read100();              
00331     
00332 }
00333 
00334 void at_eachADC(){
00335    static bool isLow = false;
00336    static bool bPrevState=isLow;
00337    static uint8_t counter = 0;
00338    static float measure;
00339    
00340           
00341    measure = photoVoltage.read();
00342    if (g_LogActive==false){
00343     if (measure > gmaxV) {
00344        maxV=measure;
00345     }
00346     if (measure < minV) {
00347         gminV=measure;
00348     }    
00349     //gmedian = gminV + (gminV + gmaxV)*10/4; % 25%
00350    }
00351    
00352    isLow =  (measure < gmedianV);
00353    if ((bPrevState != isLow)&&(isLow == true)){
00354         nr_of_hits ++; 
00355         g_nrOfHits ++;
00356        }
00357     bPrevState = isLow;
00358    
00359     counter = (counter + 1)%100;
00360     if (counter==0){
00361             // 1 second is passed
00362             bTimeReady=true;
00363             g_currMeasures2.hits =nr_of_hits; 
00364             nr_of_hits = 0;
00365         }
00366 }
00367 
00368 // Radio commands decode
00369 void decode(uint8_t * buffer, uint16_t length)
00370 {
00371     char myBuf[TXRX_BUF_LEN];
00372     uint16_t len;
00373     switch (buffer[0]) {
00374         case 'r': {// Read Operations
00375             switch (buffer[1]) {
00376                 case '0':{
00377                     sprintf(myBuf,"NH:%2d,TNH:%8d\r\n", g_currMeasures2.hits,g_nrOfHits);
00378                     len = 19;
00379                     break;
00380                 }
00381                 case '1':{
00382                     sprintf(myBuf,"P:%1.2f_%1.2f_%1.2f\r\n", gmaxV,photoVoltage.read(),gminV);
00383                     len = 18;
00384                     break;
00385                 }
00386                 case '2':{
00387                 sprintf(myBuf,"g_idx=%2d Page=%3d",g_MyDataIdx, flash_currPage());
00388                     len = 18;
00389                     break;                    
00390                 }
00391                 case '3': {
00392                     sprintf(myBuf,"V:%2.3f\r\n", read_real_value());
00393                     len = 11;
00394                     break;
00395                 }
00396                 case '4': {
00397                     sprintf(myBuf,"PhVol:%2.2f,Av:%2.2f\r\n",photoVoltage.read(),gmedian);
00398                     len = 20;
00399                     break;
00400                 }
00401                 case '5': {
00402                     //sprintf(myBuf,"Vmx_mn:%1.2f_%1.2f\r\n",maxV,minV);
00403                     //len = 18;
00404                     break;
00405                 }          
00406                 
00407                 default:{
00408                     sprintf(myBuf,"Nothing \r\n");
00409                     len = 10;
00410                     break;
00411                 }
00412             }
00413             sendRadioMsg((uint8_t *)myBuf, len);
00414             break;
00415         }
00416         case 'l': {// toogle led
00417             led = ! led;
00418             if (led==0) {
00419                 sprintf(myBuf,"%s","OFF");
00420                 len = 2;
00421             } else {
00422                 sprintf(myBuf,"%s","ON");
00423                 len = 3;
00424             }
00425             sendRadioMsg((uint8_t *)myBuf, len);
00426             break;
00427         }        
00428         case 'i':{ // Insert data values
00429             switch (buffer[1]){
00430                 case 'm':{      // median change              
00431                         memcpy(myBuf,&buffer[2],2);
00432                         gmedian=(float)atoi(myBuf)/10; // TODO check if it is a number                                          
00433                     break;
00434                 }
00435                 
00436                 default: {
00437                    // on_error_radioMsg();  // notify on radio
00438                 }
00439             }
00440             break;
00441         }
00442         case 'd':
00443         case 't': {// date /time operations            
00444             switch (buffer[1]) {
00445                 case 'i': { // date insert                   
00446                     uint8_t i; 
00447                     uint8_t * pdata = &g_myDateTimeVar.newDateTime.year; // to insert data
00448                     
00449                     if (buffer[0]=='t') {
00450                         sprintf(myBuf,"  TimeInserted");
00451                         pdata +=3;
00452                     } else {sprintf(myBuf,"  DateInserted");}
00453                     len= 14;
00454                     
00455                     for (i=0;i<3;i++){
00456                         memcpy(myBuf,&buffer[2+2*i],2);
00457                         *pdata=atoi(myBuf); // TODO check if it is a number
00458                         pdata= pdata+1;
00459                     }
00460                     g_myDateTimeVar.updateDateTime = true;
00461                     
00462                     sendRadioMsg((uint8_t *)myBuf, len);
00463                     break;
00464                 }
00465                 case 'g': { // time/date get
00466                 uint8_t * pdata1 = &g_myDateTimeVar.currentDateTime.year; // to get data
00467                    if (buffer[0]=='t') {
00468                         pdata1 +=3;
00469                         sprintf(myBuf,"H:%2d:%2d:%2d",*pdata1,*(pdata1+1),*(pdata1+2));
00470                         len = 11;
00471                     }else {
00472                         sprintf(myBuf,"D:20%2d:%2d:%2d",*pdata1,*(pdata1+1),*(pdata1+2));
00473                         len = 13;
00474                     }
00475                     sendRadioMsg((uint8_t *)myBuf, len);
00476                     break;
00477                 }
00478                 default:
00479                     MyASSERT(true,&pc, buffer[1]); // notify on serial interface
00480                     on_error_radioMsg();  // notify on radio
00481             }
00482             break;
00483         }
00484 
00485         case 'f': {// file operations
00486             switch (buffer[1]) {
00487                 case '1': {                    
00488                     sprintf(myBuf,"g_idx=%2d Page=%3d",g_MyDataIdx, flash_currPage());
00489                     len = 18;
00490                     sendRadioMsg((uint8_t *)myBuf, len);
00491                     break;
00492                 }
00493                 case '2': { // start measuring
00494                     sprintf(myBuf,"Start Meas");
00495                     len = 12;
00496                     sendRadioMsg((uint8_t *)myBuf, len);
00497                     g_LogActive = true;
00498                                       
00499                     break;
00500                 }
00501                 case '3': { // stop measuring
00502                     doMeasures.detach();
00503                     sprintf(myBuf,"Stop Meas");
00504                     len = 11;
00505                     sendRadioMsg((uint8_t *)myBuf, len);
00506                     g_LogActive = false;
00507                     ble_flash_page_write(flash_currPage(), (uint32_t*)&(g_MyData), 253);
00508                     memset(&g_MyData,0,sizeof(myDataLog_t));
00509                     flash_go_nextPage();
00510                     break;
00511                 }
00512                 case '4':{ 
00513                     break;
00514                 }
00515                 case '5':{ // read one measure
00516                                     
00517                     break;
00518                 }
00519                 default: {
00520                     // error
00521                 }
00522             }
00523             break;
00524         }
00525         default: {
00526             MyASSERT(true,&pc, buffer[1]); // notify on serial interface
00527             on_error_radioMsg();  // notify on radio;
00528         }
00529     }
00530 }
00531 
00532 // decode serial command that starts with x
00533 static void decode_s(uint8_t * buffer, uint16_t length)
00534 {
00535     uint8_t page_nr;
00536     char myBuf[5];
00537     uint32_t * p_curr_addr;
00538 
00539     switch (buffer[0]) {
00540         case 'f': { // info about selected flash page
00541             if ((buffer[1]<='9')&&(buffer[1]>='0')) {
00542                 memcpy(myBuf,&buffer[1],3);
00543                 page_nr= atoi(myBuf);
00544                 uint8_t p_word_count;
00545 
00546                 pc.printf("buffer[1]: %c \r\n",buffer[1]);
00547 
00548                 p_curr_addr= (uint32_t *)((uint16_t)BLE_FLASH_PAGE_SIZE * (flash_currPage() - page_nr));
00549                 pc.printf("page_addr: %x, pgNr = %d \r\n",p_curr_addr,(flash_currPage() - page_nr));
00550                 p_curr_addr += 1;
00551                 pc.printf("page_addr: %x \r\n",p_curr_addr);
00552                 p_word_count = (uint8_t)(*(p_curr_addr));
00553                 pc.printf("nr_of_words: %d \r\n",p_word_count);
00554                 flash_page_serial_dump((p_curr_addr-1));
00555             }
00556             break;
00557         }
00558         case 'd': { // full dump
00559             uint16_t page0;
00560             pc.printf("Full dump \r\n");
00561 
00562             page0 = flash_currPage();
00563             for (page_nr=0; page_nr<=(MAX_PAGE_NUM-MIN_PAGE_NUM); page_nr++) {
00564                 if ((page0-page_nr)< MIN_PAGE_NUM) {
00565                     page0 = MAX_PAGE_NUM + page_nr;
00566                 }
00567                 p_curr_addr= (uint32_t *)((uint16_t)BLE_FLASH_PAGE_SIZE * (page0-page_nr));
00568                 flash_page_serial_dump(p_curr_addr);
00569             }
00570             break;
00571         }
00572         case 'g': {
00573             pc.printf("g_MyDataIdx= %d\r", g_MyDataIdx);
00574             break;
00575         }
00576         case 'c': {
00577             switch (buffer[1]) {
00578                 case 'a': {
00579                     connectionUpdate(eStartAdvertising);
00580                     break;
00581                 }
00582                 case 'c' : {
00583                     connectionUpdate(eDisconnect);
00584                     break;
00585                 }
00586                 case 's' : {
00587                     connectionUpdate(eStopAdvertising);
00588                     break;
00589                 }
00590                 default:
00591                     pc.printf("Not recognized cmd !\r");
00592             }
00593             break;
00594         }
00595         default: {
00596             // nothing
00597         }
00598     }
00599 }
00600 
00601 void WrittenHandler(const GattWriteCallbackParams *Handler)
00602 {
00603     uint8_t buf[TXRX_BUF_LEN+1]= {'R',':',0};
00604     uint16_t bytesRead;
00605 
00606     if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) {
00607         ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), &buf[2], &bytesRead);
00608         memset(txPayload, 0, TXRX_BUF_LEN);
00609         memcpy(txPayload, &buf[2], bytesRead);
00610         if (txPayload[0] == 'x') {
00611             decode(&txPayload[1],bytesRead);
00612         }
00613         //echo back
00614         bytesRead+=2;
00615         sendRadioMsg(buf, bytesRead);
00616 
00617         // print on PC monitor
00618         buf[bytesRead]='\r';        
00619         pc.printf("%s",buf);
00620     }
00621 }
00622 
00623 void uartCB(void)
00624 {
00625     while(pc.readable()) {
00626         rx_buf[rx_len++] = pc.getc();
00627         if(rx_len>=20 || rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\n') {
00628             ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), rx_buf, rx_len);
00629             if ((rx_buf[0]=='x')) {
00630                 decode_s(&rx_buf[1],(rx_len-1)); // serial decode
00631             }
00632             rx_len= 0;
00633             break;
00634         }
00635     }
00636 }
00637 
00638 
00639 void g_varInit()
00640 {
00641     g_myDateTimeVar.updateDateTime = true;    
00642     /* retreive latest date, time and page flash available */
00643     search_latest_in_flash(&g_myDateTimeVar.newDateTime);    
00644 }
00645 
00646 int main(void)
00647 {
00648     ble.init();
00649     g_varInit();
00650     led= 1;
00651     
00652     ble.onDisconnection(disconnectionCallback);
00653     ble.onConnection(connectionCallback);
00654     ble.onDataWritten(WrittenHandler);
00655     //event.rise(&button);
00656     
00657     
00658     //event.rise(&accInt1);
00659     pc.baud(19200);
00660     pc.printf("SimpleChat Init \r\n");
00661     
00662     pc.attach( uartCB , pc.RxIrq);
00663     // setup advertising
00664     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00665     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00666     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00667                                      (const uint8_t *)"CntBle3", sizeof("CntBle3") - 1);
00668     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00669                                      (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
00670     //ble.accumulateAdvertisingPayload(GapAdvertisingData::TX_POWER_LEVEL,(const uint8_t *)txPower, sizeof(txPower));
00671     ble.setTxPower(txPower);
00672     // 100ms; in multiples of 0.625ms.
00673     ble.setAdvertisingInterval(160);
00674     /*
00675     // activate radio notifications - usefull for flashwrite
00676     void (*ptrFunc)(bool);
00677     ptrFunc  = ble_flash_on_radio_active_evt;
00678     //needed for flash write
00679     //ble.onRadioNotification(ptrFunc);
00680     */
00681     ble.addService(uartService);
00682     //batteryService = new BatteryService(ble, batteryLevel);
00683     ble.startAdvertising();
00684     pc.printf("Advertising Start \r\n");   
00685     //periodicActions.attach(&at_eachInstant,gTimeInstant);    
00686     doMeasures.attach_us(&at_eachADC,10000);
00687     //gBatteryValue = read100();
00688     while(1) {
00689         ble.waitForEvent();
00690         if (bTimeReady==true){
00691             bTimeReady=false;
00692             at_eachInstant();
00693         }
00694     }
00695 }