[Tinyos-beta-commits] CVS: tinyos-1.x/beta/platform/imote2
binarymover.s, NONE, 1.1 TrickleC.nc, NONE, 1.1 TrickleM.nc,
NONE, 1.1
Josh
jsherbach at users.sourceforge.net
Tue Aug 30 17:41:27 PDT 2005
Update of /cvsroot/tinyos/tinyos-1.x/beta/platform/imote2
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2983
Added Files:
binarymover.s TrickleC.nc TrickleM.nc
Log Message:
iMote2 Boot loader components
--- NEW FILE: binarymover.s ---
@@@@@@@@@@@@@@@@@@@@@@@@@
@ to create an assembly function that confirms to AAPCS (or so I think o)
@ .func function name
@ STMFD R13!, {R4 - R12, LR}..alternatively STMFD R13!, {registers used, LR}
@ {function body}
@ LDMFD R13!, {R4 - R12, PC}...must match above with LR replaced by PC
@ .endfunc
@@@@@@@@@@@@@@@@@@@@@@@@@@
.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)
.equ ARM_CPSR_INT_MASK,(0xC0)
.global __Binary_Mover
.global __Binary_Mover_true_end
__Binary_Mover:
.func __Binary_Mover @r0 = addr
@r1 = size
ldr r5,=ARM_CPSR_INT_MASK @Store int mask value
mrs r4,CPSR @Store Core Program Status Reg
orr r4,r4,r5 @Add int mask
msr CPSR,r4 @Replaces previous CPSR value
ldr r5,=0x40000000
add r5,r5,#0xe00000
add r5,r5,#0x0100
add r5,r5,#0x0c @r5 contains 0x40e0 010c, address of GPDR3
ldr r6,[r5]
ldr r7,=0x7
orr r6,r6,r7,LSL #7
str r6,[r5] @should set GPIO 103-105 to output
ldr r6,=0x18 @offset between GPDR3 and GPCR3
add r5,r5,r6 @r5 contains 0x40e0 0124
ldr r6,=0x3
mov r6,r6,LSL #7
str r6,[r5]
ldr r4,=0x0 @Counter
cmp r4,r1
beq __Binary_Mover_end @If imagesize is 0 then skip a bunch of stuff
ldr r5,=0x200000
ldr r7,=0x2000000 @Final flash addr 0x0200 0000
@preset all partitions to ReadArray
__Binary_Mover_RA_setup:
ldr r6,=FLASH_READARRAY
strh r6,[r4] @Readarray
ldrh r6,[r4] @Latch?
add r4,r4,r5 @Increment
cmp r4,r7
blo __Binary_Mover_RA_setup @Repeat
ldr r4,=0x0 @Counter
ldr r5,=0x8000 @Block size 0x0000 8000 initially...moves up to 0x0002 0000
__Binary_Mover_Erase_loop:
ldr r6,=FLASH_CLEARSTATUS @Unlock block
strh r6,[r4] @Clear Status
ldr r6,=FLASH_DLOCKBLOCK
strh r6,[r4] @Change lock
ldr r6,=FLASH_UNLOCKCONF
strh r6,[r4] @Confirm Unlock
ldr r6,=FLASH_READARRAY
strh r6,[r4] @Return to read array
ldrh r6,[r4] @latch?
ldr r6,=FLASH_CLEARSTATUS
strh r6,[r4] @Clear Status register
ldr r6,=FLASH_ERASEBLOCK
strh r6,[r4] @Send EraseBlock command
ldr r6,=FLASH_ERASECONF
strh r6,[r4] @Confirm Erase Block
EraseBlockSpin:
ldrh r6,[r4] @Read Block Status
and r6,r6,#0x80
cmp r6,#0x0 @Check if Erase is complete
beq EraseBlockSpin @Spin if not complete
ldr r6,=FLASH_READARRAY
strh r6,[r4] @Set Block back to normal read mode
ldrh r6,[r4] @latch?
add r4,r4,r5 @Increment to next block
ldr r6,=0x20 @Check if Block size needs to increase
mov r6,r6,LSL #0xc @starting address for larger size
cmp r4,r6
bne __Binary_Mover_Erase_loop_end @if r4!=r6 continue
mov r5,r5,LSL #0x2 @Times 4 making 0x8000 become 0x2 0000
__Binary_Mover_Erase_loop_end:
cmp r4,r1
blo __Binary_Mover_Erase_loop @Repeat
ldr r4,=0x0 @Reset counter for writing
__Binary_Mover_Write_loop:
ldrh r6,[r0, r4] @Get data
ldr r5,=FLASH_CLEARSTATUS @Write word start
strh r5,[r4] @Clear Status register
ldr r5,=FLASH_PROGRAMWORD
strh r5,[r4] @Send Program Word Command
strh r6,[r4] @Write Word
WriteWordSpin:
ldrh r5,[r4] @Read Block Status
and r5,r5,#0x80
cmp r5,#0x0 @Check if Write is complete
beq WriteWordSpin @Spin if not complete
ldr r5,=FLASH_READARRAY
strh r5,[r4] @Set Block back to normal read mode
ldrh r5,[r4] @Word written
add r4,r4,#0x2 @Increment Counter
cmp r4,r1
blo __Binary_Mover_Write_loop @Repeat
__Binary_Mover_end:
ldr r5,=0x40000000
add r5,r5,#0xa00000
add r5,r5,#0x18 @r5 contains 0x40a0 0018, OWER
ldr r6,=0x1
str r6,[r5] @enables watchdog timer reset
sub r5,r5,#0xC @r5 contains 0x40a0 000c OSMR3
add r4,r5,#0x4 @r4 contains 0x40a0 0010 OSCR0
ldr r6,[r4]
add r6,r6,#0x1000
str r6,[r5] @osmr3 = oscr0 + 0x1000
__Binary_Mover_spin:
b __Binary_Mover_spin @spin until watchdog timer resets this
ldr PC,=0x0 @Reset
__Binary_Mover_true_end:
nop
.endfunc
--- NEW FILE: TrickleC.nc ---
configuration TrickleC {
provides interface StdControl as Control;
}
implementation {
components
TrickleM,
HPLUSBClientC,
FlashC;
Control = TrickleM;
TrickleM.ReceiveBData -> HPLUSBClientC;
TrickleM.SendJTPacket -> HPLUSBClientC;
TrickleM.Flash -> FlashC;
}
--- NEW FILE: TrickleM.nc ---
module TrickleM {
provides interface StdControl as Control;
uses{
interface Flash;
interface ReceiveBData;
interface SendJTPacket;
}
}
implementation {
int sprintf(char *, const char *, ...) __attribute__ ((C, spontaneous));
extern void __Binary_Mover() __attribute__ ((C,spontaneous));
extern uint32_t __Binary_Mover_true_end __attribute__ ((C));
#include "Flash.h"
#include "PXA27XUSBClient.h"
void verifyData(uint32_t addr, uint32_t numBytes);
void reboot(uint32_t imageAddr, uint32_t imageSize);
uint32_t startWriteAddr, lastWriteAddr, busy = 0;
command result_t Control.init() {
return SUCCESS;
}
command result_t Control.start() {
return SUCCESS;
}
command result_t Control.stop() {
return SUCCESS;
}
void verifyData(uint32_t addr, uint32_t numBytes){
atomic busy = 1;
call SendJTPacket.send((uint8_t *)addr, numBytes,
IMOTE_HID_TYPE_CL_BINARY);
}
event result_t SendJTPacket.sendDone(uint8_t* packet, uint8_t type, result_t success){
uint8_t impType = IMOTE_HID_TYPE_CL_BINARY |
(IMOTE_HID_TYPE_MSC_BLOADER << IMOTE_HID_TYPE_MSC);
if((type & impType) == impType)
free(packet);
return SUCCESS;
}
event result_t ReceiveBData.receive(uint8_t* buffer, uint8_t numBytesRead,
uint32_t i, uint32_t n, uint8_t type){
uint32_t j;
if((type >> IMOTE_HID_TYPE_MSC) == IMOTE_HID_TYPE_MSC_BLOADER){
switch(buffer[0]){
case 0:
startWriteAddr = (buffer[1] << 24) | (buffer[2] << 16) |
(buffer[3] << 8) | buffer[4];
break;
case 1:
atomic busy = 0;
break;
case 2:
reboot((buffer[1] << 24) | (buffer[2] << 16) | (buffer[3] << 8) |
buffer[4],
(buffer[5] << 24) | (buffer[6] << 16) | (buffer[7] << 8) |
buffer[8]);
break;
}
return SUCCESS;
}
if(busy == 1)
return SUCCESS;
if(i == 0){
for(j = 0; j < numBytesRead * (n + 1); j += FLASH_BLOCK_SIZE)
call Flash.erase(startWriteAddr + j);
lastWriteAddr = startWriteAddr;
}
call Flash.write(lastWriteAddr, buffer, numBytesRead, FLASH_NORMAL);
lastWriteAddr += numBytesRead;
if(i % 5 == 0 || i - n < 5){
if(n==i){
uint8_t *temp = (uint8_t *)malloc(4);
*(uint32_t *)temp = i;
call SendJTPacket.send(temp, 4, IMOTE_HID_TYPE_CL_BINARY |
(IMOTE_HID_TYPE_MSC_BLOADER <<
IMOTE_HID_TYPE_MSC));
verifyData(startWriteAddr, lastWriteAddr - startWriteAddr);
}
else{
uint8_t *temp = (uint8_t *)malloc(4);
*(uint32_t *)temp = i;
call SendJTPacket.send(temp, 4, IMOTE_HID_TYPE_CL_BINARY |
(IMOTE_HID_TYPE_MSC_BLOADER <<
IMOTE_HID_TYPE_MSC));
}
}
return SUCCESS;
}
void reboot(uint32_t imageAddr, uint32_t imageSize){
uint32_t binSize = (uint32_t)&__Binary_Mover_true_end;
uint8_t *rebootBinary;
binSize -= (uint32_t)__Binary_Mover;
rebootBinary = (uint8_t *)malloc(binSize);
memcpy(rebootBinary, __Binary_Mover, binSize);
asm volatile(
"mov r0,%0; \
mov r1,%1; \
mov PC,%2"
:/*no output*/
:"r"(imageAddr), "r"(imageSize), "r"(rebootBinary));
/*everything is clobbered*/
}
}
More information about the Tinyos-beta-commits
mailing list