/* Ma-ma-ma-main function! */ void main() { state_t state = LISTENING; command_t cmd = CMD_NO_CMD; firmware_start firmware; uint16_t channel_timer = 0, bootloader_timer = 0, connection_timer = 0; uint8_t ch_i = 0, firmware_number = 0; bool running; uint16_t bytes_received = 0; uint16_t bytes_total = 0; uint8_t ea_default, rf_default; // Disable RF interrupt rf_default = RF; RF = 0; // Disable global interrupt ea_default = EA; EA = 0; // Set up parameters for RF communication. configureRF(); #ifdef DEBUG_LED_ P0DIR = 0; P0 = 0x55; #endif running = true; // Boot loader loop. // Will terminate after a couple of seconds if firmware has been successfully // installed. while (running) { // Polls the RF-interrupt bit every iteration. if (RFF) { RFF = 0; nrf_irq(); if (packet_received) { packet_received = false; connection_timer = 0; cmd = MSG_CMD; switch (cmd) { // Host initiates contact with the device. case CMD_INIT: // Send ACK to host, go to CONNECTED state if successful. sendInitAck(&state); // Reset timers channel_timer = bootloader_timer = 0; break; // Host starts a firmware update. case CMD_UPDATE_START: if (state == CONNECTED) { // Initiate firmware updates, go to RECEIVING_FIRMWARE state // if successful. startFirmwareUpdate(&state, &bytes_total, &bytes_received, &firmware_number); } #ifdef DEBUG_LED_ P0 = state; #endif break; // Write message containing one hex record. case CMD_WRITE: if (state == RECEIVING_FIRMWARE) { writeHexRecord(&state, &bytes_received); } #ifdef DEBUG_LED_ P0 = 0x40; #endif break; // Firmware update has been completed. case CMD_UPDATE_COMPLETE: CE_LOW(); // Check that every byte is received. if (bytes_received == bytes_total) { // Mark firmware as successfully installed. hal_flash_byte_write(FW_INSTALLED, 0x01); hal_flash_byte_write(FW_NUMBER, firmware_number); state = CONNECTED; send(CMD_ACK); } else { send(CMD_NACK); } if (!send_success) { state = ERROR; } #ifdef DEBUG_LED_ P0 = 0x10; #endif break; // Host request data from flash at specified address. case CMD_READ: readHexRecord(); #ifdef DEBUG_LED_ P0 = 0x20; #endif break; // Host sends ping to check connections with device. case CMD_PING: if (state != LISTENING) { send(CMD_PONG); } #ifdef DEBUG_LED_ P0 = 0x80; #endif break; // Host sends disconnect case CMD_EXIT: state = LISTENING; break; // These commands should no be received. case CMD_NO_CMD: default: state = ERROR; break; } // Clear command cmd = CMD_NO_CMD; } // RF interrupt bit not set } else if (state == LISTENING) { // Will listen to one channel for 'a while' before changing. channel_timer++; if (channel_timer > CHANNEL_TIMEOUT) { channel_timer = 0; // Go to next channel ch_i = (ch_i+1)%3; hal_nrf_set_rf_channel(default_channels[ch_i]); #ifdef DEBUG_LED_ P0 = ch_i; #endif // After changing channels and being in the LISTENING state // for 'a while', boot loader loop will check if there is firmware // installed, and if so end the while(running) loop. bootloader_timer++; if (bootloader_timer > BOOTLOADER_TIMEOUT) { bootloader_timer = 0; running = (hal_flash_byte_read(FW_INSTALLED) == 0x01) ? false : true; } } // While connected must receive something or connection times out. // Connection timer reset when packet received. } else if (state == CONNECTED) { connection_timer++; if (connection_timer > CONNECTION_TIMEOUT) { state = LISTENING; } } } resetRF(); #ifdef DEBUG_LED_ // Default value for P0DIR P0 = 0x00; P0DIR = 0xFF; #endif EA = ea_default; RF = rf_default; // Reads address of firmware's reset vector. temp_data[0] = hal_flash_byte_read(FW_RESET_ADDR_H); temp_data[1] = hal_flash_byte_read(FW_RESET_ADDR_L); firmware = (firmware_start)(((uint16_t)temp_data[0]<<8) | (temp_data[1])); // Jump to firmware. Goodbye! firmware(); }
/* Ma-ma-ma-main function! */ void main() { command_t cmd = CMD_NO_CMD; uint16_t channel_timer = 0, bootloader_timer = 0, connection_timer = 0; uint8_t ch_i = 0; bool running; // Disable global interrupt cli(); // Set up parameters for RF communication. configureRF(); #ifdef DEBUG_LED_ P0DIR = 0; P0 = 0x55; #endif running = true; // Boot loader loop. // Will terminate after a couple of seconds if firmware has been successfully // installed. send(CMD_PING,1); while(running) { if(send_success){ if (packet_received) { connection_timer = 0; cmd = MSG_CMD; switch (cmd) { // Host initiates contact with the device. case CMD_INIT: // Send ACK to host, go to CONNECTED state if successful. sendInitAck(); // Reset timers channel_timer = bootloader_timer = 0; break; // Host starts a firmware update. case CMD_UPDATE_START: if (state == CONNECTED) { // Initiate firmware updates, go to RECEIVING_FIRMWARE state // if successful. startFirmwareUpdate(); } #ifdef DEBUG_LED_ P0 = state; #endif break; // Write message containing one hex record. case CMD_WRITE: if (state == RECEIVING_FIRMWARE) { writeHexRecord( ); } #ifdef DEBUG_LED_ P0 = 0x40; #endif break; // Firmware update has been completed. case CMD_UPDATE_COMPLETE: // Check that every byte is received. if (bytes_received == bytes_total) { // Mark firmware as successfully installed. flash_write_byte(FW_NUMBER, firmware_number); state = CONNECTED; send(CMD_ACK,1); } else { send(CMD_NACK,1); } if (!send_success) { state = ERROR; } #ifdef DEBUG_LED_ P0 = 0x10; #endif break; // Host request data from flash at specified address. case CMD_READ: readHexRecord(); #ifdef DEBUG_LED_ P0 = 0x20; #endif break; // Host sends pong to keep connections with device. case CMD_PONG: send(CMD_PING,1); #ifdef DEBUG_LED_ P0 = 0x80; #endif break; // Host sends disconnect case CMD_EXIT: send(CMD_ACK,1); if(send_success)running=false; state = PINGING; break; // These commands should no be received. case CMD_NO_CMD: default: state = ERROR; break; } // Clear command cmd = CMD_NO_CMD; }else{ //Host app do not reply, reping send(CMD_PING,1); } }else{ //host unreached if (state == PINGING) { // Will ping to one channel for 'a while' before changing. if (++channel_timer > CHANNEL_TIMEOUT) { channel_timer = 0; // Go to next channel ch_i = (ch_i+1)%CHANNEL_SIZE; rf_set_channel(default_channels[ch_i]); #ifdef DEBUG_LED_ P0 = ch_i; #endif // After changing channels and being in the PINGING state // for 'a while', boot loader loop will check if there is firmware // installed, and if so end the while(running) loop. if (++bootloader_timer > BOOTLOADER_TIMEOUT) { bootloader_timer = 0; running = (flash_read_byte(FW_NUMBER) != 0xFF) ? false : true; }else send(CMD_PING,1); } }else { if (++connection_timer > CONNECTION_TIMEOUT) state = PINGING; send(CMD_PING,1); } } } resetRF(); #ifdef DEBUG_LED_ // Default value for P0DIR P0 = 0x00; P0DIR = 0xFF; #endif // Reads address of firmware's reset vector. temp_data[0] = flash_read_byte(FW_RESET_ADDR_H); temp_data[1] = flash_read_byte(FW_RESET_ADDR_L); // sti(); //Should we enable irqs? or should the firmware enable it later? // Jump to firmware. Goodbye! ((firmware_start)(((uint16_t)temp_data[0]<<8) | (temp_data[1])))(); }