[Tinyos-beta-commits] CVS: tinyos-1.x/beta/platform/imote2 FlashM.nc, 1.5, 1.6

Josh jsherbach at users.sourceforge.net
Wed Aug 31 13:45:47 PDT 2005


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

Modified Files:
	FlashM.nc 
Log Message:
blocks access to first partition of flash

Index: FlashM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/platform/imote2/FlashM.nc,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** FlashM.nc	25 Aug 2005 22:30:30 -0000	1.5
--- FlashM.nc	31 Aug 2005 20:45:44 -0000	1.6
***************
*** 1,440 ****
! 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 init = 0, programBufferSupported = 2, currBlock = 0;
! 
!   extern void __Flash_Erase() __attribute__ ((C,spontaneous));
!   extern void __Flash_Program_Word() __attribute__ ((C,spontaneous));
!   extern void __Flash_Program_Buffer() __attribute__ ((C,spontaneous));
!   
!   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;
!     
!     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 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;
!       programBufferSupported = 0;
!     }
!     
!     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()  __attribute__((noinline)){
!     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)  __attribute__((noinline)){
!     //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) __attribute__ ((noinline)){
!     //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)   __attribute__((noinline)){
!     uint16_t status;
!     uint32_t programBufferCommands[40];/* even though there are only 33 lines
! 					 * of assembly by my count it seems
! 					 * to work better if I allocate / allow
! 					 * for more lines...no clue but this
! 					 * is an issue*/
! 
!     memcpy(programBufferCommands,__Flash_Program_Buffer,40 * 4);
!     
!     datalen -= 1;
!     atomic{
!       asm volatile(
! 		   "mov r1, %1;           	\
!                    mov r2, %2;				\
!                    mov r3, %3;			\		 
! 		   mov r14, PC;			\
! 		   mov PC, %4;			\
! 		   mov %0, r0;"
! 		   /*
! 		   bl __Flash_Program_Buffer;	\
! 		   mov %0, r0;"
! 		   */
! 		   :"=r"(status)
! 		   :"r"(addr), "r"(data),"r"(datalen),
! 		    "r"(programBufferCommands)
! 		   : "r0", "r1", "r2", "r3", "r14", "memory");
!     }
!     return status;
!   }
!   
!   uint16_t programWord(uint32_t addr, uint16_t data)  __attribute__((noinline)){
!     uint16_t status;
!     uint32_t programWordCommands[16];
! 
!     memcpy(programWordCommands,__Flash_Program_Word,16 * 4);
!     atomic{
!       asm volatile(
! 		   "mov r1, %1;                   \
!                    mov r2, %2;			  \
!                    mov r14, PC;			  \
! 		   mov PC, %3;			  \
! 		   mov %0, r0;"		 
! 		   :"=r"(status)
! 		   :"r"(addr), "r"(data),"r"(programWordCommands)
! 		   : "r0", "r1", "r2", "memory");
!     }
!     return status;
!   }
!   
!   uint16_t eraseFlash(uint32_t addr)  __attribute__((noinline)){
!     uint16_t status;
!     uint32_t eraseFlashCommands[17];
! 
!     memcpy(eraseFlashCommands,__Flash_Erase,17 * 4);
!     atomic{
!       asm volatile(
! 		   "mov r1, %1;                   \
!                    mov r14, PC;			  \
! 		   mov PC, %2;			  \
! 		   mov %0, r0;"		 
! 		   :"=r"(status)
! 		   :"r"(addr), "r"(eraseFlashCommands)
! 		   : "r0", "r1", "memory");
!     }
!     return status;
!   }
!   
!   uint16_t getSR(uint32_t addr)  __attribute__((noinline)){
!     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;
!   }
! }
--- 1,400 ----
! module FlashM {
!   provides {
!     interface StdControl;
!     interface Flash; //does not allow writing into FLASH_PROTECTED_REGION
!   }
! }
! 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 init = 0, programBufferSupported = 2, currBlock = 0;
! 
!   extern void __Flash_Erase() __attribute__ ((C,spontaneous));
!   extern void __Flash_Program_Word() __attribute__ ((C,spontaneous));
!   extern void __Flash_Program_Buffer() __attribute__ ((C,spontaneous));
!   
!   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;
!     
!     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){
!     uint32_t i;
!     uint16_t status;
!     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;
!     if(addr < FLASH_PROTECTED_REGION)
!       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;
!       programBufferSupported = 0;
!     }
!     
!     if(blocklen == 1)
!       writeHelper(addr,data,numBytes,0xFF,0xFF);
!     else{
!       uint32_t bytesLeft = numBytes;
!       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;
!     if(addr < FLASH_PROTECTED_REGION)
!       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()  __attribute__((noinline)){
!     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)  __attribute__((noinline)){
!     //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) __attribute__ ((noinline)){
!     //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)   __attribute__((noinline)){
!     uint16_t status;
!     uint32_t programBufferCommands[40];/* even though there are only 33 lines
! 					 * of assembly by my count it seems
! 					 * to work better if I allocate / allow
! 					 * for more lines...no clue but this
! 					 * is an issue*/
! 
!     memcpy(programBufferCommands,__Flash_Program_Buffer,40 * 4);
!     
!     datalen -= 1;
!     atomic{
!       asm volatile(
! 		   "mov r1, %1;           	\
!                    mov r2, %2;				\
!                    mov r3, %3;			\		 
! 		   mov r14, PC;			\
! 		   mov PC, %4;			\
! 		   mov %0, r0;"
! 		   /*
! 		   bl __Flash_Program_Buffer;	\
! 		   mov %0, r0;"
! 		   */
! 		   :"=r"(status)
! 		   :"r"(addr), "r"(data),"r"(datalen),
! 		    "r"(programBufferCommands)
! 		   : "r0", "r1", "r2", "r3", "r14", "memory");
!     }
!     return status;
!   }
!   
!   uint16_t programWord(uint32_t addr, uint16_t data)  __attribute__((noinline)){
!     uint16_t status;
!     uint32_t programWordCommands[16];
! 
!     memcpy(programWordCommands,__Flash_Program_Word,16 * 4);
!     atomic{
!       asm volatile(
! 		   "mov r1, %1;                   \
!                    mov r2, %2;			  \
!                    mov r14, PC;			  \
! 		   mov PC, %3;			  \
! 		   mov %0, r0;"		 
! 		   :"=r"(status)
! 		   :"r"(addr), "r"(data),"r"(programWordCommands)
! 		   : "r0", "r1", "r2", "memory");
!     }
!     return status;
!   }
!   
!   uint16_t eraseFlash(uint32_t addr)  __attribute__((noinline)){
!     uint16_t status;
!     uint32_t eraseFlashCommands[17];
! 
!     memcpy(eraseFlashCommands,__Flash_Erase,17 * 4);
!     atomic{
!       asm volatile(
! 		   "mov r1, %1;                   \
!                    mov r14, PC;			  \
! 		   mov PC, %2;			  \
! 		   mov %0, r0;"		 
! 		   :"=r"(status)
! 		   :"r"(addr), "r"(eraseFlashCommands)
! 		   : "r0", "r1", "memory");
!     }
!     return status;
!   }
!   
!   uint16_t getSR(uint32_t addr)  __attribute__((noinline)){
!     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;
!   }
! }



More information about the Tinyos-beta-commits mailing list