예제 #1
0
void FLASH_command(uint8_t cmd, uint8_t isWrite){
	if (isWrite)
	{
		FLASH_command(SPIFLASH_WRITEENABLE, 0); // Write Enable
		FLASH_UNSELECT;
	}
	while(FLASH_busy()); //wait for chip to become available
	FLASH_SELECT;
	SPI_transfer(cmd);
}
예제 #2
0
uint8_t FLASH_readByte(uint32_t addr) {
	FLASH_command(SPIFLASH_ARRAYREADLOWFREQ, 0);
	SPI_transfer(addr >> 16);
	SPI_transfer(addr >> 8);
	SPI_transfer(addr);
	//SPI.transfer(0); //"dont care", needed with SPIFLASH_ARRAYREAD command only
	uint8_t result = SPI_transfer(0);
	FLASH_UNSELECT;
	return result;
}
예제 #3
0
void CheckFlashImage() {
	#ifdef DEBUG_ON
	putch('F');
	#endif
	watchdogConfig(WATCHDOG_OFF);

	
	#ifdef ANARDUINO
	#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
	DDRB |= _BV(SS) | _BV(PINB3) | _BV(PINB5); //OUTPUTS for SS, MOSI, SCK
	DDRD |= _BV(FLASHSS); //OUTPUTS for FLASH_SS
	FLASH_UNSELECT; //unselect FLASH chip
	PORTB |= _BV(SS); //set SS HIGH
	#elif defined (__AVR_ATmega1284P__) || defined (__AVR_ATmega644P__)
	DDRC |= _BV(FLASHSS); //OUTPUT for FLASH_SS
	DDRB |= _BV(SS) | _BV(PB5) | _BV(PB7); //OUTPUTS for SS, MOSI, SCK
	FLASH_UNSELECT; //unselect FLASH chip
	PORTB |= _BV(SS); //set SS HIGH
	#endif
	#else	//MOTEINO
	//SPI INIT
	#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
	DDRB |= _BV(FLASHSS) | _BV(SS) | _BV(PINB3) | _BV(PINB5); //OUTPUTS for FLASH_SS and SS, MOSI, SCK
	FLASH_UNSELECT; //unselect FLASH chip
	PORTB |= _BV(SS); //set SS HIGH
	#elif defined (__AVR_ATmega1284P__) || defined (__AVR_ATmega644P__)
	DDRC |= _BV(FLASHSS); //OUTPUT for FLASH_SS
	DDRB |= _BV(SS) | _BV(PB5) | _BV(PB7); //OUTPUTS for SS, MOSI, SCK
	FLASH_UNSELECT; //unselect FLASH chip
	PORTB |= _BV(SS); //set SS HIGH
	#endif
	#endif	// MOTEINO*/
	
	//SPCR &= ~(_BV(DORD)); //MSB first
	//SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE0 ; //SPI MODE 0
	//SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK); //clock divider = 2
	//SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);

	// Warning: if the SS pin ever becomes a LOW INPUT then SPI automatically switches to Slave, so the data direction of the SS pin MUST be kept as OUTPUT.
	SPCR |= _BV(MSTR) | _BV(SPE); //enable SPI and set SPI to MASTER mode

	//read first byte of JEDECID, if chip is present it should return a non-0 and non-FF value
	//FLASH_SELECT;
	FLASH_command(SPIFLASH_JEDECID,1);
	uint8_t deviceId = SPI_transfer(0);
	FLASH_UNSELECT;
	#ifdef DEBUG_ON
		putch(deviceId);
	#endif
	// Disabled check, as it only returns 0xFF or 0x00 for some reasons
	if (deviceId==0 || deviceId==0xFF) return;
	
	//global unprotect
	FLASH_command(SPIFLASH_STATUSWRITE, 1);
	SPI_transfer(0);
	FLASH_UNSELECT;
	#ifdef DEBUG_ON
	putch('I');
	#endif
	//check if any flash image exists on external FLASH chip
	if (FLASH_readByte(0)=='F' && FLASH_readByte(1)=='L' && FLASH_readByte(2)=='X' && FLASH_readByte(6)==':' && FLASH_readByte(9)==':')
	{
		#ifdef DEBUG_ON
		putch('L');
		#endif
		
		uint16_t imagesize = (FLASH_readByte(7)<<8) | FLASH_readByte(8);
		if (imagesize%2!=0) return; //basic check that we got even # of bytes
		
		uint16_t b, i, nextAddress=0;
		
		LED_PIN |= _BV(LED);
		for (i=0; i<imagesize; i+=2)
		{
			#ifdef DEBUG_ON
			putch('*');
			#endif
			
			//read 2 bytes (16 bits) from flash image, transfer them to page buffer
			b = FLASH_readByte(i+10); // flash image starts at position 10 on the external flash memory: FLX:XX:FLASH_IMAGE_BYTES_HERE...... (XX = two size bytes)
			b |= FLASH_readByte(i+11) << 8; //bytes are stored big endian on external flash, need to flip the bytes to little endian for transfer to internal flash
			__boot_page_fill_short((uint16_t)(void*)i,b);

			//when 1 page is full (or we're on the last page), write it to the internal flash memory
			if ((i+2)%SPM_PAGESIZE==0 || (i+2==imagesize))
			{
				__boot_page_erase_short((uint16_t)(void*)nextAddress); //(i+2-SPM_PAGESIZE)
				boot_spm_busy_wait();
				// Write from programming buffer
				__boot_page_write_short((uint16_t)(void*)nextAddress ); //(i+2-SPM_PAGESIZE)
				boot_spm_busy_wait();
				nextAddress += SPM_PAGESIZE;
			}
		}
		LED_PIN &= ~_BV(LED);

		#if defined(RWWSRE)
		// Reenable read access to flash
		boot_rww_enable();
		#endif

		#ifdef DEBUG_ON
		putch('E');
		#endif

		#ifdef ANARDUINO
		// Anarduino doesn't support 32K block erase. Do it, with 8 pages of 4k each
		int page;
		long address;
		for (page = 0, address=0; page< 8; page++) {
			FLASH_command(SPIFLASH_BLOCKERASE_4K, 1);
			SPI_transfer(address >> 16);
			SPI_transfer(address >> 8);
			SPI_transfer(address);
			FLASH_UNSELECT;
			
			while (FLASH_busy());

			address += 0x1000;
		}
		#else // MOTEINO
		//erase the first 32/64K block where flash image resided (atmega328 should be less than 31K, and atmega1284 can be up to 64K)
		if (imagesize+10<=32768) FLASH_command(SPIFLASH_BLOCKERASE_32K, 1);
		else FLASH_command(SPIFLASH_BLOCKERASE_64K, 1);
		SPI_transfer(0);
		SPI_transfer(0);
		SPI_transfer(0);
		#endif
		FLASH_UNSELECT;


		//now trigger a watchdog reset
		watchdogConfig(WATCHDOG_16MS);  // short WDT timeout
		while (1); 		                  // and busy-loop so that WD causes a reset and app start
	}
예제 #4
0
void CheckFlashImage() {
#ifdef DEBUG_ON
  putch('F');
#endif
  watchdogConfig(WATCHDOG_OFF);
  
  //SPI INIT
  FLASHSS_DDR |= _BV(FLASHSS) | _BV(SS) | _BV(PB3) | _BV(PB5); //OUTPUTS for D8 and D10, MOSI, SCK
  FLASH_UNSELECT; //unselect FLASH chip
  PINB |= _BV(SS); //set D10 HIGH
  
  //SPCR &= ~(_BV(DORD)); //MSB first
  //SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE0 ; //SPI MODE 0
  //SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK); //clock divider = 2
  //SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);

  // Warning: if the SS pin ever becomes a LOW INPUT then SPI automatically switches to Slave, so the data direction of the SS pin MUST be kept as OUTPUT.
  SPCR |= _BV(MSTR) | _BV(SPE); //enable SPI and set SPI to MASTER mode

  //read first byte of JEDECID, if chip is present it should return a non-0 and non-FF value
  FLASH_SELECT;
  SPI_transfer(SPIFLASH_JEDECID);
  uint8_t deviceId = SPI_transfer(0);
  FLASH_UNSELECT;
  if (deviceId==0 || deviceId==0xFF) return;
  
  //global unprotect  
  FLASH_command(SPIFLASH_STATUSWRITE, 1);
  SPI_transfer(0);
  FLASH_UNSELECT;
  
  //check if any flash image exists on external FLASH chip
  if (FLASH_readByte(0)=='F' && FLASH_readByte(1)=='L' && FLASH_readByte(2)=='X' && FLASH_readByte(6)==':' && FLASH_readByte(9)==':')
  {
#ifdef DEBUG_ON
    putch('L');
#endif
    
    uint16_t imagesize = (FLASH_readByte(7)<<8) | FLASH_readByte(8);
    if (imagesize%2!=0) return; //basic check that we got even # of bytes
    
    uint16_t b, i, nextAddress=0;
    
    LED_PIN |= _BV(LED);
    for (i=0; i<imagesize; i+=2)
    {
#ifdef DEBUG_ON
      putch('*');
#endif
      
      //read 2 bytes (16 bits) from flash image, transfer them to page buffer
      b = FLASH_readByte(i+10); // flash image starts at position 10 on the external flash memory: FLX:XX:FLASH_IMAGE_BYTES_HERE...... (XX = two size bytes)
      b |= FLASH_readByte(i+11) << 8; //bytes are stored big endian on external flash, need to flip the bytes to little endian for transfer to internal flash
      __boot_page_fill_short((uint16_t)(void*)i,b);

      //when 1 page is full (or we're on the last page), write it to the internal flash memory
      if ((i+2)%SPM_PAGESIZE==0 || (i+2==imagesize))
      {
        __boot_page_erase_short((uint16_t)(void*)nextAddress); //(i+2-SPM_PAGESIZE)
        boot_spm_busy_wait();
        // Write from programming buffer
        __boot_page_write_short((uint16_t)(void*)nextAddress ); //(i+2-SPM_PAGESIZE)
        boot_spm_busy_wait();
        nextAddress += SPM_PAGESIZE;
      }
    }
    LED_PIN &= ~_BV(LED);

#if defined(RWWSRE)
    // Reenable read access to flash
    boot_rww_enable();
#endif

#ifdef DEBUG_ON
    putch('E');
#endif

    //erase the first 32K block where flash image resided
    FLASH_command(SPIFLASH_BLOCKERASE_32K, 1);
    SPI_transfer(0);
    SPI_transfer(0);
    SPI_transfer(0);
    FLASH_UNSELECT;
    
    //now trigger a watchdog reset
    watchdogConfig(WATCHDOG_16MS);  // short WDT timeout
    while (1); 		                  // and busy-loop so that WD causes a reset and app start
  }
#ifdef DEBUG_ON
  putch('X');
#endif
}