[Tinyos-beta-commits] CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot Makefile, NONE, 1.1 TOSBoot.nc, NONE, 1.1 TOSBootExtFlash.h, NONE, 1.1 TOSBootExtFlash.nc, NONE, 1.1 TOSBootM.nc, NONE, 1.1 TOSBootProgFlash.h, NONE, 1.1 TOSBootProgFlash.nc, NONE, 1.1 TOSBootProgFlashM.nc, NONE, 1.1 TOSBootSTM25PC.nc, NONE, 1.1 TOSBootSTM25PM.nc, NONE, 1.1

Jonathan Hui jwhui at users.sourceforge.net
Sun Nov 21 21:30:59 PST 2004


Update of /cvsroot/tinyos/tinyos-1.x/beta/Deluge/Deluge/TOSBoot
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13752/Deluge/TOSBoot

Added Files:
	Makefile TOSBoot.nc TOSBootExtFlash.h TOSBootExtFlash.nc 
	TOSBootM.nc TOSBootProgFlash.h TOSBootProgFlash.nc 
	TOSBootProgFlashM.nc TOSBootSTM25PC.nc TOSBootSTM25PM.nc 
Log Message:
- Initial checkin of Deluge v2.0.

- New features:
  - Support for hardware write protect of external flash chip.
  - Ping results include information obtained from Ident.h.
  - CRCs are no longer inlined with program data, thus allowing for
    DMA transfers from external flash to program flash.
  - Version number information included in Deluge packets to prevent
    nodes with different versions of Deluge from conflicts.
  - Support for TinyOS 2.x hardware independent storage abstraction.
  - Metadata data-structures include CRCs generated by the host PC
    to help guard against corruption.
  - TOSBoot bootloader now written in nesC.
  - Reduced RAM and ROM requirements.
  - Other minor enhancements that I can't think of right now.

- Major user differences:
  - Golden image is now slot 0. While it cannot be written to, the user
    can retrieve Ident.h information about the golden image.
  - When specifying an image for download, the user specifies the 
    build/<platform> directory rather than just the ihex file. The issue
    is that it is very difficult to pull out the Ident.h information
    without compile-time output.

