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(); }
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; } }
/**@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(); }
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; } }
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); }
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; }
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; }
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; }
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; } }