initial merge of donbfet code, sans changes to monitor/avr/spi
authordonb127 <donb127@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 18 Oct 2011 16:12:43 +0000 (16:12 +0000)
committerdonb127 <donb127@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 18 Oct 2011 16:12:43 +0000 (16:12 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1053 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

firmware/Makefile
firmware/apps/jscan/jscan.c [new file with mode: 0644]
firmware/goodfet.c
firmware/include/avr.h
firmware/include/command.h
firmware/include/jscan.h [new file with mode: 0644]
firmware/include/spi.h
firmware/lib/atmega1284p.c [new file with mode: 0644]
firmware/lib/atmega644p.c [new file with mode: 0644]
firmware/platforms/donbfet.h [new file with mode: 0644]

index d25bab4..fbf5a33 100644 (file)
@@ -9,6 +9,12 @@
 #platform?=tilaunchpad
 platform?=goodfet
 
+# donb 
+ifeq ($(platform),donbfet)
+GCC?=avr-gcc
+mcu?=atmega644p
+CFLAGS=$(DEBUG) -mmcu=$(mcu) -W -Os -mcall-prologues -Wall -Wextra -Wuninitialized -fpack-struct -fshort-enums -funsigned-bitfields
+endif
 
 ifeq ($(platform),tilaunchpad)
 mcu?=msp430x1612
@@ -119,6 +125,11 @@ else
 config ?= monitor chipcon spi jtag430 jtag430x2 avr openocd ccspi
 endif
 
+# donb 
+ifeq ($(platform),donbfet)
+config=monitor avr spi jscan
+endif
+
 # Build the needed list of app and lib object files from the config
 apps= 
 
@@ -323,6 +334,12 @@ ifeq ($(filter ps2, $(config)), ps2)
        hdrs+= ps2.h
 endif
 
+# include jscan app
+ifeq ($(filter jscan, $(config)), jscan)
+       apps+= apps/jscan/jscan.o
+       hdrs+= jscan.h
+endif
+
 # Rules
 
 app= goodfet
@@ -372,8 +389,14 @@ erase:
        $(MSP430BSL) -e 
 $(app).c: config builddate appsfiles err
 $(app): $(libs) $(apps)
+
+ifeq ($(platform),donbfet)
+$(app).hex: $(app)
+       avr-objcopy -j .text -j .data -O ihex goodfet goodfet.hex
+else
 $(app).hex: $(app)
        msp430-objcopy goodfet -O ihex goodfet.hex
+endif
 m4s: $(app).hex
        msp430-objdump -D -m msp430 $(app).hex | m4s init
 clean:
diff --git a/firmware/apps/jscan/jscan.c b/firmware/apps/jscan/jscan.c
new file mode 100644 (file)
index 0000000..896a05f
--- /dev/null
@@ -0,0 +1,646 @@
+/*! \file jscan.c
+  \author Don A. Bailey
+  \brief JTAG Scanner
+*/
+
+/* set tabstop=8 */
+
+#include "platform.h"
+#include "command.h"
+
+#if (platform != donbfet)
+# include <signal.h>
+# include <io.h>
+# include <iomacros.h>
+#endif
+
+#include "jscan.h"
+
+#define OFFSETIO 32
+#define NPATTERN 64
+
+typedef struct Pin Pin;
+
+struct
+Pin
+{
+       Pin * next;
+       Pin * prev;
+       uint8_t id;
+       uint8_t bit;
+       uint8_t pullup;
+       volatile uint8_t * ddr;
+       volatile uint8_t * pin;
+       volatile uint8_t * port;
+};
+
+static Pin * pins;
+static int nfound;
+static uint8_t found[CMDDATALEN];
+static char * tap_shiftir = "1111101100";
+static uint8_t xdelay = JSCAN_DEFAULT_DELAY;
+static uint8_t endian = JSCAN_ENDIAN_LITTLE;
+static char pattern[NPATTERN] = "0110011101001101101000010111001001";
+
+static void jscan(uint8_t, uint8_t, uint32_t);
+
+static uint8_t setdelay(uint32_t);
+static uint8_t setpullup(uint32_t);
+static uint8_t setendian(uint32_t);
+
+static uint8_t npins(void);
+static void listpin(uint8_t);
+static uint8_t addpin(Pin * );
+static uint8_t rmpin(uint32_t);
+static uint8_t newpin(uint32_t);
+static uint8_t findpin(uint8_t, Pin ** );
+
+static void scan(uint8_t);
+static void loopback(uint8_t);
+static void getresults(uint8_t);
+static void clockstrobe(Pin * );
+static void tdipulse(Pin *, Pin *, uint8_t);
+static void tapstate(char *, Pin *, Pin * );
+static void initpins(Pin *, Pin *, Pin *, Pin *, Pin * );
+static int checkdata(char *, int, Pin *, Pin *, Pin *, int * );
+
+app_t const 
+jscan_app = 
+{
+       JSCAN,
+       jscan,
+       "JSCAN",
+       "\tThe JScan app adds support for JTAG brute-force scanning.\n"
+};
+
+static void 
+jscan(uint8_t a, uint8_t v, uint32_t l)
+{
+       switch(v)
+       {
+       case JSCAN_CMD_ADDPIN:
+               txdata(a, newpin(l), 1);
+               break;
+       case JSCAN_CMD_RMPIN:
+               txdata(a, rmpin(l), 1);
+               break;
+       case JSCAN_CMD_DELAY:
+               txdata(a, setdelay(l), 1);
+               break;
+       case JSCAN_CMD_PULLUP:
+               txdata(a, setpullup(l), 0);
+               break;
+       case JSCAN_CMD_LOOPBACK:
+               loopback(a);
+               break;
+       case JSCAN_CMD_ENDIAN:
+               txdata(a, setendian(l), 1);
+               break;
+       case JSCAN_CMD_SCAN:
+               scan(a);
+               break;
+       case JSCAN_CMD_LISTPIN:
+               listpin(a);
+               break;
+       case JSCAN_CMD_RESULTS:
+               getresults(a);
+               break;
+       default:
+               debugstr("Verb unimplemented in JSCAN application.");
+               txdata(a, NOK, 0);
+               break;
+       }
+}
+
+static uint8_t
+npins(void)
+{
+       uint8_t x;
+       Pin * p;
+
+       x = 0;
+       p = pins;
+       while(p)
+       {
+               p = p->next;
+               x++;
+       }
+
+       return x;
+}
+
+static uint8_t
+newpin(uint32_t l)
+{
+       Pin * p;
+
+       if(l != 5)
+               return NOK;
+
+       if(npins() == JSCAN_LIMIT_PINS)
+       {
+               return LIMIT;
+       }
+
+       if(findpin(cmddata[0], NULL))
+       {
+               return EXIST;
+       }
+
+       p = calloc(1, sizeof *p);
+       if(!p)
+               return NMEM;
+
+       /* enable pullups by default */
+       p->pullup       = 1;
+
+       p->id           = cmddata[0];
+       p->bit          = cmddata[1];
+       p->ddr          = (volatile uint8_t * )((uint16_t)cmddata[2] + OFFSETIO);
+       p->pin          = (volatile uint8_t * )((uint16_t)cmddata[3] + OFFSETIO);
+       p->port         = (volatile uint8_t * )((uint16_t)cmddata[4] + OFFSETIO);
+
+       /* explicitly set return value */
+       cmddata[0] = p->id;
+
+       return addpin(p);
+}
+
+static uint8_t
+addpin(Pin * p)
+{
+       Pin * a;
+
+       if(!pins)
+       {
+               pins = p;
+               return OK;
+       }
+
+       a = pins;
+       while(a && a->next)
+               a = a->next;
+       a->next = p;
+       p->prev = a;
+
+       return OK;
+}
+
+static uint8_t
+rmpin(uint32_t l)
+{
+       uint8_t i;
+       Pin * p;
+
+       if(l != 1)
+               return NOK;
+
+       i = cmddata[0];
+       if(!findpin(i, &p))
+               return NOK;
+
+       if(p->prev)
+               (p->prev)->next = p->next;
+       if(p->next)
+               (p->next)->prev = p->prev;
+       if(p == pins)
+               pins = p->next;
+
+       free(p);
+
+       cmddata[0] = i;
+
+       return OK;
+}
+
+static uint8_t 
+findpin(uint8_t i, Pin ** pp)
+{
+       Pin * p;
+
+       p = pins;
+       while(p)
+       {
+               if(p->id == i)
+               {
+                       if(pp)
+                               *pp = p;
+                       return 1;
+               }
+
+               p = p->next;
+       }
+
+       return 0;
+}
+
+static uint8_t
+setdelay(uint32_t l)
+{
+       if(l != 1)
+       {
+               cmddata[0] = xdelay;
+               return OK;
+       }
+
+       xdelay = cmddata[0];
+       return OK;
+}
+
+static uint8_t
+setpullup(uint32_t l)
+{
+       Pin * p;
+
+       if(l != 2)
+               return NOK;
+
+       /* change all or one? */
+       if(cmddata[0] != 0xff)
+       {
+               if(!findpin(l, &p))
+                       return EXIST;
+               p->pullup = cmddata[1] ? 1 : 0 ;
+       }
+       else
+       {
+               p = pins; 
+               while(p)
+               {
+                       p->pullup = cmddata[1] ? 1 : 0 ;
+                       p = p->next;
+               }
+       }
+
+       return OK;
+}
+
+static uint8_t
+setendian(uint32_t l)
+{
+       if(l != 1)
+       {
+               cmddata[0] = endian;
+               return OK;
+       }
+
+       switch(cmddata[0])
+       {
+       case JSCAN_ENDIAN_BIG:
+               endian = JSCAN_ENDIAN_BIG;
+               break;
+       case JSCAN_ENDIAN_LITTLE:
+               endian = JSCAN_ENDIAN_LITTLE;
+               break;
+       default:
+               return NOK;
+       }
+
+       return OK;
+}
+
+static void
+loopback(uint8_t a)
+{
+       Pin * tdo;
+       Pin * tdi;
+       int nb;
+       int r;
+
+       if(npins() < 2)
+       {
+               txdata(a, EXIST, 0);
+               return;
+       }
+
+       nb = 0;
+
+       tdo = pins;
+       while(tdo)
+       {
+               tdi = pins;
+               while(tdi)
+               {
+                       if(tdi == tdo)
+                       {
+                               tdi = tdi->next;
+                               continue;
+                       }
+
+                       initpins(NULL, NULL, tdi, NULL, NULL);
+
+                       r = checkdata(pattern, (2*NPATTERN), NULL, tdi, tdo, NULL);
+                       if(r == 1)
+                       {
+                               if(nb >= (CMDDATALEN-4))
+                               {
+                                       txdata(a, NMEM, 0);
+                                       return;
+                               }
+
+                               /* add the response in couples; TDI first */
+                               cmddata[nb++] = tdi->id;
+                               cmddata[nb++] = tdo->id;
+                       }
+
+                       tdi = tdi->next;
+               }
+
+               tdo = tdo->next;
+       }
+
+       txdata(a, OK, nb);
+}
+
+static void
+initpins(Pin * tck, Pin * tms, Pin * tdi, Pin * tdo, Pin * nrst)
+{
+       Pin * p;
+
+/* XXX test removing syncs */
+       p = pins;
+       while(p)
+       {
+               /* set as input by default */
+               *p->ddr &= ~(1 << p->bit);
+
+               /* sync */
+               _delay_ms(xdelay);
+
+               /* set pullup if desired while in input mode */
+               if(p->pullup)
+                       *p->port |= (1 << p->bit);
+               else
+                       *p->port &= ~(1 << p->bit);
+
+               /* sync */
+               _delay_ms(xdelay);
+
+               if(p == nrst)
+               {
+                       /* set as output */
+                       *p->ddr |= (1 << p->bit);
+
+                       /* nrst requires output fixed high */
+                       *p->port &= ~(1 << p->bit);
+                       *p->port |=  (1 << p->bit);
+               }
+               else if(p == tck || p == tms || p == tdi)
+               {
+                       /* set as output */
+                       *p->ddr |= (1 << p->bit);
+
+                       /* sync */
+                       _delay_ms(xdelay);
+
+                       /* these pins must start low */
+                       *p->port &= ~(1 << p->bit);
+               }
+
+               /* tdo should need no special sauce */
+
+               /* sync */
+               _delay_ms(xdelay);
+
+               p = p->next;
+       }
+}
+
+static int
+checkdata(char * pattern, int ntimes, Pin * tck, Pin * tdi, Pin * tdo, int * nreg)
+{
+        char rcv[NPATTERN];
+        int tdo_read;
+        int tdo_prev;
+        int ntoggle;
+        uint8_t x;
+        int np;
+        int i;
+        int w;
+
+        w = 0;
+        np = strlen(pattern);
+
+        x = (*tdo->pin & (1 << tdo->bit)) >> tdo->bit;
+
+        tdo_prev = '0' + (x == 1);
+
+        for(i = 0; i < ntimes; i++)
+        {
+                tdipulse(tck, tdi, pattern[w++] - '0');
+                if(!pattern[w])
+                {
+                        w = 0;
+                }
+
+                x = (*tdo->pin & (1 << tdo->bit)) >> tdo->bit;
+
+                tdo_read = '0' + (x == 1);
+
+                ntoggle += (tdo_read != tdo_prev);
+                tdo_prev = tdo_read;
+
+                if(i < np)
+                {
+                        rcv[i] = tdo_read;
+                }
+                else
+                {
+                        memmove(rcv, rcv + 1, np - 1);
+                        rcv[np - 1] = tdo_read;
+                }
+
+                if(i >= np - 1)
+                {
+                        if(!memcmp(pattern, rcv, np))
+                        {
+                                if(nreg)
+                                        *nreg = i + 1 - np;
+                                return 1;
+                        }
+                }
+        }
+
+        if(nreg)
+                *nreg = 0;
+
+        return ntoggle > 1 ? ntoggle : 0 ;
+}
+
+static void
+tdipulse(Pin * tck, Pin * tdi, uint8_t x)
+{
+       if(x)   
+               *tdi->port |= (1 << tdi->bit);
+       else
+               *tdi->port &= ~(1 << tdi->bit);
+
+       /* sync */
+       _delay_ms(xdelay);
+
+       clockstrobe(tck);
+}
+
+static void
+clockstrobe(Pin * tck)
+{
+       *tck->port |= (1 << tck->bit);
+       _delay_ms(xdelay);
+
+       *tck->port &= ~(1 << tck->bit);
+       _delay_ms(xdelay);
+}
+
+static void
+scan(uint8_t a)
+{
+       Pin * nrst;
+       Pin * tck;
+       Pin * tms;
+       Pin * tdi;
+       Pin * tdo;
+       int nreg;
+       int r;
+
+        if(npins() < 5)
+        {
+                txdata(a, EXIST, 0);
+                return;
+        }
+
+       nfound = 0;
+        nrst = pins;
+
+       /* send back an OK to let the user know we've started */
+       txdata(a, OK, 0);
+
+        while(nrst)
+        {
+                tck = pins;
+                while(tck)
+                {
+                        if(tck == nrst)
+                        {
+                                tck = tck->next;
+                                continue;
+                        }
+
+                        tms = pins;
+                        while(tms)
+                        {
+                                if(tms == nrst || tms == tck)
+                                {
+                                        tms = tms->next;
+                                        continue;
+                                }
+
+                                tdo = pins;
+                                while(tdo)
+                                {
+                                        if(tdo == nrst || tdo == tck || tdo == tms)
+                                        {
+                                                tdo = tdo->next;
+                                                continue;
+                                        }
+
+                                        tdi = pins;
+                                        while(tdi)
+                                        {
+                                                if(tdi == nrst || tdi == tck || tdi == tms || tdi == tdo)
+                                                {
+                                                        tdi = tdi->next;
+                                                        continue;
+                                                }
+
+                                                initpins(tck, tms, tdi, tdo, nrst);
+
+                                                tapstate(tap_shiftir, tck, tms);
+
+                                                r = checkdata(pattern, (2*NPATTERN), tck, tdi, tdo, &nreg);
+                                                if(r == 1)
+                                                {
+                                                       /* found potential JTAG */
+                                                       /* NB */
+                                                       /* can fit around 100 detections; but total should hover around 0.5% of total tests. 
+                                                        * so if the number of tests is really high, one could exceed 100 detected JTAGs,
+                                                        * so caveat emptor
+                                                        */
+                                                       if(nfound < (CMDDATALEN-4)-5)
+                                                       {
+                                                               /* order is important */
+                                                               found[nfound++] = tck->id;
+                                                               found[nfound++] = tms->id;
+                                                               found[nfound++] = tdi->id;
+                                                               found[nfound++] = tdo->id;
+                                                               found[nfound++] = nrst->id;
+                                                       }
+                                                }
+
+                                               tdi = tdi->next;
+                                        }
+
+                                        tdo = tdo->next;
+                                }
+
+                                tms = tms->next;
+                        }
+
+                        tck = tck->next;
+                }
+
+                nrst = nrst->next;
+        }
+
+}
+
+static void
+tapstate(char * s, Pin * tck, Pin * tms)
+{
+        int x;
+
+        while(*s)
+        {
+                x = *s - '0';
+                /* issue */
+                if(x)   
+                        *tms->port |= (1 << tms->bit);
+                else
+                        *tms->port &= ~(1 << tms->bit);
+
+                /* strobe */
+                *tck->port &= ~(1 << tck->bit);
+                _delay_ms(xdelay);
+                *tck->port |= (1 << tck->bit);
+
+                s++;
+        }
+}
+
+static void
+listpin(uint8_t a)
+{
+       Pin * p;
+       int nb;
+
+       nb = 0;
+       p = pins;
+       while(p)
+       {
+               cmddata[nb++] = p->id;
+               cmddata[nb++] = p->bit;
+               cmddata[nb++] = ((uint16_t)(p->ddr)) & 0xff;
+               cmddata[nb++] = ((uint16_t)(p->pin)) & 0xff;
+               cmddata[nb++] = ((uint16_t)(p->port)) & 0xff;
+               p = p->next;
+       }
+
+       txdata(a, OK, nb);
+}
+
+static void
+getresults(uint8_t a)
+{
+       memcpy(cmddata, found, nfound);
+       txdata(a, OK, nfound);
+}
+
index 39cad44..e97bd1f 100644 (file)
@@ -32,6 +32,10 @@ void init(){
   #define INITCHIP arduino_init();
 #endif
 
+#if (platform == donbfet)
+# define INITCHIP donbfet_init();
+#endif
+
 #ifdef INITCHIP
 INITCHIP
 #else
@@ -97,6 +101,9 @@ int main(void)
        } else {                // we come here after DTR high (release reset)
                dputs("\nWarmstart\n");
        }
+#elif (platform == donbfet)
+       extern void donbfet_reboot(void);
+       void (*reboot_function)(void) = donbfet_reboot;
 #else
        void (*reboot_function)(void) = (void *) 0xFFFE;
 #endif
@@ -124,20 +131,24 @@ int main(void)
                                // or
                                // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
                                // but instead we'll jump to our reboot function pointer
-                         #ifdef MSP430
-#if (platform == tilaunchpad)
+#ifdef MSP430
+# if (platform == tilaunchpad)
                                // do we really need this, we do not want to reset the TUSB3410 
                                dputs("reset_count>4\n");
                                
                                //longjmp(warmstart,111);
                                goto warmstart;
                                
-#else
+# else
                                (*reboot_function)();
-#endif
-                         #else
+# endif
+#else /* !MSP430 */
+# if (platform == donbfet)
+                               (*reboot_function)();
+# else
                                debugstr("Rebooting not supported on this platform.");
-                         #endif
+# endif
+#endif
                        }
 
                        continue;
