diff --git a/Makefile b/Makefile index 6337154cb..7c3873052 100644 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ ALL = $(TESTS:.c=.srec) $(TESTS:.c=.bin) $(TESTS:.c=.dis) all: src/start.o src/isr.o $(ALL) +tests/flasher.obj: src/maca.o src/nvm.o tests/nvm-read.obj: src/maca.o src/nvm.o tests/nvm-write.obj: src/maca.o src/nvm.o tests/rftest-rx.obj: src/maca.o src/nvm.o diff --git a/mc1322x-load.pl b/mc1322x-load.pl index b5b4a5391..2863a39b3 100755 --- a/mc1322x-load.pl +++ b/mc1322x-load.pl @@ -7,11 +7,13 @@ use Getopt::Long; use strict; my $filename = ''; +my $second = ''; my $term = '/dev/ttyUSB0'; my $baud = '115200'; my $verbose; -GetOptions ('file=s' => \$filename, +GetOptions ('file=s' => \$filename, + 'secondfile=s' => \$second, 'terminal=s' => \$term, 'verbose' => \$verbose, 'baud=s' => \$baud); @@ -20,7 +22,9 @@ $| = 1; if($filename eq '') { print "Example usage: mc1322x-load.pl -f foo.bin -t /dev/ttyS0 -b 9600\n"; + print " or : mc1322x-load.pl -f flasher.bin -s flashme.bin\n"; print " -f required: binary file to load\n"; + print " -s optional: secondary binary file to send\n"; print " -t default: /dev/ttyUSB0\n"; print " -b default: 115200\n"; exit; @@ -29,7 +33,7 @@ if($filename eq '') { my $ob = Device::SerialPort->new ($term) or die "Can't start $term\n"; # next test will die at runtime unless $ob -$baud = 115200 if (!defined($baud)); +if(($filename eq '')) die "you must specify a file with -f\n"; $ob->baudrate($baud); $ob->parity('none'); @@ -37,36 +41,55 @@ $ob->databits(8); $ob->stopbits(1); $ob->handshake("rts"); -my $c; +my $s = 0; -$ob->write(pack('C','0')); + SEND: + do { + + my $c; -my $ret = ''; -until($ret eq 'CONNECT') { - $c = $ob->input; - $ret .= $c; -} -print $ret . "\n"; + if($s == 1) { print "performing secondary send\n"; } + + $ob->write(pack('C','0')); + + my $ret = ''; + my $test; + if($s == 1) { + $test = 'ready'; + } else { + $test = 'CONNECT'; + } -if (defined $filename) { + until($ret eq $test) { + $c = $ob->input; + $ret .= $c; + } + print $ret . "\n"; + + + if (defined $filename) { + + my $size = -s $filename; + + print ("Size: $size bytes\n"); + $ob->write(pack('V',$size)); + + open(FILE, $filename) or die($!); + print "Sending $filename\n"; + + my $i = 1; + while(read(FILE, $c, 1)) { + print unpack('H',$c) . unpack('h',$c) if $verbose; + print "\n" if ($verbose && ($i%4==0)); + $i++; + select undef, undef, undef, 0.001; + $ob->write($c); + } + } - my $size = -s $filename; - - print ("Size: $size bytes\n"); - $ob->write(pack('V',$size)); - - open(FILE, $filename) or die($!); - print "Sending $filename\n"; - - my $i = 1; - while(read(FILE, $c, 1)) { - print unpack('H',$c) . unpack('h',$c) if $verbose; - print "\n" if ($verbose && ($i%4==0)); - $i++; - select undef, undef, undef, 0.001; - $ob->write($c); - } + if(-e $second) {$s=1; $filename = $second; continue SEND; } + } print "done.\n"; diff --git a/tests/flasher.c b/tests/flasher.c new file mode 100644 index 000000000..1bd01ea77 --- /dev/null +++ b/tests/flasher.c @@ -0,0 +1,165 @@ +#define GPIO_FUNC_SEL0 0x80000018 /* GPIO 15 - 0; 2 bit blocks */ + +#define BASE_UART1 0x80005000 +#define UART1_CON 0x80005000 +#define UART1_STAT 0x80005004 +#define UART1_DATA 0x80005008 +#define UR1CON 0x8000500c +#define UT1CON 0x80005010 +#define UART1_CTS 0x80005014 +#define UART1_BR 0x80005018 + +#define GPIO_PAD_DIR0 0x80000000 +#define GPIO_DATA0 0x80000008 + +#include "embedded_types.h" +#include "nvm.h" +#include "maca.h" + +#define reg(x) (*(volatile uint32_t *)(x)) + +#define DELAY 400000 + +void putc(uint8_t c); +void puts(uint8_t *s); +void put_hex(uint8_t x); +void put_hex16(uint16_t x); +void put_hex32(uint32_t x); +uint8_t getc(); + +const uint8_t hex[16]={'0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f'}; + +#include "isr.h" + +#define NBYTES 8 +#define WRITE_ADDR 0x1e000 +//#define WRITE_ADDR 0x0 +#define WRITEVAL0 0x00000001 +#define WRITEVAL1 0x00000000 + +__attribute__ ((section ("startup"))) +void main(void) { + nvmType_t type=0; + nvmErr_t err; + uint8_t c; + uint32_t buf[NBYTES/4]; + uint32_t i; + uint32_t len=0; + + *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000100; + + /* Restore UART regs. to default */ + /* in case there is still bootloader state leftover */ + + reg(UART1_CON) = 0x0000c800; /* mask interrupts, 16 bit sample --- helps explain the baud rate */ + + /* INC = 767; MOD = 9999 works: 115200 @ 24 MHz 16 bit sample */ + #define INC 767 + #define MOD 9999 + reg(UART1_BR) = INC<<16 | MOD; + + /* see Section 11.5.1.2 Alternate Modes */ + /* you must enable the peripheral first BEFORE setting the function in GPIO_FUNC_SEL */ + /* From the datasheet: "The peripheral function will control operation of the pad IF */ + /* THE PERIPHERAL IS ENABLED. */ + reg(UART1_CON) = 0x00000003; /* enable receive and transmit */ + reg(GPIO_FUNC_SEL0) = ( (0x01 << (14*2)) | (0x01 << (15*2)) ); /* set GPIO15-14 to UART (UART1 TX and RX)*/ + + vreg_init(); + +// puts("CRM status: 0x"); +// put_hex32(reg(0x80003018)); +// puts("\n\r"); + + puts("Detecting internal nvm\n\r"); + + err = nvm_detect(gNvmInternalInterface_c, &type); + + puts("nvm_detect returned: 0x"); + put_hex(err); + puts(" type is: 0x"); + put_hex32(type); + puts("\n\r"); + + + /* erase the flash */ + err = nvm_erase(gNvmInternalInterface_c, type, 0x4fffffff); + puts("nvm_erase returned: 0x"); + put_hex(err); + puts("\n\r"); + + /* say we are ready */ +ready: + len = 0; + puts("ready"); + + /* read the length */ + for(i=0; i<4; i++) { + c = getc(); + /* bail if the first byte of the length is zero */ + if((i==0) && (c==0)) goto ready; + len += (len<<(i*8)); + puts("len: "); + put_hex32(len); + puts("\n\r"); + } + + /* write the OKOK magic */ + buf[0] = 'O'; buf[1] = 'K'; buf[2] = 'O'; buf[3] = 'K'; + err = nvm_write(gNvmInternalInterface_c, type, (uint8_t *)buf, 0, 4); + + /* read a byte, write a byte */ + /* byte at a time will make this work as a contiki process better */ + /* for OTAP */ + for(i=0; i> 4]); + putc(hex[x & 15]); +} + +void put_hex16(uint16_t x) +{ + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} + +void put_hex32(uint32_t x) +{ + put_hex((x >> 24) & 0xFF); + put_hex((x >> 16) & 0xFF); + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +}