[Tinyos-beta-commits] CVS: tinyos-1.x/beta/platform/imote2 Flash.h, NONE, 1.1 FlashC.nc, NONE, 1.1 FlashM.nc, NONE, 1.1 HPLUSBClient.h, NONE, 1.1 HPLUSBClientC.nc, NONE, 1.1 HPLUSBClientGPIOM.nc, NONE, 1.1 UIDC.nc, NONE, 1.1

Josh jsherbach at users.sourceforge.net
Thu Aug 18 13:42:14 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/beta/platform/imote2
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24900

Added Files:
	Flash.h FlashC.nc FlashM.nc HPLUSBClient.h HPLUSBClientC.nc 
	HPLUSBClientGPIOM.nc UIDC.nc 
Log Message:
imote2 specific Flash writing/erasing component, UID reading component, and USBClient component

--- NEW FILE: Flash.h ---
#ifndef __FLASH_H__
#define __FLASH_H__

#define DEBUG 0
#define ASSERT 0

#define FLASH_PARTITION_COUNT 16
#define FLASH_PARTITION_SIZE 0x200000

#define FLASH_STATE_READ_INACTIVE 0
#define FLASH_STATE_PROGRAM 1
#define FLASH_STATE_ERASE 2
#define FLASH_STATE_READ_ACTIVE 3


#define FLASH_BLOCK_COUNT 256
#define FLASH_BLOCK_SIZE 0x20000

#define FLASH_BLOCK_CLEAN 0
#define FLASH_BLOCK_USED 1


#define FLASH_PROGRAM_BUFFER_SIZE 32
#define FLASH_NOT_SUPPORTED 0x100

#define FLASH_NORMAL 0
#define FLASH_OVERWRITE 1

#endif

--- NEW FILE: FlashC.nc ---
configuration FlashC {
  provides interface Flash;
}
implementation {
  components 
    Main,
    FlashM;

  Main.StdControl -> FlashM;
  Flash = FlashM;
}

--- NEW FILE: FlashM.nc ---
module FlashM {
  provides {
    interface StdControl;
    interface Flash;
  }
}
implementation {
  
#include "Flash.h"
  
  //void trace(const char *format, ...) __attribute__ ((C, spontaneous));
  
  uint16_t unlock(uint32_t addr);
  uint16_t lock(uint32_t addr);
  uint16_t getSR(uint32_t addr);
  uint16_t eraseFlash(uint32_t addr);
  uint32_t CFIQuery();
  uint16_t programWord(uint32_t addr, uint16_t data);
  uint16_t programBuffer(uint32_t addr, uint16_t data[], uint8_t datalen);
  uint16_t writeHelper(uint32_t addr, uint8_t* data, uint32_t numBytes,
		       uint8_t prebyte, uint8_t postbyte);
  
  
  uint8_t FlashPartitionState[FLASH_PARTITION_COUNT];
  uint8_t FlashBlockState[FLASH_BLOCK_COUNT];
  uint8_t init = 0, programBufferSupported = 2, currBlock = 0;
  
  command result_t StdControl.init() {
    int i = 0;
    if(init != 0)
      return SUCCESS;
    init = 1;
    for(i = 0; i < FLASH_PARTITION_COUNT; i++)
      FlashPartitionState[i] = FLASH_STATE_READ_INACTIVE;
    FlashPartitionState[0] = FLASH_STATE_READ_ACTIVE;//program
    
    for(i = 0; i < FLASH_BLOCK_COUNT; i++)
      if(i < FLASH_PARTITION_SIZE / FLASH_BLOCK_SIZE)
	FlashBlockState[i] = FLASH_BLOCK_USED;//saying first partition is used
      else
	FlashBlockState[i] = FLASH_BLOCK_CLEAN;
    FlashBlockState[i - 1] = FLASH_BLOCK_USED; //UID block is not touched
    
    asm volatile(
		 ".equ FLASH_READARRAY,(0x00FF);         \
		 .equ FLASH_CFIQUERY,(0x0098);		 \
		 .equ FLASH_READSTATUS,(0x0070);	 \
		 .equ FLASH_CLEARSTATUS,(0x0050);	 \
		 .equ FLASH_PROGRAMWORD,(0x0040);	 \
		 .equ FLASH_PROGRAMBUFFER,(0x00E8);	 \
		 .equ FLASH_ERASEBLOCK,(0x0020);	 \
		 .equ FLASH_DLOCKBLOCK,(0x0060);	 \
		 .equ FLASH_PROGRAMBUFFERCONF,(0x00D0);	 \
		 .equ FLASH_LOCKCONF,(0x0001);		 \
		 .equ FLASH_UNLOCKCONF,(0x00D0);	 \
		 .equ FLASH_ERASECONF,(0x00D0);		 \
                 .equ FLASH_OP_NOT_SUPPORTED,(0x10);");
    //flash_op_not_supported needs to be LSL 1 to be the correct value of 0x100
    return SUCCESS;
  }
  
  command result_t StdControl.start() {    
    return SUCCESS;
  }
  
  command result_t StdControl.stop() {
    return SUCCESS;
  }
  
  uint16_t writeHelper(uint32_t addr, uint8_t* data, uint32_t numBytes,
		       uint8_t prebyte, uint8_t postbyte){
    uint32_t i = 0, j = 0, k = 0;
    uint16_t status;
    uint16_t buffer[FLASH_PROGRAM_BUFFER_SIZE];
    
    if(numBytes == 0)
      return FAIL;
    
    if(addr % 2 == 1){
      status = programWord(addr - 1, prebyte | (data[i] << 8));
      i++;
      if(status != 0x80)
	return FAIL;
    }

    if(addr % 2 == numBytes % 2){
      if(programBufferSupported == 1)
	for(; i < numBytes; i = k){
	  for(j = 0, k = i; k < numBytes && 
		j < FLASH_PROGRAM_BUFFER_SIZE; j++, k+=2)
	    buffer[j] = data[k] | (data[k + 1] << 8);
	  status = programBuffer(addr + i, buffer, j);
	  if(status != 0x80)
	    return FAIL;
	}
      else
	for(; i < numBytes; i+=2){
	  status = programWord(addr + i, (data[i + 1] << 8) | data[i]);
	  if(status != 0x80)
	    return FAIL;
	}
    }
    else{
      if(programBufferSupported == 1)
	for(; i < numBytes - 1; i = k){
	  for(j = 0, k = i; k < numBytes - 1 && 
		j < FLASH_PROGRAM_BUFFER_SIZE; j++, k+=2)
	    buffer[j] = data[k] | (data[k + 1] << 8);
	  status = programBuffer(addr + i, buffer, j);
	  if(status != 0x80)
	    return FAIL;
	}
      else
	for(; i < numBytes - 1; i+=2){
	  status = programWord(addr + i, (data[i + 1] << 8) | data[i]);
	  if(status != 0x80)
	    return FAIL;
	}
      status = programWord(addr + i, data[i] | (postbyte << 8));
      if(status != 0x80)
	return FAIL;
    }
    return SUCCESS;
  }
  
  command result_t Flash.write(uint32_t addr, uint8_t* data, uint32_t numBytes,
			       uint8_t type){
    uint32_t tempBlock = 0x01fc0000, i;
    uint16_t status;
    uint8_t error = 0;
    uint8_t blocklen;
    uint32_t blockAddr = (addr / FLASH_BLOCK_SIZE) * FLASH_BLOCK_SIZE;
    
    if(addr + numBytes > 0x02000000) //not in the flash memory space
      return FAIL;
    
    for(i = 0; i < FLASH_PARTITION_COUNT; i++)
      if(i != addr / FLASH_PARTITION_SIZE &&
	 FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE &&
	 FlashPartitionState[i] != FLASH_STATE_READ_ACTIVE)
	return FAIL;
    
    
    for(i = addr / FLASH_PARTITION_SIZE;
	i < (numBytes + addr) / FLASH_PARTITION_SIZE;
	i++)
      if(FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE)
	return FAIL;
    
    for(i = addr / FLASH_PARTITION_SIZE;
	i < (numBytes + addr) / FLASH_PARTITION_SIZE;
	i++)
      FlashPartitionState[i] = FLASH_STATE_PROGRAM;
    
    for(blocklen = 0, i = blockAddr;
	i < addr + numBytes;
	i += FLASH_BLOCK_SIZE, blocklen++)
      unlock(i);
    
    if(programBufferSupported == 2){
      uint16_t testBuf[1];
      
      if(addr % 2 == 0){
	testBuf[0] = data[0] | ((*((uint8_t *)(addr + 1))) << 8);
	status = programBuffer(addr, testBuf, 1);
      }
      else{
	testBuf[0] = *((uint8_t *)(addr - 1)) | (data[0] << 8);
	status = programBuffer(addr - 1, testBuf, 1);
      }      
      if(status == FLASH_NOT_SUPPORTED)
	programBufferSupported = 0;
      else 
	programBufferSupported = 1;
    }
    
    if(blocklen == 1){
      if(type == FLASH_NORMAL)
	writeHelper(addr,data,numBytes,0xFF,0xFF);
      else if(type == FLASH_OVERWRITE){
	call Flash.erase(tempBlock);
	writeHelper(tempBlock, (uint8_t *)blockAddr, addr - blockAddr, 0xFF, data[0]);
	writeHelper(tempBlock + (addr - blockAddr), data, numBytes,
		    ((uint8_t *)blockAddr)[addr - blockAddr - 1], 0xFF);
	writeHelper(tempBlock + (addr - blockAddr) + numBytes,
		    (uint8_t *)(blockAddr + (addr - blockAddr) + numBytes),
		    FLASH_BLOCK_SIZE - (addr - blockAddr) - numBytes,
		    data[numBytes - 1], 0xFF);
	call Flash.erase(blockAddr);
	writeHelper(blockAddr,(uint8_t *)tempBlock,FLASH_BLOCK_SIZE,0xFF,0xFF);
      }
    }
    else{
      uint32_t bytesLeft = numBytes;
      if(type == FLASH_OVERWRITE){
	call Flash.erase(tempBlock);
	writeHelper(tempBlock, (uint8_t *)blockAddr, addr - blockAddr, 0xFF, data[0]);
	writeHelper(tempBlock + (addr - blockAddr), data,
		    FLASH_BLOCK_SIZE - (addr - blockAddr),
		    ((uint8_t *)blockAddr)[addr - blockAddr - 1], 0xFF);
	call Flash.erase(blockAddr);
	writeHelper(blockAddr,(uint8_t *)tempBlock,FLASH_BLOCK_SIZE,0xFF,0xFF);
	bytesLeft = numBytes - (FLASH_BLOCK_SIZE - (addr - blockAddr));
	
	for(i = 1; i < blocklen - 1; i++){
	  call Flash.erase(blockAddr + i * FLASH_BLOCK_SIZE);
	  writeHelper(blockAddr + i * FLASH_BLOCK_SIZE,
		      (uint8_t *)(data + numBytes - bytesLeft),
		      FLASH_BLOCK_SIZE,0xFF,0xFF);
	  bytesLeft -= FLASH_BLOCK_SIZE;
	}
	
	call Flash.erase(tempBlock);
	writeHelper(tempBlock, data + (numBytes - bytesLeft), bytesLeft, 0xFF,
		    ((uint8_t *)blockAddr)[i * FLASH_BLOCK_SIZE + bytesLeft]);
	writeHelper(tempBlock, 
		    (uint8_t *)(blockAddr + i * FLASH_BLOCK_SIZE + bytesLeft),
		    FLASH_BLOCK_SIZE - bytesLeft, data[numBytes - 1], 0xFF);
	call Flash.erase(blockAddr + i * FLASH_BLOCK_SIZE);
	writeHelper(blockAddr + i * FLASH_BLOCK_SIZE,
		    (uint8_t *)tempBlock,FLASH_BLOCK_SIZE,0xFF,0xFF);
      }
      else if(type == FLASH_NORMAL){
	writeHelper(addr,data, blockAddr + FLASH_BLOCK_SIZE - addr,0xFF,0xFF);
	bytesLeft = numBytes - (FLASH_BLOCK_SIZE - (addr - blockAddr));
	for(i = 1; i < blocklen - 1; i++){
	  writeHelper(blockAddr + i * FLASH_BLOCK_SIZE,
		      (uint8_t *)(data + numBytes - bytesLeft),
		      FLASH_BLOCK_SIZE,0xFF,0xFF);
	  bytesLeft -= FLASH_BLOCK_SIZE;
	}
	writeHelper(blockAddr + i * FLASH_BLOCK_SIZE,
		    data + (numBytes - bytesLeft), bytesLeft, 0xFF,0xFF);
      }
    }
    
    for(i = addr / FLASH_PARTITION_SIZE;
	i < (numBytes + addr) / FLASH_PARTITION_SIZE;
	i++)
      FlashPartitionState[i] = FLASH_STATE_READ_INACTIVE;
    
    return SUCCESS;
  }
  
  command result_t Flash.erase(uint32_t addr){
    uint16_t status, i;
    
    if(addr > 0x02000000) //not in the flash memory space
      return FAIL;
    
    addr = (addr / FLASH_BLOCK_SIZE) * FLASH_BLOCK_SIZE;

    for(i = 0; i < FLASH_PARTITION_COUNT; i++)
      if(i != addr / FLASH_PARTITION_SIZE &&
	 FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE &&
	 FlashPartitionState[i] != FLASH_STATE_READ_ACTIVE)
	return FAIL;
    
    if(FlashPartitionState[addr / FLASH_PARTITION_SIZE] != FLASH_STATE_READ_INACTIVE)
      return FAIL;
    
    FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_ERASE;
    
    unlock(addr);
    status = eraseFlash(addr);
    FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_READ_INACTIVE;
    if(status != 0x80)
      return FAIL;
    
    return SUCCESS;
  }
  
  uint32_t CFIQuery(){
    uint32_t result, retval = 0;
    uint16_t query;
    uint8_t i;
    
    for(i = 0; i < 3; i++){   
      query = i + 0x10;
      query = query << 1;
      asm volatile(
		   "ldr r1,=FLASH_CFIQUERY;        \
  	            ldr r2,=FLASH_READARRAY;	   \
		    ldr r3,=0x0;		   \
		    ldr r4,=FLASH_CLEARSTATUS;	   \
		    b _goCFIQueryCacheLine;	   \
		   .align 5;			   \
		   _goCFIQueryCacheLine:	   \
                   strh r4,[r3];		   \
	           strh r1,[r3];		   \
		   ldrh %0,[r3, %1];		   \
		   strh r2,[r3];		   \
		   ldrh r2,[r3];		   \
		   nop;				   \
		   nop;				   \
		   nop;"
		   :"=r"(result)
		   :"r"(query)
		   : "r1", "r2", "r3", "r4", "memory");
      retval = ((result & 0xff) << (8 * i));
    }
    return retval;
  }
  
  uint16_t unlock(uint32_t addr){
    //addr <<= 1;
    addr = (addr / FLASH_BLOCK_SIZE) * FLASH_BLOCK_SIZE;
    
    asm volatile(
		 "ldr r1,=FLASH_DLOCKBLOCK;   \
		 ldr r2,=FLASH_READARRAY;     \
		 ldr r3,=FLASH_UNLOCKCONF;    \
		 ldr r4,=FLASH_CLEARSTATUS;   \
		 b _goUnlockCacheLine;	      \
		 .align 5;		      \
		 _goUnlockCacheLine:	      \
		 strh r4,[r3];		      \
		 strh r1,[%0];		      \
		 strh r3,[%0];		      \
		 strh r2,[%0];		      \
		 ldrh r2,[%0];		      \
		 nop;			      \
		 nop;			      \
		 nop;"
		 :/*no output info*/
		 :"r"(addr)
		 : "r1", "r2", "r3", "r4", "memory");
    return SUCCESS;
  }
  
  uint16_t lock(uint32_t addr){
    //addr <<= 1;
    asm volatile(
		 "ldr r1,=FLASH_DLOCKBLOCK;   \
		 ldr r2,=FLASH_READARRAY;     \
		 ldr r3,=FLASH_LOCKCONF;      \
		 ldr r4,=FLASH_CLEARSTATUS;   \
		 b _goLockCacheLine;	      \
		 .align 5;		      \
		 _goLockCacheLine:	      \
		 strh r4,[r3];		      \
		 strh r1,[%1];		      \
		 strh r3,[%1];		      \
		 strh r2,[%1];		      \
		 ldrh r2,[%1];		      \
		 nop;			      \
		 nop;			      \
		 nop;"
		 :/*no output info*/
		 :"r"(addr)
		 : "r1", "r2", "r3", "r4", "memory");
    return SUCCESS;
  }
  
  uint16_t programBuffer(uint32_t addr, uint16_t data[], uint8_t datalen){
    uint16_t status;
    //addr <<= 1;
    
    datalen -= 1;
    asm volatile(
		 "ldr r1,=FLASH_PROGRAMBUFFER;    \
		 ldr r2,=FLASH_READARRAY;	  \
		 ldr r3,=0x0;			  \
		 ldr r4,=FLASH_CLEARSTATUS;	  \
                 ldr r5,=FLASH_PROGRAMBUFFERCONF; \
                 strh r4,[r3];			  \
		 strh r1,[%1];			  \
		 ldrh r1,[%1];			  \
                 and r1,r1,#0x80;		  \
                 cmp r1,#0x0;			  \
                 beq _goProgramBufferNS;	  \
                 strh %3, [%1];			  \
                 _goProgramBufferLoop:		  \
                 mov r4,r3,LSL #1;		  \
		 ldrh r6, [%2,r4];		  \
                 strh r6, [%1,r4];		  \
                 add r3,r3,#1;			  \
                 cmp r3, %3;			  \
                 ble _goProgramBufferLoop;	  \
                 mov r4,r3,LSL #1;		  \
                 strh r5,[%1,r4];		  \
                 _goProgramBufferSpin:		  \
		 ldrh r1,[%1];			  \
                 and r1,r1,#0x80;		  \
                 cmp r1,#0x0;			  \
                 beq _goProgramBufferSpin;	  \
                 ldrh r1,[%1];			  \
                 strh r2,[%1];			  \
                 ldrh r2,[%1];			  \
                 mov %0, r1;			  \
		 b _goProgramBufferEnd;		  \
                 _goProgramBufferNS:		  \
                 ldrh %0,=FLASH_OP_NOT_SUPPORTED; \
                 mov %0,%0,LSL #1;		  \
                 _goProgramBufferEnd:"
		 :"=r"(status)
		 :"r"(addr), "r"(data), "r"(datalen)
		 : "r1", "r2", "r3", "r4", "r5", "r6", "memory");
    return status;
  }
  
  uint16_t programWord(uint32_t addr, uint16_t data){
    uint16_t status;
    //addr <<= 1;
    
    asm volatile(
		 "ldr r1,=FLASH_PROGRAMWORD;    \
		 ldr r2,=FLASH_READARRAY;	\
		 ldr r3,=0x0;			\
		 ldr r4,=FLASH_CLEARSTATUS;	\
		 b _goProgramWordCacheLine;	\
		 .align 5;			\
		 _goProgramWordCacheLine:	\
                 strh r4,[r3];			\
		 strh r1,[%1];			\
		 strh %2,[%1];			\
		 nop;				\
		 nop;				\
		 nop;				\
		 nop;				\
		 nop;				\
                 _goProgramWordSpin:		\
		 ldrh r1,[%1];			\
                 and r1,r1,#0x80;		\
                 cmp r1,#0x0;			\
                 beq _goProgramWordSpin;	\
                 ldrh r1,[%1];			\
                 strh r2,[%1];			\
                 ldrh r2,[%1];			\
                 mov %0, r1;"
		 :"=r"(status)
		 :"r"(addr), "r"(data)
		 : "r1", "r2", "r3", "r4", "memory");
    
    return status;
  }
  
  uint16_t eraseFlash(uint32_t addr){
    uint16_t status;
    //addr <<= 1;
    asm volatile(
		 "ldr r1,=FLASH_ERASEBLOCK;     \
		 ldr r2,=FLASH_READARRAY;	\
		 ldr r3,=0x0;			\
		 ldr r4,=FLASH_ERASECONF;	\
		 ldr r5,=FLASH_CLEARSTATUS;	\
		 b _goEraseFlashCacheLine;	\
		 .align 5;			\
		 _goEraseFlashCacheLine:	\
		 strh r5,[r3];			\
		 strh r1,[%1];			\
		 strh r4,[%1];			\
		 nop;				\
		 nop;				\
		 nop;				\
		 nop;				\
		 nop;				\
                 _goEraseFlashSpin:		\
		 ldrh r1,[%1];			\
                 and r1,r1,#0x80;		\
                 cmp r1,#0x0;			\
                 beq _goEraseFlashSpin;         \
                 ldrh r1,[%1];			\
                 strh r2,[%1];			\
                 ldrh r2,[%1];			\
                 mov  %0, r1;"
		 :"=r"(status)
		 :"r"(addr)
		 : "r1", "r2", "r3", "r4", "r5", "memory");
    return status;
  }
  
  uint16_t getSR(uint32_t addr){
    uint16_t result;    
    //addr <<= 1; cut?
    asm volatile(
		 "ldr r1,=FLASH_READSTATUS;   \
		 ldr r2,=FLASH_READARRAY;     \
		 b _goRSRCacheLine;	      \
		 .align 5;		      \
		 _goRSRCacheLine:	      \
		 strh r1,[%1];		      \
		 ldrh r3,[%1];		      \
		 strh r2,[%1];		      \
		 ldrh r2,[%1];		      \
                 mov %0, r3;		      \
		 nop;			      \
		 nop;			      \
		 nop;"
		 :"=r"(result)
		 :"r"(addr)
		 : "r1", "r2", "r3", "memory");
    return result;
  }
}

