From 028e460924c2c9e95f5bc2b140601fee62bac07d Mon Sep 17 00:00:00 2001 From: Dan White Date: Fri, 7 Sep 2012 12:58:04 -0500 Subject: [PATCH] snapshot hacking --- msp4th/Makefile | 18 ++- msp4th/flash.py | 1 + msp4th/x.c | 179 ++++++++++++++++++----------- python-lib/flash.py | 274 ++++++++++++++++++++++++++++++++++++++++++++ python-lib/usbio.py | 57 ++++++--- 5 files changed, 440 insertions(+), 89 deletions(-) create mode 120000 msp4th/flash.py create mode 100755 python-lib/flash.py diff --git a/msp4th/Makefile b/msp4th/Makefile index dcf0b57..e377f04 100755 --- a/msp4th/Makefile +++ b/msp4th/Makefile @@ -5,23 +5,31 @@ MAIN=x.c -default: $(MAIN:.c=.hex) $(MAIN:.c=.xout) +default: $(MAIN:.c=.hex) $(MAIN:.c=.xout) $(MAIN:.c=.asm) + +all: default flash #msp430-gcc -nostartfiles -mmcu=msp430x2013 -O2 -g -Wall -Wa,-ahlms=$(<:.c=.lst) %.a43: %.c - msp430-gcc -nostartfiles -mmcu=msp430x2013 -Wall -Wa,-ahlms=$(<:.c=.lst) \ + msp430-gcc -O0 -nostartfiles -mmcu=msp430xG438 -Wall -Wa,-ahlms=$(<:.c=.lst) \ -mendup-at=main -o $@ $< -L -Xlinker -T ldscript_ns430 +%.asm: %.c + msp430-gcc -S -O0 -nostartfiles -mmcu=msp430xG438 -Wall \ + -mendup-at=main -o $@ $< + %.hex: %.a43 msp430-objcopy -O ihex $< $@ %.xout: %.a43 - #msp430-objdump -dSt $< > $@ - #msp430-objdump --disassemble-all --architecture=msp:54 $< > $@ + @#msp430-objdump -dSt $< > $@ + @#msp430-objdump --disassemble-all --architecture=msp:54 $< > $@ msp430-objdump --disassemble-all $< > $@ +flash: $(MAIN:.c=.hex) + ./flash.py $< clean: - rm -f *.a43 *.hex *.xout *.lst + rm -f *.a43 *.hex *.xout *.lst *.asm diff --git a/msp4th/flash.py b/msp4th/flash.py new file mode 120000 index 0000000..6a60bdf --- /dev/null +++ b/msp4th/flash.py @@ -0,0 +1 @@ +../python-lib/flash.py \ No newline at end of file diff --git a/msp4th/x.c b/msp4th/x.c index 4b53fe4..63ad6c6 100644 --- a/msp4th/x.c +++ b/msp4th/x.c @@ -7,14 +7,13 @@ // last update 3/9/08 #include - -#include +/*#include */ #include #include "ns430-atoi.h" #include "ns430-uart.h" -#define DEBUG_STUFF 1 // just print lots of junk +#define DEBUG_STUFF 1 // just print lots of junk #define CMD_LIST_SIZE 128 #define MATH_STACK_SIZE 16 #define ADDR_STACK_SIZE 32 @@ -28,7 +27,8 @@ // The order is important .... don't insert anything! // the order matches the execN function -const uint8_t cmdListBi[] = +/*const uint8_t cmdListBi[] = */ +const char cmdListBi[] = {"exit + - * / " // 1 -> 5 ". dup drop swap < " // 6 -> 10 "> = .hb gw dfn " // 11 -> 15 @@ -46,13 +46,14 @@ const uint8_t cmdListBi[] = // these commands are interps -const uint8_t cmdListBi2[] = {"[ : var "}; +/*const uint8_t cmdListBi2[] = {"[ : var "};*/ +const char cmdListBi2[] = {"[ : var "}; // these values point to where in progBi[] these routines start const int16_t cmdList2N[] = {0,10000,10032,10135}; // need an extra zero at the front -#define LAST_PREDEFINED 40 // update this when we add commands to the built in list +#define LAST_PREDEFINED 40 // update this when we add commands to the built in list int16_t mathStack[MATH_STACK_SIZE]; @@ -281,7 +282,7 @@ uint8_t lineBuffer[128]; /* input line buffer */ uint16_t lineBufferPtr; /* input line buffer pointer */ // uint8_t xit; /* set to 1 to kill program */ -uint8_t wordBuffer[32]; // just get a word +uint8_t wordBuffer[32]; // just get a word @@ -431,8 +432,8 @@ interrupt (4) timerInterrupt(void){ static void __inline__ delay(register unsigned int n){ __asm__ __volatile__ ( "1: \n" - " dec %[n] \n" - " jne 1b \n" + " dec %[n] \n" + " jne 1b \n" : [n] "+r"(n)); } @@ -449,7 +450,8 @@ void emit(uint8_t c){ */ int16_t i; - while ((UART0_SR & TDRE) == 0) { + /*while ((UART0_SR & TDRE) == 0) {*/ + while ((UART0_SR & (TDRE | TXEMPTY)) == 0) { // wait for register to clear i++; } @@ -472,6 +474,7 @@ uint8_t getKey(){ // wait for char } i = UART0_RDR & 0x00ff; + delay(100); return(i); } @@ -480,7 +483,7 @@ uint8_t getKey(){ void initVars(){ - uint16_t i; + uint16_t i; // I override the C startup code .... so I must init all vars. outputCharCntrN = 0; @@ -510,92 +513,119 @@ void initVars(){ uint8_t getKeyB(){ - uint8_t i; - i = lineBuffer[lineBufferPtr]; - if(i != 0) lineBufferPtr++; - return(i); + uint8_t c; + c = lineBuffer[lineBufferPtr]; + lineBufferPtr = lineBufferPtr + 1; + /*if(c != 0) lineBufferPtr++;*/ + return(c); } -void printHexByte(int16_t n); +/*void printHexByte(uint8_t n);*/ void getLine(){ - int16_t i; + uint8_t c; + int16_t flag; lineBufferPtr = 0; - emit(0x0D); - emit(0x0A); + emit('\r'); + emit('\n'); emit('>'); // this is our prompt - i = 1; - while(i){ // just hang in loop until we get CR - i = getKey(); - if(i == 0x08){ + flag = 1; + while(flag){ // just hang in loop until we get CR + c = getKey(); + emit(c); + printHexByte(c); + if(c == '\b'){ if(lineBufferPtr > 0){ - emit(0x08); emit(' '); - emit(0x08); + c = 0; + emit('\b'); lineBufferPtr--; } - } else { - emit(i); - if(i == 0x0D){ + } else if (c == '\r'){ + /*emit(c);*/ + /*if((c=='\n') || (c=='\r')){*/ + /*if(c == '\r'){*/ // hit cr lineBuffer[lineBufferPtr] = 0; - i = 0; - } else { - - lineBuffer[lineBufferPtr++] = i; + emit('\n'); + flag = 0; + } else if (c >= ' '){ + lineBuffer[lineBufferPtr++] = c; lineBuffer[lineBufferPtr] = 0; if(lineBufferPtr > 125){ // prevent overflow of line buffer - i=0; + flag = 0; } - } + } else { + // non-printable char, do nothing } } - emit(0x0A); lineBufferPtr = 0; + emit('.'); } void getWord(){ - int16_t k; - uint8_t c; + uint8_t k; + volatile uint8_t c=1; wordBuffer[0] = 0; while(wordBuffer[0] == 0){ k = 0; - c = getKeyB(); - while(( c <= ' ') && ( c != 0 )) c = getKeyB(); /* strip leading spaces */ - if( c > 0 ){ + /* + while (c != 0){ + c = getKeyB(); + emit(c); + } + */ + /* strip leading whitespace */ + while((c <= ' ') && (c != 0)){ + c = getKeyB(); + printHexByte(c); + emit(c); + } + + /* end of buffer, get more text */ + emit(c); + if(c == 0){ + wordBuffer[0] = 0; + getLine(); + } else { if( c == '"' ){ c = getKeyB(); - while((c != '"')&&(c != 0)){ - if(c != '"') wordBuffer[k++] = c; + emit(c); + while((c != '"') && (c != 0)){ + if(c != '"'){ + wordBuffer[k++] = c; + } c = getKeyB(); + emit(c); } } else { - while(c > ' ' && c != 0){ + while((c > ' ') && (c != 0)){ wordBuffer[k++] = c; c = getKeyB(); + emit(c); } } - wordBuffer[k] = 0; - } else { - wordBuffer[0] = 0; - getLine(); } } + wordBuffer[k] = 0; } -void printString(const uint8_t *c){ - while(c[0]){ - emit(c[0]); - c++; +void printString(char *c){ + uint16_t i; + emit('.'); + i = 0; + while(c[i] != 0){ + emit(c[i]); + i = i + 1; } } @@ -725,7 +755,7 @@ void luFunc(){ void numFunc(){ // the word to test is in wordBuffer int16_t i,j,n; - printString((const uint8_t *)"in numFunc()\r\n"); + printString("in numFunc()\r\n"); printString(wordBuffer); // first check for neg sign i = 0; @@ -851,24 +881,24 @@ void printNumber(int16_t n){ emit(' '); } -void printHexChar(int16_t n){ +void printHexChar(uint8_t n){ n &= 0x0F; if(n > 9){ n += 7; } n += '0'; - emit(n); + emit((uint8_t)n); } -void printHexByte(int16_t n){ +void printHexByte(uint8_t n){ n &= 0xFF; printHexChar(n >> 4); printHexChar(n); } -void printHexWord(int16_t n){ - printHexByte(n >> 8); - printHexByte(n); +void printHexWord(uint16_t n){ + printHexByte((uint8_t)(n >> 8)); + printHexByte((uint8_t)(n & 0xFF)); } void execN(int16_t n); // proto ... this could get recursive @@ -900,9 +930,9 @@ void execFunc(){ void execN(int16_t n){ int16_t i,j,k,m; int32_t x,y,z; - printString((const uint8_t *)"execN: "); + printString("execN: "); printNumber(n); - printString((const uint8_t *)"\r\n"); + printString("\r\n"); switch(n){ case 1: // xit = 1; @@ -1057,7 +1087,7 @@ void execN(int16_t n){ case 30: // num - printString((const uint8_t *)"in case 30\r\n"); + printString("in case 30\r\n"); numFunc(); break; @@ -1134,7 +1164,7 @@ void execN(int16_t n){ j = popAddrStack(); // loop address k = popAddrStack(); // count m = popAddrStack(); // limit - k++; // up the count + k++; // up the count if(k >= m){ // we are done } else { @@ -1280,7 +1310,7 @@ void processLoop(){ // this processes the forth opcodes. while(1){ - printString((const uint8_t *)"processLoop()\r\n"); + printString("processLoop()\r\n"); if(progCounter > 9999){ opcode = progBi[progCounter - 10000]; } else { @@ -1316,16 +1346,33 @@ int main(void){ /* 8e6 / (16*19200) - 1 = 25.0416 */ /* 8e6 / (16*2400) - 1 = 207.33 */ - UART0_BCR = 207; + /* 25e6 / (16*2400) - 1 = 207.33 */ + UART0_BCR = 324; UART0_CR = UARTEn; - emit(0x00); + dint(); + emit('!'); + + while (1) { + uint8_t c; + c = getKey(); + if (c == '`') break; + emit(c); + } + emit('t'); + emit('e'); + emit('s'); + emit('t'); + emit('i'); + emit('n'); + emit('g'); + printString("This is a test of the UART serial printing\r\nit really does work ...\r\n"); // xit = 0; addrStackPtr = ADDR_STACK_SIZE; // this is one past the end !!!! as it should be progCounter = 10000; - progPtr = 1; // this will be the first opcode + progPtr = 1; // this will be the first opcode i=0; cmdListPtr = 0; cmdList[0] = 0; diff --git a/python-lib/flash.py b/python-lib/flash.py new file mode 100755 index 0000000..7d923c7 --- /dev/null +++ b/python-lib/flash.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python + +import sys +import optparse +from intelhex import IntelHex +from myhdl import intbv +import mpsse + + +parser = optparse.OptionParser() + +parser.add_option('-e', '--erase', dest='erase', default=False, + action='store_true', help='Erase flash contents first') + +parser.add_option('-v', '--verify', dest='verify', default=False, + action='store_true', help='Verify contents with ihex file') + +parser.add_option('-p', '--program', dest='program', default=False, + action='store_true', help='Verify contents with ihex file') + +(opt, args) = parser.parse_args() + +# +# helpers +# + +def str2hex(x): + return ''.join(map(lambda h: '%02x' % ord(h), x)) + +def int2str(value, width): + if (width % 8) != 0: + raise Exception, 'width must be multiple of 8' + v = intbv(value, max=2**width) + b = [v[i:i-8] for i in range(width, 0, -8)] + return ''.join(map(chr, b)) + + +# +# old libmpsse based code +# +class AtoiSPI0(mpsse.MPSSE): + def __init__(self, freq): + super(AtoiSPI0, self).__init__() + self._freq = int(freq) + self.Open(0x0403, 0x6011, mpsse.SPI1, int(freq), + interface=mpsse.IFACE_A) + self._cs = None + self._cs_mode = { + 'flash': mpsse.SPI0, + 'dac': mpsse.SPI1, + 'adc': mpsse.SPI1, + 'convst': mpsse.SPI1, + } + + def SetCS(self, name): + """Setup the chip-select pins for a given 'name'.""" + if name == self._cs: + return + + if name not in self._cs_mode: + raise Exception, 'Unknown CS name: %s' % name + + # different SPI modes require restarting the bus for some reason + if self.context.mode != self._cs_mode[name]: + self.Close() + self.Open(0x0403, 0x6011, + self._cs_mode[name], + self._freq, + interface=mpsse.IFACE_A) + + if name == 'flash': + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xc0 + elif name == 'dac': + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xd8 + elif name == 'adc': + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xe8 + elif name == 'convst': + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xf8 + else: + raise Exception, 'Unknown CS name: %s' % name + + self._cs = name + + +# old code +class M25PExx(object): + def __init__(self, spibus): + self.bus = spibus + + def _write(self, data): + self.bus.SetCS('flash') + self.bus.Start() + self.bus.Write(data) + self.bus.Stop() + + def _exchange(self, data): + self.bus.SetCS('flash') + self.bus.Start() + d = self.bus.Exchange(data) + self.bus.Stop() + return d + + def writeEnable(self, enable): + if enable: + x = '\x06' + else: + x = '\x04' + self._write(x) + + def id(self): + d = self._exchange('\x9f' + 3*'\x00') + return d[1:] + + def status(self): + d = self._exchange('\x05\x00') + return ord(d[1]) + + def read(self, addr, n): + a = int2str(addr, 3*8) + while not self.isReady(): + pass + d = self._exchange('\x03' + a + n*'\x00') + return d[4:] + + def fastRead(self, addr, n): + a = int2str(addr, 3*8) + while not self.isReady(): + pass + d = self._exchange('\x0b' + a + n*'\x00') + return d[4:] + + def writePage(self, addr, data): + if ((addr & 0xff) + len(data)) > 256: + raise Exception, 'Too much data: %i' % len(data) + a = int2str(addr, 3*8) + while not self.isReady(): + pass + self._write('\x0a' + a + data) + + def programPage(self, addr, data): + if ((addr & 0xff) + len(data)) > 256: + raise Exception, 'Too much data: %i' % len(data) + a = int2str(addr, 3*8) + while not self.isReady(): + pass + self._write('\x02' + a + data) + + def erasePage(self, addr): + if (addr & 0xff) != 0: + raise Exception, 'Address must be a page boundary: %i' % addr + while not self.isReady(): + pass + self._write('\xdb' + a) + + def eraseAll(self): + while not self.isReady(): + pass + self._write('\xc7') + + def power(self, on): + if on: + self._write('\xab') + else: + self._write('\xb9') + + def isReady(self): + return (self.status() & 0x01) == 0 + + def write(self, addr, data): + if addr & 0xff != 0: + raise Exception, 'Address must start on a page boundary (0x....00).' + + n = len(data) + nPages = (n // 256) + 1 + for i in range(nPages): + s = i * 256 + e = min(s+256, len(data)) + a = addr + s + while not self.isReady(): + print hex(self.status()) + print 'writing page: %06x %s' % (a, str2hex(data[s:e])) + self.writeEnable(True) + self.writePage(a, data[s:e]) + print hex(self.status()) + + def program(self, addr, data): + if addr & 0xff != 0: + raise Exception, 'Address must start on a page boundary (0x....00).' + + n = len(data) + nPages = (n // 256) + 1 + for i in range(nPages): + s = i * 256 + e = min(s+256, len(data)) + a = addr + s + while not self.isReady(): + pass + self.programPage(a, data[s:e]) + + + + +spi0 = AtoiSPI0(1000e3) #port A + +############################################################################## +# Flash testing +# +#flash = M25PExx(spi0, 'flash') +flash = M25PExx(spi0) +flash.power(True) +print flash.status() +print 'id:', str2hex(flash.id()) +print flash.status() +print 'data:', str2hex(flash.read(0x4000, 16)) + +flash.writeEnable(True) +if opt.erase: + flash.eraseAll() + print 'erasing', + while not flash.isReady(): + print '.', + print + +#h = IntelHex('../msp4th/hello-world.hex') +#h = IntelHex('../msp4th/x.hex') +h = IntelHex(args[0]) + +#code space in RAM, only get/send used block of bytes +a = [a for a in h.addresses() if (a >= 0x4000 and a < 0xff00)] +alen = max(a) - min(a) + 1 +#alen = 32 +code = h.gets(0x4000, alen) +if 1: + flash.writeEnable(True) + flash.write(min(a), code) + +# 0xffd0 -- 0xffff are interrupt vectors +# gcc et.al. for some reason do not give a value for 0xfffe word +# the flash loader in ROM jumps to addr pointed here +# force to start of RAM +# +# the flash uses 256-byte pages, include code from 0xff00 - 0xffcf +# as it was excluded above + vectors = ''.join([chr(h[i]) for i in range(0xff00, 0x10000-2)]) + vectors += '\x00\x40' + flash.write(0xff00, vectors) + +while not flash.isReady(): + print 'waiting...' + +if 1: + nread = 0 + c2 = '' + while nread < len(code): + nr = min(256, len(code)-nread) + c = flash.read(0x4000 + nread, nr) + c2 += c + print 'read: %06x %s' % (0x4000+nread, str2hex(c)) + nread += nr + + print len(code), len(c2) + if 0: + for i in range(len(code)): + print i, code[i] == c2[i] + print len(code), len(c2) + print str2hex(code[-4:]), str2hex(c2[-4:]) + print all([code[i] == c2[i] for i in range(len(code))]) + +print str2hex(code[:4]) +print str2hex(c2[:4]) diff --git a/python-lib/usbio.py b/python-lib/usbio.py index 8e8fdbc..67c83ca 100644 --- a/python-lib/usbio.py +++ b/python-lib/usbio.py @@ -399,7 +399,7 @@ class SPI(object): raise Exception, self.ftdi.get_error_string(self.context) r += s #NOTE: including ftdi.SEND_IMMEDIATE commands make this redundant - #self.ftdi.usb_purge_rx_buffer(self.context) + self.ftdi.usb_purge_rx_buffer(self.context) return r def set_freq(self, freq): @@ -450,7 +450,7 @@ class SPI(object): self._pindir |= self.cs['_mask'][1] # chip-select pins are always outputs self._pindir &= 0xFB # pin 2/DI is an input for sure # most implementations force pin 3/CS to an output, IT DOES NOT - # NEED DO BE. The top 5 pins are available for GPIO, CS, or both + # NEED TO BE. The top 5 pins are available for GPIO, CS, or both # in SPI mode. With a 5-bit one-cold decoder, we can control up to # (2**5 - 1) = 31 chips with this port. @@ -463,6 +463,7 @@ class SPI(object): else: self._pinstate = pinstate + #print 'set pins: %02x, %02x' % (self._pinstate, self._pindir) cmd = chr(self.ftdi.SET_BITS_LOW) + chr(self._pinstate) + chr(self._pindir) self._raw_write(cmd) @@ -493,19 +494,30 @@ class SPI(object): mode, pins = self.cs[device] # set SK before asserting CS to not violate timing - if True: + if False: # first, ensure SK starts in the correct state p = self._pinstate - if mode in (0, 1): + #if mode == 0: + #p &= 0xfe + #elif mode == 1: + #p |= 0x01 + if mode == 0: + #p |= 0x01 + p &= 0xfe + elif mode == 1: p |= 0x01 elif mode in (2, 3): p &= 0xfe cmd = chr(self.ftdi.SET_BITS_LOW) + chr(p) + chr(self._pindir) + #print 'set pins: %02x, %02x' % (self._pinstate, self._pindir) + #print '%s; mask %02x, mode %02x, pins %02x' % (device, mask, mode, pins) + #print 'pins: %02x' % p p &= ~mask p += pins & mask self._pinstate = p cmd += chr(self.ftdi.SET_BITS_LOW) + chr(p) + chr(self._pindir) + #print 'set pins: %02x, %02x' % (self._pinstate, self._pindir) # old behavior: set CS and SK in same command else: p = self._pinstate & ~mask @@ -580,6 +592,7 @@ class SPI(object): self._write_cmd(device, data) + self._cs_cmd_cache['_idle']) self._raw_write(cmd) + #print 'write to %s: %s' % (device, str2hex(data)) def read(self, device, n): """Read data from the selected device, DO pin stays in its last @@ -600,7 +613,10 @@ class SPI(object): self._exchange_cmd(device, data) + self._cs_cmd_cache['_idle']) self._raw_write(cmd) - return self._raw_read(len(data)) + #print 'exchange %s: %s' % (device, str2hex(data)) + r = self._raw_read(len(data)) + #print ' ', str2hex(r) + return r @@ -1429,20 +1445,24 @@ class ADS8201(object): class M25PExx(object): - def __init__(self, spibus): + def __init__(self, spibus, csname): self.bus = spibus + self.csname = csname def _write(self, data): - self.bus.SetCS('flash') - self.bus.Start() - self.bus.Write(data) - self.bus.Stop() + self.bus.write(self.csname, data) + #self.bus.SetCS('flash') + #self.bus.Start() + #self.bus.Write(data) + #self.bus.Stop() def _exchange(self, data): - self.bus.SetCS('flash') - self.bus.Start() - d = self.bus.Exchange(data) - self.bus.Stop() + d = self.bus.exchange(self.csname, data) + #self.bus.SetCS('flash') + #self.bus.Start() + #d = self.bus.Exchange(data) + #self.bus.Stop() + #print str2hex(d) return d def writeEnable(self, enable): @@ -1522,11 +1542,12 @@ class M25PExx(object): e = min(s+256, len(data)) a = addr + s while not self.isReady(): - print hex(self.status()) + pass + #print hex(self.status()) print 'writing page: %06x %s' % (a, str2hex(data[s:e])) self.writeEnable(True) self.writePage(a, data[s:e]) - print hex(self.status()) + #print hex(self.status()) def program(self, addr, data): if addr & 0xff != 0: @@ -1551,14 +1572,14 @@ class AtoiSPI0(SPI): interface=ftdi.INTERFACE_A, cs={'_idle': (-1, 0xc8), '_mask': (-1, 0x38), #TODO - 'flash': (0, 0xc0), + 'flash': (3, 0xc0), 'dac': (1, 0xd8), 'adc': (1, 0xe8), 'convst': (1, 0xf8)}, freq=int(freq), vid=0x0403, pid=0x6011, - pindir=0xc0, + pindir=0xc8, pinstate=0xc8, latency=1 ) -- 2.25.1