index bcf76ef..99e9fbf 100644 (file)
@@ -9,7 +9,8 @@
 #include "spi.h"
 #include "app.h"
 
-#define AVR 0x32
+/* AVR is a known macro for the AVR C includes */
+#define XAVR 0x32
 
 //! Setup the AVR pins.
 void avrsetup();
@@ -20,24 +21,24 @@ void avrconnect();
 //! Enable AVR programming mode.
 void avr_prgen();
 //! Read AVR device code.
-u8 avr_sig(u8 i);
+uint8_t avr_sig(uint8_t i);
 //! Erase an AVR device
 void avr_erase();
 //! Read lock bits.
-u8 avr_lockbits();
+uint8_t avr_lockbits();
 //! Write lock bits.
-void avr_setlock(u8 bits);
+void avr_setlock(uint8_t bits);
 
 //! Read a byte of Flash
-u8 avr_peekflash(u16 adr);
+uint8_t avr_peekflash(uint16_t adr);
 
 //! Read a byte of EEPROM.
-u8 avr_peekeeprom(u16 adr);
+uint8_t avr_peekeeprom(uint16_t adr);
 //! Read a byte of EEPROM.
-u8 avr_pokeeeprom(u16 adr, u8 val);
+uint8_t avr_pokeeeprom(uint16_t adr, uint8_t val);
 
 //! Is the AVR ready or busy?
