/* 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();
}
Exemple #2
0
/* 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])))();
}