--- NEW FILE: HPLUSBClient.h ---
#ifndef __HPLUSBCLIENT_H__
#define __HPLUSBCLIENT_H__

#define isFlagged(_BITFIELD, _FLAG) (((_BITFIELD) & (_FLAG)) != 0)
#define USBC_GPIOX_EN 88
#define USBC_GPION_DET 13

#endif

--- NEW FILE: HPLUSBClientC.nc ---
#include "HPLUSBClient.h"

configuration HPLUSBClientC {
  provides{
    interface SendVarLenPacket;
    interface SendJTPacket;
    interface ReceiveData;
    interface ReceiveMsg;
    interface ReceiveBData;
    interface BareSendMsg;
  }
}

implementation {
  components
    Main,
    UIDC,
    HPLUSBClientGPIOM,
    PXA27XGPIOIntC,
    PXA27XUSBClientC;
  
  SendVarLenPacket = PXA27XUSBClientC;
  SendJTPacket = PXA27XUSBClientC;
  BareSendMsg = PXA27XUSBClientC;
  ReceiveData = PXA27XUSBClientC;
  ReceiveMsg = PXA27XUSBClientC;
  ReceiveBData = PXA27XUSBClientC;
  
  Main.StdControl -> PXA27XGPIOIntC;
  PXA27XUSBClientC -> PXA27XGPIOIntC.PXA27XGPIOInt[USBC_GPION_DET];
  PXA27XUSBClientC.HPLUSBClientGPIO -> HPLUSBClientGPIOM;

  PXA27XUSBClientC.UID -> UIDC;
}

--- NEW FILE: HPLUSBClientGPIOM.nc ---
#include "HPLUSBClient.h"

module HPLUSBClientGPIOM{
  provides interface HPLUSBClientGPIO;
}
implementation{
 
  async command result_t HPLUSBClientGPIO.init(){
    _GPDR(USBC_GPION_DET) &= ~_GPIO_bit(USBC_GPION_DET); 
    
    _GPDR(USBC_GPIOX_EN) |= _GPIO_bit(USBC_GPIOX_EN);
    _GPSR(USBC_GPIOX_EN) |= _GPIO_bit(USBC_GPIOX_EN);    
  }
  
  async command result_t HPLUSBClientGPIO.checkConnection(){
    if(isFlagged(_GPLR(USBC_GPION_DET), _GPIO_bit(USBC_GPION_DET)))
      return SUCCESS;
  }
}

--- NEW FILE: UIDC.nc ---
module UIDC {
  provides interface UID;
}

implementation {
  async command uint32_t UID.getUID(){
    return *((uint32_t *)0x01FE0000);
  }
}



More information about the Tinyos-beta-commits mailing list