-u8 avr_isready();
+uint8_t avr_isready();
 
 //Command codes.
 //! Perform a chip erase.
index fd50ccb..ca2f6a8 100644 (file)
@@ -48,6 +48,9 @@ extern unsigned char silent;
 #define STOP  0x21
 #define CALL  0x30
 #define EXEC  0x31
+#define LIMIT 0x7B /* limit reached */
+#define EXIST 0x7C /* already or doesnt exist */
+#define NMEM  0x7D /* OOM */
 #define NOK   0x7E
 #define OK    0x7F
 
diff --git a/firmware/include/jscan.h b/firmware/include/jscan.h
new file mode 100644 (file)
index 0000000..346fe41
--- /dev/null
@@ -0,0 +1,39 @@
+/*! \file jscan.h
+  \author Don A. Bailey
+  \brief JSCAN App
+*/
+
+#ifndef JSCAN_H
+#define JSCAN_H
+
+#include "spi.h"
+#include "app.h"
+
+/* app id 'd' */
+#define JSCAN 0x64
+
+/* limits */
+#define JSCAN_LIMIT_PINS       254
+#define JSCAN_DEFAULT_DELAY    1
+
+/* endianness */
+#define JSCAN_ENDIAN_BIG       0
+#define JSCAN_ENDIAN_LITTLE    1
+
+/* commands */
+#define JSCAN_CMD              0x80
+#define JSCAN_CMD_SCAN                 (JSCAN_CMD + 0)
+#define JSCAN_CMD_ENDIAN       (JSCAN_CMD + 1)
+#define JSCAN_CMD_SYNC         (JSCAN_CMD + 2)
+#define JSCAN_CMD_ADDPIN       (JSCAN_CMD + 3)
+#define JSCAN_CMD_RMPIN                (JSCAN_CMD + 4)
+#define JSCAN_CMD_DELAY                (JSCAN_CMD + 5)
+#define JSCAN_CMD_PULLUP       (JSCAN_CMD + 6)
+#define JSCAN_CMD_LOOPBACK     (JSCAN_CMD + 7)
+#define JSCAN_CMD_LISTPIN      (JSCAN_CMD + 8)
+#define JSCAN_CMD_RESULTS      (JSCAN_CMD + 9)
+
+extern app_t const jscan_app;
+
+#endif 
+
index 0f272da..cede5c4 100644 (file)
 #define SPI 0x01
 
 //Pins and I/O
