Example #1
0
/* returns 1 if the id was expected and set, 0 otherwise */
static void set_node_id(unsigned char id)
{
    TIMER_ID_INPUT = UINT_MAX;
    if(flash_write_byte((unsigned char *) NODE_ID_LOCATION, id) != 0)
    {
        flash_erase_segment((unsigned int *) NODE_ID_LOCATION);
        flash_write_byte((unsigned char *) NODE_ID_LOCATION, id);
    }
    node_id = id;
    printf("this node id is now 0x%02X\r\n", id);
}
Example #2
0
void blackbox_write(uchar type, const char* data, uchar length)
{
    uint32_t tick = clock_tics;                 // Get number of ticks (this might change during writing, so we need a local copy)

    flash_write_byte(BLACKBOX_FRAME_START);     // Write start byte
    flash_write_byte(type);                     // Write type
    flash_write_byte(tick >> 24);               // Write tick
    flash_write_byte(tick >> 16);               //
    flash_write_byte(tick >> 8);                //
    flash_write_byte(tick);                     //
    flash_write_byte(length);                   // Write length
    flash_write(data, length);                  // Write data
    flash_write_byte(BLACKBOX_FRAME_END);       // Write end byte
}
Example #3
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]);
}
Example #4
0
/*
 * write a command, consisting of 8 cmd bits, and 24 address bits.
 */
static void flash_write_cmd( uint8_t cmd, uint32_t addr )
{
    cs_low( );
    flash_write_byte( cmd );
    flash_write_byte( addr >> 24 );
    flash_write_byte( addr >> 16 );
    flash_write_byte( addr >>  8 );
}
Example #5
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;
}
Example #6
0
U8 eeprom_write_byte(U8 log_addr, U8 byte)
{
	U16 phy_addr;
	if (log_addr >= EE_SIZE)
		return ERROR;

	/* The page is full, we need to find a new page*/
	if(page.tail >= FL_PAGE_SIZE) {
		phy_addr = eeprom_get_next_page(page.idx) + EE_TAG_SIZE;
		flash_write_byte(phy_addr, log_addr);
		flash_write_byte(phy_addr + 1, byte);
		flash_copy_page();
	}else{
		phy_addr = page.addr + page.tail;
		flash_write_byte(phy_addr, log_addr);
		flash_write_byte(phy_addr + 1, byte);
		page.tail += EE_VARIABLE_SIZE;
	}
	return SUCCESS;
}
Example #7
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);
}
Example #8
0
char flash_write(short size, int offset, uint32 value){
	switch(size){
		case 8:
                        flash_write_byte (offset, value);
                        break;
                case 16:
                        flash_write_halfword(offset, value);
                        break;
                case 32:
                        flash_write_word(offset, value);
                        break;
                default:
                        return -1;

	}
	return 0;

}
Example #9
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);
}
Example #10
0
void blackbox_write_adc(const uint16_t *data)
{
    uint32_t tick = clock_tics;                 // Get number of ticks (this might change during writing, so we need a local copy)

    flash_write_byte(BLACKBOX_FRAME_START);     // Write start byte
    flash_write_byte(BLACKBOX_FRAME_TYPE_ADC);  // Write type
    flash_write_byte(tick >> 24);               // Write tick
    flash_write_byte(tick >> 16);               //
    flash_write_byte(tick >> 8);                //
    flash_write_byte(tick);                     //
    flash_write_byte(ADC_NUM_CHANNELS*2);       // Write length
    for (uchar i=0; i<ADC_NUM_CHANNELS; i++)
    {
        flash_write_byte(data[i] >> 8);         // Write high byte
        flash_write_byte(data[i]);              // Write low byte
    }
    flash_write_byte(BLACKBOX_FRAME_END);       // Write end byte

    //blackbox_write(BLACKBOX_FRAME_TYPE_ADC, (char *)adc_values, sizeof(uint16_t) * ADC_NUM_CHANNELS);
}
Example #11
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])))();
}
Example #12
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;
}