Ejemplo n.º 1
0
void read_one_bank_params_from_FLASH(uint8_t bank_i){

	flash_bankstatus[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_bankstatus + (FLASH_SIZE_parambank * bank_i));

	flash_read_array((uint8_t *)flash_note[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_note + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t *)flash_scale[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_scale + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t *)flash_scale_bank[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_scale_bank + (FLASH_SIZE_parambank * bank_i), 6);

	flash_read_array((uint8_t  *)flash_lock[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_lock + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t  *)flash_q_locked[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_q_locked + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t  *)flash_qval[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_qval + (FLASH_SIZE_parambank * bank_i), 24);
	flash_read_array((uint8_t  *)flash_freq_nudge[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_freq_nudge + (FLASH_SIZE_parambank * bank_i), 24);

	flash_freqblock[bank_i]   = flash_read_word(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_freqblock + (FLASH_SIZE_parambank * bank_i));

	flash_filter_type[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_filter_type + (FLASH_SIZE_parambank * bank_i));
	flash_filter_mode[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_filter_mode + (FLASH_SIZE_parambank * bank_i));

	//Force ONEPASS if we read a legacy slot as BPRE
	if (flash_filter_type[bank_i] == BPRE) flash_filter_mode[bank_i] = ONEPASS;

	//Force TWOPASS for legacy banks
	if (flash_filter_mode[bank_i] != ONEPASS) flash_filter_mode[bank_i] = TWOPASS;

	flash_cur_colsch[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_cur_colsch + (FLASH_SIZE_parambank * bank_i));


}
Ejemplo n.º 2
0
/*
 * int ifs_init(void): Initialize IFS files
 */
int ifs_init(void)
{
	uint8_t *src, *dest;
#if FLASHEND >0xffff
	uint32_t flash_src;
#define flash_read_byte(addr) pgm_read_byte_far(addr)
#else
	uint16_t flash_src;
#define flash_read_byte(addr) pgm_read_byte_near(addr)
#endif /* FLASHEND */

	// initialize .ifs_int_0
	for(dest = __ifs_int_0_start; dest < __ifs_int_0_end; dest++) {
		*dest = 0x00;
	}
	// poll until eeprom is ready
	while(!eeprom_is_ready()) ;
	src =__ifs_int_eep_loadstart;
	for(dest = __ifs_int_eep_start; dest < __ifs_int_eep_end; dest++) {
		*dest = eeprom_read_byte(src++);
	}
#if FLASHEND >0xffff
	flash_src = ptr_to_ui32(__ifs_int_flash_loadstart);
#else
	flash_src = __ifs_int_flash_loadstart;
#endif /* FLASHEND */
	for(dest = __ifs_int_flash_start; dest < __ifs_int_flash_end; dest++) {
		*dest = flash_read_byte(flash_src++);
	}
#if defined (USE_EXT_RAM)
	// initialize .ifs_ext_0
	for(dest = __ifs_ext_0_start; dest < __ifs_ext_0_end; dest++) {
		*dest = 0x00;
	}
	// poll until eeprom is ready
	while(!eeprom_is_ready()) ;
	src =__ifs_ext_eep_loadstart;
	for(dest = __ifs_ext_eep_start; dest < __ifs_ext_eep_end; dest++) {
		*dest = eeprom_read_byte(src++);
	}
#if FLASHEND >0xffff
	flash_src = ptr_to_ui32(__ifs_ext_flash_loadstart);
#else
	flash_src = __ifs_ext_flash_loadstart;
#endif /* FLASHEND */
	for(dest = __ifs_ext_flash_start; dest < __ifs_ext_flash_end; dest++) {
		*dest = flash_read_byte(flash_src++);
	}
#endif /* USE_EXT_RAM */
	return 0;
}
/**
 * Calculate ADCS boot counter and save in flash. The boot counter is available
 * in global variable adcs_boot_counter.
 * @return The status of Flash memory and if the boot counter is valid
 */
adcs_error_status increment_boot_counter() {
    adcs_boot_cnt = 0;
    uint8_t adcs_boot_cnt_8[4] = { 0 };
    uint32_t flash_read_address = BOOT_CNT_BASE_ADDRESS;

    for (uint8_t i = 0; i < 4; i++) {
        if (flash_read_byte(&adcs_boot_cnt_8[i], flash_read_address)
                == FLASH_NORMAL) {
            flash_read_address = flash_read_address + BOOT_CNT_OFFSET_ADDRESS;
        } else {
            return ERROR_FLASH;
        }
    }
    cnv8_32(adcs_boot_cnt_8, &adcs_boot_cnt);
    adcs_boot_cnt++;
    if (flash_erase_block4K(BOOT_CNT_BASE_ADDRESS) == FLASH_ERROR) {
        return ERROR_FLASH;
    }
    cnv32_8(adcs_boot_cnt, &adcs_boot_cnt_8);
    if (flash_write_page(adcs_boot_cnt_8, sizeof(adcs_boot_cnt_8),
    BOOT_CNT_BASE_ADDRESS) == FLASH_ERROR) {
        return FLASH_ERROR;
    }
    return error_propagation(ERROR_OK);

}
Ejemplo n.º 4
0
/**
 * @fn static void eeprom_format_page(U16 phy_addr)
 * @brief erase page and write erase count plus 1 in TAG position.
 *	for erase count equal 0xFFFFFF, plus '1' will get 0x1000000, and will only
 *	write 24 bits 0x000000 into flash.
 * @param phy_addr physical page address
 *
 * @return none
 */
static void eeprom_format_page(U16 phy_addr)
{
	UU32 erase_count;
	/* Ignore first byte in page, it is flash status byte*/
	erase_count.U8[0] = 0;
	erase_count.U8[1] = flash_read_byte(phy_addr + 1);
	erase_count.U8[2] = flash_read_byte(phy_addr + 2);
	erase_count.U8[3] = flash_read_byte(phy_addr + 3);
	erase_count.U32 += 1;

	flash_erase_page(phy_addr);

	flash_write_byte(phy_addr + 1, erase_count.U8[1]);
	flash_write_byte(phy_addr + 2, erase_count.U8[2]);
	flash_write_byte(phy_addr + 3, erase_count.U8[3]);
}
Ejemplo n.º 5
0
U8 eeprom_read_byte(U8 log_addr, U8 *byte)
{
	U16 phy_addr;
	if (log_addr >= EE_SIZE)
		return ERROR;

	phy_addr = page.addr + page.tail - EE_VARIABLE_SIZE;
	while(phy_addr >= (page.addr + EE_TAG_SIZE)){
		if (log_addr == flash_read_byte(phy_addr)) {
			*byte = flash_read_byte(phy_addr + 1);
			return SUCCESS;
		}
		phy_addr -= EE_VARIABLE_SIZE;
	}
	*byte = 0xFF;
	return SUCCESS;
}
Ejemplo n.º 6
0
//Reads from FLASH memory and stores it in SRAM variables
void read_all_params_from_FLASH(void){ //~200uS
	uint8_t bank_i;
	uint32_t t;

	flash_firmware_version = flash_read_word(FLASH_ADDR_firmware_version) - FLASH_SYMBOL_firmwareoffset;

	flash_startupbank = flash_read_byte(FLASH_ADDR_startupbank) - FLASH_SYMBOL_startupoffset;

	flash_clipmode = flash_read_byte(FLASH_ADDR_clipmode);

	t = flash_read_word(FLASH_ADDR_trackcomp1);
	if (t==0xFFFFFFFF) t=1;
	flash_trackcomp[0]=*(float *)&t;

	t = flash_read_word(FLASH_ADDR_trackcomp2);
	if (t==0xFFFFFFFF) t=1;
	flash_trackcomp[1]=*(float *)&t;

	flash_trackoffset[0] = flash_read_word(FLASH_ADDR_trackoffset1);
	flash_trackoffset[1] = flash_read_word(FLASH_ADDR_trackoffset2);


	for (bank_i=0;bank_i<6;bank_i++){
		flash_bankstatus[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_bankstatus + (FLASH_SIZE_parambank * bank_i));

		flash_read_array((uint8_t *)flash_note[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_note + (FLASH_SIZE_parambank * bank_i), 6);
		flash_read_array((uint8_t *)flash_scale[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_scale + (FLASH_SIZE_parambank * bank_i), 6);
		flash_read_array((uint8_t *)flash_scale_bank[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_scale_bank + (FLASH_SIZE_parambank * bank_i), 6);

		flash_read_array((uint8_t *)flash_lock[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_lock + (FLASH_SIZE_parambank * bank_i), 6);
		flash_read_array((uint8_t *)flash_q_locked[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_q_locked + (FLASH_SIZE_parambank * bank_i), 6);
		flash_read_array((uint8_t *)flash_qval[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_qval + (FLASH_SIZE_parambank * bank_i), 24);

		flash_filter_type[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_filter_type + (FLASH_SIZE_parambank * bank_i));
		flash_cur_colsch[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_cur_colsch + (FLASH_SIZE_parambank * bank_i));

		flash_read_array((uint8_t *)flash_freq_nudge[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_freq_nudge + (FLASH_SIZE_parambank * bank_i), 24);

	}

	flash_read_array((uint8_t *)flash_COLOR_CH, FLASH_ADDR_colschem, FLASH_SIZE_colschem);

	flash_read_array((uint8_t *)flash_user_scalebank, FLASH_ADDR_user_scalebank, FLASH_SIZE_user_scalebank);

}
Ejemplo n.º 7
0
/**
 * @fn static void eeprom_scan_page(U16 phy_addr, U8 idx)
 * @brief scan page and update page information
 *
 * @param phy_addr page physical address,
 * @param idx page index
 */
static void eeprom_scan_page(U16 phy_addr, U8 idx)
{
	U16 tail;
	for (tail = EE_TAG_SIZE; tail < FL_PAGE_SIZE; tail += EE_VARIABLE_SIZE) {
		if( 0xFF == flash_read_byte(phy_addr + tail))
			break;
	}
	eeprom_update_page_info(idx, phy_addr, tail);
}
Ejemplo n.º 8
0
void read_one_bank_params_from_FLASH(uint8_t bank_i){

	flash_bankstatus[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_bankstatus + (FLASH_SIZE_parambank * bank_i));

	flash_read_array((uint8_t *)flash_note[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_note + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t *)flash_scale[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_scale + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t *)flash_scale_bank[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_scale_bank + (FLASH_SIZE_parambank * bank_i), 6);

	flash_read_array((uint8_t *)flash_lock[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_lock + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t *)flash_q_locked[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_q_locked + (FLASH_SIZE_parambank * bank_i), 6);
	flash_read_array((uint8_t *)flash_qval[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_qval + (FLASH_SIZE_parambank * bank_i), 24);
	flash_read_array((uint8_t *)flash_freq_nudge[bank_i], FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_freq_nudge + (FLASH_SIZE_parambank * bank_i), 24);

	flash_filter_type[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_filter_type + (FLASH_SIZE_parambank * bank_i));

	flash_cur_colsch[bank_i] = flash_read_byte(FLASH_ADDR_START_PARAMBANKS + FLASH_OFFSET_cur_colsch + (FLASH_SIZE_parambank * bank_i));


}
Ejemplo n.º 9
0
// Sends model number and firmware version number to host.
static void sendInitAck()
{
  // Send model number and firmware number
  send_buf[1] = MODEL_NUM;
  send_buf[2] = flash_read_byte(FW_NUMBER); 
  send(CMD_ACK,3);

  if (send_success) state = CONNECTED;
  else state = PINGING;
}
Ejemplo n.º 10
0
/*
 * read the Flash status byte
 */
static uint8_t flash_read_status( void )
{
    uint8_t status;

    cs_low( );
    flash_write_byte( AT_STATUS );
    status = flash_read_byte( );
    cs_high( );
    return status;
}
Ejemplo n.º 11
0
/**
 * @fn static void eeprom_check_pages(void)
 * @brief Check page status, handle different page status.
 *
 *  The first byte of flash page is status byte. It contains three status:
 *  RECEIVING, ACTIVE, ERASED. We will format RECEIVING page; if ERASED page
 *  is not blank, we will format it too. If we have two more ACTIVE pages,
 *  we will erase full one
 *
 * @return none
 */
static void eeprom_check_pages(void)
{
    U8 i, status, idx, active_pages = 0;
    U16 phy_addr ,active_page_addr = EE_BASE_ADDR;
    for (i = 0; i < FL_PAGES; i++) {
        phy_addr = EE_BASE_ADDR + i * FL_PAGE_SIZE;
        status = flash_read_byte(phy_addr);
        switch (status) {
            case PAGE_STATUS_RECEIVING:
            	eeprom_format_page(phy_addr);
                break;
            case PAGE_STATUS_ERASED:
                if (!eeprom_is_formatted(phy_addr))
                	eeprom_format_page(phy_addr);
                break;
            case PAGE_STATUS_ACTIVE:
                if (active_pages++) {
                    U16 tmp = phy_addr + FL_PAGE_SIZE - EE_VARIABLE_SIZE;
                    /* erase a full contents page*/
                    if (flash_read_byte(tmp) == 0xFF) {
                    	eeprom_format_page(phy_addr);
                    }else{
                    	eeprom_format_page(active_page_addr);
                    	active_page_addr = phy_addr;
                    	idx = i;
                    }
                }else{
                	active_page_addr = phy_addr;
                	idx = i;
                }
                break;
            default:
                break;
        }
    }
    /* If there is no active page, we update page status position with active status flag*/
	if (0 == active_pages)
		flash_write_byte(active_page_addr,PAGE_STATUS_ACTIVE);
	eeprom_scan_page(active_page_addr,idx);
}
Ejemplo n.º 12
0
/**
 * @fn static U8 eeprom_is_formatted(U16 phy_addr)
 * @brief Check page formatted or not.
 * 
 * @param phy_addr page physical address
 * @return TRUE: page is formatted; FALSE: page is not formatted
 */
static U8 eeprom_is_formatted(U16 phy_addr)
{
    U16 i;
    UU32 tag;
    tag.U8[0] = flash_read_byte(phy_addr++);
    tag.U8[1] = flash_read_byte(phy_addr++);
    tag.U8[2] = flash_read_byte(phy_addr++);
    tag.U8[3] = flash_read_byte(phy_addr++);

    /* Change status is erased or erase count not equal 0xFFFFFF*/
    if((tag.U8[0] != PAGE_STATUS_ERASED) ||
      ((tag.U8[1] == 0xFF)&&(tag.U8[2] = 0xFF)&&(tag.U8[3] = 0xFF))) {
    	return FALSE;
    }

    for (i = EE_TAG_SIZE; i < FL_PAGE_SIZE; i++) {
        if (flash_read_byte(phy_addr++) != 0xFF) {
            return FALSE;
        }
    }
    return TRUE;
}
Ejemplo n.º 13
0
/* 
 * simple test: dump all contents of built-in cartridge
 */
void flash_test( void )
{
    uint8_t i = 0;
    long size = 2048L * 264L;

    flash_write_cmd( AT_CAR, 0 );
    flash_clocks( 32 );
    while( --size >= 0 && usb_peek() != 3 )
    {
        printf( "%02x%c", flash_read_byte(), ++i % 16 ? ' ' : '\n' );
    }
    cs_high( );
}
Ejemplo n.º 14
0
/**
 * @fn void flash_copy_page()
 * @brief move valid data from one page to another page.
 *
 * When an active page is full, it will find next available page, and write data
 * in it, and then call this function. It copies data from source page to
 * destination page.
 *
 * @note When calling this function, be aware that destination page already write
 * a pair of the data. Before copy loop start, we need to read it out and set
 * bitmap correspond bit to '1'.
 *
 * @return none
 */
static void flash_copy_page()
{
	U16 src, dest, tail;
	U8 log_addr,idx;
	U8 eeprom_bitmap[EE_BITMAP_SIZE];

	for (idx = 0; idx < EE_BITMAP_SIZE; idx++) {
        eeprom_bitmap[idx] = 0;
    }
	/* Source page scan start from bottom*/
	src = page.addr + FL_PAGE_SIZE - EE_VARIABLE_SIZE;

	dest = eeprom_get_next_page(page.idx);
	/* Mark destination page as receiving status */
	flash_write_byte(dest,PAGE_STATUS_RECEIVING);
	EE_SET_BITMAP(flash_read_byte(dest + EE_TAG_SIZE));
	tail =EE_TAG_SIZE + EE_VARIABLE_SIZE;
	/* Read data from source page and copy it to destination page*/
	while (src >= (page.addr + EE_TAG_SIZE)) {
		log_addr = flash_read_byte(src);
		if (log_addr < EE_SIZE) {
			if (!EE_GET_BITMAP(log_addr)) {
                flash_write_byte(dest + tail, log_addr);
                flash_write_byte(dest + tail + 1, flash_read_byte(src + 1));
				tail += EE_VARIABLE_SIZE;
				EE_SET_BITMAP(log_addr);
			}
		}
		src -= EE_VARIABLE_SIZE;
	}
    /* Mark destination page as active status*/
	flash_write_byte(dest,PAGE_STATUS_ACTIVE);
	/* Erase source page and update erase count in page TAG position*/
	eeprom_format_page(page.addr);
	/* Update page information*/
	idx = (dest - EE_BASE_ADDR) / FL_PAGE_SIZE;
	eeprom_update_page_info(idx, dest, tail);
}
Ejemplo n.º 15
0
char flash_read(short size, int offset, uint32 * value){
	switch(size){
		case 8:
			*(uint8 *)value = (uint8)flash_read_byte (offset);
			break;
		case 16:
			*(uint16 *)value = (uint16)flash_read_halfword(offset);
			break;
		case 32:
			*value = flash_read_word(offset);
			break;
		default:
			return -1;
	}
	return 0;

}
Ejemplo n.º 16
0
static unsigned char dump_address( unsigned int address, unsigned char area )
{
    unsigned char c = 0xff;

    switch( area )
    {
        case 0: /* idata/SFR */
            if( (unsigned char)address < 0x80 )
                c = *(unsigned char __idata *)address;
            else
                c = read_mcs51_sfr( (unsigned char)address );
            break;
        case 1: /* xdata/code */
            c = *(unsigned char __xdata *)address;
            break;
        case 2: /* code (anywhere in the SPI flash) */
            c = flash_read_byte(m.address_page, m.address);
            break;
    }
    puthex( c );
    return c;
}
Ejemplo n.º 17
0
// Bootloader protocol logic
//
static void
bootloader(void)
{
	uint8_t		c;
	uint8_t		count, i;
	static uint16_t	address;

	// Wait for a command byte
	LED_BOOTLOADER = LED_ON;
	c = cin();
	LED_BOOTLOADER = LED_OFF;

	// common tests for EOC
	switch (c) {
	case PROTO_GET_SYNC:
	case PROTO_GET_DEVICE:
	case PROTO_CHIP_ERASE:
	case PROTO_PARAM_ERASE:
	case PROTO_READ_FLASH:
	case PROTO_DEBUG:
		if (cin() != PROTO_EOC)
			goto cmd_bad;
	}

	switch (c) {

	case PROTO_GET_SYNC:		// sync
		break;

	case PROTO_GET_DEVICE:
		cout(BOARD_ID);
		cout(board_frequency);
		break;

	case PROTO_CHIP_ERASE:		// erase the program area
		flash_erase_app();
		break;

	case PROTO_PARAM_ERASE:
		flash_erase_scratch();
		break;

	case PROTO_LOAD_ADDRESS:	// set address
		address = cin();
		address |= (uint16_t)cin() << 8;
		if (cin() != PROTO_EOC)
			goto cmd_bad;
		break;

	case PROTO_PROG_FLASH:		// program byte
		c = cin();
		if (cin() != PROTO_EOC)
			goto cmd_bad;
		flash_write_byte(address++, c);
		break;

	case PROTO_READ_FLASH:		// readback byte
		c = flash_read_byte(address++);
		cout(c);
		break;

	case PROTO_PROG_MULTI:
		count = cin();
		if (count > sizeof(buf))
			goto cmd_bad;
		for (i = 0; i < count; i++)
			buf[i] = cin();
		if (cin() != PROTO_EOC)
			goto cmd_bad;
		for (i = 0; i < count; i++)
			flash_write_byte(address++, buf[i]);
		break;

	case PROTO_READ_MULTI:
		count = cin();
		if (cin() != PROTO_EOC)
			goto cmd_bad;
		for (i = 0; i < count; i++) {
			c = flash_read_byte(address++);
			cout(c);
		}
		break;

	case PROTO_REBOOT:
		// generate a software reset, which should boot to the application
		RSTSRC |= (1 << 4);

	case PROTO_DEBUG:
		// XXX reserved for ad-hoc debugging as required
		break;

	default:
		goto cmd_bad;
	}
	sync_response();
cmd_bad:
	return;
}
Ejemplo n.º 18
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])))();
}