-#define MOSI BIT1
-#define MISO BIT2
-#define SCK  BIT3
+#if (platform == donbfet)
+# define MOSI (1 << PA2)
+# define MISO (1 << PA1)
+# define SCK  (1 << PA0)
+# define SS   (1 << PA3)
+# define TST  (1 << PA4)
+# define XRST (1 << PA5)
+#else
+# define MOSI BIT1
+# define MISO BIT2
+# define SCK  BIT3
+#endif
 
 #define SETMOSI SPIOUT|=MOSI
 #define CLRMOSI SPIOUT&=~MOSI
 #define READMISO (SPIIN&MISO?1:0)
 
 //FIXME this should be defined by the platform.
-#define SETTST P4OUT|=TST
-#define CLRTST P4OUT&=~TST
-#define SETRST P2OUT|=RST
-#define CLRRST P2OUT&=~RST
+#if (platform == donbfet)
+# define SETTST PORTA|=(1 << PA4);
+# define CLRTST PORTA&=~(1 << PA4);
+# define SETRST PORTA|=(1 << PA5);
+# define CLRRST PORTA&=~(1 << PA5);
+#else
+# define SETTST P4OUT|=TST
+# define CLRTST P4OUT&=~TST
+# define SETRST P2OUT|=RST
+# define CLRRST P2OUT&=~RST
+#endif
 
 //! Set up the pins for SPI mode.
 void spisetup();
