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
--- /dev/null
+../python-lib/flash.py
\ No newline at end of file
// last update 3/9/08
#include <signal.h>
-
-#include <io.h>
+/*#include <io.h>*/
#include <iomacros.h>
#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
// 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
// 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];
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
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));
}
*/
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++;
}
// wait for char
}
i = UART0_RDR & 0x00ff;
+ delay(100);
return(i);
}
void initVars(){
- uint16_t i;
+ uint16_t i;
// I override the C startup code .... so I must init all vars.
outputCharCntrN = 0;
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;
}
}
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;
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
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;
case 30: // num
- printString((const uint8_t *)"in case 30\r\n");
+ printString("in case 30\r\n");
numFunc();
break;
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 {
while(1){
- printString((const uint8_t *)"processLoop()\r\n");
+ printString("processLoop()\r\n");
if(progCounter > 9999){
opcode = progBi[progCounter - 10000];
} else {
/* 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;
--- /dev/null
+#!/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])
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):
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.
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)
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
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
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
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):
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:
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
)