예제 #1
0
void sd_maskBootloader(uint8_t mask)
{
	uint32_t boot_set = 0;
	sd_power_gpregret_get(&boot_set);
	boot_set = boot_set |(uint32_t)mask;
	sd_power_gpregret_set(boot_set);
	sd_nvic_SystemReset();
}
예제 #2
0
static void handleBootloaderCmd(struct esbPacket_s *packet)
{
  static bool resetInit = false;
  static struct esbPacket_s txpk;

  switch (packet->data[2]) {
    case BOOTLOADER_CMD_RESET_INIT:

      resetInit = true;

      txpk.data[0] = 0xff;
      txpk.data[1] = 0xfe;
      txpk.data[2] = BOOTLOADER_CMD_RESET_INIT;

      memcpy(&(txpk.data[3]), (uint32_t*)NRF_FICR->DEVICEADDR, 6);

      txpk.size = 9;
#if BLE
      bleCrazyfliesSendPacket(&txpk);
#endif
      if (esbCanTxPacket()) {
        struct esbPacket_s *pk = esbGetTxPacket();
        memcpy(pk, &txpk, sizeof(struct esbPacket_s));
        esbSendTxPacket(pk);
      }

      break;
    case BOOTLOADER_CMD_RESET:
      if (resetInit && (packet->size == 4)) {
        msDelay(100);
        if (packet->data[3] == 0) {
          NRF_POWER->GPREGRET |= 0x40;
        } else {
          //Set bit 0x20 forces boot to firmware
          NRF_POWER->GPREGRET |= 0x20U;
        }
#ifdef BLE
        sd_nvic_SystemReset();
#else
        NVIC_SystemReset();
#endif
      }
      break;
    default:
      break;
  }
}
예제 #3
0
파일: main.c 프로젝트: ruelsison/simplewave
/**@brief Error handler function, which is called when an error has occurred. 
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyze 
 *          how your product is supposed to react in case of error.
 *
 * @param[in] error_code  Error code supplied to the handler.
 * @param[in] line_num    Line number where the handler is called.
 * @param[in] p_file_name Pointer to the file name. 
 */
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
    //nrf_gpio_pin_set(ASSERT_LED_PIN_NO);
	
		errorLEDs();

    // This call can be used for debug purposes during development of an application.
    // @note CAUTION: Activating this code will write the stack to flash on an error.
    //                This function should NOT be used in a final product.
    //                It is intended STRICTLY for development/debugging purposes.
    //                The flash write will happen EVEN if the radio is active, thus interrupting
    //                any communication.
    //                Use with care. Un-comment the line below to use.
    //ble_debug_assert_handler(error_code, line_num, p_file_name);

    // On assert, the system can only recover with a reset.
    //NVIC_SystemReset();
		sd_nvic_SystemReset();
}
예제 #4
0
uint32_t dfu_jump_to_bootloader(void)
{
    if (NRF_UICR->BOOTLOADERADDR != 0xFFFFFFFF)
    {
        interrupts_disable();

#ifdef SOFTDEVICE_PRESENT
        sd_power_reset_reason_clr(0x0F000F);
        sd_power_gpregret_set(RBC_MESH_GPREGRET_CODE_FORCED_REBOOT);
        sd_nvic_SystemReset();
#else
        NRF_POWER->RESETREAS = 0x0F000F; /* erase reset-reason to avoid wrongful state-readout on reboot */
        NRF_POWER->GPREGRET = RBC_MESH_GPREGRET_CODE_FORCED_REBOOT;
        NVIC_SystemReset(); //TODO: Wait for serial commands and flash?
#endif
        return NRF_SUCCESS; /* unreachable */
    }
    else
    {
        /* the UICR->BOOTLOADERADDR isn't set, and we have no way to find the bootloader-address. */
        return NRF_ERROR_FORBIDDEN;
    }
}
예제 #5
0
void mainLoop(void)
{
    bool resetToFw = false;
    static CrtpPacket crtpPacket;
    static bool stmStarted = false;

    while(!resetToFw) {
        EsbPacket *packet;
        buttonProcess();

        if (buttonGetState() != buttonIdle) {
            resetToFw = true;
        }

        if ((stmStarted == false) && (nrf_gpio_pin_read(UART_RX_PIN))) {
            nrf_gpio_cfg_input(UART_RTS_PIN, NRF_GPIO_PIN_NOPULL);
            uartInit();
            stmStarted = true;
        }


        if (cstate != connect_ble) {
            packet = esbGetRxPacket();
            if (packet != NULL) {

                if ( ((packet->size >= 2) &&
                        (packet->data[0]==0xff) &&
                        (packet->data[1]==0xff)) ||
                        ((packet->size >= 2) &&
                         (packet->data[0]==0xff) &&
                         (packet->data[1]==0xfe))
                   ) {
                    // Disable Bluetooth advertizing when receiving a bootloader SB packet
                    if (cstate == connect_idle) {
                        //sd_ble_gap_adv_stop();
                        cstate = connect_sb;
                    }
                }

                // If we are connected SB, the packet is read and used
                if (cstate == connect_sb) {
                    memcpy(crtpPacket.raw, packet->data, packet->size);
                    crtpPacket.datalen = packet->size-1;
                }
                esbReleaseRxPacket(packet);
            }
        }
        if (cstate != connect_sb) {
            if (bleCrazyfliesIsPacketReceived()) {
                cstate = connect_ble;

                packet = bleCrazyfliesGetRxPacket();
                memcpy(crtpPacket.raw, packet->data, packet->size);
                crtpPacket.datalen = packet->size-1;
                bleCrazyfliesReleaseRxPacket(packet);
            }
        }

        if (crtpPacket.datalen != 0xffu) {
            struct syslinkPacket slPacket;
            slPacket.type = SYSLINK_RADIO_RAW;
            memcpy(slPacket.data, crtpPacket.raw, crtpPacket.datalen+1);
            slPacket.length = crtpPacket.datalen+1;

            if (bootloaderProcess(&crtpPacket) == false) {
                // Send packet to stm32
                syslinkSend(&slPacket);

                crtpPacket.datalen = 0xFFU;
                // If packet received from stm32, send it back
                if (syslinkReceive(&slPacket)) {
                    if (slPacket.type == SYSLINK_RADIO_RAW) {
                        memcpy(crtpPacket.raw, slPacket.data, slPacket.length);
                        crtpPacket.datalen = slPacket.length-1;
                    }
                }
            }
        }
        if (crtpPacket.datalen != 0xFFU) {
            if (cstate == connect_sb) {
                EsbPacket *pk = esbGetTxPacket();
                if (pk) {
                    memcpy(pk->data, crtpPacket.raw, crtpPacket.datalen+1);
                    pk->size = crtpPacket.datalen+1;
                    esbSendTxPacket(pk);
                }
            } else if (cstate == connect_ble) {
                static EsbPacket pk;
                memcpy(pk.data, crtpPacket.raw, crtpPacket.datalen+1);
                pk.size = crtpPacket.datalen+1;
                bleCrazyfliesSendPacket(&pk);
            }
        }

        crtpPacket.datalen = 0xFFU;

        // Blink the LED
        if (NRF_TIMER1->EVENTS_COMPARE[0]) {
            NRF_TIMER1->EVENTS_COMPARE[0] = 0;
#ifndef DEBUG_TIMESLOT
            NRF_GPIOTE->TASKS_OUT[0] = 1;
#endif
        }
    }

    //Set bit 0x20 forces boot to firmware
    NRF_POWER->GPREGRET |= 0x20U;
    sd_nvic_SystemReset();

    while(1);
}
예제 #6
0
bool Node::TerminalCommandHandler(string commandName, vector<string> commandArgs)
{
	/************* SYSTEM ***************/
	if (commandName == "reset")
	{
		sd_nvic_SystemReset();
	}
	else if (commandName == "startterm")
	{
		Terminal::promptAndEchoMode = true;
	}
	else if (commandName == "stopterm")
	{
		Terminal::promptAndEchoMode = false;
		Logger::getInstance().disableAll();
	}
	/************* NODE ***************/
	else if (commandName == "status")
	{
		PrintStatus();
	}
	else if (commandName == "bufferstat")
	{
		PrintBufferStatus();
	}
	else if (commandName == "stat")
	{
		PrintSingleLineStatus();
	}

	else if (commandName == "data")
	{
		nodeID receiverId = 0;
		if(commandArgs.size() > 0){
			if(commandArgs[0] == "sink") receiverId = NODE_ID_SHORTEST_SINK;
			else if(commandArgs[0] == "hop") receiverId = NODE_ID_HOPS_BASE + 1;
			else receiverId = NODE_ID_BROADCAST;
		}

		//Send data over all connections
		connPacketData1 data;
		data.header.messageType = MESSAGE_TYPE_DATA_1;
		data.header.sender = persistentConfig.nodeId;
		data.header.receiver = receiverId;

		data.payload.length = 7;
		data.payload.data[0] = 1;
		data.payload.data[1] = 3;
		data.payload.data[2] = 3;

		bool reliable = (commandArgs.size() == 0) ? false : true;

		cm->SendMessageToReceiver(NULL, (u8*) &data, SIZEOF_CONN_PACKET_DATA_1, reliable);
	}
	else if(commandName == "datal")
	{
		//Send some large data that is split over messages
		const u8 dataLength = 45;
		u8 _packet[dataLength];
		connPacketHeader* packet = (connPacketHeader*)_packet;
		packet->messageType = MESSAGE_TYPE_DATA_1;
		packet->receiver = 0;
		packet->sender = persistentConfig.nodeId;

		for(u32 i=0; i< dataLength-5; i++){
			_packet[i+5] = i+1;
		}

		cm->SendMessageToReceiver(NULL, _packet, dataLength, true);


	}
	else if (commandName == "loss")
	{
		//Simulate connection loss
		this->persistentConfig.connectionLossCounter++;
		clusterId = this->GenerateClusterID();
		this->UpdateJoinMePacket(NULL);

	}
	else if (commandName == "settime")
	{
		u64 timeStamp = (atoi(commandArgs[0].c_str()) * (u64)APP_TIMER_CLOCK_FREQ);

		//Set the time for our node
		globalTime = timeStamp;
		app_timer_cnt_get(&globalTimeSetAt);
	}
	else if(commandName == "gettime")
	{
		u32 rtc1;
		app_timer_cnt_get(&rtc1);

		char timestring[50];
		Logger::getInstance().convertTimestampToString(globalTime, timestring);

		trace("Time is currently %s, setAt:%d, rtc1:%u" EOL, timestring, globalTimeSetAt, rtc1);
	}
	else if (commandName == "sendtime")
	{
		//Generate a timestamp packet and send it to all other nodes
		connPacketUpdateTimestamp packet;

		packet.header.messageType = MESSAGE_TYPE_UPDATE_TIMESTAMP;
		packet.header.sender = persistentConfig.nodeId;
		packet.header.receiver = 0;

		//Data must not be filled because it is set in the fillTransmitBuffers method
		//Because it might still take some time from filling the buffer to sending the packet
		//We should use the radio event or estimate the sending based on the connetion parameters

		//It is then received and processed in the Connectionmanager::messageReceivedCallback

		cm->SendMessageToReceiver(NULL, (u8*)&packet, SIZEOF_CONN_PACKET_UPDATE_TIMESTAMP, true);

	}
	else if (commandName == "discovery")
	{
		if (commandArgs.size() < 1 || commandArgs[0] == "high")
		{
			noNodesFoundCounter = 0;
			ChangeState(discoveryState::DISCOVERY_HIGH);
		}
		else if (commandArgs[0] == "low")
		{
			noNodesFoundCounter = 50;
			ChangeState(discoveryState::DISCOVERY_LOW);

		}
		else if (commandArgs[0] == "off")
		{
			ChangeState(discoveryState::DISCOVERY_OFF);
		}
	}
	else if (commandName == "discover")
	{
		ChangeState(discoveryState::DISCOVERY_HIGH);
	}
	else if (commandName == "discoverylow")
	{
		noNodesFoundCounter = 50;

	}
	//Trigger this to save the current node configuration
	else if (commandName == "savenode")
	{
		persistentConfig.reserved++;
		Storage::getInstance().QueuedWrite((u8*) &persistentConfig, sizeof(NodeConfiguration), 0, this);

	}
	else if (commandName == "stop")
	{
		DisableStateMachine(true);
	}
	else if (commandName == "start")
	{
		DisableStateMachine(false);
	}
	else if (commandName == "break")
	{
		Config->breakpointToggleActive = !Config->breakpointToggleActive;
	}
	else if (commandName == "connect")
	{

		for (int i = 0; i <NUM_TEST_DEVICES ; i++)
		{
			if (strcmp(commandArgs[0].c_str(), testDevices[i].name) == 0)
			{
				trace("Trying to connecting to node %s", testDevices[i].name);

				cm->ConnectAsMaster(testDevices[i].id, &testDevices[i].addr, 14);

			}
		}

	}
	else if (commandName == "disconnect")
	{
		if (commandArgs.size() > 0)
		{
			u8 connectionNumber = atoi(commandArgs[0].c_str());

			cm->connections[connectionNumber]->Disconnect();
		}
	}

	else if (commandName == "heap")
	{

		Utility::CheckFreeHeap();

		return true;

	}
	else if (commandName == "modules")
	{

		for(u32 i=0; i<MAX_MODULE_COUNT; i++)
		{
			if(activeModules[i] != NULL) log("Module: %s", activeModules[i]->moduleName);
		}

		return true;

	}
	else if (commandName == "yousink")
	{

		this->persistentConfig.deviceType = deviceTypes::DEVICE_TYPE_SINK;

		return true;

	}
	else if (commandName == "set_nodeid")
	{

		this->persistentConfig.nodeId = atoi(commandArgs[0].c_str());

		return true;

	}

	/************* UART COMMANDS ***************/
	else if (commandName == "uart_set_campaign")
	{
		if (commandArgs.size() > 0){
			AdvertisingController::SetScanResponseData(this, commandArgs[0]);
		} else {
			uart_error(Logger::ARGUMENTS_WRONG);
		}
	}
	else
	{
		return false;
	}
	return true;
}
예제 #7
0
void sd_triggerBootloader(void)
{
	uint32_t boot_set = 0xFF;
	sd_power_gpregret_set(boot_set);
	sd_nvic_SystemReset();
}
/**@brief Function for handling the Device Manager events.
 *
 * @param[in] p_evt  Data associated to the device manager event.
 */
static uint32_t device_manager_evt_handler(dm_handle_t const * p_handle,
                                           dm_event_t const  * p_event,
                                           ret_code_t        event_result)
{
    uint32_t err_code;
   
    static bool device_delete_all_started;
    
    // Recovery in the event of DM_DEVICE_CONTEXT_FULL
    if(event_result == DM_DEVICE_CONTEXT_FULL)
    {
        /* Clear all devices from the bond table*/ 
        err_code = dm_device_delete_all(&m_app_handle);
        APP_ERROR_CHECK(err_code);
        
        device_delete_all_started = true;
             
    }
    else
    {
        APP_ERROR_CHECK(event_result);   
    }
    
    if (p_event->event_id == DM_EVT_DEVICE_CONTEXT_STORED)
    {
        table_index_t table_index;
        
        //Find first and last bond created from m_bond_index_table 
        app_bond_find(&m_app_bond_table,&table_index);
        
		//Increment counter if a new bond was created
        if(!(table_index.mr_cnt_val >= m_app_bond_table.app_bond_cnt[p_handle->device_id]))
        {
           table_index.mr_cnt_val++;
           m_app_bond_table.app_bond_cnt[p_handle->device_id] = table_index.mr_cnt_val;
        }
                
        //Delete first created bond if bond table is full 
        if(((table_index.mr_cnt_val-table_index.lr_cnt_val)== DEVICE_MANAGER_MAX_BONDS-1)
             && (table_index.lr_cnt_val != NO_APP_CONTEXT))
          {
                uint32_t err_code;
                dm_handle_t device;
                
                device.appl_id = 0;
                    
                m_app_bond_table.app_bond_cnt[table_index.lr_index]=NO_APP_CONTEXT; 
                device.device_id = m_app_bond_table.device_id[table_index.lr_index];
                    
                err_code = dm_device_delete(&device); 
                APP_ERROR_CHECK(err_code);
                    
          }   
                
        //Update the app context for new device
        app_bond_update_context(&m_app_bond_table,p_handle); 
        
    }
    else if (p_event->event_id ==DM_EVT_DEVICE_CONTEXT_DELETED)
    {
        
         /* Wait for all devices to be cleared before perfoming a sys reset */ 
         if(device_delete_all_started && (p_handle->device_id == DEVICE_MANAGER_MAX_BONDS -1))
         {
             err_code = sd_nvic_SystemReset();
             APP_ERROR_CHECK(err_code);
         }
         
    }


    return NRF_SUCCESS;
}
예제 #9
0
bool Testing::TerminalCommandHandler(string commandName, vector<string> commandArgs)
{
	if (commandName == "SEND")
	{
		//parameter 1: R=reliable, U=unreliable, B=both
		//parameter 2: count

		connPacketData1 data;
		data.header.messageType = MESSAGE_TYPE_DATA_1;
		data.header.sender = nodeId;
		data.header.receiver = 0;

		data.payload.length = 7;
		data.payload.data[2] = 7;


		u8 reliable = (commandArgs.size() < 1 || commandArgs[0] == "b") ? 2 : (commandArgs[0] == "u" ? 0 : 1);

		//Second parameter is number of messages
		u8 count = commandArgs.size() > 1 ? atoi(commandArgs[1].c_str()) : 5;

		for (int i = 0; i < count; i++)
		{
			if(reliable == 0 || reliable == 2){
				data.payload.data[0] = i*2;
				data.payload.data[1] = 0;
				if(cm->inConnection->handshakeDone) cm->SendMessage(cm->inConnection, (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, false);
				if(cm->outConnections[0]->handshakeDone) cm->SendMessage(cm->outConnections[0], (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, false);
				if(cm->outConnections[1]->handshakeDone) cm->SendMessage(cm->outConnections[1], (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, false);
				if(cm->outConnections[2]->handshakeDone) cm->SendMessage(cm->outConnections[2], (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, false);
			}

			if(reliable == 1 || reliable == 2){
				data.payload.data[0] = i*2+1;
				data.payload.data[1] = 1;
				if(cm->inConnection->handshakeDone) cm->SendMessage(cm->inConnection, (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, true);
				if(cm->outConnections[0]->handshakeDone) cm->SendMessage(cm->outConnections[0], (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, true);
				if(cm->outConnections[1]->handshakeDone) cm->SendMessage(cm->outConnections[1], (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, true);
				if(cm->outConnections[2]->handshakeDone) cm->SendMessage(cm->outConnections[2], (u8*)&data, SIZEOF_CONN_PACKET_DATA_1, true);
			}
		}

	}
	else if (commandName == "FILL")
	{
		cm->fillTransmitBuffers();
	}
	else if (commandName == "ADVERTISE")
	{

		AdvertisingController::SetAdvertisingState(advState::ADV_STATE_HIGH);

	}
	else if (commandName == "SCAN")
	{

		ScanController::SetScanState(scanState::SCAN_STATE_HIGH);

	}
	else if (commandName == "RESET")
	{
		sd_nvic_SystemReset();

	}
	else
	{
		return false;
	}
	return true;
}
예제 #10
0
파일: main.c 프로젝트: ruelsison/simplewave
int main(void)
{
    bool init_status;
    int retValue;
	int i = defaultPerso.fall_detection_window;

    // initialize LEDs
    nrf_gpio_cfg_output(LED_RESETTING);
    nrf_gpio_cfg_output(LED_NO_FALL);
    nrf_gpio_cfg_output(LED_FALL_DETECTED);
		nrf_gpio_cfg_output(LED_OTHER);
		
		welcomeLEDs();

    // Initialize
    timers_init();
    ble_stack_init();
    gap_params_init();
    services_init();
    advertising_init();
    conn_params_init();
    sec_params_init();
    twi_master_init();
		
#ifdef TEST_ACTIVITY_LOG		
		testActivityLog();
#endif
		
		initActivityLog();
		initSnapshotBuffer();
		initCoefficients();

    // initialize values
    retValue = 0;

    init_status = mpu6050_init(MPU6050_DEVICE_ADDR);
    if ( false == init_status )
    {
        init_status = mpu6050_init(MPU6050_DEVICE_ADDR+1);
        if ( false == init_status )
        {   
            retValue = -1;
						errorLEDs();
					sd_nvic_SystemReset();
        }
    }
    if ( 0 == retValue )
    {    
      init_status = false;

			
			i = 0;
        while ( false == init_status )
        {
          if (i == 6) 
					{
						errorLEDs();
						sd_nvic_SystemReset();
					}
					
					init_status = accel_setup();
					i++;
					
				}
    }
		
		
    if (0 == retValue) {
			 
			char outbuf[20];
			
			// Start execution - write a log entry with zero steps to indicate startup
				
//				writeLogEntry(999);
        advertising_start();
				setup_wdt();
        timers_start(); // start sampliing
        
        while(1)
        {
					if (ReadSnapshots == 1)
					{

						FullSnapshotEntry* entry = (FullSnapshotEntry*)(SNAPSHOT_DATA_ADDRESS_START) ;
						
						SnapshotHeader *h;
						Sensor_Reading *r;

            sprintf (outbuf, "ID: %s                                   ", getPerso()->uname);    
						ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
                

                for(int i=0;i < getActivityLogSize(); i++)
                {
                  h = &entry->hdr;
									
									sprintf (outbuf, ": SNAPSHOT # %d  \n                           ",(i));
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 16);
									
									sprintf (outbuf, "Version: 2 \n");//
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 12);
									
									sprintf (outbuf, "t:%d n:%d last:%d",h->data.time, h->data.num_of_data_points, h->data.latest_data_point_index);
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
//									ptr++;
								
									r = entry->r;
										
									for (int j = 0; j < NUMBER_OF_ENTRIES; j++)
									{
										#define FLASH_READ_DELAY 40
										nrf_gpio_pin_set(LED_RESETTING); 
		
										sprintf (outbuf, "i: %d T: %04x           ",j,r[j].val.temp);
										ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
										
										nrf_delay_ms(FLASH_READ_DELAY);

										sprintf (outbuf, "A: x%04xy%04xz%04x",r[j].val.x_ac,r[j].val.y_ac,r[j].val.z_ac);
										ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
										
										nrf_delay_ms(FLASH_READ_DELAY);
								
										sprintf (outbuf, "G: x%04xy%04xz%04x",r[j].val.x_gy,r[j].val.y_gy,r[j].val.z_gy);
										ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
										
										nrf_delay_ms(FLASH_READ_DELAY);
										
										nrf_gpio_pin_clear(LED_RESETTING);
										
										nrf_delay_ms(FLASH_READ_DELAY);
										
										//ptr += sizeof(Sensor_Reading);
										

									}
									entry++;
                    
									
                    
                }  	
						
						
						ReadSnapshots = 0;
					}

					if (ReadSnapshotsPartial == 1)
					{
						
						PartialSnapTotal = ((PartialSnap1-('0'))*10)+(PartialSnap2-('0'));
						
						FullSnapshotEntry* entry = (FullSnapshotEntry*)(SNAPSHOT_DATA_ADDRESS_START+(((PartialSnapTotal*sizeof(FullSnapshotEntry)*10))/4)) ;
						
						SnapshotHeader *h;
						Sensor_Reading *r;

            sprintf (outbuf, "ID: %s                                   ", getPerso()->uname);    
						ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
                

                for(int i=0;i < 10; i++)
                {
                  h = &entry->hdr;
									
									sprintf (outbuf, ": SNAPSHOT # %d  \n                           ",(i+(PartialSnapTotal*10)));
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 16);
									
									sprintf (outbuf, "Version: 2 \n");//
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 12);
									
									sprintf (outbuf, "t:%d n:%d last:%d",h->data.time, h->data.num_of_data_points, h->data.latest_data_point_index);
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
//									ptr++;
								
									r = entry->r;
										
									for (int j = 0; j < NUMBER_OF_ENTRIES; j++)
									{
										#define FLASH_READ_DELAY 40
										nrf_gpio_pin_set(LED_RESETTING); 
		
										sprintf (outbuf, "i: %d T: %04x           ",j,r[j].val.temp);
										ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
										
										nrf_delay_ms(FLASH_READ_DELAY);

										sprintf (outbuf, "A: x%04xy%04xz%04x",r[j].val.x_ac,r[j].val.y_ac,r[j].val.z_ac);
										ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
										
										nrf_delay_ms(FLASH_READ_DELAY);
								
										sprintf (outbuf, "G: x%04xy%04xz%04x",r[j].val.x_gy,r[j].val.y_gy,r[j].val.z_gy);
										ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
										
										nrf_delay_ms(FLASH_READ_DELAY);
										
										nrf_gpio_pin_clear(LED_RESETTING);
										
										nrf_delay_ms(FLASH_READ_DELAY);
										
										//ptr += sizeof(Sensor_Reading);
										

									}
									entry++;
                    
									
                    
                }  	
						
						
						ReadSnapshotsPartial = 0;
					}
					
					if (ReadDataBuffer == 1)
					{
						LogEntry *addr;
 
			
						sprintf (outbuf, "ID: %s                                   ", getPerso()->uname);
							ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
							
						addr = (LogEntry *)(STEP_DATA_ADDRESS_START);
							for(int i=0;i < getActivityLogSize(); i++)
							{
								nrf_gpio_pin_set(LED_RESETTING); 
								nrf_delay_ms(20);
								nrf_gpio_pin_clear(LED_RESETTING);
								nrf_delay_ms(20);  
								
									
					//			sprintf ( outbuf, ": h:%d s:%d a:%04f                                   ",addr->item.hour, addr->item.sec, addr->item.activity_level);
								sprintf ( outbuf, "%d:%d - %03f                                   ",addr->item.hour, (addr->item.sec)/60, addr->item.activity_level);
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
									//nrf_delay_ms(1);
								addr++;
									
							}  
							ReadDataBuffer = 0;
					}

					if (ReadDataBufferPartial == 1)
					{
						LogEntry *addr;
 
			
						sprintf (outbuf, "ID: %s                                   ", getPerso()->uname);
							ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
						
						PartialCountTotal = ((PartialCount1-('0'))*10)+(PartialCount2-('0'));							
						
						addr = (LogEntry *)(STEP_DATA_ADDRESS_START+(2*(PartialCountTotal*1000)));

							for(int i=0;i < 1000; i++)
							{
								nrf_gpio_pin_set(LED_RESETTING); 
								nrf_delay_ms(20);
								nrf_gpio_pin_clear(LED_RESETTING);
								nrf_delay_ms(20);  
								
									
					//			sprintf ( outbuf, ": h:%d s:%d a:%04f                                   ",addr->item.hour, addr->item.sec, addr->item.activity_level);
								sprintf ( outbuf, "%d:%d - %03f                                   ",addr->item.hour, (addr->item.sec)/60, addr->item.activity_level);
									ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
									//nrf_delay_ms(1);
								addr++;
									
							}  
							ReadDataBufferPartial = 0;
					}
				 
					if (Dumper == 1)
					{
						
						sprintf (outbuf, "Log: %d                                   ",getActivityLogSize());
							ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);   

							Dumper = 0;
					}
					
					if (ReadBigSnapshot == 1)
					{	
						SnapshotHeader *h = getSnapshotHeader();
						
						sprintf (outbuf, "t:%d n:%d last:%d",h->data.time, h->data.num_of_data_points, h->data.latest_data_point_index);
						ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
						
						for (i = 0; i < NUMBER_OF_ENTRIES; i++) //i <= h->data.latest_data_point_index; i++)
						{      
							#define RAM_READ_DELAY 15
							
							sprintf (outbuf, "i: %d T: %04x           ",i,raw_data[i].val.temp);
							ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
							nrf_delay_ms(RAM_READ_DELAY);

							sprintf (outbuf, "A: x%04xy%04xz%04x",raw_data[i].val.x_ac,raw_data[i].val.y_ac,raw_data[i].val.z_ac);
							ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
							nrf_delay_ms(RAM_READ_DELAY);

							sprintf (outbuf, "G: x%04xy%04xz%04x",raw_data[i].val.x_gy,raw_data[i].val.y_gy,raw_data[i].val.z_gy);
							ble_nus_send_string(&m_nus, (unsigned char*)outbuf, 20);
							nrf_delay_ms(RAM_READ_DELAY);
							
							
						}
						
						ReadBigSnapshot = 0;
						
					}
												
					if (do_post_processing == true)
					{
						do_post_processing = false;
						
						if (emergencyCall == 1) 
							{
								makeTheCall();
								emergencyCall = 0;
							}
						
						post_comm_processing();
						
					}
				
        // Power Method 1
				//		nrf_gpio_pin_write(LED_OTHER,1);
           // power_manage();
				//		nrf_gpio_pin_write(LED_OTHER,0);
        }
    }
    return retValue;

		
}
static void flash_bank_entry(void)
{
    bl_info_bank_t* p_bank_entry = mp_bank_entry; /* make local copy to avoid race conditions */
    if (p_bank_entry == NULL)
    {
        return;
    }

    bl_info_entry_t bank_entry_replacement;
    memcpy(&bank_entry_replacement, p_bank_entry, sizeof(bl_info_bank_t));
    switch (p_bank_entry->state)
    {
        case BL_INFO_BANK_STATE_IDLE:
            {
                m_waiting_for_idle = true;
                bank_entry_replacement.bank.state = BL_INFO_BANK_STATE_FLASH_FW;
                bootloader_info_entry_overwrite((bl_info_type_t) (BL_INFO_TYPE_BANK_BASE + m_dfu_type), &bank_entry_replacement);

                /* Wait for this to take effect before moving on, as the
                   potential mbr commands in the flash_fw state may trigger
                   sudden reboots. */
                return;
            }

        case BL_INFO_BANK_STATE_FLASH_FW:
            switch (m_dfu_type)
            {
                case DFU_TYPE_BOOTLOADER:
                    /* Check to see if the bank transfer has been executed */
                    if (memcmp(p_bank_entry->p_bank_addr,
                                (uint32_t*) bootloader_info_entry_get(BL_INFO_TYPE_SEGMENT_BL)->segment.start,
                                p_bank_entry->length) != 0)
                    {
                        /* move the bank with MBR. BOOTLOADERADDR() must
                           have been set. */
                        sd_mbr_command_t sd_mbr_cmd;

                        sd_mbr_cmd.command               = SD_MBR_COMMAND_COPY_BL;
                        sd_mbr_cmd.params.copy_bl.bl_src = p_bank_entry->p_bank_addr;
                        sd_mbr_cmd.params.copy_bl.bl_len = p_bank_entry->length / sizeof(uint32_t);
                        APP_ERROR_CHECK(sd_mbr_command(&sd_mbr_cmd));
                        return; /* Can't be reached, only here for readability. */
                    }
                    else
                    {
                        bank_entry_replacement.bank.state = BL_INFO_BANK_STATE_FLASH_META;
                        bootloader_info_entry_overwrite(BL_INFO_TYPE_BANK_BL, &bank_entry_replacement);
                    }
                    break;

                case DFU_TYPE_SD:
                    /* Check to see if the bank transfer has been executed */
                    if (memcmp(p_bank_entry->p_bank_addr,
                                (uint32_t*) bootloader_info_entry_get(BL_INFO_TYPE_SEGMENT_SD)->segment.start,
                                p_bank_entry->length) != 0)
                    {
                        /* move the bank with MBR. */
                        sd_mbr_command_t sd_mbr_cmd;

                        sd_mbr_cmd.command               = SD_MBR_COMMAND_COPY_SD;
                        sd_mbr_cmd.params.copy_sd.src    = p_bank_entry->p_bank_addr;
                        sd_mbr_cmd.params.copy_sd.len    = p_bank_entry->length / sizeof(uint32_t);
                        sd_mbr_cmd.params.copy_sd.dst    = (uint32_t*) 0x1000;
                        APP_ERROR_CHECK(sd_mbr_command(&sd_mbr_cmd));
                        return; /* Can't be reached, only here for readability. */
                    }
                    else
                    {
                        bank_entry_replacement.bank.state = BL_INFO_BANK_STATE_FLASH_META;
                        bootloader_info_entry_overwrite((bl_info_type_t) (BL_INFO_TYPE_BANK_BASE + m_dfu_type), &bank_entry_replacement);
                    }
                    break;

                case DFU_TYPE_APP:
                    /* This nukes the call stack and any flash-callbacks on the
                       app side. If we're in the application, we have to jump
                       to bootloader. */
                    if (bootloader_is_in_application())
                    {
                        /* All paths leading to this call warns about this
                           reset. We'll come back to finalize the transfer
                           after the reset. */
                        __LOG("IN APP MODE. RESET!\n");

#if 1 //def SOFTDEVICE_PRESENT
                        sd_power_reset_reason_clr(0x0F000F);

#if NORDIC_SDK_VERSION >= 11
                        sd_power_gpregret_set(0, RBC_MESH_GPREGRET_CODE_GO_TO_APP);
#else
                        sd_power_gpregret_set(RBC_MESH_GPREGRET_CODE_GO_TO_APP);
#endif
                        sd_nvic_SystemReset();
#else
                        NRF_POWER->RESETREAS = 0x0F000F; /* erase reset-reason to avoid wrongful state-readout on reboot */
                        NRF_POWER->GPREGRET = RBC_MESH_GPREGRET_CODE_GO_TO_APP;
                        NVIC_SystemReset();
#endif
                    }
                    else
                    {
                        /* Erase, Flash the FW, flash FW flag, flash the signature, erase the bank entry. */
                        bl_info_entry_t* p_app_entry = bootloader_info_entry_get(BL_INFO_TYPE_SEGMENT_APP);

                        APP_ERROR_CHECK_BOOL(p_app_entry != NULL);
                        APP_ERROR_CHECK_BOOL(IS_PAGE_ALIGNED(p_app_entry->segment.start));

                        /* Erase existing FW */
                        bl_evt_t flash_evt;
                        flash_evt.type = BL_EVT_TYPE_FLASH_ERASE;
                        flash_evt.params.flash.erase.start_addr = p_app_entry->segment.start;
                        flash_evt.params.flash.erase.length = ((p_bank_entry->length + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)); /* Pad the rest of the page */
                        if (bootloader_evt_send(&flash_evt) != NRF_SUCCESS)
                        {
                            m_waiting_for_idle = true;
                            return;
                        }

                        /* Flash bank */
                        flash_evt.type = BL_EVT_TYPE_FLASH_WRITE;
                        flash_evt.params.flash.write.p_data = (uint8_t*) p_bank_entry->p_bank_addr;
                        flash_evt.params.flash.write.length = p_bank_entry->length;
                        flash_evt.params.flash.write.start_addr = p_app_entry->segment.start;
                        if (bootloader_evt_send(&flash_evt) != NRF_SUCCESS)
                        {
                            m_waiting_for_idle = true;
                            return;
                        }

                        /* Update state */
                        bank_entry_replacement.bank.state = BL_INFO_BANK_STATE_FLASH_META;
                        bootloader_info_entry_overwrite((bl_info_type_t) (BL_INFO_TYPE_BANK_BASE + m_dfu_type), &bank_entry_replacement);
                    }
                    break;

                default:
                    APP_ERROR_CHECK(NRF_ERROR_INVALID_DATA);
                    break;
            }
            /* deliberate fallthrough */
        case BL_INFO_BANK_STATE_FLASH_META:
            {
                bl_info_entry_t fwid_entry;
                bl_info_type_t signature_type;
                bl_info_entry_t flags_entry;
                bl_info_entry_t* p_old_fwid_entry  = bootloader_info_entry_get(BL_INFO_TYPE_VERSION);
                bl_info_entry_t* p_old_flags_entry = bootloader_info_entry_get(BL_INFO_TYPE_FLAGS);
                APP_ERROR_CHECK_BOOL(p_old_fwid_entry);
                APP_ERROR_CHECK_BOOL(p_bank_entry);

                memcpy(&fwid_entry, p_old_fwid_entry, sizeof(bl_info_version_t));
                memcpy(&flags_entry, p_old_flags_entry, sizeof(bl_info_flags_t));
                switch (m_dfu_type)
                {
                    case DFU_TYPE_SD:
                        fwid_entry.version.sd = p_bank_entry->fwid.sd;
                        signature_type = BL_INFO_TYPE_SIGNATURE_SD;
                        flags_entry.flags.sd_intact = true;
                        break;
                    case DFU_TYPE_BOOTLOADER:
                        fwid_entry.version.bootloader.id  = p_bank_entry->fwid.bootloader.id;
                        fwid_entry.version.bootloader.ver = p_bank_entry->fwid.bootloader.ver;
                        signature_type = BL_INFO_TYPE_SIGNATURE_BL;
                        flags_entry.flags.bl_intact = true;
                        break;
                    case DFU_TYPE_APP:
                        fwid_entry.version.app.company_id   = p_bank_entry->fwid.app.company_id;
                        fwid_entry.version.app.app_id       = p_bank_entry->fwid.app.app_id;
                        fwid_entry.version.app.app_version  = p_bank_entry->fwid.app.app_version;
                        signature_type = BL_INFO_TYPE_SIGNATURE_APP;
                        flags_entry.flags.app_intact = true;
                        break;
                    default:
                        APP_ERROR_CHECK(NRF_ERROR_INVALID_DATA);
                        return;
                }
                if (!bootloader_info_entry_put(BL_INFO_TYPE_VERSION,
                            &fwid_entry,
                            BL_INFO_LEN_FWID))
                {
                    m_waiting_for_idle = true;
                    return;
                }
                if (p_bank_entry->has_signature)
                {
                    if (!bootloader_info_entry_put(signature_type,
                                (bl_info_entry_t*) p_bank_entry->signature,
                                BL_INFO_LEN_SIGNATURE))
                    {
                        m_waiting_for_idle = true;
                        return;
                    }
                }
                if (!bootloader_info_entry_put(BL_INFO_TYPE_FLAGS,
                            &flags_entry,
                            BL_INFO_LEN_FLAGS))
                {
                    m_waiting_for_idle = true;
                    return;
                }

                /* Update state */
                __LOG("Bank: Set state to FLASHED\n");
                bank_entry_replacement.bank.state = BL_INFO_BANK_STATE_FLASHED;
                bootloader_info_entry_overwrite((bl_info_type_t) (BL_INFO_TYPE_BANK_BASE + m_dfu_type), &bank_entry_replacement);

            }
            /* deliberate fallthrough */
        case BL_INFO_BANK_STATE_FLASHED:
            /* We may invalidate the bank entry in the device page now,
               it's all redundant. */
            __LOG("Bank: Invalidate.\n");
            if (bootloader_info_entry_invalidate((bl_info_type_t) (BL_INFO_TYPE_BANK_BASE + m_dfu_type)) == NRF_SUCCESS)
            {
                __LOG("Bank invalidated.\n");
                mp_bank_entry = NULL; /* reset the static bank pointer, as we no longer need it. */
            }
            else
            {
                m_waiting_for_idle = true;
            }
            break;

    }
}