diff --git a/firmware/lib/atmega1284p.c b/firmware/lib/atmega1284p.c
new file mode 100644 (file)
index 0000000..2199ecf
--- /dev/null
@@ -0,0 +1,173 @@
+#include "platform.h"
+
+#include <avr/io.h>
+#include <util/delay.h>
+
+//! Receive a byte.
+unsigned char serial0_rx(){
+  while( !(UCSR0A & (1 << RXC0)) );
+  return UDR0;
+}
+
+//! Receive a byte.
+unsigned char serial1_rx(){
+  return 0;
+}
+
+//! Transmit a byte.
+void serial0_tx(unsigned char x){
+  while (!(UCSR0A & (1<<UDRE0)) );
+  UDR0 = x;
+}
+
+//! Transmit a byte on the second UART.
+void serial1_tx(unsigned char x){
+}
+
+//! Set the baud rate.
+void setbaud0(unsigned char rate){
+        /* disable briefly */
+        UCSR0B = 0;
+
+        UBRR0L = 4;   /* 500,000 baud at 20MHz */
+        //UBRR0L = 1;   /* 500,000 baud at 8MHz */
+        //UBRR0L = 103; /* 9600 baud */
+        // XXX UBRR0L = 8;     /* 115200 baud ERROR RATE TOO HIGH */
+        UBRR0H = 0;
+
+        UCSR0A = (1 << U2X0);   /* double the baud rate */
+        UCSR0C = (3 << UCSZ00); /* 8N1 */
+
+        /* enabling rx/tx must be done after frame/baud setup */
+        UCSR0B = ((1 << TXEN0) | (1 << RXEN0));
+
+  return;
+  
+}
+
+//! Set the baud rate of the second uart.
+void setbaud1(unsigned char rate){
+  //http://mspgcc.sourceforge.net/baudrate.html
+  switch(rate){
+  case 1://9600 baud
+    
+    break;
+  case 2://19200 baud
+    
+    break;
+  case 3://38400 baud
+    
+    break;
+  case 4://57600 baud
+    
+    break;
+  default:
+  case 5://115200 baud
+    
+    break;
+  }
+}
+
+
+void donbfet_init_uart0(){
+  setbaud0(0);
+  _delay_ms(500); //takes a bit to stabilize
+}
+
+void 
+led_on()
+{
+       PLEDOUT |= (1 << PLEDPIN);
+}
+
+void
+led_off()
+{
+       PLEDOUT &= ~(1 << PLEDPIN);
+}
+
+void 
+donbfet_init()
+{
+        uint8_t x;
+
+        /* explicitly clear interrupts */
+        cli();
+
+        /* move the vectors */
+
+        /* move interrupts from boot flash section */
+        /* NB */
+        /* you MUST use a variable during this process. even highly optimized,
+         * masking the bit, shifting, ANDing, and setting MCUCR will exceed
+         * 4 CPU cycles! set a variable with the desired value for MCUCR and
+         * then set the register once IVCE is enabled
+         */
+        x = MCUCR & ~(1 << IVSEL);
+
+        /* enable change of interrupt vectors */
+        /* NOTE: setting IVCE disables interrupts until the bit is auto-unset 
+         * 4 cycles after being set or after IVSEL is written
+         */
+        MCUCR |= (1 << IVCE);
+        MCUCR = x;
+
+        /* disable the watchdog timer; this macro will disable interrupts for us */
+        /* NOTE: ensure that the WDRF flag is unset in the MCUSR or we will spinlock
+         * when the watchdog times out
+         */
+        MCUSR &= ~(1 << WDRF);
+        wdt_disable();
+
+        /* init the USART */
+        donbfet_init_uart0();
+
+       /* set the LED as an output */
+       PLEDDIR |= (1 << PLEDPIN);
+       PLEDOUT |= (1 << PLEDPIN);
+
+        /* explicitly enable interrupts */
+        sei();
+}
+
+void
+donbfet_reboot()
+{
+       MCUSR &= ~(1 << WDRF);
+       wdt_enable(WDTO_15MS);
+       while(1)
+               _delay_ms(127);
+}
+
+void donbfet_init_uart1(){
+}
+
+uint8_t
+donbfet_get_byte(uint16_t v)
+{
+       /* NB */
+       /* we are only passed in a 16bit word. should 
+        * be increased to 32bit if we want to handle
+        * far reads as well
+        */
+/* XXX should be far on the 1284P, but there are bugs with flash reads using _far */
+/* XXX until the bugs are figured out (probably my fault?) use _near */
+       return pgm_read_byte_near(v);
+}
+
+int * 
+donbfet_ramend(void)
+{
+       /* NB */
+       /* ATmega1284P has 16K SRAM */
+       return (int * )0x4000; 
+}
+
+void
+led_toggle(void)
+{
+       led_on();
+       _delay_ms(30);
+       led_off();
+}
+
diff --git a/firmware/lib/atmega644p.c b/firmware/lib/atmega644p.c
new file mode 100644 (file)
index 0000000..20975b4
--- /dev/null
@@ -0,0 +1,171 @@
+#include "platform.h"
+
+#include <avr/io.h>
+#include <util/delay.h>
+
+//! Receive a byte.
+unsigned char serial0_rx(){
+  while( !(UCSR0A & (1 << RXC0)) );
+  return UDR0;
+}
+
+//! Receive a byte.
+unsigned char serial1_rx(){
+  return 0;
+}
+
+//! Transmit a byte.
+void serial0_tx(unsigned char x){
+  while (!(UCSR0A & (1<<UDRE0)) );
+  UDR0 = x;
+}
+
+//! Transmit a byte on the second UART.
+void serial1_tx(unsigned char x){
+}
+
+//! Set the baud rate.
+void setbaud0(unsigned char rate){
+        /* disable briefly */
+        UCSR0B = 0;
+
+        UBRR0L = 4;   /* 500,000 baud at 20MHz */
+        //UBRR0L = 1;   /* 500,000 baud at 8MHz */
+        //UBRR0L = 103; /* 9600 baud */
+        // XXX UBRR0L = 8;     /* 115200 baud ERROR RATE TOO HIGH */
+        UBRR0H = 0;
+
+        UCSR0A = (1 << U2X0);   /* double the baud rate */
+        UCSR0C = (3 << UCSZ00); /* 8N1 */
+
+        /* enabling rx/tx must be done after frame/baud setup */
+        UCSR0B = ((1 << TXEN0) | (1 << RXEN0));
+
+  return;
+  
+}
+
+//! Set the baud rate of the second uart.
+void setbaud1(unsigned char rate){
+  //http://mspgcc.sourceforge.net/baudrate.html
+  switch(rate){
+  case 1://9600 baud
+    
+    break;
+  case 2://19200 baud
+    
+    break;
+  case 3://38400 baud
+    
+    break;
+  case 4://57600 baud
+    
+    break;
+  default:
+  case 5://115200 baud
+    
+    break;
+  }
+}
+
+
+void donbfet_init_uart0(){
+  setbaud0(0);
+  _delay_ms(500); //takes a bit to stabilize
+}
+
+void 
+led_on()
+{
+       PLEDOUT |= (1 << PLEDPIN);
+}
+
+void
+led_off()
+{
+       PLEDOUT &= ~(1 << PLEDPIN);
+}
+
+void 
+donbfet_init()
+{
+        uint8_t x;
+
+        /* explicitly clear interrupts */
+        cli();
+
+        /* move the vectors */
+
+        /* move interrupts from boot flash section */
+        /* NB */
+        /* you MUST use a variable during this process. even highly optimized,
+         * masking the bit, shifting, ANDing, and setting MCUCR will exceed
+         * 4 CPU cycles! set a variable with the desired value for MCUCR and
+         * then set the register once IVCE is enabled
+         */
+        x = MCUCR & ~(1 << IVSEL);
+
+        /* enable change of interrupt vectors */
+        /* NOTE: setting IVCE disables interrupts until the bit is auto-unset 
+         * 4 cycles after being set or after IVSEL is written
+         */
+        MCUCR |= (1 << IVCE);
+        MCUCR = x;
+
+        /* disable the watchdog timer; this macro will disable interrupts for us */
+        /* NOTE: ensure that the WDRF flag is unset in the MCUSR or we will spinlock
+         * when the watchdog times out
+         */
+        MCUSR &= ~(1 << WDRF);
+        wdt_disable();
+
+        /* init the USART */
+        donbfet_init_uart0();
+
+       /* set the LED as an output */
+       PLEDDIR |= (1 << PLEDPIN);
+       PLEDOUT |= (1 << PLEDPIN);
+
+        /* explicitly enable interrupts */
+        sei();
+}
+
+void
+donbfet_reboot()
+{
+       MCUSR &= ~(1 << WDRF);
+       wdt_enable(WDTO_15MS);
+       while(1)
+               _delay_ms(127);
+}
+
+void donbfet_init_uart1(){
+}
+
+uint8_t
+donbfet_get_byte(uint16_t v)
+{
+       /* NB */
+       /* we are only passed in a 16bit word. should 
+        * be increased to 32bit if we want to handle
+        * far reads as well
+        */
+       return pgm_read_byte_near(v);
+}
+
+int * 
+donbfet_ramend(void)
+{
+       /* NB */
+       /* ATmega644P has 4K SRAM */
+       return (int * )0x1000; 
+}
+
+void
+led_toggle(void)
+{
+       led_on();
+       _delay_ms(30);
+       led_off();
+}
+
diff --git a/firmware/platforms/donbfet.h b/firmware/platforms/donbfet.h
new file mode 100644 (file)
index 0000000..41879fe
--- /dev/null
@@ -0,0 +1,110 @@
+/*! \file donbfet.h
+  \author Don A. Bailey
+  \brief Port descriptions for the DonbFET platform.
+*/
+
+/* NB: define default CPU frequency */
+//XXX #define F_CPU 8000000UL
+#define F_CPU 20000000UL
+
+#include <avr/io.h>
+#include <avr/wdt.h>
+#include <avr/boot.h>
+#include <avr/sleep.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include <util/delay.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+
+/* all AVR SRAM starts after I/O mapped memory and registers */
+#define RAMSTART 0x100
+
+#ifndef PB0
+# define PB0 PORTB0
+#endif
+#ifndef PA0
+# define PA0 PORTA0
+#endif
+#ifndef PA1
+# define PA1 PORTA1
+#endif
+#ifndef PA2
+# define PA2 PORTA2
+#endif
+#ifndef PA3
+# define PA3 PORTA3
+#endif
+#ifndef PA4
+# define PA4 PORTA4
+#endif
+#ifndef PA5
+# define PA5 PORTA5
+#endif
+
+//LED on P1.0
+#define PLEDOUT PORTB
+#define PLEDDIR DDRB
+#define PLEDPIN PB0
+
+//Use P3 instead of P5 for target I/O on chips without P5.
+#ifdef msp430x2274
+//#warning "No P5, using P3 instead.  Will break 2618 and 1612 support."
+# define P5OUT P3OUT
+# define P5DIR P3DIR
+# define P5IN P3IN
+# define P5REN P3REN
+
+# define SPIOUT P3OUT
+# define SPIDIR P3DIR
+# define SPIIN  P3IN
+# define SPIREN P3REN
+#else
+
+# if (platform == donbfet)
+#  define SPIOUT PORTA
+#  define SPIDIR DDRA
+#  define SPIIN  PINA
+//# define SPIREN P5REN
+# endif
+#endif
+
+//This is how things used to work, don't do it anymore.
+//#ifdef msp430x1612
+//#define P5REN somedamnedextern
+//#endif
+
+#if (platform == donbfet)
+# define SETSS PORTA|=SS;
+# define CLRSS PORTA&=~SS;
+# define DIRSS DDRA|=SS;
+#else
+//No longer works for Hope badge.
+# define SETSS P5OUT|=BIT0
+# define CLRSS P5OUT&=~BIT0
+# define DIRSS P5DIR|=BIT0;
+#endif
+
+//Used for the Nordic port, !RST pin on regular GoodFET.
+#define SETCE P2OUT|=BIT6
+#define CLRCE P2OUT&=~BIT6
+#define DIRCE P2DIR|=BIT6
+
+// network byte order converters
+#define htons(x) ((((uint16_t)(x) & 0xFF00) >> 8) | \
+                                (((uint16_t)(x) & 0x00FF) << 8))
+#define htonl(x) ((((uint32_t)(x) & 0xFF000000) >> 24) | \
+                                 (((uint32_t)(x) & 0x00FF0000) >> 8) | \
+                                 (((uint32_t)(x) & 0x0000FF00) << 8) | \
+                                 (((uint32_t)(x) & 0x000000FF) << 24))
+
+#define ntohs htons
+#define ntohl htonl
+
+extern uint8_t donbfet_get_byte(uint16_t);
+