- Known issues:
  - Does not support more than 1 downloadable image (actually, it might, 
    but I haven't tested it yet).

- To setup the Deluge tools, create the directory net/tinyos/deluge
and copy all files in 'delugetools' into it.

- Operation is very similar to Deluge v1.0.
  Ping:
    $ java net.tinyos.deluge.Deluge -p
  Download:
    $ java net.tinyos.deluge.Deluge -i -if <builddir> -in <imagenum>
  Reboot:
    $ java net.tinyos.deluge.Deluge -r -in <imagenum>



--- NEW FILE: Makefile ---

COMPONENT=TOSBoot

PFLAGS += \
-DDELUGE_LEDS \
-I%T/lib/Deluge2 \
-I%T/lib/Deluge2/TOSBoot \
-DBOOTLOADER_START=0x4000

include $(TOSDIR)/../apps/Makerules

--- NEW FILE: TOSBoot.nc ---

includes Deluge;
includes TOSBoot;
includes TOSBootExtFlash;
includes TOSBootProgFlash;

configuration TOSBoot {
}
implementation {

  components
    TOSBootM,
    HPLInitC,
    InternalFlashC as IntFlash,
    LedsC,
    TOSBootProgFlashM as ProgFlash,
    TOSBootSTM25PC as ExtFlash;

  TOSBootM.SubControl -> ExtFlash.StdControl;

  TOSBootM.ExtFlash -> ExtFlash;
  TOSBootM.HardwareInit -> HPLInitC;
  TOSBootM.IntFlash -> IntFlash;
  TOSBootM.Leds -> LedsC;
  TOSBootM.ProgFlash -> ProgFlash;

}

--- NEW FILE: TOSBootExtFlash.h ---

#ifndef __TOSBOOTEXTFLASH_H__
#define __TOSBOOTEXTFLASH_H__

#define BL_EXT_PAGE_SIZE ((uint32_t)65536)

#endif

--- NEW FILE: TOSBootExtFlash.nc ---

interface TOSBootExtFlash {
  command result_t startRead(uint32_t addr);
  command uint8_t  readByte();
  command result_t stopRead();
}

--- NEW FILE: TOSBootM.nc ---

module TOSBootM {
  uses {
    command result_t HardwareInit();
    interface InternalFlash as IntFlash;
    interface Leds;
    interface TOSBootExtFlash as ExtFlash;
    interface TOSBootProgFlash as ProgFlash;
    interface StdControl as SubControl;
  }
}
implementation {

  void startupLeds() {

    uint8_t  output = 0x7;
    uint8_t  i;
    uint16_t j;

    call Leds.set(0x7);
    for (i = 0; i < 3; i++ ) {
      for (j = 1024; j > 0; j -= 4) {
	call Leds.set(output);
	TOSH_uwait(j);
	call Leds.set(output >> 0x1);
	TOSH_uwait(1024-j);
      }
      output >>= 0x1;
    }

  }

  void gestureNotify() {

    uint8_t output = 0x7;
    uint8_t i, j;

    for ( i = 0; i < 3; i++ ) {
      call Leds.set(output);
      for ( j = 0; j < 4; j++ )
	TOSH_uwait(0x7fff);
      call Leds.set(0x0);
      for ( j = 0; j < 4; j++ )
	TOSH_uwait(0x7fff);
    }

  }

  result_t programBuf(uint32_t addr, uint8_t* buf, uint16_t len) {
    call ProgFlash.write(addr, buf, len);
    return SUCCESS;
  }

  result_t programImage(uint32_t startAddr) {

    uint8_t  buf[TOSBOOT_INT_PAGE_SIZE];
    uint32_t pageAddr;
    uint32_t intAddr;
    uint32_t secLength;
    uint16_t i;

    call ExtFlash.startRead(startAddr);

    intAddr = 0;
    for ( i = 0; i < 4; i++ )
      intAddr |= ((uint32_t)call ExtFlash.readByte() & 0xff) << (i*8);

    secLength = 0;
    for ( i = 0; i < 4; i++ )
      secLength |= ((uint32_t)call ExtFlash.readByte() & 0xff) << (i*8);   

    while (secLength > 0) {
      for ( i = 0; i < secLength; i++, intAddr++) {
	if (i != 0 && intAddr % TOSBOOT_INT_PAGE_SIZE == 0) {
	  pageAddr = (intAddr / TOSBOOT_INT_PAGE_SIZE) - ((uint32_t) 1);
	  call Leds.set(pageAddr);
	  if (programBuf(pageAddr * TOSBOOT_INT_PAGE_SIZE, buf, TOSBOOT_INT_PAGE_SIZE) == FAIL)
	    return FAIL;
	}

	buf[intAddr % TOSBOOT_INT_PAGE_SIZE] = call ExtFlash.readByte();
      }

      pageAddr = intAddr / TOSBOOT_INT_PAGE_SIZE;
      if (intAddr % TOSBOOT_INT_PAGE_SIZE == 0)
	pageAddr--;
      
      if (programBuf(pageAddr * TOSBOOT_INT_PAGE_SIZE, buf, TOSBOOT_INT_PAGE_SIZE) == FAIL)
	return FAIL;

      intAddr = 0;
      for ( i = 0; i < 4; i++ )
	intAddr |= ((uint32_t)call ExtFlash.readByte() & 0xff) << (i*8);

      secLength = 0;
      for ( i = 0; i < 4; i++ )
	secLength |= ((uint32_t)call ExtFlash.readByte() & 0xff) << (i*8);

    }

    call ExtFlash.stopRead();

    return SUCCESS;

  }

  void reboot() {
    WDTCTL = WDT_ARST_1_9;
    while(1);
  }

  void runApp() {
    __asm__ __volatile__ ("br #0x5000\n\t" ::);
  }

  void startupSequence() {

    uint32_t newImgAddr;
    uint8_t  loadImg;
    uint8_t  gestureCount;
    uint8_t  oneByte;
    uint32_t addr;
    uint8_t  flags;

    // get current value of counter
    call IntFlash.read((uint8_t*)TOSBOOT_GESTURE_COUNT_ADDR, &gestureCount, sizeof(gestureCount));

    // increment gesture counter
    gestureCount = (gestureCount==0xff) ? 0x1 : gestureCount+1;

    // read flags
    call IntFlash.read((uint8_t*)TOSBOOT_FLAGS_ADDR, &flags, sizeof(flags));

    call IntFlash.read((uint8_t*)TOSBOOT_LOAD_IMG_ADDR, &loadImg, sizeof(loadImg));

    if (gestureCount >= TOSBOOT_GESTURE_MAX_COUNT
	&& !(flags & TOSBOOT_GOLDEN_IMG_LOADED)) {
      // gesture has been detected, display receipt of gesture on LEDs
      gestureNotify();

      // update new image start address
      addr = TOSBOOT_GOLDEN_IMG_ADDR;
      call IntFlash.write((uint8_t*)TOSBOOT_NEW_IMG_START_ADDR, &addr, sizeof(addr));

      // load golden image from flash
      if (programImage(TOSBOOT_GOLDEN_IMG_ADDR) == FAIL)
	reboot();
      
      // update current image start address
      addr = TOSBOOT_GOLDEN_IMG_ADDR;
      call IntFlash.write((uint8_t*)TOSBOOT_CUR_IMG_START_ADDR, &addr, sizeof(addr));

      // clear gesture counter
      gestureCount = 0xff;
    }

    // update gesture counter
    call IntFlash.write((uint8_t*)TOSBOOT_GESTURE_COUNT_ADDR, &gestureCount, sizeof(gestureCount));
    
    if (loadImg != 0xff) {
      // get address of new program
      call IntFlash.read((uint8_t*)TOSBOOT_NEW_IMG_START_ADDR, &newImgAddr, sizeof(newImgAddr));

      if (programImage(newImgAddr) == FAIL)
	reboot();
      
      // update current image start address
      call IntFlash.write((uint8_t*)TOSBOOT_CUR_IMG_START_ADDR, &newImgAddr, sizeof(newImgAddr));
      oneByte = 0xff;
      call IntFlash.write((uint8_t*)TOSBOOT_LOAD_IMG_ADDR, &oneByte, sizeof(oneByte));
    }

    // give user some time and count down LEDs
    startupLeds();

    // reset counter
    oneByte = 0xff;
    call IntFlash.write((uint8_t*)TOSBOOT_GESTURE_COUNT_ADDR, &oneByte, sizeof(oneByte));
    
    runApp();

  }

  int main() __attribute__ ((C, spontaneous)) {

    __nesc_disable_interrupt();

    TOSH_SET_PIN_DIRECTIONS();

    TOSH_MAKE_UCLK0_OUTPUT();
    TOSH_MAKE_SIMO0_OUTPUT();
    TOSH_MAKE_SOMI0_INPUT();
    BCSCTL1 = RSEL0 + RSEL1 + RSEL2;
    DCOCTL = DCO0 + DCO1 + DCO2;
    
    call SubControl.init();
    call SubControl.start();
    
    call Leds.init();
    
    startupSequence();

    return 0;

  }

}

--- NEW FILE: TOSBootProgFlash.h ---

#ifndef __TOSBOOTPROGFLASH_H__
#define __TOSBOOTPROGFLASH_H__

#define BL_INT_PAGE_SIZE  ((uint32_t)512)
#define BL_MSP_RESET_ADDR 0xfffe

#endif

--- NEW FILE: TOSBootProgFlash.nc ---

interface TOSBootProgFlash {
  command result_t write(uint32_t addr, uint8_t* buf, uint16_t len);
}

--- NEW FILE: TOSBootProgFlashM.nc ---

module TOSBootProgFlashM {
  provides {
    interface TOSBootProgFlash as ProgFlash;
  }
}

implementation {

  command result_t ProgFlash.write(uint32_t addr, uint8_t* buf, uint16_t len) {

    volatile uint16_t *flashAddr = (uint16_t*)(uint16_t)addr;
    uint16_t *wordBuf = (uint16_t*)buf;
    uint16_t i = 0;
    
    FCTL2 = FWKEY + FSSEL1 + FN2;
    FCTL3 = FWKEY;
    FCTL1 = FWKEY + ERASE;
    *flashAddr = 0;
    FCTL1 = FWKEY + WRT;
    if (addr == (BL_MSP_RESET_ADDR/BL_INT_PAGE_SIZE)*BL_INT_PAGE_SIZE)
      *(uint16_t*)BL_MSP_RESET_ADDR = BOOTLOADER_START;
    for (i = 0; i < len / sizeof(uint16_t); i++) {
      if ((uint16_t)flashAddr != BL_MSP_RESET_ADDR)
	*flashAddr++ = wordBuf[i];
    }
    FCTL1 = FWKEY;
    FCTL3 = FWKEY + LOCK;

    return SUCCESS;

  }

}

--- NEW FILE: TOSBootSTM25PC.nc ---

configuration TOSBootSTM25PC {
  provides {
    interface StdControl;
    interface TOSBootExtFlash;
  }
}

implementation {

  components 
    TOSBootSTM25PM,
    HPLUSART0M;

  StdControl = TOSBootSTM25PM;
  TOSBootExtFlash = TOSBootSTM25PM;

  TOSBootSTM25PM.USARTControl -> HPLUSART0M;

}

--- NEW FILE: TOSBootSTM25PM.nc ---

module TOSBootSTM25PM {
  provides {
    interface StdControl;
    interface TOSBootExtFlash;
  }
  uses {
    interface HPLUSARTControl as USARTControl;
  }
}

implementation {

  command result_t StdControl.init() {
    call USARTControl.setModeSPI();
    call USARTControl.disableRxIntr();
    call USARTControl.disableTxIntr();
    return SUCCESS;
  }

  command result_t StdControl.start() { return SUCCESS; }
  command result_t StdControl.stop() { return SUCCESS; }

  void powerOnFlash() {

    uint8_t i;

    TOSH_CLR_FLASH_CS_PIN();
    TOSH_SET_FLASH_HOLD_PIN();

    // command byte
    call USARTControl.tx(0xab);
    while(!(call USARTControl.isTxIntrPending()));
    
    // dummy bytes
    for ( i = 0; i < 3; i++ ) {
      call USARTControl.tx(0);
      while(!(call USARTControl.isTxIntrPending()));
    }
    
    // signature
    call USARTControl.rx(); // clear receive interrupt
    call USARTControl.tx(0);
    while(!(call USARTControl.isRxIntrPending()));
    call USARTControl.rx(); // read signature

    TOSH_CLR_FLASH_HOLD_PIN();
    TOSH_SET_FLASH_CS_PIN();

  }

  command result_t TOSBootExtFlash.startRead(uint32_t addr) {

    powerOnFlash();

    TOSH_CLR_FLASH_CS_PIN();
    TOSH_SET_FLASH_HOLD_PIN();

    // command
    call USARTControl.tx(0x3);
    while(!(call USARTControl.isTxIntrPending()));

    // address
    call USARTControl.tx((addr >> 16) & 0xff);
    while(!(call USARTControl.isTxIntrPending()));
    call USARTControl.tx((addr >> 8) & 0xff);
    while(!(call USARTControl.isTxIntrPending()));
    call USARTControl.tx((addr >> 0) & 0xff);
    while(!(call USARTControl.isTxIntrPending()));
    
    call USARTControl.rx(); // clear receive interrupt

    return SUCCESS;

  }

  command uint8_t TOSBootExtFlash.readByte() {
    call USARTControl.tx(0);
    while(!(call USARTControl.isRxIntrPending()));
    return call USARTControl.rx();
  }

  command result_t TOSBootExtFlash.stopRead() {

    TOSH_CLR_FLASH_HOLD_PIN();
    TOSH_SET_FLASH_CS_PIN();

    return SUCCESS;

  }

}




More information about the Tinyos-beta-commits mailing list