From 41777a0dda559dc2b2738720a39f3b5d57b5cee0 Mon Sep 17 00:00:00 2001 From: donb127 Date: Tue, 18 Oct 2011 16:12:43 +0000 Subject: [PATCH] initial merge of donbfet code, sans changes to monitor/avr/spi git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1053 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- firmware/Makefile | 23 ++ firmware/apps/jscan/jscan.c | 646 +++++++++++++++++++++++++++++++++++ firmware/goodfet.c | 23 +- firmware/include/avr.h | 17 +- firmware/include/command.h | 3 + firmware/include/jscan.h | 39 +++ firmware/include/spi.h | 30 +- firmware/lib/atmega1284p.c | 173 ++++++++++ firmware/lib/atmega644p.c | 171 ++++++++++ firmware/platforms/donbfet.h | 110 ++++++ 10 files changed, 1214 insertions(+), 21 deletions(-) create mode 100644 firmware/apps/jscan/jscan.c create mode 100644 firmware/include/jscan.h create mode 100644 firmware/lib/atmega1284p.c create mode 100644 firmware/lib/atmega644p.c create mode 100644 firmware/platforms/donbfet.h diff --git a/firmware/Makefile b/firmware/Makefile index d25bab4..fbf5a33 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -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 index 0000000..896a05f --- /dev/null +++ b/firmware/apps/jscan/jscan.c @@ -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 +# include +# include +#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); +} + diff --git a/firmware/goodfet.c b/firmware/goodfet.c index 39cad44..e97bd1f 100644 --- a/firmware/goodfet.c +++ b/firmware/goodfet.c @@ -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; diff --git a/firmware/include/avr.h b/firmware/include/avr.h index bcf76ef..99e9fbf 100644 --- a/firmware/include/avr.h +++ b/firmware/include/avr.h @@ -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. diff --git a/firmware/include/command.h b/firmware/include/command.h index fd50ccb..ca2f6a8 100644 --- a/firmware/include/command.h +++ b/firmware/include/command.h @@ -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 index 0000000..346fe41 --- /dev/null +++ b/firmware/include/jscan.h @@ -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 + diff --git a/firmware/include/spi.h b/firmware/include/spi.h index 0f272da..cede5c4 100644 --- a/firmware/include/spi.h +++ b/firmware/include/spi.h @@ -11,9 +11,18 @@ #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 @@ -22,10 +31,17 @@ #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 index 0000000..2199ecf --- /dev/null +++ b/firmware/lib/atmega1284p.c @@ -0,0 +1,173 @@ +#include "platform.h" + +#include +#include + +//! 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< +#include + +//! 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< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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); + -- 2.20.1