From 70e0c8cd2fcdff065f470d24b1bc80ee26d04e5a Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Wed, 19 Sep 2012 12:08:51 +0100 Subject: [PATCH 01/13] first cut rfcat version. add semaphores, buttons and LED/USB target specific changes --- Makefile | 25 ++++++++++++++++++++++++- src/hal.c | 26 ++++++++++++++++++-------- src/hal.h | 24 ++++++++++++++++++++++++ src/main.c | 53 +++++++++++++++++++++++++++++++++++++++++------------ 4 files changed, 107 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index aecfe17..05e255c 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ ASM_REL = $(ASM_SRC:.asm=.rel) ASM_RST = $(ASM_SRC:.asm=.rst) ASM_SYM = $(ASM_SRC:.asm=.sym) -PROGS = CCBootloader.hex +PROGS = CCBootloader.hex CCBootloader-rfcat-chronosdongle.hex CCBootloader-rfcat-donsdongle.hex PCDB = $(PROGS:.hex=.cdb) PLNK = $(PROGS:.hex=.lnk) PMAP = $(PROGS:.hex=.map) @@ -63,8 +63,31 @@ all: $(PROGS) CCBootloader.hex: $(REL) $(ASM_REL) Makefile $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader.hex $(ASM_REL) $(REL) +CCBootloader-rfcat-chronosdongle.hex: CFLAGS += -DRFCAT -DRFCAT_CHRONOS +CCBootloader-rfcat-chronosdongle.hex: $(REL) $(ASM_REL) Makefile + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-chronosdongle.hex $(ASM_REL) $(REL) + +CCBootloader-rfcat-donsdongle.hex: CFLAGS += -DRFCAT -DRFCAT_DONSDONGLE +CCBootloader-rfcat-donsdongle.hex: $(REL) $(ASM_REL) Makefile + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-donsdongle.hex $(ASM_REL) $(REL) + clean: rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) rm -f $(ASM_ADB) $(ASM_LNK) $(ASM_LST) $(ASM_REL) $(ASM_RST) $(ASM_SYM) rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) +install: CCBootloader.hex + goodfet.cc erase + goodfet.cc flash CCBootloader.hex + goodfet.cc verify CCBootloader.hex + +installchronosdongle: CCBootloader-rfcat-chronosdongle.hex + goodfet.cc erase + goodfet.cc flash CCBootloader-rfcat-chronosdongle.hex + goodfet.cc verify CCBootloader-rfcat-chronosdongle.hex + +installdonsdongle: CCBootloader-rfcat-donsdongle.hex + goodfet.cc erase + goodfet.cc flash CCBootloader-rfcat-donsdongle.hex + goodfet.cc verify CCBootloader-rfcat-donsdongle.hex + diff --git a/src/hal.c b/src/hal.c index 0c1bdc6..8a91327 100644 --- a/src/hal.c +++ b/src/hal.c @@ -18,29 +18,39 @@ */ #include "cc1111.h" +#include "hal.h" void setup_led() { // Setup LED and turn it off - P1DIR |= 2; - P1_1 = 0; + P1DIR |= LED_MASK; + LED = 0; +} + +void setup_button() { + #ifdef RFCAT_DONSDONGLE + P1DIR &= ~4; + #endif + #ifdef RFCAT_CHRONOS + P2DIR &= ~4; + #endif } void led_on() { - P1_1 = 1; + LED = 1; } void led_off() { - P1_1 = 0; + LED = 0; } void usb_up() { // Bring up the USB link - P1DIR |= 1; - P1_0 = 1; + P1DIR |= USB_MASK; + USB_ENABLE = 1; } void usb_down() { // Bring down the USB link - P1_0 = 0; - P1DIR &= ~1; + USB_ENABLE = 0; + P1DIR &= ~USB_MASK; } diff --git a/src/hal.h b/src/hal.h index 1e1075c..d141d67 100644 --- a/src/hal.h +++ b/src/hal.h @@ -20,11 +20,35 @@ #ifndef _HAL_H_ #define _HAL_H_ +// enable RFCAT and dongle version to build custom RFCAT version +// http://code.google.com/p/rfcat/ +// this would normally be done in the Makefile +//#define RFCAT +//#define RFCAT_DONSDONGLE +//#define RFCAT_CHRONOS + +#ifdef RFCAT_CHRONOS + #define LED P1_0 + #define LED_MASK 1 + #define USB_ENABLE P1_1 + #define USB_MASK 2 +#else + #define LED P1_1 + #define LED_MASK 2 + #define USB_ENABLE P1_0 + #define USB_MASK 1 +#endif + void setup_led(); void led_on(); void led_off(); +void setup_button(); void usb_up(); void usb_down(); +#define CC1111EM_BUTTON P1_2 +#define CC1111CHRONOS_PIN_DC P2_2 +#define BUTTON_PRESSED 0 +#define GROUNDED 0 #endif // _HAL_H_ diff --git a/src/main.c b/src/main.c index 85ece0c..7f62457 100644 --- a/src/main.c +++ b/src/main.c @@ -71,22 +71,26 @@ void jump_to_user() { EA = 0; IEN0 = IEN1 = IEN2 = 0; - // Bring down the USB link - usb_down(); - - // Flag bootloader not running - bootloader_running = 0; if (check_for_payload()) { + // Bring down the USB link + usb_down(); + + // Flag bootloader not running + bootloader_running = 0; // Jump to user code __asm ljmp #USER_CODE_BASE __endasm; while (1) {} } else { + #ifdef RFCAT + return; // need to run bootloader! + #else // Oops, no payload. We're stuck now! led_on(); while (1) {} + #endif } } @@ -172,8 +176,18 @@ uint8_t want_bootloader() { if (!Px_y) return 0; */ - + + #ifdef RFCAT + // we use the unused I2S SFRs as semaphores. + // this would be safe even if I2S is in use as they should be reconfigured by + // user code + if(I2SCLKF2 == 0x69) + return 1; + // no thanks + return 0; + #else return 1; + #endif } void bootloader_main () @@ -181,10 +195,24 @@ void bootloader_main () __xdata char buff[100]; uint8_t ihx_status; uint16_t read_start_addr, read_len; - + + #ifdef RFCAT + // use I2S SFR to signal that bootloader is present + I2SCLKF0= 0xF0; + I2SCLKF1= 0x0D; + + setup_button(); + + if (CC1111EM_BUTTON != BUTTON_PRESSED && CC1111CHRONOS_PIN_DC != GROUNDED && !want_bootloader()) + #else if (!want_bootloader()) + #endif jump_to_user(); - + #ifdef RFCAT + // reset semaphore + I2SCLKF2= 0x00; + #endif + clock_init(); setup_led(); @@ -197,11 +225,12 @@ void bootloader_main () usb_init(); // Enable interrupts - EA = 1; + EA = 1; // Bring up the USB link usb_up(); - + led_on(); + while (1) { ihx_readline(buff); @@ -259,6 +288,6 @@ void bootloader_main () } else { usb_putchar(ihx_status + '0'); usb_flush(); - } - } + } + } } From e21def381118e66a87a86f5528b19b0bf48e2bc3 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Thu, 20 Sep 2012 11:18:58 +0100 Subject: [PATCH 02/13] fix read command (length being shifted into oblivion) --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 7f62457..22771ed 100644 --- a/src/main.c +++ b/src/main.c @@ -275,7 +275,7 @@ void bootloader_main () case IHX_RECORD_READ: // Read out a section of flash over USB read_start_addr = ihx_record_address(buff); - read_len = ihx_data_byte(buff, 0)<<8 + ihx_data_byte(buff, 1); + read_len = (ihx_data_byte(buff, 0)<<8) + ihx_data_byte(buff, 1); usb_putchar('\n'); ihx_read_print((__xdata uint8_t*)read_start_addr, read_len); break; From f44abe5036a78c2e6755386290108ce37561eee9 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Thu, 20 Sep 2012 13:02:57 +0100 Subject: [PATCH 03/13] add verify function --- bootload.py | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/bootload.py b/bootload.py index 84aa66c..a37c21d 100755 --- a/bootload.py +++ b/bootload.py @@ -30,6 +30,36 @@ def download_code(ihx_file, serial_port): print "Skipping non data record: '%s'" % line[:-1] return True +def verify_code(ihx_file, serial_port): + for line in ihx_file.readlines(): + record_type = int(line[7:9], 16) + if (record_type == 0x00): + length= int(line[1:3], 16) + start_addr= int(line[3:7], 16) + data= line[9:9+(length*2)] + # we can only read 16 byte chunks on 16 byte boundries + block_start= (start_addr / 16) * 16 + offset= (start_addr - block_start) + block_length= (((length + offset) / 16) + 1) * 16 + print "\rVerifying %04d bytes at address: %04X" % (length, start_addr), + do_flash_read(serial_port, block_start, block_length) + verify_data= '' + for read_data in serial_port: + read_data= read_data.strip() + if (not data or read_data == ":00000001FF"): + break + # strip header and checksum + verify_data += read_data[9:-2] + if (data == verify_data[offset*2:(offset*2)+(length*2)]): + print '(OK)', + else: + print 'Failed! Expected:', data, 'Got:', verify_data[offset*2:(offset*2)+(length*2)] + exit(0) + sys.stdout.flush() + else: + print "Skipping non data record: '%s'" % line[:-1] + return True + def run_user_code(serial_port): # User code is entered on intel HEX EOF record serial_port.write(":00000001FF\n") @@ -75,7 +105,7 @@ def erase_user_page(serial_port, page): return False return True -def flash_read(serial_port, start_addr, length): +def do_flash_read(serial_port, start_addr, length): chksum = (0xD9 + (0x100 - (start_addr & 0xFF)) + (0x100 - ((start_addr>>8) & 0xFF)) + @@ -83,6 +113,10 @@ def flash_read(serial_port, start_addr, length): (0x100 - ((length>>8) & 0xFF)) ) & 0xFF serial_port.write(":02%04X25%04X%02X\n" % (start_addr, length, chksum)) + + +def flash_read(serial_port, start_addr, length): + do_flash_read(serial_port, start_addr, length) for line in serial_port: print line, if (line == ":00000001FF\n"): @@ -123,6 +157,9 @@ def print_usage(): read start_addr len Reads len bytes from flash memory starting from start_addr. start_addr and len should be specified in hexadecimal (e.g. 0x1234). + + verify hex_file + Verify hex_file matches device flash memory. """ if __name__ == '__main__': @@ -137,13 +174,16 @@ def print_usage(): serial_port = serial.Serial(serial_port_name, timeout=1) try: - if (command == 'download'): + if (command == 'download' or command == 'verify'): if (len(options) < 1): print_usage() else: ihx_filename = options[0] ihx_file = open(ihx_filename, 'r') - download_code(ihx_file, serial_port) + if (command == 'download'): + download_code(ihx_file, serial_port) + else: + verify_code(ihx_file, serial_port) elif (command == 'run'): run_user_code(serial_port) From 5e33c7f2d2e7a7abe18df14c53f382a4e5132c26 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Thu, 20 Sep 2012 13:10:52 +0100 Subject: [PATCH 04/13] exit with an errorcode if verify fails --- bootload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootload.py b/bootload.py index a37c21d..883715f 100755 --- a/bootload.py +++ b/bootload.py @@ -54,7 +54,7 @@ def verify_code(ihx_file, serial_port): print '(OK)', else: print 'Failed! Expected:', data, 'Got:', verify_data[offset*2:(offset*2)+(length*2)] - exit(0) + exit(1) sys.stdout.flush() else: print "Skipping non data record: '%s'" % line[:-1] From 6c8bf58b643d2ad41be9677c519c31ad8a6f9396 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Thu, 20 Sep 2012 16:50:47 +0100 Subject: [PATCH 05/13] OpenMoko kindly assigned us our own USB IDs http://wiki.openmoko.org/wiki/USB_Product_IDs#USB_Vendor_and_Product_IDs --- src/usb.h | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/usb.h b/src/usb.h index d0ca438..d94298b 100644 --- a/src/usb.h +++ b/src/usb.h @@ -18,6 +18,8 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include "hal.h" + #ifndef _USB_H_ #define _USB_H_ @@ -118,17 +120,41 @@ struct usb_line_coding { #define USB_READ_AGAIN ((char) -1) -#define USB_VID 0xFFFE -#define USB_PID 0x000A - -// iManufacturer -#define USB_iManufacturer_LEN 0x10 -#define USB_iManufacturer_STRING "JobyGPS" -#define USB_iManufacturer_UCS2 'J', 0, 'o', 0, 'b', 0, 'y', 0, 'G', 0, 'P', 0, 'S', 0 -// iProduct -#define USB_iProduct_LEN 0x1C -#define USB_iProduct_STRING "CC Bootloader" -#define USB_iProduct_UCS2 'C', 0, 'C', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 +#ifdef RFCAT_CHRONOS + #define USB_VID 0x1D50 + #define USB_PID 0x6049 + // iManufacturer + #define USB_iManufacturer_LEN 0x0C + #define USB_iManufacturer_STRING "RfCat" + #define USB_iManufacturer_UCS2 'R', 0, 'f', 0, 'C', 0, 'a', 0, 't', 0 + // iProduct + #define USB_iProduct_LEN 0x26 + #define USB_iProduct_STRING "Chronos Bootloader" + #define USB_iProduct_UCS2 'C', 0, 'h', 0, 'r', 0, 'o', 0, 'n', 0, 'o', 0, 's', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 +#elif defined RFCAT_DONSDONGLE + #define USB_VID 0x1D50 + #define USB_PID 0x604A + // iManufacturer + #define USB_iManufacturer_LEN 0x0C + #define USB_iManufacturer_STRING "RfCat" + #define USB_iManufacturer_UCS2 'R', 0, 'f', 0, 'C', 0, 'a', 0, 't', 0 + // iProduct + #define USB_iProduct_LEN 0x20 + #define USB_iProduct_STRING "Dons Bootloader" + #define USB_iProduct_UCS2 'D', 0, 'o', 0, 'n', 0, 's', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 +#else + #define USB_VID 0xFFFE + #define USB_PID 0x000A + // iManufacturer + #define USB_iManufacturer_LEN 0x10 + #define USB_iManufacturer_STRING "JobyGPS" + #define USB_iManufacturer_UCS2 'J', 0, 'o', 0, 'b', 0, 'y', 0, 'G', 0, 'P', 0, 'S', 0 + // iProduct + #define USB_iProduct_LEN 0x1C + #define USB_iProduct_STRING "CC Bootloader" + #define USB_iProduct_UCS2 'C', 0, 'C', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 +#endif + // iSerial #define USB_iSerial_LEN 0x0e #define USB_iSerial_STRING "000001" From 70545587be7e3faecc84ecdd5cc234182dee8411 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Fri, 21 Sep 2012 17:39:55 +0100 Subject: [PATCH 06/13] make read command produce download/verify compatible output. tidy up help. --- bootload.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/bootload.py b/bootload.py index 883715f..7c5aa8c 100755 --- a/bootload.py +++ b/bootload.py @@ -118,9 +118,10 @@ def do_flash_read(serial_port, start_addr, length): def flash_read(serial_port, start_addr, length): do_flash_read(serial_port, start_addr, length) for line in serial_port: - print line, - if (line == ":00000001FF\n"): - break + if not line == "\n": + print line, + if (line == ":00000001FF\n"): + break def print_usage(): import sys @@ -130,13 +131,17 @@ def print_usage(): Usage: ./bootload.py serial_port command Commands: - download hex_file + + download + Download hex_file to the device. run + Run the user code. reset + The bootloader will not erase pages that have previously been written to before writing new data to that page. This allows for random access writes but prevents you from overwriting downloaded code unless the device is @@ -145,20 +150,25 @@ def print_usage(): cycling. erase_all + Erases the entire user flash area. - erage n + erage + Erases page n of the flash memory (organised into 1024 byte pages). The bootloader occupies the first few pages and the rest are reserved for user code. Attempting to erase a bootloader page will have no effect. To determine which page the user code starts on please check the USER_CODE_BASE setting in main.h. - read start_addr len + read + Reads len bytes from flash memory starting from start_addr. start_addr and - len should be specified in hexadecimal (e.g. 0x1234). + len should be specified in hexadecimal (e.g. 0x1234) and must be a multiple + of 16. Output is compatible with download and verify commands. + + verify - verify hex_file Verify hex_file matches device flash memory. """ From 3d9ef20e54e26b7fe8a23fbb4329786ad1af3dab Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Fri, 21 Sep 2012 17:43:14 +0100 Subject: [PATCH 07/13] clarification on read len --- bootload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootload.py b/bootload.py index 7c5aa8c..33bfc8f 100755 --- a/bootload.py +++ b/bootload.py @@ -164,7 +164,7 @@ def print_usage(): read Reads len bytes from flash memory starting from start_addr. start_addr and - len should be specified in hexadecimal (e.g. 0x1234) and must be a multiple + len should be specified in hexadecimal (e.g. 0x1234) and len must be a multiple of 16. Output is compatible with download and verify commands. verify From b7c091d97165e9e29647b8761b8f425e3e8519aa Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Sat, 22 Sep 2012 10:51:33 +0100 Subject: [PATCH 08/13] turns out we can read from arbitrary starting point, not just 16 byte boundries --- bootload.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bootload.py b/bootload.py index 33bfc8f..c7dccce 100755 --- a/bootload.py +++ b/bootload.py @@ -37,12 +37,10 @@ def verify_code(ihx_file, serial_port): length= int(line[1:3], 16) start_addr= int(line[3:7], 16) data= line[9:9+(length*2)] - # we can only read 16 byte chunks on 16 byte boundries - block_start= (start_addr / 16) * 16 - offset= (start_addr - block_start) - block_length= (((length + offset) / 16) + 1) * 16 + # we can only read 16 byte chunks + block_length= ((length / 16) + 1) * 16 print "\rVerifying %04d bytes at address: %04X" % (length, start_addr), - do_flash_read(serial_port, block_start, block_length) + do_flash_read(serial_port, start_addr, block_length) verify_data= '' for read_data in serial_port: read_data= read_data.strip() @@ -50,10 +48,10 @@ def verify_code(ihx_file, serial_port): break # strip header and checksum verify_data += read_data[9:-2] - if (data == verify_data[offset*2:(offset*2)+(length*2)]): + if (data == verify_data[:length*2]): print '(OK)', else: - print 'Failed! Expected:', data, 'Got:', verify_data[offset*2:(offset*2)+(length*2)] + print 'Failed! Expected:', data, 'Got:', verify_data[:length*2] exit(1) sys.stdout.flush() else: From 606e17fafd4fcb675d8b6600f8eafea1782a1769 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Sat, 22 Sep 2012 17:33:32 +0100 Subject: [PATCH 09/13] read (and verify) arbitrary block sizes. optionally read to file. --- bootload.py | 57 +++++++++++++++++++++++++++++++++++++------------ src/intel_hex.c | 28 ++++++++++++++---------- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/bootload.py b/bootload.py index c7dccce..5186799 100755 --- a/bootload.py +++ b/bootload.py @@ -31,14 +31,32 @@ def download_code(ihx_file, serial_port): return True def verify_code(ihx_file, serial_port): + can_read_any= None for line in ihx_file.readlines(): record_type = int(line[7:9], 16) if (record_type == 0x00): - length= int(line[1:3], 16) - start_addr= int(line[3:7], 16) - data= line[9:9+(length*2)] - # we can only read 16 byte chunks - block_length= ((length / 16) + 1) * 16 + length = int(line[1:3], 16) + start_addr = int(line[3:7], 16) + data = line[9:9+(length*2)] + # first time around, check if we can only read 16 byte chunks + if can_read_any == None: + can_read_any = False + do_flash_read(serial_port, start_addr, 1) + for read_data in serial_port: + read_data = read_data.strip() + if not read_data: + continue + if not read_data == ":00000001FF": + can_read_any = True + else: + break + if not can_read_any: + print "*** warning! this version of CC-Bootloader can only read 16 byte blocks!" + print "*** upgrade recommended!" + if can_read_any: + block_length= length + else: + block_length= ((length / 16) + 1) * 16 print "\rVerifying %04d bytes at address: %04X" % (length, start_addr), do_flash_read(serial_port, start_addr, block_length) verify_data= '' @@ -113,13 +131,16 @@ def do_flash_read(serial_port, start_addr, length): serial_port.write(":02%04X25%04X%02X\n" % (start_addr, length, chksum)) -def flash_read(serial_port, start_addr, length): +def flash_read(ihx_file, serial_port, start_addr, length): do_flash_read(serial_port, start_addr, length) for line in serial_port: if not line == "\n": + if(ihx_file): + ihx_file.write(line) + else: print line, - if (line == ":00000001FF\n"): - break + if (line == ":00000001FF\n"): + break def print_usage(): import sys @@ -159,11 +180,11 @@ def print_usage(): determine which page the user code starts on please check the USER_CODE_BASE setting in main.h. - read + read [hex_file] - Reads len bytes from flash memory starting from start_addr. start_addr and - len should be specified in hexadecimal (e.g. 0x1234) and len must be a multiple - of 16. Output is compatible with download and verify commands. + Reads len bytes from flash memory starting from start_addr and optionally + write to hex_file. start_addr and len should be specified in hexadecimal + (e.g. 0x1234). verify @@ -212,8 +233,16 @@ def print_usage(): if (len(options) < 2): print_usage() else: - flash_read(serial_port, int(options[0], 16), int(options[1], 16)) - + ihx_file = None + if(len(options) == 3): + try: + ihx_filename = options[2] + ihx_file = open(ihx_filename, 'w') + print 'reading to:', ihx_filename + except: + print "couldn't open output file:", ihx_filename + exit(2) + flash_read(ihx_file, serial_port, int(options[0], 16), int(options[1], 16)) else: print_usage() diff --git a/src/intel_hex.c b/src/intel_hex.c index 10813c4..4678bba 100644 --- a/src/intel_hex.c +++ b/src/intel_hex.c @@ -164,15 +164,18 @@ void to_hex16_ascii(char buff[], uint16_t x) { void ihx_read_print(__xdata uint8_t* start_addr, uint16_t len) { __xdata char buff[45]; - uint8_t byte, sum, i; + uint8_t byte, sum, i, chunk; - while (len >= 0x10) { + while (len) { sum = 0; + if(len > 0x10) + chunk = 0x10; + else + chunk = len; buff[0] = ':'; - // Record length is 0x10 - to_hex8_ascii(&buff[1], 0x10); - sum += 0x10; + to_hex8_ascii(&buff[1], chunk); + sum += chunk; // Write address into buffer to_hex16_ascii(&buff[3], (uint16_t)start_addr); sum += (uint16_t)start_addr & 0xFF; @@ -180,22 +183,25 @@ void ihx_read_print(__xdata uint8_t* start_addr, uint16_t len) { // Write record type into buffer to_hex8_ascii(&buff[7], 0x00); // Write data bytes into buffer - for (i=0; i<0x10; i++) { + for (i=0; i 0x10) { + start_addr += 0x10; + len -= 0x10; + } else // we're done + len = 0; } usb_putstr(":00000001FF\n"); } From 7b87326fcb1954820b916fc2e98af72435bb6c87 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Wed, 25 Feb 2015 10:25:49 +0000 Subject: [PATCH 10/13] add YARD Stick One target --- Makefile | 11 ++++++++++- src/usb.h | 11 +++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 05e255c..9484c8c 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ ASM_REL = $(ASM_SRC:.asm=.rel) ASM_RST = $(ASM_SRC:.asm=.rst) ASM_SYM = $(ASM_SRC:.asm=.sym) -PROGS = CCBootloader.hex CCBootloader-rfcat-chronosdongle.hex CCBootloader-rfcat-donsdongle.hex +PROGS = CCBootloader.hex CCBootloader-rfcat-chronosdongle.hex CCBootloader-rfcat-donsdongle.hex CCBootloader-rfcat-ys1.hex PCDB = $(PROGS:.hex=.cdb) PLNK = $(PROGS:.hex=.lnk) PMAP = $(PROGS:.hex=.map) @@ -71,6 +71,10 @@ CCBootloader-rfcat-donsdongle.hex: CFLAGS += -DRFCAT -DRFCAT_DONSDONGLE CCBootloader-rfcat-donsdongle.hex: $(REL) $(ASM_REL) Makefile $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-donsdongle.hex $(ASM_REL) $(REL) +CCBootloader-rfcat-ys1.hex: CFLAGS += -DRFCAT -DRFCAT_YARDSTICK1 +CCBootloader-rfcat-ys1.hex: $(REL) $(ASM_REL) Makefile + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-ys1.hex $(ASM_REL) $(REL) + clean: rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) rm -f $(ASM_ADB) $(ASM_LNK) $(ASM_LST) $(ASM_REL) $(ASM_RST) $(ASM_SYM) @@ -91,3 +95,8 @@ installdonsdongle: CCBootloader-rfcat-donsdongle.hex goodfet.cc flash CCBootloader-rfcat-donsdongle.hex goodfet.cc verify CCBootloader-rfcat-donsdongle.hex +installys1dongle: CCBootloader-rfcat-ys1.hex + goodfet.cc erase + goodfet.cc flash CCBootloader-rfcat-ys1.hex + goodfet.cc verify CCBootloader-rfcat-ys1.hex + diff --git a/src/usb.h b/src/usb.h index d94298b..45f72e4 100644 --- a/src/usb.h +++ b/src/usb.h @@ -142,6 +142,17 @@ struct usb_line_coding { #define USB_iProduct_LEN 0x20 #define USB_iProduct_STRING "Dons Bootloader" #define USB_iProduct_UCS2 'D', 0, 'o', 0, 'n', 0, 's', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 +#elif defined RFCAT_YARDSTICK1 + #define USB_VID 0x1D50 + #define USB_PID 0x605C + // iManufacturer + #define USB_iManufacturer_LEN 0x28 + #define USB_iManufacturer_STRING "Great Scott Gadgets" + #define USB_iManufacturer_UCS2 'G', 0, 'r', 0, 'e', 0, 'a', 0, 't', 0, ' ', 0, 'S', 0, 'c', 0, 'o', 0, 't', 0, 't', 0, ' ', 0, 'G', 0, 'a', 0, 'd', 0, 'g', 0, 'e', 0, 't', 0, 's', 0 + // iProduct + #define USB_iProduct_LEN 0x34 + #define USB_iProduct_STRING "YARD Stick One Bootloader" + #define USB_iProduct_UCS2 'Y', 0, 'A', 0, 'R', 0, 'D', 0, ' ', 0, 'S', 0, 't', 0, 'i', 0, 'c', 0, 'k', 0, ' ', 0, 'O', 0, 'n', 0, 'e', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 #else #define USB_VID 0xFFFE #define USB_PID 0x000A From f545a5949917dee2b3d1dc8c60a5291eb6aaba99 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Wed, 25 Feb 2015 18:49:35 +0000 Subject: [PATCH 11/13] configure LEDs and amp pins for yardstick1 --- src/hal.c | 30 +++++++++++++++++++++++++----- src/hal.h | 37 ++++++++++++++++++++++++++----------- src/main.c | 17 ++++++++++++++--- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/hal.c b/src/hal.c index 8a91327..38b3000 100644 --- a/src/hal.c +++ b/src/hal.c @@ -23,24 +23,44 @@ void setup_led() { // Setup LED and turn it off P1DIR |= LED_MASK; - LED = 0; + led_off(); } void setup_button() { - #ifdef RFCAT_DONSDONGLE +#ifdef RFCAT_DONSDONGLE P1DIR &= ~4; - #endif - #ifdef RFCAT_CHRONOS +#endif +#ifdef RFCAT_CHRONOS + P2DIR &= ~4; +#endif +#ifdef RFCAT_YARDSTICK1 P2DIR &= ~4; - #endif + // amplifer configuration pins + P2DIR |= 0x19; + TX_AMP_EN = 0; + RX_AMP_EN = 0; + AMP_BYPASS_EN = 1; +#endif } void led_on() { +#ifdef RFCAT_YARDSTICK1 + LED1 = 1; + LED2 = 1; + LED3 = 1; +#else LED = 1; +#endif } void led_off() { +#ifdef RFCAT_YARDSTICK1 + LED1 = 0; + LED2 = 0; + LED3 = 0; +#else LED = 0; +#endif } void usb_up() { diff --git a/src/hal.h b/src/hal.h index d141d67..336fdd3 100644 --- a/src/hal.h +++ b/src/hal.h @@ -28,15 +28,32 @@ //#define RFCAT_CHRONOS #ifdef RFCAT_CHRONOS - #define LED P1_0 - #define LED_MASK 1 - #define USB_ENABLE P1_1 - #define USB_MASK 2 -#else - #define LED P1_1 - #define LED_MASK 2 - #define USB_ENABLE P1_0 - #define USB_MASK 1 + #define LED P1_0 + #define LED_MASK 1 + #define USB_ENABLE P1_1 + #define USB_MASK 2 + #define CC1111CHRONOS_PIN_DC P2_2 +#endif + +#ifdef RFCAT_DONSDONGLE + #define LED P1_1 + #define LED_MASK 2 + #define USB_ENABLE P1_0 + #define USB_MASK 1 + #define CC1111EM_BUTTON P1_2 +#endif + +#ifdef RFCAT_YARDSTICK1 + #define LED1 P1_1 + #define LED2 P1_2 + #define LED3 P1_3 + #define LED_MASK 0x0E + #define USB_ENABLE P1_0 + #define USB_MASK 1 + #define CC1111YSONE_PIN_DC P2_2 + #define TX_AMP_EN P2_0 + #define RX_AMP_EN P2_4 + #define AMP_BYPASS_EN P2_3 #endif void setup_led(); @@ -47,8 +64,6 @@ void setup_button(); void usb_up(); void usb_down(); -#define CC1111EM_BUTTON P1_2 -#define CC1111CHRONOS_PIN_DC P2_2 #define BUTTON_PRESSED 0 #define GROUNDED 0 #endif // _HAL_H_ diff --git a/src/main.c b/src/main.c index 22771ed..65bdd15 100644 --- a/src/main.c +++ b/src/main.c @@ -196,14 +196,25 @@ void bootloader_main () uint8_t ihx_status; uint16_t read_start_addr, read_len; - #ifdef RFCAT +#ifdef RFCAT // use I2S SFR to signal that bootloader is present I2SCLKF0= 0xF0; I2SCLKF1= 0x0D; setup_button(); - if (CC1111EM_BUTTON != BUTTON_PRESSED && CC1111CHRONOS_PIN_DC != GROUNDED && !want_bootloader()) + #ifdef RFCAT_DONSDONGLE + if (CC1111EM_BUTTON != BUTTON_PRESSED && !want_bootloader()) + #endif + + #ifdef RFCAT_CHRONOS + if (CC1111CHRONOS_PIN_DC != GROUNDED && !want_bootloader()) + #endif + + #ifdef RFCAT_YARDSTICKONE + if (CC1111YSONE_PIN_DC != GROUNDED && !want_bootloader()) + #endif + #else if (!want_bootloader()) #endif @@ -211,7 +222,7 @@ void bootloader_main () #ifdef RFCAT // reset semaphore I2SCLKF2= 0x00; - #endif +#endif clock_init(); From f8a176566d2dc7b53fba111678cd6f65501ce894 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Wed, 25 Feb 2015 19:30:53 +0000 Subject: [PATCH 12/13] fix typo by using same #defines as main rfcat project. this also fixes bootloder re-entry on ys1 --- Makefile | 2 +- src/hal.c | 6 +++--- src/hal.h | 9 +-------- src/main.c | 6 +++--- src/usb.h | 2 +- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 9484c8c..b68b8e2 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ CCBootloader-rfcat-donsdongle.hex: CFLAGS += -DRFCAT -DRFCAT_DONSDONGLE CCBootloader-rfcat-donsdongle.hex: $(REL) $(ASM_REL) Makefile $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-donsdongle.hex $(ASM_REL) $(REL) -CCBootloader-rfcat-ys1.hex: CFLAGS += -DRFCAT -DRFCAT_YARDSTICK1 +CCBootloader-rfcat-ys1.hex: CFLAGS += -DRFCAT -DRFCAT_YARDSTICKONE CCBootloader-rfcat-ys1.hex: $(REL) $(ASM_REL) Makefile $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-ys1.hex $(ASM_REL) $(REL) diff --git a/src/hal.c b/src/hal.c index 38b3000..86d5790 100644 --- a/src/hal.c +++ b/src/hal.c @@ -33,7 +33,7 @@ void setup_button() { #ifdef RFCAT_CHRONOS P2DIR &= ~4; #endif -#ifdef RFCAT_YARDSTICK1 +#ifdef RFCAT_YARDSTICKONE P2DIR &= ~4; // amplifer configuration pins P2DIR |= 0x19; @@ -44,7 +44,7 @@ void setup_button() { } void led_on() { -#ifdef RFCAT_YARDSTICK1 +#ifdef RFCAT_YARDSTICKONE LED1 = 1; LED2 = 1; LED3 = 1; @@ -54,7 +54,7 @@ void led_on() { } void led_off() { -#ifdef RFCAT_YARDSTICK1 +#ifdef RFCAT_YARDSTICKONE LED1 = 0; LED2 = 0; LED3 = 0; diff --git a/src/hal.h b/src/hal.h index 336fdd3..f1be2bf 100644 --- a/src/hal.h +++ b/src/hal.h @@ -20,13 +20,6 @@ #ifndef _HAL_H_ #define _HAL_H_ -// enable RFCAT and dongle version to build custom RFCAT version -// http://code.google.com/p/rfcat/ -// this would normally be done in the Makefile -//#define RFCAT -//#define RFCAT_DONSDONGLE -//#define RFCAT_CHRONOS - #ifdef RFCAT_CHRONOS #define LED P1_0 #define LED_MASK 1 @@ -43,7 +36,7 @@ #define CC1111EM_BUTTON P1_2 #endif -#ifdef RFCAT_YARDSTICK1 +#ifdef RFCAT_YARDSTICKONE #define LED1 P1_1 #define LED2 P1_2 #define LED3 P1_3 diff --git a/src/main.c b/src/main.c index 65bdd15..fef8e55 100644 --- a/src/main.c +++ b/src/main.c @@ -215,11 +215,11 @@ void bootloader_main () if (CC1111YSONE_PIN_DC != GROUNDED && !want_bootloader()) #endif - #else +#else if (!want_bootloader()) - #endif +#endif jump_to_user(); - #ifdef RFCAT +#ifdef RFCAT // reset semaphore I2SCLKF2= 0x00; #endif diff --git a/src/usb.h b/src/usb.h index 45f72e4..f3f606a 100644 --- a/src/usb.h +++ b/src/usb.h @@ -142,7 +142,7 @@ struct usb_line_coding { #define USB_iProduct_LEN 0x20 #define USB_iProduct_STRING "Dons Bootloader" #define USB_iProduct_UCS2 'D', 0, 'o', 0, 'n', 0, 's', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 -#elif defined RFCAT_YARDSTICK1 +#elif defined RFCAT_YARDSTICKONE #define USB_VID 0x1D50 #define USB_PID 0x605C // iManufacturer From b7f95ed3bcc9e1ad15c83871589195d3761b1265 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Thu, 26 Feb 2015 10:51:45 +0000 Subject: [PATCH 13/13] add gpio setup section. add specific gpio setups for YS1 amp pins. --- src/hal.c | 10 ++++++++++ src/hal.h | 11 ++++++----- src/main.c | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/hal.c b/src/hal.c index 86d5790..5b2724f 100644 --- a/src/hal.c +++ b/src/hal.c @@ -35,7 +35,17 @@ void setup_button() { #endif #ifdef RFCAT_YARDSTICKONE P2DIR &= ~4; +#endif +} + +// any other gpio pins +void setup_gpio() { +#ifdef RFCAT_YARDSTICKONE // amplifer configuration pins + //P0_0 input with pull-up (antenna port power off) + P0DIR &= ~1; // Set direction to IN (clear bit for P0_0) + P0INP &= ~P0INP_MDP0_0_TRISTATE; // Set as pull up/down (rather than tristate) + P2INP &= ~P2INP_PDUP0_PULL_DOWN; // clear pull down bit (i.e. pull up) P2DIR |= 0x19; TX_AMP_EN = 0; RX_AMP_EN = 0; diff --git a/src/hal.h b/src/hal.h index f1be2bf..560b471 100644 --- a/src/hal.h +++ b/src/hal.h @@ -22,17 +22,17 @@ #ifdef RFCAT_CHRONOS #define LED P1_0 - #define LED_MASK 1 + #define LED_MASK 0x01 #define USB_ENABLE P1_1 - #define USB_MASK 2 + #define USB_MASK 0x02 #define CC1111CHRONOS_PIN_DC P2_2 #endif #ifdef RFCAT_DONSDONGLE #define LED P1_1 - #define LED_MASK 2 + #define LED_MASK 0x02 #define USB_ENABLE P1_0 - #define USB_MASK 1 + #define USB_MASK 0x01 #define CC1111EM_BUTTON P1_2 #endif @@ -42,7 +42,7 @@ #define LED3 P1_3 #define LED_MASK 0x0E #define USB_ENABLE P1_0 - #define USB_MASK 1 + #define USB_MASK 0x01 #define CC1111YSONE_PIN_DC P2_2 #define TX_AMP_EN P2_0 #define RX_AMP_EN P2_4 @@ -53,6 +53,7 @@ void setup_led(); void led_on(); void led_off(); void setup_button(); +void setup_gpio(); void usb_up(); void usb_down(); diff --git a/src/main.c b/src/main.c index fef8e55..f864d60 100644 --- a/src/main.c +++ b/src/main.c @@ -202,6 +202,7 @@ void bootloader_main () I2SCLKF1= 0x0D; setup_button(); + setup_gpio(); #ifdef RFCAT_DONSDONGLE if (CC1111EM_BUTTON != BUTTON_PRESSED && !want_bootloader())