├── src ├── .gitignore ├── flash.h ├── hal.h ├── main.h ├── hal.c ├── intel_hex.h ├── start.asm ├── usb_descriptors.c ├── flash.c ├── intel_hex.c ├── usb.h ├── main.c ├── usb.c └── cc1111.h ├── example_payload ├── .gitignore ├── Makefile └── main.c ├── .gitignore ├── start.asm ├── driver └── CCBootloader.inf ├── Makefile ├── README.markdown ├── bootload.py └── LICENSE /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.asm 2 | *.lst 3 | *.rel 4 | *.rst 5 | *.sym 6 | -------------------------------------------------------------------------------- /example_payload/.gitignore: -------------------------------------------------------------------------------- 1 | *.asm 2 | *.lst 3 | *.rel 4 | *.rst 5 | *.sym 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.cdb 2 | *.hex 3 | *.ihx 4 | *.lk 5 | *.map 6 | *.mem 7 | *.omf 8 | -------------------------------------------------------------------------------- /start.asm: -------------------------------------------------------------------------------- 1 | ;-------------------------------------------------------- 2 | ; interrupt vector 3 | ;-------------------------------------------------------- 4 | .area HOME (CODE) 5 | __interrupt_vect: 6 | ljmp __sdcc_gsinit_startup 7 | reti 8 | .ds 7 9 | reti 10 | .ds 7 11 | reti 12 | .ds 7 13 | reti 14 | .ds 7 15 | reti 16 | .ds 7 17 | reti 18 | .ds 7 19 | ljmp _usb_isr 20 | .ds 5 21 | reti 22 | .ds 7 23 | reti 24 | .ds 7 25 | reti 26 | .ds 7 27 | reti 28 | .ds 7 29 | reti 30 | .ds 7 31 | reti 32 | .ds 7 33 | reti 34 | .ds 7 35 | reti 36 | .ds 7 37 | reti 38 | .ds 7 39 | reti 40 | .ds 7 41 | reti 42 | .ds 7 43 | reti 44 | .ds 7 45 | 46 | .area GSFINAL (CODE) 47 | ljmp __sdcc_program_startup 48 | ;-------------------------------------------------------- 49 | ; Home 50 | ;-------------------------------------------------------- 51 | .area HOME (CODE) 52 | .area HOME (CODE) 53 | __sdcc_program_startup: 54 | lcall _bootloader_main 55 | ; return from main will lock up 56 | sjmp . -------------------------------------------------------------------------------- /example_payload/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # CC Debugger - Example Payload 3 | # Fergus Noble (c) 2011 4 | # 5 | 6 | CC = sdcc 7 | 8 | CFLAGS = --model-small --opt-code-speed 9 | 10 | # NOTE: code-loc should be the same as the value specified for 11 | # USER_CODE_BASE in the bootloader! 12 | LDFLAGS_FLASH = \ 13 | --out-fmt-ihx \ 14 | --code-loc 0x1400 --code-size 0x8000 \ 15 | --xram-loc 0xf000 --xram-size 0x300 \ 16 | --iram-size 0x100 17 | 18 | ifdef DEBUG 19 | CFLAGS += --debug 20 | endif 21 | 22 | SRC = main.c 23 | 24 | ADB=$(SRC:.c=.adb) 25 | ASM=$(SRC:.c=.asm) 26 | LNK=$(SRC:.c=.lnk) 27 | LST=$(SRC:.c=.lst) 28 | REL=$(SRC:.c=.rel) 29 | RST=$(SRC:.c=.rst) 30 | SYM=$(SRC:.c=.sym) 31 | 32 | PROGS=example_payload.hex 33 | PCDB=$(PROGS:.hex=.cdb) 34 | PLNK=$(PROGS:.hex=.lnk) 35 | PMAP=$(PROGS:.hex=.map) 36 | PMEM=$(PROGS:.hex=.mem) 37 | PAOM=$(PROGS:.hex=) 38 | 39 | %.rel : %.c 40 | $(CC) -c $(CFLAGS) -o$*.rel $< 41 | 42 | all: $(PROGS) 43 | 44 | example_payload.hex: $(REL) Makefile 45 | $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o example_payload.hex $(REL) 46 | 47 | clean: 48 | rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) 49 | rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) 50 | 51 | -------------------------------------------------------------------------------- /example_payload/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Example Payload 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #include "../src/cc1111.h" 21 | 22 | #define nop() __asm nop __endasm; 23 | 24 | void delay (unsigned char n) { 25 | unsigned char i = 0; 26 | unsigned char j = 0; 27 | 28 | n <<= 1; 29 | while (--n != 0) 30 | while (--i != 0) 31 | while (--j != 0) 32 | nop(); 33 | } 34 | 35 | void main() 36 | { 37 | // Setup LED and turn it off 38 | P1DIR |= 2; 39 | P1_1 = 0; 40 | 41 | while (1) 42 | { 43 | P1_1 ^= 1; 44 | delay(3); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/flash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Flash controller driver 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #ifndef _FLASH_H_ 21 | #define _FLASH_H_ 22 | 23 | // Flash write timer value: 24 | // FWT = 21000 * FCLK / (16 * 10^9) 25 | // For FCLK = 24MHz, FWT = 0x1F 26 | #define FLASH_FWT 0x1F 27 | // Address of flash controller data register 28 | #define FLASH_FWDATA_ADDR 0xDFAF 29 | 30 | void flash_erase_page(uint8_t page); 31 | 32 | void flash_write(uint16_t buff[], uint16_t len, uint16_t flash_addr); 33 | 34 | // Check if a page was previously erased 35 | uint8_t flash_erased_page(uint8_t page); 36 | // Erase page only if it was never previously erased 37 | void flash_check_and_erase(uint8_t page); 38 | // Write to flash, erasing pages as needed that have never yet been erased 39 | void flash_check_erase_and_write(uint16_t buff[], uint16_t len, uint16_t flash_addr); 40 | // Reset record of which pages have been erased 41 | void flash_reset(); 42 | // Erase all user flash pages 43 | void flash_erase_all_user(); 44 | 45 | #endif // _FLASH_H_ -------------------------------------------------------------------------------- /src/hal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Hardware Abstraction Layer 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #ifndef _HAL_H_ 21 | #define _HAL_H_ 22 | 23 | #ifdef RFCAT_CHRONOS 24 | #define LED P1_0 25 | #define LED_MASK 0x01 26 | #define USB_ENABLE P1_1 27 | #define USB_MASK 0x02 28 | #define CC1111CHRONOS_PIN_DC P2_2 29 | #endif 30 | 31 | #ifdef RFCAT_DONSDONGLE 32 | #define LED P1_1 33 | #define LED_MASK 0x02 34 | #define USB_ENABLE P1_0 35 | #define USB_MASK 0x01 36 | #define CC1111EM_BUTTON P1_2 37 | #endif 38 | 39 | #ifdef RFCAT_YARDSTICKONE 40 | #define LED1 P1_1 41 | #define LED2 P1_2 42 | #define LED3 P1_3 43 | #define LED_MASK 0x0E 44 | #define USB_ENABLE P1_0 45 | #define USB_MASK 0x01 46 | #define CC1111YSONE_PIN_DC P2_2 47 | #define TX_AMP_EN P2_0 48 | #define RX_AMP_EN P2_4 49 | #define AMP_BYPASS_EN P2_3 50 | #endif 51 | 52 | void setup_led(); 53 | void led_on(); 54 | void led_off(); 55 | void setup_button(); 56 | void setup_gpio(); 57 | 58 | void usb_up(); 59 | void usb_down(); 60 | 61 | #define BUTTON_PRESSED 0 62 | #define GROUNDED 0 63 | #endif // _HAL_H_ 64 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Main 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #ifndef _MAIN_H_ 21 | #define _MAIN_H_ 22 | 23 | // The address of the start of the user code section 24 | // This must be a multiple of 1kb to fit on a flash page boundary 25 | // !!! NOTE: at the moment you must also change this in start.asm IVT !!! 26 | #define USER_CODE_BASE (5*1024) 27 | #define USER_FIRST_PAGE (USER_CODE_BASE/1024) 28 | 29 | // Change to match the CC1111 part you are using 30 | #define FLASH_SIZE 0x8000 31 | //(32*1024) 32 | #define FLASH_PAGES (FLASH_SIZE/1024) 33 | 34 | // If TIMER is enabled then the bootloader will jump to user code after 35 | // a period of time if there has been no activity on the USB interface. 36 | //#define TIMER 37 | // TIMER_TIMEOUT sets the period of the timer timeout in units of 38 | // approximately 43.7 milliseconds. 39 | #define TIMER_TIMEOUT 229 // 10s timeout 40 | 41 | // Useful for printf etc. but uses a bunch of code space 42 | //#define STDIO 43 | #ifdef STDIO 44 | #include 45 | #else 46 | // TODO: put prototypes here maybe so things don't break when 47 | // this is disabled? 48 | #endif 49 | 50 | #define nop() __asm nop __endasm; 51 | 52 | extern uint8_t bootloader_running; 53 | 54 | #endif // _MAIN_H_ -------------------------------------------------------------------------------- /src/hal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Hardware Abstraction Layer 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #include "cc1111.h" 21 | #include "hal.h" 22 | 23 | void setup_led() { 24 | // Setup LED and turn it off 25 | P1DIR |= LED_MASK; 26 | led_off(); 27 | } 28 | 29 | void setup_button() { 30 | #ifdef RFCAT_DONSDONGLE 31 | P1DIR &= ~4; 32 | #endif 33 | #ifdef RFCAT_CHRONOS 34 | P2DIR &= ~4; 35 | #endif 36 | #ifdef RFCAT_YARDSTICKONE 37 | P2DIR &= ~4; 38 | #endif 39 | } 40 | 41 | // any other gpio pins 42 | void setup_gpio() { 43 | #ifdef RFCAT_YARDSTICKONE 44 | // amplifer configuration pins 45 | //P0_0 input with pull-up (antenna port power off) 46 | P0DIR &= ~1; // Set direction to IN (clear bit for P0_0) 47 | P0INP &= ~P0INP_MDP0_0_TRISTATE; // Set as pull up/down (rather than tristate) 48 | P2INP &= ~P2INP_PDUP0_PULL_DOWN; // clear pull down bit (i.e. pull up) 49 | P2DIR |= 0x19; 50 | TX_AMP_EN = 0; 51 | RX_AMP_EN = 0; 52 | AMP_BYPASS_EN = 1; 53 | #endif 54 | } 55 | 56 | void led_on() { 57 | #ifdef RFCAT_YARDSTICKONE 58 | LED1 = 1; 59 | LED2 = 1; 60 | LED3 = 1; 61 | #else 62 | LED = 1; 63 | #endif 64 | } 65 | 66 | void led_off() { 67 | #ifdef RFCAT_YARDSTICKONE 68 | LED1 = 0; 69 | LED2 = 0; 70 | LED3 = 0; 71 | #else 72 | LED = 0; 73 | #endif 74 | } 75 | 76 | void usb_up() { 77 | // Bring up the USB link 78 | P1DIR |= USB_MASK; 79 | USB_ENABLE = 1; 80 | } 81 | 82 | void usb_down() { 83 | // Bring down the USB link 84 | USB_ENABLE = 0; 85 | P1DIR &= ~USB_MASK; 86 | } 87 | -------------------------------------------------------------------------------- /driver/CCBootloader.inf: -------------------------------------------------------------------------------- 1 | ; Copyright (C) 2010 Keith Packard (keithp@keithp.com) 2 | ; released under GNU General Public License version 2 3 | ; Modified by Fergus Noble for CC Bootloader 2011 4 | 5 | [Version] 6 | Signature = "$Windows NT$" 7 | Class = Modem 8 | ClassGUID = {4D36E96D-E325-11CE-BFC1-08002BE10318} 9 | Provider = %Mfg% 10 | DriverVer = 08/05/2010,7.1.1.0 11 | PnpLockDown = 0 12 | DriverPackageDisplayName = %DriverName% 13 | 14 | [DestinationDirs] 15 | FakeModemCopyFileSection = 12 16 | DefaultDestDir = 12 17 | 18 | [ControlFlags] 19 | 20 | [Manufacturer] 21 | %Mfg% = Models, NTx86, NTamd64, NTia64 22 | 23 | [Models] 24 | %CCBootloader% = CCBootloader.Install, USB\VID_FFFE&PID_000A, CCBootloaderSerial 25 | 26 | [Models.NTx86] 27 | %CCBootloader% = CCBootloader.Install, USB\VID_FFFE&PID_000A, CCBootloaderSerial 28 | 29 | [Models.NTamd64] 30 | %CCBootloader% = CCBootloader.Install, USB\VID_FFFE&PID_000A, CCBootloaderSerial 31 | 32 | [Models.NTia64] 33 | %CCBootloader% = CCBootloader.Install, USB\VID_FFFE&PID_000A, CCBootloaderSerial 34 | 35 | ;---------------------------------------------------------------------------- 36 | ; Installation sections 37 | ;---------------------------------------------------------------------------- 38 | 39 | [CCBootloader.Install.NT] 40 | include = mdmcpq.inf 41 | CopyFiles = FakeModemCopyFileSection 42 | AddReg = All.AddReg, Modem.AddReg, Uninstall.AddReg 43 | 44 | [CCBootloader.Install.NT.Services] 45 | include = mdmcpq.inf 46 | AddService = usbser, 0x00000000, LowerFilter_Service_Inst 47 | 48 | [CCBootloader.Install.NT.HW] 49 | include = mdmcpq.inf 50 | AddReg = LowerFilterAddReg 51 | 52 | ;---------------------------------------------------------------------------- 53 | ; AddReg sections 54 | ;---------------------------------------------------------------------------- 55 | 56 | [All.AddReg] 57 | HKR,,FriendlyDriver,, Unimodem.vxd 58 | HKR,,DevLoader,, *vcomm 59 | HKR,,ConfigDialog,, modemui.dll 60 | HKR,,EnumPropPages,, "modemui.dll,EnumPropPages" 61 | HKR,,PortSubClass, 1, 02 62 | HKR,,DeviceType, 1, 01 63 | 64 | [Modem.AddReg] 65 | HKR,, Properties, 1, C0,01,00,00, 00,00,00,00, FF,00,00,00, 07,00,00,00, 0F,00,00,00, F7,0F,00,00, 00,84,03,00, C0,DA,00,00 66 | 67 | [Uninstall.AddReg] 68 | HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\%CCBootloader%,DisplayName,,"%CCBootloader%" 69 | 70 | [Strings] 71 | Mfg = "JobyGPS" 72 | CCBootloader = "CCBootloader" 73 | DriverName = "CC1111 Bootloader Device Driver" 74 | 75 | -------------------------------------------------------------------------------- /src/intel_hex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Intel HEX file format functions 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #ifndef _INTEL_HEX_H_ 21 | #define _INTEL_HEX_H_ 22 | 23 | #define IHX_OK 0 24 | #define IHX_INVALID 1 25 | #define IHX_BAD_CHECKSUM 2 26 | #define IHX_BAD_ADDRESS 3 27 | #define IHX_BAD_RECORD_TYPE 4 28 | #define IHX_RECORD_TOO_LONG 5 29 | 30 | #define IHX_MAX_LEN 0x10 31 | 32 | #define HEX_INVALID 0xFF 33 | 34 | #define IHX_RECORD_DATA 0x00 35 | #define IHX_RECORD_EOF 0x01 36 | 37 | // Custom record types used to implement some extra bootloader functionality. 38 | 39 | // Reset record will reset the page erase map which usually ensures each page is only 40 | // erased once, allowing for random writes but preventing overwriting of data already written 41 | // this session. 42 | // :00000022DE 43 | #define IHX_RECORD_RESET 0x22 44 | 45 | // Erases all of the user code flash pages 46 | // :00000023DD 47 | #define IHX_RECORD_ERASE_ALL 0x23 48 | 49 | // Erases a single page of the user code flash 50 | // :01000024xxyy 51 | // xx - Page number, yy - Checksum 52 | #define IHX_RECORD_ERASE_PAGE 0x24 53 | 54 | // Reads back a section of flash in Intel HEX format 55 | // :04xxxx24yyyyzz 56 | // xxxx - Start address, yyyy - Num bytes to read, zz - Checksum 57 | #define IHX_RECORD_READ 0x25 58 | 59 | 60 | uint8_t hex4(char c); 61 | uint8_t hex8(char s[]); 62 | uint16_t hex16(char s[]); 63 | char to_hex4_ascii(uint8_t x); 64 | void to_hex8_ascii(char buff[], uint8_t x); 65 | void to_hex16_ascii(char buff[], uint16_t x); 66 | 67 | uint8_t ihx_check_line(char line[]); 68 | void ihx_readline(char line[]); 69 | void ihx_write(char line[]); 70 | uint8_t ihx_record_type(char line[]); 71 | uint16_t ihx_record_address(char line[]); 72 | uint8_t ihx_data_byte(char line[], uint8_t n); 73 | void ihx_read_print(__xdata uint8_t* start_addr, uint16_t len); 74 | 75 | #endif // _INTEL_HEX_H_ -------------------------------------------------------------------------------- /src/start.asm: -------------------------------------------------------------------------------- 1 | .globl __start__stack 2 | ;-------------------------------------------------------- 3 | ; Stack segment in internal ram 4 | ;-------------------------------------------------------- 5 | .area SSEG (DATA) 6 | __start__stack: 7 | .ds 1 8 | 9 | ;-------------------------------------------------------- 10 | ; interrupt vector 11 | ;-------------------------------------------------------- 12 | .area VECTOR (CODE) 13 | .globl __interrupt_vect 14 | __interrupt_vect: 15 | ljmp __sdcc_gsinit_startup 16 | 17 | ljmp #(0x1400+0x03) 18 | .ds 5 19 | ljmp #(0x1400+0x0B) 20 | .ds 5 21 | ljmp #(0x1400+0x13) 22 | .ds 5 23 | ljmp #(0x1400+0x1B) 24 | .ds 5 25 | ljmp #(0x1400+0x23) 26 | .ds 5 27 | ljmp #(0x1400+0x2B) 28 | .ds 5 29 | ljmp usb_isr_forward 30 | .ds 5 31 | ljmp #(0x1400+0x3B) 32 | .ds 5 33 | ljmp #(0x1400+0x43) 34 | .ds 5 35 | ljmp _timer1_isr_forward ; defined in main.c 36 | .ds 5 37 | ljmp #(0x1400+0x53) 38 | .ds 5 39 | ljmp #(0x1400+0x5B) 40 | .ds 5 41 | ljmp #(0x1400+0x63) 42 | .ds 5 43 | ljmp #(0x1400+0x6B) 44 | .ds 5 45 | ljmp #(0x1400+0x73) 46 | .ds 5 47 | ljmp #(0x1400+0x7B) 48 | .ds 5 49 | ljmp #(0x1400+0x83) 50 | .ds 5 51 | ljmp #(0x1400+0x8B) 52 | .ds 5 53 | 54 | usb_isr_forward: 55 | push acc 56 | mov a, _bootloader_running 57 | jnz usb_isr_forward_bootloader 58 | ; Bootloader not running, jump into the payload ISR 59 | pop acc 60 | ljmp #(0x1400+0x33) 61 | usb_isr_forward_bootloader: 62 | pop acc 63 | ljmp _usb_isr 64 | 65 | ;-------------------------------------------------------- 66 | ; external initialized ram data 67 | ;-------------------------------------------------------- 68 | .area XISEG (XDATA) 69 | .area HOME (CODE) 70 | .area GSINIT0 (CODE) 71 | .area GSINIT1 (CODE) 72 | .area GSINIT2 (CODE) 73 | .area GSINIT3 (CODE) 74 | .area GSINIT4 (CODE) 75 | .area GSINIT5 (CODE) 76 | .area GSINIT (CODE) 77 | .area GSFINAL (CODE) 78 | .area CSEG (CODE) 79 | 80 | ;-------------------------------------------------------- 81 | ; global & static initialisations 82 | ;-------------------------------------------------------- 83 | 84 | .area GSINIT (CODE) 85 | .globl __sdcc_gsinit_startup 86 | .globl __sdcc_program_startup 87 | .globl __start__stack 88 | .globl __mcs51_genXINIT 89 | .globl __mcs51_genXRAMCLEAR 90 | .globl __mcs51_genRAMCLEAR 91 | .area GSFINAL (CODE) 92 | .globl __sdcc_program_startup 93 | ljmp __sdcc_program_startup 94 | ;-------------------------------------------------------- 95 | ; Home 96 | ;-------------------------------------------------------- 97 | .area HOME (CODE) 98 | .area HOME (CODE) 99 | __sdcc_program_startup: 100 | lcall _bootloader_main 101 | ; return from main will lock up 102 | sjmp . -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # CC Debugger 3 | # Fergus Noble (c) 2011 4 | # 5 | 6 | CC = sdcc 7 | AS = sdas8051 8 | 9 | CFLAGS = --model-small --opt-code-size 10 | 11 | LDFLAGS_FLASH = \ 12 | --out-fmt-ihx \ 13 | --code-loc 0x0000 --code-size 0x1400 \ 14 | --xram-loc 0xf000 --xram-size 0x300 \ 15 | --iram-size 0x100 16 | 17 | ASFLAGS = -plosgff 18 | 19 | ifdef DEBUG 20 | CFLAGS += --debug 21 | endif 22 | 23 | SRC = \ 24 | src/main.c \ 25 | src/usb.c \ 26 | src/flash.c \ 27 | src/intel_hex.c \ 28 | src/hal.c \ 29 | src/usb_descriptors.c 30 | 31 | ASM_SRC = src/start.asm 32 | 33 | ADB = $(SRC:.c=.c.adb) 34 | ASM = $(SRC:.c=.c.asm) 35 | LNK = $(SRC:.c=.c.lnk) 36 | LST = $(SRC:.c=.c.lst) 37 | REL = $(SRC:.c=.c.rel) 38 | RST = $(SRC:.c=.c.rst) 39 | SYM = $(SRC:.c=.c.sym) 40 | 41 | ASM_ADB = $(ASM_SRC:.asm=.adb) 42 | ASM_LNK = $(ASM_SRC:.asm=.lnk) 43 | ASM_LST = $(ASM_SRC:.asm=.lst) 44 | ASM_REL = $(ASM_SRC:.asm=.rel) 45 | ASM_RST = $(ASM_SRC:.asm=.rst) 46 | ASM_SYM = $(ASM_SRC:.asm=.sym) 47 | 48 | PROGS = CCBootloader.hex CCBootloader-rfcat-chronosdongle.hex CCBootloader-rfcat-donsdongle.hex CCBootloader-rfcat-ys1.hex 49 | PCDB = $(PROGS:.hex=.cdb) 50 | PLNK = $(PROGS:.hex=.lnk) 51 | PMAP = $(PROGS:.hex=.map) 52 | PMEM = $(PROGS:.hex=.mem) 53 | PAOM = $(PROGS:.hex=) 54 | 55 | %.c.rel : %.c 56 | $(CC) -c $(CFLAGS) -o$*.c.rel $< 57 | 58 | %.rel : %.asm 59 | $(AS) -c $(ASFLAGS) $< 60 | 61 | all: $(PROGS) 62 | 63 | CCBootloader.hex: $(REL) $(ASM_REL) Makefile 64 | $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader.hex $(ASM_REL) $(REL) 65 | 66 | CCBootloader-rfcat-chronosdongle.hex: CFLAGS += -DRFCAT -DRFCAT_CHRONOS 67 | CCBootloader-rfcat-chronosdongle.hex: $(REL) $(ASM_REL) Makefile 68 | $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-chronosdongle.hex $(ASM_REL) $(REL) 69 | 70 | CCBootloader-rfcat-donsdongle.hex: CFLAGS += -DRFCAT -DRFCAT_DONSDONGLE 71 | CCBootloader-rfcat-donsdongle.hex: $(REL) $(ASM_REL) Makefile 72 | $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-donsdongle.hex $(ASM_REL) $(REL) 73 | 74 | CCBootloader-rfcat-ys1.hex: CFLAGS += -DRFCAT -DRFCAT_YARDSTICKONE 75 | CCBootloader-rfcat-ys1.hex: $(REL) $(ASM_REL) Makefile 76 | $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o CCBootloader-rfcat-ys1.hex $(ASM_REL) $(REL) 77 | 78 | clean: 79 | rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) 80 | rm -f $(ASM_ADB) $(ASM_LNK) $(ASM_LST) $(ASM_REL) $(ASM_RST) $(ASM_SYM) 81 | rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) 82 | 83 | install: CCBootloader.hex 84 | goodfet.cc erase 85 | goodfet.cc flash CCBootloader.hex 86 | goodfet.cc verify CCBootloader.hex 87 | 88 | installchronosdongle: CCBootloader-rfcat-chronosdongle.hex 89 | goodfet.cc erase 90 | goodfet.cc flash CCBootloader-rfcat-chronosdongle.hex 91 | goodfet.cc verify CCBootloader-rfcat-chronosdongle.hex 92 | 93 | installdonsdongle: CCBootloader-rfcat-donsdongle.hex 94 | goodfet.cc erase 95 | goodfet.cc flash CCBootloader-rfcat-donsdongle.hex 96 | goodfet.cc verify CCBootloader-rfcat-donsdongle.hex 97 | 98 | installys1dongle: CCBootloader-rfcat-ys1.hex 99 | goodfet.cc erase 100 | goodfet.cc flash CCBootloader-rfcat-ys1.hex 101 | goodfet.cc verify CCBootloader-rfcat-ys1.hex 102 | 103 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | CC Bootloader 2 | ============= 3 | 4 | CC Bootloader is a simple USB bootloader for the CC1111 microcontroller (and 5 | probably others in the family e.g. CC2511). It allows the update of the 6 | microcontroller firmware over its USB port. It also supports reading and 7 | writing to the flash memory of the microcontroller e.g. for user data storage. 8 | 9 | The bootloader consists of two components, a piece of firmware that is flashed 10 | onto the device and a python utility for downloading code and manipulating the 11 | flash memory. 12 | 13 | Usage 14 | ----- 15 | 16 | The first step is to flash your device with the `CCBootloader.hex` firmware 17 | file. Once the device is flashed with this firmware it will identify itself 18 | over USB as a CDC-class device which means it should show up as a serial port 19 | without requiring any drivers on Linux and Mac OS X. Windows users should use 20 | the `CCBootloader.inf` driver file in the `driver` subdirectory. 21 | 22 | If you have downloaded a release version of CC Bootloader it will include a 23 | `CCBootloader.hex` file that you can simply flash onto your device. If you 24 | have downloaded a development version then see the Building section below to 25 | build the `CCBootloader.hex` file. You may also want to build your own version 26 | to enable or disable certain features. 27 | 28 | You can now use the bootloader.py python script to download your payload code. 29 | This script requires the [pySerial](http://pyserial.sourceforge.net/) library. 30 | If you have `easy_install` then installing pySerial should be simple: 31 | 32 | `sudo easy_install pyserial` 33 | 34 | For usage instructions of this script, run the script with no arguments: 35 | 36 | `./bootloader.py` 37 | 38 | Preparing your user code for usage with the bootloader is very simple. All you 39 | need to do is set your linker to start the code section at a higher location 40 | in memory specified by the `USER_CODE_BASE` define in `src/main.h`. For an 41 | example of this see the `Makefile` file in the `example_payload` subdirectory. 42 | This is the relevant line: 43 | 44 | `LDFLAGS_FLASH = ... --code-loc 0x1400 ...` 45 | 46 | Building 47 | -------- 48 | 49 | This requires [sdcc](http://sdcc.sourceforge.net/) (Small Device C Compiler). 50 | Then it should be as simple as issuing 51 | 52 | `make` 53 | 54 | from the root directory of the project. 55 | 56 | Build Options 57 | ------------- 58 | 59 | The only option that can currently be enabled or disabled is weather to start 60 | running the user payload code after a certain timeout with no command issued 61 | over USB. Once a USB command is issued this timeout will be canceled and a 62 | command must be issued to explicitly start the user code. This option is 63 | specified in `src/main.h`. Just comment or uncomment this line: 64 | 65 | `#define TIMER` 66 | 67 | You may also change the length of the timeout (default 10 seconds): 68 | 69 | `#define TIMER_TIMEOUT 229 // 10s timeout` 70 | 71 | Please note that if you make changes to the bootloader you may need to adjust 72 | the value of `USER_CODE_BASE`. You will need to do this if the linker 73 | complains that it has run out of space. This value muse be a multiple of 1,024 74 | so that the user code begins on a page boundary. 75 | 76 | You must reflect this change in several places: 77 | 78 | 1. Change the value of `USER_CODE_BASE` in `src/main.h` 79 | 80 | 2. Change the value of `--code-size` in `Makefile` 81 | 82 | 3. Change all the lines similar to `ljmp #(0x1400+0x03)` in `src/start.asm`. 83 | The constant `0x1400` should be changed to match `USER_CODE_BASE` but the 84 | `+0x??` part should be unchanged. 85 | 86 | Hopefully step three will not be needed in the future when I find a better 87 | way to implement this part of the code. 88 | 89 | If you want the bootloader to only be invoked under certain conditions, e.g. 90 | the presence of USB power then please modify the `want_bootloader` function 91 | in `main.c` 92 | 93 | All the board specific code is in `hal.c` so make sure to take a look at that 94 | if you are porting the code to a new board. 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - USB descriptors 3 | * 4 | * Adapted from AltOS code by Fergus Noble (c) 2011 5 | * AltOS code Copyright © 2009 Keith Packard 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 2 of the License. 10 | * 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, write to the Free Software Foundation, Inc., 18 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 | */ 20 | 21 | #include "cc1111.h" 22 | #include "usb.h" 23 | 24 | // USB descriptors in one giant block of bytes 25 | __code __at(0x00aa) uint8_t usb_descriptors [] = 26 | { 27 | // Device descriptor 28 | 0x12, 29 | USB_DESC_DEVICE, 30 | LE_WORD(0x0110), // bcdUSB 31 | 0x02, // bDeviceClass 32 | 0x00, // bDeviceSubClass 33 | 0x00, // bDeviceProtocol 34 | USB_CONTROL_SIZE, // bMaxPacketSize 35 | LE_WORD(USB_VID), // idVendor 36 | LE_WORD(USB_PID), // idProduct 37 | LE_WORD(0x010), // bcdDevice 38 | 0x01, // iManufacturer 39 | 0x02, // iProduct 40 | 0x03, // iSerialNumber 41 | 0x01, // bNumConfigurations 42 | 43 | // Configuration descriptor 44 | 0x09, 45 | USB_DESC_CONFIGURATION, 46 | LE_WORD(67), // wTotalLength 47 | 0x02, // bNumInterfaces 48 | 0x01, // bConfigurationValue 49 | 0x00, // iConfiguration 50 | 0xC0, // bmAttributes 51 | 0x32, // bMaxPower 52 | 53 | // Control class interface 54 | 0x09, 55 | USB_DESC_INTERFACE, 56 | 0x00, // bInterfaceNumber 57 | 0x00, // bAlternateSetting 58 | 0x01, // bNumEndPoints 59 | 0x02, // bInterfaceClass 60 | 0x02, // bInterfaceSubClass 61 | 0x01, // bInterfaceProtocol, linux requires value of 1 for the cdc_acm module 62 | 0x00, // iInterface 63 | 64 | // Header functional descriptor 65 | 0x05, 66 | CS_INTERFACE, 67 | 0x00, // bDescriptor SubType Header 68 | LE_WORD(0x0110), // CDC version 1.1 69 | 70 | // Call management functional descriptor 71 | 0x05, 72 | CS_INTERFACE, 73 | 0x01, // bDescriptor SubType Call Management 74 | 0x01, // bmCapabilities = device handles call management 75 | 0x01, // bDataInterface call management interface number 76 | 77 | // ACM functional descriptor 78 | 0x04, 79 | CS_INTERFACE, 80 | 0x02, // bDescriptor SubType Abstract Control Management 81 | 0x02, // bmCapabilities = D1 (Set_line_Coding, Set_Control_Line_State, Get_Line_Coding and Serial_State) 82 | 83 | // Union functional descriptor 84 | 0x05, 85 | CS_INTERFACE, 86 | 0x06, // bDescriptor SubType Union Functional descriptor 87 | 0x00, // bMasterInterface 88 | 0x01, // bSlaveInterface0 89 | 90 | // Notification EP 91 | 0x07, 92 | USB_DESC_ENDPOINT, 93 | USB_INT_EP|0x80, // bEndpointAddress 94 | 0x03, // bmAttributes = intr 95 | LE_WORD(8), // wMaxPacketSize 96 | 0x0A, // bInterval 97 | 98 | // Data class interface descriptor 99 | 0x09, 100 | USB_DESC_INTERFACE, 101 | 0x01, // bInterfaceNumber 102 | 0x00, // bAlternateSetting 103 | 0x02, // bNumEndPoints 104 | 0x0A, // bInterfaceClass = data 105 | 0x00, // bInterfaceSubClass 106 | 0x00, // bInterfaceProtocol 107 | 0x00, // iInterface 108 | 109 | // Data EP OUT 110 | 0x07, 111 | USB_DESC_ENDPOINT, 112 | USB_OUT_EP, // bEndpointAddress 113 | 0x02, // bmAttributes = bulk 114 | LE_WORD(USB_OUT_SIZE), // wMaxPacketSize 115 | 0x00, // bInterval 116 | 117 | // Data EP in 118 | 0x07, 119 | USB_DESC_ENDPOINT, 120 | USB_IN_EP|0x80, // bEndpointAddress 121 | 0x02, // bmAttributes = bulk 122 | LE_WORD(USB_IN_SIZE), // wMaxPacketSize 123 | 0x00, // bInterval 124 | 125 | // String descriptors 126 | 0x04, 127 | USB_DESC_STRING, 128 | LE_WORD(0x0409), 129 | 130 | // iManufacturer 131 | USB_iManufacturer_LEN, 132 | USB_DESC_STRING, 133 | USB_iManufacturer_UCS2, 134 | 135 | // iProduct 136 | USB_iProduct_LEN, 137 | USB_DESC_STRING, 138 | USB_iProduct_UCS2, 139 | 140 | // iSerial 141 | USB_iSerial_LEN, 142 | USB_DESC_STRING, 143 | USB_iSerial_UCS2, 144 | 145 | // Terminating zero 146 | 0 147 | }; -------------------------------------------------------------------------------- /src/flash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Flash controller driver 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #include "cc1111.h" 21 | #include "flash.h" 22 | #include "main.h" 23 | #include "usb.h" 24 | 25 | static __xdata struct cc_dma_channel dma0_config; 26 | uint32_t erased_page_flags = 0; 27 | 28 | void flash_erase_page(uint8_t page) { 29 | // Don't let's erase the bootloader, please 30 | if (page < USER_FIRST_PAGE) 31 | return; 32 | 33 | // Waiting for the flash controller to be ready 34 | while (FCTL & FCTL_BUSY) {} 35 | 36 | // Set bit showing that the flash page has been erased 37 | erased_page_flags |= ((uint32_t)1 << page); 38 | 39 | // Configure flash controller for a flash page erase 40 | // FADDRH[5:1] contains the page to erase 41 | // FADDRH[1]:FADDRL[7:0] contains the address within the page 42 | // (16-bit word addressed) 43 | FWT = FLASH_FWT; 44 | FADDRH = page << 1; 45 | FADDRL = 0x00; 46 | 47 | // Erase the page that will be written to 48 | FCTL |= FCTL_ERASE; 49 | nop(); // Required, see datasheet 50 | 51 | // Wait for the erase operation to complete 52 | while (FCTL & FCTL_BUSY) {} 53 | 54 | //FCTL &= ~FCTL_ERASE; 55 | } 56 | 57 | void flash_write_trigger() { 58 | // Enable flash write. Generates a DMA trigger. Must be aligned on a 2-byte 59 | // boundary and is therefore implemented in assembly. 60 | 61 | // p.s. if this looks a little crazy its because it is, sdcc doesn't currently 62 | // support explicitly specifying code alignment which would make this easier 63 | 64 | __asm 65 | .globl flash_write_trigger_instruction 66 | .globl flash_write_trigger_done 67 | 68 | ; Put our trigger instruction in the HOME segment (shared with some startup code) 69 | ; where it wont move around too much 70 | .area HOME (CODE) 71 | ; Comment or uncomment these lines to adjust if you change the start.asm code 72 | nop ; Padding to get onto 16-bit boundary 73 | flash_write_trigger_instruction: 74 | orl _FCTL, #0x02 ; FCTL |= FCTL_ERASE 75 | nop ; Required, see datasheet. 76 | ljmp flash_write_trigger_done ; Jump back into our function 77 | 78 | ; Meanwhile, back in the main CSEG segment... 79 | .area CSEG (CODE) 80 | ; Jump to the trigger instruction 81 | ljmp flash_write_trigger_instruction 82 | flash_write_trigger_done: 83 | __endasm; 84 | } 85 | 86 | void flash_write(uint16_t buff[], uint16_t len, uint16_t flash_addr) { 87 | // NOTE: len is the number of 16-bit words to transfer 88 | 89 | // Setup DMA descriptor 90 | dma0_config.src_high = ((uint16_t)buff >> 8) & 0x00FF; 91 | dma0_config.src_low = (uint16_t)buff & 0x00FF; 92 | dma0_config.dst_high = (FLASH_FWDATA_ADDR >> 8) & 0x00FF; 93 | dma0_config.dst_low = FLASH_FWDATA_ADDR & 0x00FF; 94 | dma0_config.len_high = DMA_LEN_HIGH_VLEN_LEN; 95 | dma0_config.len_high |= ((len*2) >> 8) & DMA_LEN_HIGH_MASK; 96 | dma0_config.len_low = (len*2) & 0x00FF; 97 | 98 | dma0_config.cfg0 = \ 99 | DMA_CFG0_WORDSIZE_8 | \ 100 | DMA_CFG0_TMODE_SINGLE | \ 101 | DMA_CFG0_TRIGGER_FLASH; 102 | 103 | dma0_config.cfg1 = \ 104 | DMA_CFG1_SRCINC_1 | \ 105 | DMA_CFG1_DESTINC_0 | \ 106 | DMA_CFG1_PRIORITY_HIGH; 107 | 108 | // Point DMA controller at our DMA descriptor 109 | DMA0CFGH = ((uint16_t)&dma0_config >> 8) & 0x00FF; 110 | DMA0CFGL = (uint16_t)&dma0_config & 0x00FF; 111 | 112 | // Waiting for the flash controller to be ready 113 | while (FCTL & FCTL_BUSY) {} 114 | 115 | // Configure the flash controller 116 | FWT = FLASH_FWT; 117 | FADDRH = (flash_addr >> 9) & 0x3F; 118 | FADDRL = (flash_addr >> 1) & 0xFF; 119 | 120 | // Arm the DMA channel, so that a DMA trigger will initiate DMA writing 121 | DMAARM |= DMAARM_DMAARM0; 122 | 123 | // Enable flash write - triggers the DMA transfer 124 | flash_write_trigger(); 125 | 126 | // Wait for DMA transfer to complete 127 | while (!(DMAIRQ & DMAIRQ_DMAIF0)) {} 128 | 129 | // Wait until flash controller not busy 130 | while (FCTL & (FCTL_BUSY | FCTL_SWBSY)) {} 131 | 132 | // By now, the transfer is completed, so the transfer count is reached. 133 | // The DMA channel 0 interrupt flag is then set, so we clear it here. 134 | DMAIRQ &= ~DMAIRQ_DMAIF0; 135 | } 136 | 137 | uint8_t flash_erased_page(uint8_t page) { 138 | // Check if a page was previously erased 139 | if (erased_page_flags & ((uint32_t)1 << page)) 140 | return 1; 141 | else 142 | return 0; 143 | } 144 | 145 | void flash_check_and_erase(uint8_t page) { 146 | // Erase page only if it was never previously erased 147 | if (!flash_erased_page(page)) 148 | flash_erase_page(page); 149 | } 150 | 151 | void flash_check_erase_and_write(uint16_t buff[], uint16_t len, uint16_t flash_addr) { 152 | uint8_t i, start_page, end_page; 153 | 154 | start_page = flash_addr / 1024; 155 | end_page = (flash_addr + len) / 1024; 156 | 157 | // Check and erase pages in range 158 | for (i=start_page; i<=end_page; i++) 159 | flash_check_and_erase(i); 160 | 161 | flash_write(buff, len, flash_addr); 162 | } 163 | 164 | void flash_reset() { 165 | erased_page_flags = 0; 166 | } 167 | 168 | void flash_erase_all_user() { 169 | // Erase all user flash pages 170 | uint8_t i; 171 | for (i=USER_FIRST_PAGE; i= '0' && c <= '9') 30 | return (uint8_t)(c - '0'); 31 | else if (c >= 'A' && c <= 'F') 32 | return 10 + (uint8_t)(c - 'A'); 33 | else if (c >= 'a' && c <= 'f') 34 | return 10 + (uint8_t)(c - 'a'); 35 | else 36 | return HEX_INVALID; 37 | } 38 | 39 | uint8_t hex8(char s[]) { 40 | // Converts a string representation of a hexadecimal byte into a uint8. 41 | // TODO: handle the case of hex4 failing. 42 | return hex4(s[1]) + 16*hex4(s[0]); 43 | } 44 | 45 | uint16_t hex16(char s[]) { 46 | // Converts a string representation of a 16-bit hexadecimal word into a uint16. 47 | // TODO: handle the case of hex8 failing. 48 | return hex8(&s[2]) + 256*(uint16_t)hex8(&s[0]); 49 | } 50 | 51 | uint8_t ihx_record_type(char line[]) { 52 | return hex8(&line[7]); 53 | } 54 | 55 | uint16_t ihx_record_address(char line[]) { 56 | return hex16(&line[3]); 57 | } 58 | 59 | uint8_t ihx_data_byte(char line[], uint8_t n) { 60 | return hex8(&line[9 + n*2]); 61 | } 62 | 63 | uint8_t ihx_check_line(char line[]) { 64 | // :ccaaaattxxxxss 65 | uint8_t byte_count, record_type, checksum, sum, i; 66 | uint16_t address; 67 | 68 | if (line[0] != ':') 69 | return IHX_INVALID; 70 | 71 | byte_count = hex8(&line[1]); 72 | address = ihx_record_address(line); 73 | record_type = ihx_record_type(line); 74 | 75 | if (byte_count > IHX_MAX_LEN) 76 | return IHX_RECORD_TOO_LONG; 77 | 78 | checksum = ihx_data_byte(line, byte_count); 79 | 80 | if (record_type > 0x01 && (record_type < 0x22 || record_type > 0x25)) 81 | return IHX_BAD_RECORD_TYPE; 82 | 83 | if (record_type == IHX_RECORD_DATA && (address < USER_CODE_BASE || address > FLASH_SIZE)) 84 | return IHX_BAD_ADDRESS; 85 | 86 | sum = 0; 87 | i = 0; 88 | for (i=0; i>4) & 0xF); 158 | } 159 | 160 | void to_hex16_ascii(char buff[], uint16_t x) { 161 | to_hex8_ascii(&buff[2], x & 0xFF); 162 | to_hex8_ascii(&buff[0], (x>>8) & 0xFF); 163 | } 164 | 165 | void ihx_read_print(__xdata uint8_t* start_addr, uint16_t len) { 166 | __xdata char buff[45]; 167 | uint8_t byte, sum, i, chunk; 168 | 169 | while (len) { 170 | sum = 0; 171 | if(len > 0x10) 172 | chunk = 0x10; 173 | else 174 | chunk = len; 175 | 176 | buff[0] = ':'; 177 | to_hex8_ascii(&buff[1], chunk); 178 | sum += chunk; 179 | // Write address into buffer 180 | to_hex16_ascii(&buff[3], (uint16_t)start_addr); 181 | sum += (uint16_t)start_addr & 0xFF; 182 | sum += ((uint16_t)start_addr >> 8) & 0xFF; 183 | // Write record type into buffer 184 | to_hex8_ascii(&buff[7], 0x00); 185 | // Write data bytes into buffer 186 | for (i=0; i 0x10) { 201 | start_addr += 0x10; 202 | len -= 0x10; 203 | } else // we're done 204 | len = 0; 205 | } 206 | usb_putstr(":00000001FF\n"); 207 | } 208 | -------------------------------------------------------------------------------- /src/usb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - USB CDC class (serial) driver 3 | * 4 | * Adapted from AltOS code by Fergus Noble (c) 2011 5 | * AltOS code Copyright © 2009 Keith Packard 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 2 of the License. 10 | * 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, write to the Free Software Foundation, Inc., 18 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 | */ 20 | 21 | #include "hal.h" 22 | 23 | #ifndef _USB_H_ 24 | #define _USB_H_ 25 | 26 | // External interface 27 | 28 | void usb_init(); 29 | void usb_disable(); 30 | void usb_enable(); 31 | char usb_getchar(); 32 | void usb_putchar(char c); 33 | void usb_flush(); 34 | 35 | void usb_putstr(char* buff); 36 | void usb_readline(char* buff); 37 | 38 | // End external interface 39 | 40 | // USB interrupt handler 41 | void usb_isr() __interrupt 6; 42 | 43 | #define USB_SETUP_DIR_MASK (0x01 << 7) 44 | #define USB_SETUP_TYPE_MASK (0x03 << 5) 45 | #define USB_SETUP_RECIP_MASK (0x1f) 46 | 47 | #define USB_DIR_OUT 0 48 | #define USB_DIR_IN (1 << 7) 49 | 50 | #define USB_TYPE_STANDARD 0 51 | #define USB_TYPE_CLASS (1 << 5) 52 | #define USB_TYPE_VENDOR (2 << 5) 53 | #define USB_TYPE_RESERVED (3 << 5) 54 | 55 | #define USB_RECIP_DEVICE 0 56 | #define USB_RECIP_INTERFACE 1 57 | #define USB_RECIP_ENDPOINT 2 58 | #define USB_RECIP_OTHER 3 59 | 60 | // Standard requests 61 | #define USB_REQ_GET_STATUS 0x00 62 | #define USB_REQ_CLEAR_FEATURE 0x01 63 | #define USB_REQ_SET_FEATURE 0x03 64 | #define USB_REQ_SET_ADDRESS 0x05 65 | #define USB_REQ_GET_DESCRIPTOR 0x06 66 | #define USB_REQ_SET_DESCRIPTOR 0x07 67 | #define USB_REQ_GET_CONFIGURATION 0x08 68 | #define USB_REQ_SET_CONFIGURATION 0x09 69 | #define USB_REQ_GET_INTERFACE 0x0A 70 | #define USB_REQ_SET_INTERFACE 0x0B 71 | #define USB_REQ_SYNCH_FRAME 0x0C 72 | 73 | #define USB_DESC_DEVICE 1 74 | #define USB_DESC_CONFIGURATION 2 75 | #define USB_DESC_STRING 3 76 | #define USB_DESC_INTERFACE 4 77 | #define USB_DESC_ENDPOINT 5 78 | #define USB_DESC_DEVICE_QUALIFIER 6 79 | #define USB_DESC_OTHER_SPEED 7 80 | #define USB_DESC_INTERFACE_POWER 8 81 | 82 | #define USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF) 83 | #define USB_GET_DESC_INDEX(x) ((x)&0xFF) 84 | 85 | #define USB_CONTROL_EP 0 86 | #define USB_INT_EP 1 87 | #define USB_OUT_EP 4 88 | #define USB_IN_EP 5 89 | #define USB_CONTROL_SIZE 32 90 | 91 | // Double buffer IN and OUT EPs, so each 92 | // gets half of the available space 93 | // 94 | // Ah, but USB bulk packets can only come in 8, 16, 32 and 64 95 | // byte sizes, so we'll use 64 for everything 96 | #define USB_IN_SIZE 64 97 | #define USB_OUT_SIZE 64 98 | 99 | #define USB_EP0_IDLE 0 100 | #define USB_EP0_DATA_IN 1 101 | #define USB_EP0_DATA_OUT 2 102 | 103 | #define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) 104 | 105 | // CDC definitions 106 | #define CS_INTERFACE 0x24 107 | #define CS_ENDPOINT 0x25 108 | 109 | #define SET_LINE_CODING 0x20 110 | #define GET_LINE_CODING 0x21 111 | #define SET_CONTROL_LINE_STATE 0x22 112 | 113 | // Data structure for GET_LINE_CODING / SET_LINE_CODING class requests 114 | struct usb_line_coding { 115 | uint32_t rate; 116 | uint8_t char_format; 117 | uint8_t parity; 118 | uint8_t data_bits; 119 | }; 120 | 121 | #define USB_READ_AGAIN ((char) -1) 122 | 123 | #ifdef RFCAT_CHRONOS 124 | #define USB_VID 0x1D50 125 | #define USB_PID 0x6049 126 | // iManufacturer 127 | #define USB_iManufacturer_LEN 0x0C 128 | #define USB_iManufacturer_STRING "RfCat" 129 | #define USB_iManufacturer_UCS2 'R', 0, 'f', 0, 'C', 0, 'a', 0, 't', 0 130 | // iProduct 131 | #define USB_iProduct_LEN 0x26 132 | #define USB_iProduct_STRING "Chronos Bootloader" 133 | #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 134 | #elif defined RFCAT_DONSDONGLE 135 | #define USB_VID 0x1D50 136 | #define USB_PID 0x604A 137 | // iManufacturer 138 | #define USB_iManufacturer_LEN 0x0C 139 | #define USB_iManufacturer_STRING "RfCat" 140 | #define USB_iManufacturer_UCS2 'R', 0, 'f', 0, 'C', 0, 'a', 0, 't', 0 141 | // iProduct 142 | #define USB_iProduct_LEN 0x20 143 | #define USB_iProduct_STRING "Dons Bootloader" 144 | #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 145 | #elif defined RFCAT_YARDSTICKONE 146 | #define USB_VID 0x1D50 147 | #define USB_PID 0x605C 148 | // iManufacturer 149 | #define USB_iManufacturer_LEN 0x28 150 | #define USB_iManufacturer_STRING "Great Scott Gadgets" 151 | #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 152 | // iProduct 153 | #define USB_iProduct_LEN 0x34 154 | #define USB_iProduct_STRING "YARD Stick One Bootloader" 155 | #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 156 | #else 157 | #define USB_VID 0xFFFE 158 | #define USB_PID 0x000A 159 | // iManufacturer 160 | #define USB_iManufacturer_LEN 0x10 161 | #define USB_iManufacturer_STRING "JobyGPS" 162 | #define USB_iManufacturer_UCS2 'J', 0, 'o', 0, 'b', 0, 'y', 0, 'G', 0, 'P', 0, 'S', 0 163 | // iProduct 164 | #define USB_iProduct_LEN 0x1C 165 | #define USB_iProduct_STRING "CC Bootloader" 166 | #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 167 | #endif 168 | 169 | // iSerial 170 | #define USB_iSerial_LEN 0x0e 171 | #define USB_iSerial_STRING "000001" 172 | #define USB_iSerial_UCS2 '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '1', 0 173 | 174 | extern __code __at(0x00aa) uint8_t usb_descriptors[]; 175 | 176 | #endif // _USB_H_ 177 | -------------------------------------------------------------------------------- /bootload.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import serial 4 | 5 | bootloader_error_codes = { 6 | '0' : "OK", 7 | '1' : "Intel HEX Invalid", 8 | '2' : "Bad Checksum", 9 | '3' : "Bad Address", 10 | '4' : "Bad Record Type", 11 | '5' : "Record Too Long" 12 | } 13 | 14 | def download_code(ihx_file, serial_port): 15 | for line in ihx_file.readlines(): 16 | record_type = int(line[7:9], 16) 17 | if (record_type == 0x00): 18 | print "Writing", line[:-1], 19 | serial_port.write(line) 20 | rc = serial_port.read() 21 | print " RC =", rc, 22 | if rc in bootloader_error_codes: 23 | print "(%s)" % bootloader_error_codes[rc] 24 | else: 25 | print "(Unknown Error)" 26 | if (rc != '0'): 27 | print "Error downloading code!" 28 | return False 29 | else: 30 | print "Skipping non data record: '%s'" % line[:-1] 31 | return True 32 | 33 | def verify_code(ihx_file, serial_port): 34 | can_read_any= None 35 | for line in ihx_file.readlines(): 36 | record_type = int(line[7:9], 16) 37 | if (record_type == 0x00): 38 | length = int(line[1:3], 16) 39 | start_addr = int(line[3:7], 16) 40 | data = line[9:9+(length*2)] 41 | # first time around, check if we can only read 16 byte chunks 42 | if can_read_any == None: 43 | can_read_any = False 44 | do_flash_read(serial_port, start_addr, 1) 45 | for read_data in serial_port: 46 | read_data = read_data.strip() 47 | if not read_data: 48 | continue 49 | if not read_data == ":00000001FF": 50 | can_read_any = True 51 | else: 52 | break 53 | if not can_read_any: 54 | print "*** warning! this version of CC-Bootloader can only read 16 byte blocks!" 55 | print "*** upgrade recommended!" 56 | if can_read_any: 57 | block_length= length 58 | else: 59 | block_length= ((length / 16) + 1) * 16 60 | print "\rVerifying %04d bytes at address: %04X" % (length, start_addr), 61 | do_flash_read(serial_port, start_addr, block_length) 62 | verify_data= '' 63 | for read_data in serial_port: 64 | read_data= read_data.strip() 65 | if (not data or read_data == ":00000001FF"): 66 | break 67 | # strip header and checksum 68 | verify_data += read_data[9:-2] 69 | if (data == verify_data[:length*2]): 70 | print '(OK)', 71 | else: 72 | print 'Failed! Expected:', data, 'Got:', verify_data[:length*2] 73 | exit(1) 74 | sys.stdout.flush() 75 | else: 76 | print "Skipping non data record: '%s'" % line[:-1] 77 | return True 78 | 79 | def run_user_code(serial_port): 80 | # User code is entered on intel HEX EOF record 81 | serial_port.write(":00000001FF\n") 82 | return True 83 | 84 | def reset_bootloader(serial_port): 85 | serial_port.write(":00000022DE\n") 86 | rc = serial_port.read() 87 | print "RC =", rc, 88 | if rc in bootloader_error_codes: 89 | print "(%s)" % bootloader_error_codes[rc] 90 | else: 91 | print "(Unknown Error)" 92 | if (rc != '0'): 93 | print "Error resetting bootloader!" 94 | return False 95 | return True 96 | 97 | def erase_all_user(serial_port): 98 | serial_port.write(":00000023DD\n") 99 | rc = serial_port.read() 100 | print "RC =", rc, 101 | if rc in bootloader_error_codes: 102 | print "(%s)" % bootloader_error_codes[rc] 103 | else: 104 | print "(Unknown Error)" 105 | if (rc != '0'): 106 | print "Error erasing all user flash!" 107 | return False 108 | return True 109 | 110 | def erase_user_page(serial_port, page): 111 | chksum = (0xDB + 0x100 - page) & 0xFF 112 | serial_port.write(":01000024%02X%02X\n" % (page, chksum)) 113 | rc = serial_port.read() 114 | print "RC =", rc, 115 | if rc in bootloader_error_codes: 116 | print "(%s)" % bootloader_error_codes[rc] 117 | else: 118 | print "(Unknown Error)" 119 | if (rc != '0'): 120 | print "Error erasing user flash page!" 121 | return False 122 | return True 123 | 124 | def do_flash_read(serial_port, start_addr, length): 125 | chksum = (0xD9 + 126 | (0x100 - (start_addr & 0xFF)) + 127 | (0x100 - ((start_addr>>8) & 0xFF)) + 128 | (0x100 - (length & 0xFF)) + 129 | (0x100 - ((length>>8) & 0xFF)) 130 | ) & 0xFF 131 | serial_port.write(":02%04X25%04X%02X\n" % (start_addr, length, chksum)) 132 | 133 | 134 | def flash_read(ihx_file, serial_port, start_addr, length): 135 | do_flash_read(serial_port, start_addr, length) 136 | for line in serial_port: 137 | if not line == "\n": 138 | if(ihx_file): 139 | ihx_file.write(line) 140 | else: 141 | print line, 142 | if (line == ":00000001FF\n"): 143 | break 144 | 145 | def print_usage(): 146 | import sys 147 | print """ 148 | CC Bootloader Download Utility 149 | 150 | Usage: ./bootload.py serial_port command 151 | 152 | Commands: 153 | 154 | download 155 | 156 | Download hex_file to the device. 157 | 158 | run 159 | 160 | Run the user code. 161 | 162 | reset 163 | 164 | The bootloader will not erase pages that have previously been written to 165 | before writing new data to that page. This allows for random access writes 166 | but prevents you from overwriting downloaded code unless the device is 167 | power cycled. This command will reset the bootloader's record of what 168 | pages have been written to, allowing you to overwrite without power 169 | cycling. 170 | 171 | erase_all 172 | 173 | Erases the entire user flash area. 174 | 175 | erage 176 | 177 | Erases page n of the flash memory (organised into 1024 byte pages). The 178 | bootloader occupies the first few pages and the rest are reserved for user 179 | code. Attempting to erase a bootloader page will have no effect. To 180 | determine which page the user code starts on please check the 181 | USER_CODE_BASE setting in main.h. 182 | 183 | read [hex_file] 184 | 185 | Reads len bytes from flash memory starting from start_addr and optionally 186 | write to hex_file. start_addr and len should be specified in hexadecimal 187 | (e.g. 0x1234). 188 | 189 | verify 190 | 191 | Verify hex_file matches device flash memory. 192 | """ 193 | 194 | if __name__ == '__main__': 195 | import sys 196 | if (len(sys.argv) < 3): 197 | print_usage() 198 | sys.exit(1) 199 | 200 | serial_port_name = sys.argv[1] 201 | command = sys.argv[2] 202 | options = sys.argv[3:] 203 | serial_port = serial.Serial(serial_port_name, timeout=1) 204 | 205 | try: 206 | if (command == 'download' or command == 'verify'): 207 | if (len(options) < 1): 208 | print_usage() 209 | else: 210 | ihx_filename = options[0] 211 | ihx_file = open(ihx_filename, 'r') 212 | if (command == 'download'): 213 | download_code(ihx_file, serial_port) 214 | else: 215 | verify_code(ihx_file, serial_port) 216 | 217 | elif (command == 'run'): 218 | run_user_code(serial_port) 219 | 220 | elif (command == 'reset'): 221 | reset_bootloader(serial_port) 222 | 223 | elif (command == 'erase_all'): 224 | erase_all_user(serial_port) 225 | 226 | elif (command == 'erase'): 227 | if (len(options) < 1): 228 | print_usage() 229 | else: 230 | erase_user_page(serial_port, int(options[0])) 231 | 232 | elif (command == 'read'): 233 | if (len(options) < 2): 234 | print_usage() 235 | else: 236 | ihx_file = None 237 | if(len(options) == 3): 238 | try: 239 | ihx_filename = options[2] 240 | ihx_file = open(ihx_filename, 'w') 241 | print 'reading to:', ihx_filename 242 | except: 243 | print "couldn't open output file:", ihx_filename 244 | exit(2) 245 | flash_read(ihx_file, serial_port, int(options[0], 16), int(options[1], 16)) 246 | 247 | else: 248 | print_usage() 249 | finally: 250 | serial_port.close() 251 | 252 | 253 | 254 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - Main 3 | * 4 | * Fergus Noble (c) 2011 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 18 | */ 19 | 20 | #include "cc1111.h" 21 | #include "main.h" 22 | #include "usb.h" 23 | #include "hal.h" 24 | #include "flash.h" 25 | #include "intel_hex.h" 26 | 27 | uint8_t bootloader_running = 1; 28 | 29 | void clock_init() 30 | { 31 | // Switch system clock to crystal oscilator 32 | CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_XTAL); 33 | 34 | while (!(SLEEP & SLEEP_XOSC_STB)) {} 35 | 36 | // Crank up the timer tick and system clock speed 37 | CLKCON = ((CLKCON & ~(CLKCON_TICKSPD_MASK | CLKCON_CLKSPD_MASK)) | 38 | (CLKCON_TICKSPD_1_128 | CLKCON_CLKSPD_1)); 39 | 40 | while ((CLKCON & (CLKCON_TICKSPD_MASK|CLKCON_CLKSPD_MASK)) != 41 | (CLKCON_TICKSPD_1_128 | CLKCON_CLKSPD_1) 42 | ) {} 43 | } 44 | 45 | #ifdef STDIO 46 | void putchar(char c) { 47 | usb_putchar(c); 48 | } 49 | #endif 50 | 51 | void delay (unsigned char n) { 52 | unsigned char i = 0; 53 | unsigned char j = 0; 54 | 55 | n <<= 1; 56 | while (--n != 0) 57 | while (--i != 0) 58 | while (--j != 0) 59 | nop(); 60 | } 61 | 62 | uint8_t check_for_payload() { 63 | if (*((__xdata uint8_t*)USER_CODE_BASE) == 0xFF) 64 | return 0; 65 | else 66 | return 1; 67 | } 68 | 69 | void jump_to_user() { 70 | // Disable all interrupts 71 | EA = 0; 72 | IEN0 = IEN1 = IEN2 = 0; 73 | 74 | 75 | if (check_for_payload()) { 76 | // Bring down the USB link 77 | usb_down(); 78 | 79 | // Flag bootloader not running 80 | bootloader_running = 0; 81 | // Jump to user code 82 | __asm 83 | ljmp #USER_CODE_BASE 84 | __endasm; 85 | while (1) {} 86 | } else { 87 | #ifdef RFCAT 88 | return; // need to run bootloader! 89 | #else 90 | // Oops, no payload. We're stuck now! 91 | led_on(); 92 | while (1) {} 93 | #endif 94 | } 95 | } 96 | 97 | #ifdef TIMER 98 | void setup_timer1() { 99 | // Clear Timer 1 channel 1 and overflow interrupt flag 100 | // CPU interrupt flag (IRCON) for Timer 1 is cleared automatically by hardware. 101 | T1CTL &= ~T1CTL_OVFIF; 102 | 103 | // Enable Timer 1 interrupts by setting [IEN1.T1IE=1] 104 | IEN1 |= IEN1_T1IE; 105 | 106 | T1CC0H = TIMER_TIMEOUT; 107 | T1CC0L = 0x00; 108 | 109 | // set Timer 1 to modulo mode 110 | T1CTL = TxCTL_OVFIM | TxCTL_DIV_128 | TxCTL_MODE_MODULO; 111 | } 112 | #endif 113 | 114 | #ifdef TIMER 115 | void disable_timer1() { 116 | // Disable Timer 1 interrupt 117 | IEN1 &= ~IEN1_T1IE; 118 | } 119 | #endif 120 | 121 | #ifdef TIMER 122 | void timer1_isr() __naked { 123 | T1CTL &= ~T1CTL_OVFIF; 124 | 125 | // We need to issue a RETI instruction to 126 | // get out of interrupt mode. We push the 127 | // address of a dummy label onto the stack 128 | // to spoof the return address of the RETI 129 | // instruction. 130 | __asm 131 | ; Push address of label just past RETI 132 | mov a, #silly_reti ; High byte 135 | push acc 136 | ; Issue RETI to get out of interrupt 137 | ; Should return to silly_reti 138 | reti 139 | silly_reti: 140 | __endasm; 141 | 142 | // Now go to user code, don't worry about the fact we have 143 | // frigged the stack, the user code will just reset it anyway. 144 | jump_to_user(); 145 | } 146 | #endif 147 | 148 | void timer1_isr_forward() __naked { 149 | #ifdef TIMER 150 | __asm 151 | push acc 152 | mov a, _bootloader_running 153 | jnz timer1_isr_forward_bootloader 154 | ; Bootloader not running, jump into the payload ISR 155 | pop acc 156 | ljmp #(USER_CODE_BASE+0x4B) 157 | timer1_isr_forward_bootloader: 158 | pop acc 159 | ljmp _timer1_isr 160 | __endasm; 161 | #else 162 | __asm 163 | ljmp #(USER_CODE_BASE+0x4B) 164 | __endasm; 165 | #endif 166 | } 167 | 168 | uint8_t want_bootloader() { 169 | // Check if we want to the bootloader to run 170 | // Here is the place to check for things like USB power and jump straight to 171 | // user code under some conditions. 172 | 173 | /* 174 | // Check for USB +5V, if not present go straight to user code 175 | PxDIR &= ~y; 176 | if (!Px_y) 177 | return 0; 178 | */ 179 | 180 | #ifdef RFCAT 181 | // we use the unused I2S SFRs as semaphores. 182 | // this would be safe even if I2S is in use as they should be reconfigured by 183 | // user code 184 | if(I2SCLKF2 == 0x69) 185 | return 1; 186 | // no thanks 187 | return 0; 188 | #else 189 | return 1; 190 | #endif 191 | } 192 | 193 | void bootloader_main () 194 | { 195 | __xdata char buff[100]; 196 | uint8_t ihx_status; 197 | uint16_t read_start_addr, read_len; 198 | 199 | #ifdef RFCAT 200 | // use I2S SFR to signal that bootloader is present 201 | I2SCLKF0= 0xF0; 202 | I2SCLKF1= 0x0D; 203 | 204 | setup_button(); 205 | setup_gpio(); 206 | 207 | #ifdef RFCAT_DONSDONGLE 208 | if (CC1111EM_BUTTON != BUTTON_PRESSED && !want_bootloader()) 209 | #endif 210 | 211 | #ifdef RFCAT_CHRONOS 212 | if (CC1111CHRONOS_PIN_DC != GROUNDED && !want_bootloader()) 213 | #endif 214 | 215 | #ifdef RFCAT_YARDSTICKONE 216 | if (CC1111YSONE_PIN_DC != GROUNDED && !want_bootloader()) 217 | #endif 218 | 219 | #else 220 | if (!want_bootloader()) 221 | #endif 222 | jump_to_user(); 223 | #ifdef RFCAT 224 | // reset semaphore 225 | I2SCLKF2= 0x00; 226 | #endif 227 | 228 | clock_init(); 229 | 230 | setup_led(); 231 | 232 | // Setup timer if enabled 233 | #ifdef TIMER 234 | setup_timer1(); 235 | #endif 236 | 237 | usb_init(); 238 | 239 | // Enable interrupts 240 | EA = 1; 241 | 242 | // Bring up the USB link 243 | usb_up(); 244 | led_on(); 245 | 246 | while (1) 247 | { 248 | ihx_readline(buff); 249 | 250 | // Got something over USB, disable the timer 251 | #ifdef TIMER 252 | disable_timer1(); 253 | #endif 254 | 255 | ihx_status = ihx_check_line(buff); 256 | 257 | if (ihx_status == IHX_OK) { 258 | switch (ihx_record_type(buff)) { 259 | case IHX_RECORD_DATA: 260 | ihx_write(buff); 261 | usb_putchar('0'); 262 | usb_flush(); 263 | break; 264 | case IHX_RECORD_EOF: 265 | jump_to_user(); 266 | break; 267 | case IHX_RECORD_RESET: 268 | // Reset record will reset the page erase map which usually ensures each page is only 269 | // erased once, allowing for random writes but preventing overwriting of data already written 270 | // this session. 271 | flash_reset(); 272 | usb_putchar('0'); 273 | usb_flush(); 274 | break; 275 | case IHX_RECORD_ERASE_ALL: 276 | // Erase all user flash pages 277 | flash_erase_all_user(); 278 | usb_putchar('0'); 279 | usb_flush(); 280 | break; 281 | case IHX_RECORD_ERASE_PAGE: 282 | // Erase flash page 283 | flash_erase_page(ihx_data_byte(buff, 0)); 284 | usb_putchar('0'); 285 | usb_flush(); 286 | break; 287 | case IHX_RECORD_READ: 288 | // Read out a section of flash over USB 289 | read_start_addr = ihx_record_address(buff); 290 | read_len = (ihx_data_byte(buff, 0)<<8) + ihx_data_byte(buff, 1); 291 | usb_putchar('\n'); 292 | ihx_read_print((__xdata uint8_t*)read_start_addr, read_len); 293 | break; 294 | default: 295 | // Return the error code for unknown type in this case too 296 | usb_putchar(IHX_BAD_RECORD_TYPE + '0'); 297 | usb_flush(); 298 | break; 299 | } 300 | } else { 301 | usb_putchar(ihx_status + '0'); 302 | usb_flush(); 303 | } 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /src/usb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - USB CDC class (serial) driver 3 | * 4 | * Adapted from AltOS code by Fergus Noble (c) 2011 5 | * AltOS code Copyright © 2009 Keith Packard 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 2 of the License. 10 | * 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, write to the Free Software Foundation, Inc., 18 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 | */ 20 | 21 | #include "cc1111.h" 22 | #include "usb.h" 23 | 24 | static __xdata uint16_t usb_in_bytes; 25 | static __xdata uint16_t usb_in_bytes_last; 26 | static __xdata uint16_t usb_out_bytes; 27 | volatile static __xdata uint8_t usb_iif; 28 | static __xdata uint8_t usb_running; 29 | 30 | static void usb_set_interrupts() 31 | { 32 | // IN interrupts on the control an IN endpoints 33 | USBIIE = (1 << USB_CONTROL_EP) | (1 << USB_IN_EP); 34 | // OUT interrupts on the OUT endpoint 35 | USBOIE = (1 << USB_OUT_EP); 36 | // Only care about reset 37 | USBCIE = USBCIE_RSTIE; 38 | } 39 | 40 | struct usb_setup { 41 | uint8_t dir_type_recip; 42 | uint8_t request; 43 | uint16_t value; 44 | uint16_t index; 45 | uint16_t length; 46 | } __xdata usb_setup; 47 | 48 | __xdata uint8_t usb_ep0_state; 49 | uint8_t * __xdata usb_ep0_in_data; 50 | __xdata uint8_t usb_ep0_in_len; 51 | __xdata uint8_t usb_ep0_in_buf[2]; 52 | __xdata uint8_t usb_ep0_out_len; 53 | __xdata uint8_t *__xdata usb_ep0_out_data; 54 | __xdata uint8_t usb_configuration; 55 | 56 | // Send an IN data packet 57 | static void usb_ep0_flush() 58 | { 59 | __xdata uint8_t this_len; 60 | __xdata uint8_t cs0; 61 | 62 | // If the IN packet hasn't been picked up, just return 63 | USBINDEX = 0; 64 | cs0 = USBCS0; 65 | if (cs0 & USBCS0_INPKT_RDY) 66 | return; 67 | 68 | this_len = usb_ep0_in_len; 69 | if (this_len > USB_CONTROL_SIZE) 70 | this_len = USB_CONTROL_SIZE; 71 | cs0 = USBCS0_INPKT_RDY; 72 | if (this_len != USB_CONTROL_SIZE) { 73 | cs0 = USBCS0_INPKT_RDY | USBCS0_DATA_END; 74 | usb_ep0_state = USB_EP0_IDLE; 75 | } 76 | usb_ep0_in_len -= this_len; 77 | while (this_len--) 78 | USBFIFO[0] = *usb_ep0_in_data++; 79 | USBINDEX = 0; 80 | USBCS0 = cs0; 81 | } 82 | 83 | __xdata static struct usb_line_coding usb_line_coding = {115200, 0, 0, 8}; 84 | 85 | // Walk through the list of descriptors and find a match 86 | static void usb_get_descriptor(uint16_t value) 87 | { 88 | const uint8_t *__xdata descriptor; 89 | __xdata uint8_t type = value >> 8; 90 | __xdata uint8_t index = value; 91 | 92 | descriptor = usb_descriptors; 93 | while (descriptor[0] != 0) { 94 | if (descriptor[1] == type && index-- == 0) { 95 | if (type == USB_DESC_CONFIGURATION) 96 | usb_ep0_in_len = descriptor[2]; 97 | else 98 | usb_ep0_in_len = descriptor[0]; 99 | usb_ep0_in_data = descriptor; 100 | break; 101 | } 102 | descriptor += descriptor[0]; 103 | } 104 | } 105 | 106 | // Read data from the ep0 OUT fifo 107 | static void usb_ep0_fill() 108 | { 109 | __xdata uint8_t len; 110 | 111 | USBINDEX = 0; 112 | len = USBCNT0; 113 | if (len > usb_ep0_out_len) 114 | len = usb_ep0_out_len; 115 | usb_ep0_out_len -= len; 116 | while (len--) 117 | *usb_ep0_out_data++ = USBFIFO[0]; 118 | } 119 | 120 | void usb_ep0_queue_byte (uint8_t a) 121 | { 122 | usb_ep0_in_buf[usb_ep0_in_len++] = a; 123 | } 124 | 125 | void usb_set_address (uint8_t address) 126 | { 127 | usb_running = 1; 128 | USBADDR = address | 0x80; 129 | while (USBADDR & 0x80) {} 130 | } 131 | 132 | static void usb_set_configuration() 133 | { 134 | // Set the IN max packet size, double buffered 135 | USBINDEX = USB_IN_EP; 136 | USBMAXI = USB_IN_SIZE >> 3; 137 | USBCSIH |= USBCSIH_IN_DBL_BUF; 138 | 139 | // Set the OUT max packet size, double buffered 140 | USBINDEX = USB_OUT_EP; 141 | USBMAXO = USB_OUT_SIZE >> 3; 142 | USBCSOH = USBCSOH_OUT_DBL_BUF; 143 | } 144 | 145 | static void usb_ep0_setup() 146 | { 147 | // Pull the setup packet out of the fifo 148 | usb_ep0_out_data = (__xdata uint8_t *) &usb_setup; 149 | usb_ep0_out_len = 8; 150 | usb_ep0_fill(); 151 | if (usb_ep0_out_len != 0) 152 | return; 153 | 154 | // Figure out how to ACK the setup packet 155 | if (usb_setup.dir_type_recip & USB_DIR_IN) { 156 | if (usb_setup.length) 157 | usb_ep0_state = USB_EP0_DATA_IN; 158 | else 159 | usb_ep0_state = USB_EP0_IDLE; 160 | } else { 161 | if (usb_setup.length) 162 | usb_ep0_state = USB_EP0_DATA_OUT; 163 | else 164 | usb_ep0_state = USB_EP0_IDLE; 165 | } 166 | USBINDEX = 0; 167 | if (usb_ep0_state == USB_EP0_IDLE) 168 | USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; 169 | else 170 | USBCS0 = USBCS0_CLR_OUTPKT_RDY; 171 | 172 | usb_ep0_in_data = usb_ep0_in_buf; 173 | usb_ep0_in_len = 0; 174 | switch(usb_setup.dir_type_recip & USB_SETUP_TYPE_MASK) { 175 | case USB_TYPE_STANDARD: 176 | switch(usb_setup.dir_type_recip & USB_SETUP_RECIP_MASK) { 177 | case USB_RECIP_DEVICE: 178 | switch(usb_setup.request) { 179 | case USB_REQ_GET_STATUS: 180 | usb_ep0_queue_byte(0); 181 | usb_ep0_queue_byte(0); 182 | break; 183 | case USB_REQ_SET_ADDRESS: 184 | usb_set_address(usb_setup.value); 185 | break; 186 | case USB_REQ_GET_DESCRIPTOR: 187 | usb_get_descriptor(usb_setup.value); 188 | break; 189 | case USB_REQ_GET_CONFIGURATION: 190 | usb_ep0_queue_byte(usb_configuration); 191 | break; 192 | case USB_REQ_SET_CONFIGURATION: 193 | usb_configuration = usb_setup.value; 194 | usb_set_configuration(); 195 | break; 196 | } 197 | break; 198 | case USB_RECIP_INTERFACE: 199 | #pragma disable_warning 110 200 | switch(usb_setup.request) { 201 | case USB_REQ_GET_STATUS: 202 | usb_ep0_queue_byte(0); 203 | usb_ep0_queue_byte(0); 204 | break; 205 | case USB_REQ_GET_INTERFACE: 206 | usb_ep0_queue_byte(0); 207 | break; 208 | case USB_REQ_SET_INTERFACE: 209 | break; 210 | } 211 | break; 212 | case USB_RECIP_ENDPOINT: 213 | switch(usb_setup.request) { 214 | case USB_REQ_GET_STATUS: 215 | usb_ep0_queue_byte(0); 216 | usb_ep0_queue_byte(0); 217 | break; 218 | } 219 | break; 220 | } 221 | break; 222 | case USB_TYPE_CLASS: 223 | switch (usb_setup.request) { 224 | case SET_LINE_CODING: 225 | usb_ep0_out_len = 7; 226 | usb_ep0_out_data = (__xdata uint8_t *) &usb_line_coding; 227 | break; 228 | case GET_LINE_CODING: 229 | usb_ep0_in_len = 7; 230 | usb_ep0_in_data = (uint8_t *) &usb_line_coding; 231 | break; 232 | case SET_CONTROL_LINE_STATE: 233 | break; 234 | } 235 | break; 236 | } 237 | if (usb_ep0_state != USB_EP0_DATA_OUT) { 238 | if (usb_setup.length < usb_ep0_in_len) 239 | usb_ep0_in_len = usb_setup.length; 240 | usb_ep0_flush(); 241 | } 242 | } 243 | 244 | // End point 0 receives all of the control messages. 245 | // This function must be called periodically to process ep0 messages. 246 | static void usb_ep0() 247 | { 248 | __xdata uint8_t cs0; 249 | 250 | // If the ep0 flag has been set by the USB interrupt then do some processing 251 | if (usb_iif & 1) 252 | { 253 | usb_iif &= ~1; // clear flag 254 | 255 | USBINDEX = 0; 256 | cs0 = USBCS0; 257 | if (cs0 & USBCS0_SETUP_END) { 258 | usb_ep0_state = USB_EP0_IDLE; 259 | USBCS0 = USBCS0_CLR_SETUP_END; 260 | } 261 | if (cs0 & USBCS0_SENT_STALL) { 262 | usb_ep0_state = USB_EP0_IDLE; 263 | USBCS0 &= ~USBCS0_SENT_STALL; 264 | } 265 | if (usb_ep0_state == USB_EP0_DATA_IN && 266 | (cs0 & USBCS0_INPKT_RDY) == 0) 267 | { 268 | usb_ep0_flush(); 269 | } 270 | if (cs0 & USBCS0_OUTPKT_RDY) { 271 | switch (usb_ep0_state) { 272 | case USB_EP0_IDLE: 273 | usb_ep0_setup(); 274 | break; 275 | case USB_EP0_DATA_OUT: 276 | usb_ep0_fill(); 277 | if (usb_ep0_out_len == 0) 278 | usb_ep0_state = USB_EP0_IDLE; 279 | USBINDEX = 0; 280 | if (usb_ep0_state == USB_EP0_IDLE) 281 | USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; 282 | else 283 | USBCS0 = USBCS0_CLR_OUTPKT_RDY; 284 | break; 285 | } 286 | } 287 | } 288 | } 289 | 290 | // This interrupt is shared with port 2, 291 | // so when we hook that up, fix this 292 | void usb_isr() __interrupt 6 293 | { 294 | USBIF = 0; 295 | usb_iif |= USBIIF; 296 | usb_ep0(); 297 | 298 | if (USBCIF & USBCIF_RSTIF) 299 | usb_set_interrupts(); 300 | } 301 | 302 | // Wait for a free IN buffer 303 | static void usb_in_wait() 304 | { 305 | while (1) { 306 | USBINDEX = USB_IN_EP; 307 | if ((USBCSIL & USBCSIL_INPKT_RDY) == 0) 308 | break; 309 | while (!(usb_iif & (1 << USB_IN_EP))) {} 310 | } 311 | } 312 | 313 | // Send the current IN packet 314 | static void usb_in_send() 315 | { 316 | USBINDEX = USB_IN_EP; 317 | USBCSIL |= USBCSIL_INPKT_RDY; 318 | usb_in_bytes_last = usb_in_bytes; 319 | usb_in_bytes = 0; 320 | } 321 | 322 | void usb_flush() 323 | { 324 | if (!usb_running) 325 | return; 326 | 327 | // If there are pending bytes, or if the last packet was full, 328 | // send another IN packet 329 | if (usb_in_bytes || (usb_in_bytes_last == USB_IN_SIZE)) { 330 | usb_in_wait(); 331 | usb_in_send(); 332 | } 333 | } 334 | 335 | void usb_putchar(char c) __reentrant 336 | { 337 | if (!usb_running) 338 | return; 339 | 340 | usb_in_wait(); 341 | 342 | // Queue a byte, sending the packet when full 343 | USBFIFO[USB_IN_EP << 1] = c; 344 | if (++usb_in_bytes == USB_IN_SIZE) 345 | usb_in_send(); 346 | } 347 | 348 | char usb_pollchar() 349 | { 350 | char c; 351 | if (usb_out_bytes == 0) { 352 | USBINDEX = USB_OUT_EP; 353 | if ((USBCSOL & USBCSOL_OUTPKT_RDY) == 0) 354 | return USB_READ_AGAIN; 355 | usb_out_bytes = (USBCNTH << 8) | USBCNTL; 356 | if (usb_out_bytes == 0) { 357 | USBINDEX = USB_OUT_EP; 358 | USBCSOL &= ~USBCSOL_OUTPKT_RDY; 359 | return USB_READ_AGAIN; 360 | } 361 | } 362 | --usb_out_bytes; 363 | c = USBFIFO[USB_OUT_EP << 1]; 364 | if (usb_out_bytes == 0) { 365 | USBINDEX = USB_OUT_EP; 366 | USBCSOL &= ~USBCSOL_OUTPKT_RDY; 367 | } 368 | return c; 369 | } 370 | 371 | char usb_getchar() 372 | { 373 | char c; 374 | while ((c = usb_pollchar()) == USB_READ_AGAIN) 375 | { 376 | while (!(USBOIF & (1 << USB_OUT_EP))) {} 377 | } 378 | return c; 379 | } 380 | 381 | void usb_enable() 382 | { 383 | // Turn on the USB controller 384 | SLEEP |= SLEEP_USB_EN; 385 | 386 | usb_set_configuration(); 387 | usb_set_interrupts(); 388 | 389 | // enable USB interrupts 390 | IEN2 |= IEN2_USBIE; 391 | 392 | // Clear any pending interrupts 393 | USBCIF = 0; 394 | USBOIF = 0; 395 | USBIIF = 0; 396 | USBIF = 0; 397 | } 398 | 399 | void usb_disable() 400 | { 401 | // Disable USB interrupts 402 | USBIIE = 0; 403 | USBOIE = 0; 404 | USBCIE = 0; 405 | IEN2 &= ~IEN2_USBIE; 406 | 407 | // Clear any pending interrupts 408 | USBCIF = 0; 409 | USBOIF = 0; 410 | USBIIF = 0; 411 | 412 | // Turn off the USB controller 413 | SLEEP &= ~SLEEP_USB_EN; 414 | } 415 | 416 | void usb_init() 417 | { 418 | // Init ep0 419 | usb_ep0_state = USB_EP0_IDLE; 420 | usb_iif = 0; 421 | usb_enable(); 422 | } 423 | 424 | void usb_readline(char* buff) { 425 | char c; 426 | while ((c = usb_getchar()) != '\n') { 427 | *buff++ = c; 428 | } 429 | *buff = 0; 430 | } 431 | 432 | void usb_putstr(char* buff) { 433 | while (*buff) { 434 | usb_putchar(*buff++); 435 | } 436 | usb_flush(); 437 | } 438 | 439 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /src/cc1111.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | Register Declarations for the ChipCon CC1111 Processor Range 3 | 4 | Modified 2011 by Fergus Noble to update depreciated sdcc keywords 5 | and add some missing sfr definitions. 6 | 7 | Copyright © 2008 Keith Packard 8 | 9 | This program is free software; you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation; version 2 of the License. 12 | 13 | This program is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 | 22 | Adapted from the Cygnal C8051F12x config file which is: 23 | 24 | Copyright (C) 2003 - Maarten Brock, sourceforge.brock@dse.nl 25 | 26 | This library is free software; you can redistribute it and/or 27 | modify it under the terms of the GNU Lesser General Public 28 | License as published by the Free Software Foundation; either 29 | version 2.1 of the License, or (at your option) any later version. 30 | 31 | This library is distributed in the hope that it will be useful, 32 | but WITHOUT ANY WARRANTY; without even the implied warranty of 33 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 34 | Lesser General Public License for more details. 35 | 36 | You should have received a copy of the GNU Lesser General Public 37 | License along with this library; if not, write to the Free Software 38 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 39 | -------------------------------------------------------------------------*/ 40 | 41 | #ifndef _CC1111_H_ 42 | #define _CC1111_H_ 43 | #include 44 | #include 45 | 46 | // Flash controller 47 | 48 | __sfr __at 0xAB FWT; // Flash Write Timing 49 | __sfr __at 0xAC FADDRL; // Flash Address Low Byte 50 | __sfr __at 0xAD FADDRH; // Flash Address High Byte 51 | __sfr __at 0xAE FCTL; // Flash Control 52 | __sfr __at 0xAF FWDATA; // Flash Write Data 53 | 54 | // FCTL (0xAE) - Flash Control 55 | #define FCTL_BUSY 0x80 56 | #define FCTL_SWBSY 0x40 57 | #define FCTL_CONTRD 0x10 58 | #define FCTL_WRITE 0x02 59 | #define FCTL_ERASE 0x01 60 | 61 | __sfr __at 0xA8 IEN0; /* Interrupt Enable 0 Register */ 62 | 63 | __sbit __at 0xA8 RFTXRXIE; /* RF TX/RX done interrupt enable */ 64 | __sbit __at 0xA9 ADCIE; /* ADC interrupt enable */ 65 | __sbit __at 0xAA URX0IE; /* USART0 RX interrupt enable */ 66 | __sbit __at 0xAB URX1IE; /* USART1 RX interrupt enable (shared with I2S RX) */ 67 | __sbit __at 0xAB I2SRXIE; /* I2S RX interrupt enable (shared with USART1 RX) */ 68 | __sbit __at 0xAC ENCIE; /* AES encryption/decryption interrupt enable */ 69 | __sbit __at 0xAD STIE; /* Sleep Timer interrupt enable */ 70 | __sbit __at 0xAF EA; /* Enable All */ 71 | 72 | #define IEN0_EA (1 << 7) 73 | #define IEN0_STIE (1 << 5) 74 | #define IEN0_ENCIE (1 << 4) 75 | #define IEN0_URX1IE (1 << 3) 76 | #define IEN0_I2SRXIE (1 << 3) 77 | #define IEN0_URX0IE (1 << 2) 78 | #define IEN0_ADCIE (1 << 1) 79 | #define IEN0_RFTXRXIE (1 << 0) 80 | 81 | __sfr __at 0xB8 IEN1; /* Interrupt Enable 1 Register */ 82 | 83 | #define IEN1_P0IE (1 << 5) /* Port 0 interrupt enable */ 84 | #define IEN1_T4IE (1 << 4) /* Timer 4 interrupt enable */ 85 | #define IEN1_T3IE (1 << 3) /* Timer 3 interrupt enable */ 86 | #define IEN1_T2IE (1 << 2) /* Timer 2 interrupt enable */ 87 | #define IEN1_T1IE (1 << 1) /* Timer 1 interrupt enable */ 88 | #define IEN1_DMAIE (1 << 0) /* DMA transfer interrupt enable */ 89 | 90 | /* IEN2 */ 91 | __sfr __at 0x9A IEN2; /* Interrupt Enable 2 Register */ 92 | 93 | #define IEN2_WDTIE (1 << 5) /* Watchdog timer interrupt enable */ 94 | #define IEN2_P1IE (1 << 4) /* Port 1 interrupt enable */ 95 | #define IEN2_UTX1IE (1 << 3) /* USART1 TX interrupt enable */ 96 | #define IEN2_I2STXIE (1 << 3) /* I2S TX interrupt enable */ 97 | #define IEN2_UTX0IE (1 << 2) /* USART0 TX interrupt enable */ 98 | #define IEN2_P2IE (1 << 1) /* Port 2 interrupt enable */ 99 | #define IEN2_USBIE (1 << 1) /* USB interrupt enable */ 100 | #define IEN2_RFIE (1 << 0) /* RF general interrupt enable */ 101 | 102 | /* CLKCON 0xC6 */ 103 | __sfr __at 0xC6 CLKCON; /* Clock Control */ 104 | 105 | #define CLKCON_OSC32K_RC (1 << 7) 106 | #define CLKCON_OSC32K_XTAL (0 << 7) 107 | #define CLKCON_OSC32K_MASK (1 << 7) 108 | #define CLKCON_OSC_RC (1 << 6) 109 | #define CLKCON_OSC_XTAL (0 << 6) 110 | #define CLKCON_OSC_MASK (1 << 6) 111 | #define CLKCON_TICKSPD_MASK (7 << 3) 112 | # define CLKCON_TICKSPD_1 (0 << 3) 113 | # define CLKCON_TICKSPD_1_2 (1 << 3) 114 | # define CLKCON_TICKSPD_1_4 (2 << 3) 115 | # define CLKCON_TICKSPD_1_8 (3 << 3) 116 | # define CLKCON_TICKSPD_1_16 (4 << 3) 117 | # define CLKCON_TICKSPD_1_32 (5 << 3) 118 | # define CLKCON_TICKSPD_1_64 (6 << 3) 119 | # define CLKCON_TICKSPD_1_128 (7 << 3) 120 | 121 | #define CLKCON_CLKSPD_MASK (7 << 0) 122 | # define CLKCON_CLKSPD_1 (0 << 0) 123 | # define CLKCON_CLKSPD_1_2 (1 << 0) 124 | # define CLKCON_CLKSPD_1_4 (2 << 0) 125 | # define CLKCON_CLKSPD_1_8 (3 << 0) 126 | # define CLKCON_CLKSPD_1_16 (4 << 0) 127 | # define CLKCON_CLKSPD_1_32 (5 << 0) 128 | # define CLKCON_CLKSPD_1_64 (6 << 0) 129 | # define CLKCON_CLKSPD_1_128 (7 << 0) 130 | 131 | /* SLEEP 0xBE */ 132 | #define SLEEP_USB_EN (1 << 7) 133 | #define SLEEP_XOSC_STB (1 << 6) 134 | #define SLEEP_HFRC_STB (1 << 5) 135 | #define SLEEP_RST_POWER (0 << 3) 136 | #define SLEEP_RST_EXTERNAL (1 << 3) 137 | #define SLEEP_RST_WATCHDOG (2 << 3) 138 | #define SLEEP_RST_MASK (3 << 3) 139 | #define SLEEP_OSC_PD (1 << 2) 140 | #define SLEEP_MODE_PM0 (0 << 0) 141 | #define SLEEP_MODE_PM1 (1 << 0) 142 | #define SLEEP_MODE_PM2 (2 << 0) 143 | #define SLEEP_MODE_PM3 (3 << 0) 144 | #define SLEEP_MODE_MASK (3 << 0) 145 | 146 | /* PCON 0x87 */ 147 | __sfr __at 0x87 PCON; /* Power Mode Control Register */ 148 | 149 | #define PCON_IDLE (1 << 0) 150 | 151 | /* 152 | * TCON 153 | */ 154 | __sfr __at 0x88 TCON; /* CPU Interrupt Flag 1 */ 155 | 156 | __sbit __at 0x8F URX1IF; /* USART1 RX interrupt flag. Automatically cleared */ 157 | __sbit __at 0x8F I2SRXIF; /* I2S RX interrupt flag. Automatically cleared */ 158 | __sbit __at 0x8D ADCIF; /* ADC interrupt flag. Automatically cleared */ 159 | __sbit __at 0x8B URX0IF; /* USART0 RX interrupt flag. Automatically cleared */ 160 | __sbit __at 0x89 RFTXRXIF; /* RF TX/RX complete interrupt flag. Automatically cleared */ 161 | 162 | #define TCON_URX1IF (1 << 7) 163 | #define TCON_I2SRXIF (1 << 7) 164 | #define TCON_ADCIF (1 << 5) 165 | #define TCON_URX0IF (1 << 3) 166 | #define TCON_RFTXRXIF (1 << 1) 167 | 168 | /* 169 | * S0CON 170 | */ 171 | __sfr __at 0x98 S0CON; /* CPU Interrupt Flag 2 */ 172 | 173 | __sbit __at 0x98 ENCIF_0; /* AES interrupt 0. */ 174 | __sbit __at 0x99 ENCIF_1; /* AES interrupt 1. */ 175 | 176 | #define S0CON_ENCIF_1 (1 << 1) 177 | #define S0CON_ENCIF_0 (1 << 0) 178 | 179 | /* 180 | * S1CON 181 | */ 182 | __sfr __at 0x9B S1CON; /* CPU Interrupt Flag 3 */ 183 | 184 | #define S1CON_RFIF_1 (1 << 1) 185 | #define S1CON_RFIF_0 (1 << 0) 186 | 187 | /* 188 | * IRCON 189 | */ 190 | __sfr __at 0xC0 IRCON; /* CPU Interrupt Flag 4 */ 191 | 192 | __sbit __at 0xC0 DMAIF; /* DMA complete interrupt flag */ 193 | __sbit __at 0xC1 T1IF; /* Timer 1 interrupt flag. Automatically cleared */ 194 | __sbit __at 0xC2 T2IF; /* Timer 2 interrupt flag. Automatically cleared */ 195 | __sbit __at 0xC3 T3IF; /* Timer 3 interrupt flag. Automatically cleared */ 196 | __sbit __at 0xC4 T4IF; /* Timer 4 interrupt flag. Automatically cleared */ 197 | __sbit __at 0xC5 P0IF; /* Port0 interrupt flag */ 198 | __sbit __at 0xC7 STIF; /* Sleep Timer interrupt flag */ 199 | 200 | #define IRCON_DMAIF (1 << 0) /* DMA complete interrupt flag */ 201 | #define IRCON_T1IF (1 << 1) /* Timer 1 interrupt flag. Automatically cleared */ 202 | #define IRCON_T2IF (1 << 2) /* Timer 2 interrupt flag. Automatically cleared */ 203 | #define IRCON_T3IF (1 << 3) /* Timer 3 interrupt flag. Automatically cleared */ 204 | #define IRCON_T4IF (1 << 4) /* Timer 4 interrupt flag. Automatically cleared */ 205 | #define IRCON_P0IF (1 << 5) /* Port0 interrupt flag */ 206 | #define IRCON_STIF (1 << 7) /* Sleep Timer interrupt flag */ 207 | 208 | /* 209 | * IRCON2 210 | */ 211 | __sfr __at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */ 212 | 213 | __sbit __at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */ 214 | __sbit __at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */ 215 | __sbit __at 0xE9 UTX0IF; /* USART0 TX interrupt flag */ 216 | __sbit __at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */ 217 | __sbit __at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */ 218 | __sbit __at 0xEB P1IF; /* Port1 interrupt flag */ 219 | __sbit __at 0xEC WDTIF; /* Watchdog timer interrupt flag */ 220 | 221 | #define IRCON2_USBIF (1 << 0) /* USB interrupt flag (shared with Port2) */ 222 | #define IRCON2_P2IF (1 << 0) /* Port2 interrupt flag (shared with USB) */ 223 | #define IRCON2_UTX0IF (1 << 1) /* USART0 TX interrupt flag */ 224 | #define IRCON2_UTX1IF (1 << 2) /* USART1 TX interrupt flag (shared with I2S TX) */ 225 | #define IRCON2_I2STXIF (1 << 2) /* I2S TX interrupt flag (shared with USART1 TX) */ 226 | #define IRCON2_P1IF (1 << 3) /* Port1 interrupt flag */ 227 | #define IRCON2_WDTIF (1 << 4) /* Watchdog timer interrupt flag */ 228 | 229 | /* 230 | * IP1 - Interrupt Priority 1 231 | */ 232 | 233 | /* 234 | * Interrupt priority groups: 235 | * 236 | * IPG0 RFTXRX RF DMA 237 | * IPG1 ADC T1 P2INT/USB 238 | * IPG2 URX0 T2 UTX0 239 | * IPG3 URX1/I2SRX T3 UTX1 / I2STX 240 | * IPG4 ENC T4 P1INT 241 | * IPG5 ST P0INT WDT 242 | * 243 | * Priority = (IP1 << 1) | IP0. Higher priority interrupts served first 244 | */ 245 | 246 | __sfr __at 0xB9 IP1; /* Interrupt Priority 1 */ 247 | __sfr __at 0xA9 IP0; /* Interrupt Priority 0 */ 248 | 249 | #define IP1_IPG5 (1 << 5) 250 | #define IP1_IPG4 (1 << 4) 251 | #define IP1_IPG3 (1 << 3) 252 | #define IP1_IPG2 (1 << 2) 253 | #define IP1_IPG1 (1 << 1) 254 | #define IP1_IPG0 (1 << 0) 255 | 256 | #define IP0_IPG5 (1 << 5) 257 | #define IP0_IPG4 (1 << 4) 258 | #define IP0_IPG3 (1 << 3) 259 | #define IP0_IPG2 (1 << 2) 260 | #define IP0_IPG1 (1 << 1) 261 | #define IP0_IPG0 (1 << 0) 262 | 263 | /* 264 | * Timer 1 265 | */ 266 | #define T1CTL_MODE_SUSPENDED (0 << 0) 267 | #define T1CTL_MODE_FREE (1 << 0) 268 | #define T1CTL_MODE_MODULO (2 << 0) 269 | #define T1CTL_MODE_UP_DOWN (3 << 0) 270 | #define T1CTL_MODE_MASK (3 << 0) 271 | #define T1CTL_DIV_1 (0 << 2) 272 | #define T1CTL_DIV_8 (1 << 2) 273 | #define T1CTL_DIV_32 (2 << 2) 274 | #define T1CTL_DIV_128 (3 << 2) 275 | #define T1CTL_DIV_MASK (3 << 2) 276 | #define T1CTL_OVFIF (1 << 4) 277 | #define T1CTL_CH0IF (1 << 5) 278 | #define T1CTL_CH1IF (1 << 6) 279 | #define T1CTL_CH2IF (1 << 7) 280 | 281 | #define T1CCTL_NO_CAPTURE (0 << 0) 282 | #define T1CCTL_CAPTURE_RISING (1 << 0) 283 | #define T1CCTL_CAPTURE_FALLING (2 << 0) 284 | #define T1CCTL_CAPTURE_BOTH (3 << 0) 285 | #define T1CCTL_CAPTURE_MASK (3 << 0) 286 | 287 | #define T1CCTL_MODE_CAPTURE (0 << 2) 288 | #define T1CCTL_MODE_COMPARE (1 << 2) 289 | 290 | #define T1CTL_CMP_SET (0 << 3) 291 | #define T1CTL_CMP_CLEAR (1 << 3) 292 | #define T1CTL_CMP_TOGGLE (2 << 3) 293 | #define T1CTL_CMP_SET_CLEAR (3 << 3) 294 | #define T1CTL_CMP_CLEAR_SET (4 << 3) 295 | 296 | #define T1CTL_IM_DISABLED (0 << 6) 297 | #define T1CTL_IM_ENABLED (1 << 6) 298 | 299 | #define T1CTL_CPSEL_NORMAL (0 << 7) 300 | #define T1CTL_CPSEL_RF (1 << 7) 301 | 302 | /* 303 | * Timer 3 and Timer 4 304 | */ 305 | 306 | /* Timer count */ 307 | __sfr __at 0xCA T3CNT; 308 | __sfr __at 0xEA T4CNT; 309 | 310 | /* Timer control */ 311 | 312 | __sfr __at 0xCB T3CTL; 313 | __sfr __at 0xEB T4CTL; 314 | 315 | #define TxCTL_DIV_1 (0 << 5) 316 | #define TxCTL_DIV_2 (1 << 5) 317 | #define TxCTL_DIV_4 (2 << 5) 318 | #define TxCTL_DIV_8 (3 << 5) 319 | #define TxCTL_DIV_16 (4 << 5) 320 | #define TxCTL_DIV_32 (5 << 5) 321 | #define TxCTL_DIV_64 (6 << 5) 322 | #define TxCTL_DIV_128 (7 << 5) 323 | #define TxCTL_START (1 << 4) 324 | #define TxCTL_OVFIM (1 << 3) 325 | #define TxCTL_CLR (1 << 2) 326 | #define TxCTL_MODE_FREE (0 << 0) 327 | #define TxCTL_MODE_DOWN (1 << 0) 328 | #define TxCTL_MODE_MODULO (2 << 0) 329 | #define TxCTL_MODE_UP_DOWN (3 << 0) 330 | 331 | /* Timer 4 channel 0 compare control */ 332 | 333 | __sfr __at 0xCC T3CCTL0; 334 | __sfr __at 0xCE T3CCTL1; 335 | __sfr __at 0xEC T4CCTL0; 336 | __sfr __at 0xEE T4CCTL1; 337 | 338 | #define TxCCTLy_IM (1 << 6) 339 | #define TxCCTLy_CMP_SET (0 << 3) 340 | #define TxCCTLy_CMP_CLEAR (1 << 3) 341 | #define TxCCTLy_CMP_TOGGLE (2 << 3) 342 | #define TxCCTLy_CMP_SET_UP_CLEAR_DOWN (3 << 3) 343 | #define TxCCTLy_CMP_CLEAR_UP_SET_DOWN (4 << 3) 344 | #define TxCCTLy_CMP_SET_CLEAR_FF (5 << 3) 345 | #define TxCCTLy_CMP_CLEAR_SET_00 (6 << 3) 346 | #define TxCCTLy_CMP_MODE_ENABLE (1 << 2) 347 | 348 | /* Timer compare value */ 349 | __sfr __at 0xCD T3CC0; 350 | __sfr __at 0xCF T3CC1; 351 | __sfr __at 0xED T4CC0; 352 | __sfr __at 0xEF T4CC1; 353 | 354 | /* 355 | * Peripheral control 356 | */ 357 | 358 | __sfr __at 0xf1 PERCFG; 359 | #define PERCFG_T1CFG_ALT_1 (0 << 6) 360 | #define PERCFG_T1CFG_ALT_2 (1 << 6) 361 | #define PERCFG_T1CFG_ALT_MASK (1 << 6) 362 | 363 | #define PERCFG_T3CFG_ALT_1 (0 << 5) 364 | #define PERCFG_T3CFG_ALT_2 (1 << 5) 365 | #define PERCFG_T3CFG_ALT_MASK (1 << 5) 366 | 367 | #define PERCFG_T4CFG_ALT_1 (0 << 4) 368 | #define PERCFG_T4CFG_ALT_2 (1 << 4) 369 | #define PERCFG_T4CFG_ALT_MASK (1 << 4) 370 | 371 | #define PERCFG_U1CFG_ALT_1 (0 << 1) 372 | #define PERCFG_U1CFG_ALT_2 (1 << 1) 373 | #define PERCFG_U1CFG_ALT_MASK (1 << 1) 374 | 375 | #define PERCFG_U0CFG_ALT_1 (0 << 0) 376 | #define PERCFG_U0CFG_ALT_2 (1 << 0) 377 | #define PERCFG_U0CFG_ALT_MASK (1 << 0) 378 | 379 | /* directly addressed USB registers */ 380 | __xdata __at (0xde00) volatile uint8_t USBADDR; 381 | __xdata __at (0xde01) volatile uint8_t USBPOW; 382 | __xdata __at (0xde02) volatile uint8_t USBIIF; 383 | 384 | __xdata __at (0xde04) volatile uint8_t USBOIF; 385 | 386 | __xdata __at (0xde06) volatile uint8_t USBCIF; 387 | 388 | # define USBCIF_SOFIF (1 << 3) 389 | # define USBCIF_RSTIF (1 << 2) 390 | # define USBCIF_RESUMEIF (1 << 1) 391 | # define USBCIF_SUSPENDIF (1 << 0) 392 | 393 | __xdata __at (0xde07) volatile uint8_t USBIIE; 394 | 395 | __xdata __at (0xde09) volatile uint8_t USBOIE; 396 | 397 | __xdata __at (0xde0b) volatile uint8_t USBCIE; 398 | 399 | # define USBCIE_SOFIE (1 << 3) 400 | # define USBCIE_RSTIE (1 << 2) 401 | # define USBCIE_RESUMEIE (1 << 1) 402 | # define USBCIE_SUSPENDIE (1 << 0) 403 | 404 | __xdata __at (0xde0c) volatile uint8_t USBFRML; 405 | __xdata __at (0xde0d) volatile uint8_t USBFRMH; 406 | __xdata __at (0xde0e) volatile uint8_t USBINDEX; 407 | 408 | /* indexed USB registers, must set USBINDEX to 0-5 */ 409 | __xdata __at (0xde10) volatile uint8_t USBMAXI; 410 | __xdata __at (0xde11) volatile uint8_t USBCS0; 411 | 412 | # define USBCS0_CLR_SETUP_END (1 << 7) 413 | # define USBCS0_CLR_OUTPKT_RDY (1 << 6) 414 | # define USBCS0_SEND_STALL (1 << 5) 415 | # define USBCS0_SETUP_END (1 << 4) 416 | # define USBCS0_DATA_END (1 << 3) 417 | # define USBCS0_SENT_STALL (1 << 2) 418 | # define USBCS0_INPKT_RDY (1 << 1) 419 | # define USBCS0_OUTPKT_RDY (1 << 0) 420 | 421 | __xdata __at (0xde11) volatile uint8_t USBCSIL; 422 | 423 | # define USBCSIL_CLR_DATA_TOG (1 << 6) 424 | # define USBCSIL_SENT_STALL (1 << 5) 425 | # define USBCSIL_SEND_STALL (1 << 4) 426 | # define USBCSIL_FLUSH_PACKET (1 << 3) 427 | # define USBCSIL_UNDERRUN (1 << 2) 428 | # define USBCSIL_PKT_PRESENT (1 << 1) 429 | # define USBCSIL_INPKT_RDY (1 << 0) 430 | 431 | __xdata __at (0xde12) volatile uint8_t USBCSIH; 432 | 433 | # define USBCSIH_AUTOSET (1 << 7) 434 | # define USBCSIH_ISO (1 << 6) 435 | # define USBCSIH_FORCE_DATA_TOG (1 << 3) 436 | # define USBCSIH_IN_DBL_BUF (1 << 0) 437 | 438 | __xdata __at (0xde13) volatile uint8_t USBMAXO; 439 | __xdata __at (0xde14) volatile uint8_t USBCSOL; 440 | 441 | # define USBCSOL_CLR_DATA_TOG (1 << 7) 442 | # define USBCSOL_SENT_STALL (1 << 6) 443 | # define USBCSOL_SEND_STALL (1 << 5) 444 | # define USBCSOL_FLUSH_PACKET (1 << 4) 445 | # define USBCSOL_DATA_ERROR (1 << 3) 446 | # define USBCSOL_OVERRUN (1 << 2) 447 | # define USBCSOL_FIFO_FULL (1 << 1) 448 | # define USBCSOL_OUTPKT_RDY (1 << 0) 449 | 450 | __xdata __at (0xde15) volatile uint8_t USBCSOH; 451 | 452 | # define USBCSOH_AUTOCLEAR (1 << 7) 453 | # define USBCSOH_ISO (1 << 6) 454 | # define USBCSOH_OUT_DBL_BUF (1 << 0) 455 | 456 | __xdata __at (0xde16) volatile uint8_t USBCNT0; 457 | __xdata __at (0xde16) volatile uint8_t USBCNTL; 458 | __xdata __at (0xde17) volatile uint8_t USBCNTH; 459 | 460 | __xdata __at (0xde20) volatile uint8_t USBFIFO[12]; 461 | 462 | /* ADC Data register, low and high */ 463 | __sfr __at 0xBA ADCL; 464 | __sfr __at 0xBB ADCH; 465 | __xdata __at (0xDFBA) volatile uint16_t ADCXDATA; 466 | 467 | /* ADC Control Register 1 */ 468 | __sfr __at 0xB4 ADCCON1; 469 | 470 | # define ADCCON1_EOC (1 << 7) /* conversion complete */ 471 | # define ADCCON1_ST (1 << 6) /* start conversion */ 472 | 473 | # define ADCCON1_STSEL_MASK (3 << 4) /* start select */ 474 | # define ADCCON1_STSEL_EXTERNAL (0 << 4) /* P2_0 pin triggers */ 475 | # define ADCCON1_STSEL_FULLSPEED (1 << 4) /* full speed, no waiting */ 476 | # define ADCCON1_STSEL_TIMER1 (2 << 4) /* timer 1 channel 0 */ 477 | # define ADCCON1_STSEL_START (3 << 4) /* set start bit */ 478 | 479 | # define ADCCON1_RCTRL_MASK (3 << 2) /* random number control */ 480 | # define ADCCON1_RCTRL_COMPLETE (0 << 2) /* operation completed */ 481 | # define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2) /* Clock the LFSR once */ 482 | 483 | /* ADC Control Register 2 */ 484 | __sfr __at 0xB5 ADCCON2; 485 | 486 | # define ADCCON2_SREF_MASK (3 << 6) /* reference voltage */ 487 | # define ADCCON2_SREF_1_25V (0 << 6) /* internal 1.25V */ 488 | # define ADCCON2_SREF_EXTERNAL (1 << 6) /* external on AIN7 cc1110 */ 489 | # define ADCCON2_SREF_VDD (2 << 6) /* VDD on the AVDD pin */ 490 | # define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6) /* external on AIN6-7 cc1110 */ 491 | 492 | # define ADCCON2_SDIV_MASK (3 << 4) /* decimation rate */ 493 | # define ADCCON2_SDIV_64 (0 << 4) /* 7 bits */ 494 | # define ADCCON2_SDIV_128 (1 << 4) /* 9 bits */ 495 | # define ADCCON2_SDIV_256 (2 << 4) /* 10 bits */ 496 | # define ADCCON2_SDIV_512 (3 << 4) /* 12 bits */ 497 | 498 | # define ADCCON2_SCH_MASK (0xf << 0) /* Sequence channel select */ 499 | # define ADCCON2_SCH_SHIFT 0 500 | # define ADCCON2_SCH_AIN0 (0 << 0) 501 | # define ADCCON2_SCH_AIN1 (1 << 0) 502 | # define ADCCON2_SCH_AIN2 (2 << 0) 503 | # define ADCCON2_SCH_AIN3 (3 << 0) 504 | # define ADCCON2_SCH_AIN4 (4 << 0) 505 | # define ADCCON2_SCH_AIN5 (5 << 0) 506 | # define ADCCON2_SCH_AIN6 (6 << 0) 507 | # define ADCCON2_SCH_AIN7 (7 << 0) 508 | # define ADCCON2_SCH_AIN0_AIN1 (8 << 0) 509 | # define ADCCON2_SCH_AIN2_AIN3 (9 << 0) 510 | # define ADCCON2_SCH_AIN4_AIN5 (0xa << 0) 511 | # define ADCCON2_SCH_AIN6_AIN7 (0xb << 0) 512 | # define ADCCON2_SCH_GND (0xc << 0) 513 | # define ADCCON2_SCH_VREF (0xd << 0) 514 | # define ADCCON2_SCH_TEMP (0xe << 0) 515 | # define ADCCON2_SCH_VDD_3 (0xf << 0) 516 | 517 | 518 | /* ADC Control Register 3 */ 519 | __sfr __at 0xB6 ADCCON3; 520 | 521 | # define ADCCON3_EREF_MASK (3 << 6) /* extra conversion reference */ 522 | # define ADCCON3_EREF_1_25 (0 << 6) /* internal 1.25V */ 523 | # define ADCCON3_EREF_EXTERNAL (1 << 6) /* external AIN7 cc1110 */ 524 | # define ADCCON3_EREF_VDD (2 << 6) /* VDD on the AVDD pin */ 525 | # define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6) /* external AIN6-7 cc1110 */ 526 | # define ADCCON3_EDIV_MASK (3 << 4) /* extral decimation */ 527 | # define ADCCON3_EDIV_64 (0 << 4) /* 7 bits */ 528 | # define ADCCON3_EDIV_128 (1 << 4) /* 9 bits */ 529 | # define ADCCON3_EDIV_256 (2 << 4) /* 10 bits */ 530 | # define ADCCON3_EDIV_512 (3 << 4) /* 12 bits */ 531 | # define ADCCON3_ECH_MASK (0xf << 0) /* Sequence channel select */ 532 | # define ADCCON3_ECH_SHIFT 0 533 | # define ADCCON3_ECH_AIN0 (0 << 0) 534 | # define ADCCON3_ECH_AIN1 (1 << 0) 535 | # define ADCCON3_ECH_AIN2 (2 << 0) 536 | # define ADCCON3_ECH_AIN3 (3 << 0) 537 | # define ADCCON3_ECH_AIN4 (4 << 0) 538 | # define ADCCON3_ECH_AIN5 (5 << 0) 539 | # define ADCCON3_ECH_AIN6 (6 << 0) 540 | # define ADCCON3_ECH_AIN7 (7 << 0) 541 | # define ADCCON3_ECH_AIN0_AIN1 (8 << 0) 542 | # define ADCCON3_ECH_AIN2_AIN3 (9 << 0) 543 | # define ADCCON3_ECH_AIN4_AIN5 (0xa << 0) 544 | # define ADCCON3_ECH_AIN6_AIN7 (0xb << 0) 545 | # define ADCCON3_ECH_GND (0xc << 0) 546 | # define ADCCON3_ECH_VREF (0xd << 0) 547 | # define ADCCON3_ECH_TEMP (0xe << 0) 548 | # define ADCCON3_ECH_VDD_3 (0xf << 0) 549 | 550 | /* 551 | * ADC configuration register, this selects which 552 | * GPIO pins are to be used as ADC inputs 553 | */ 554 | __sfr __at 0xF2 ADCCFG; 555 | 556 | /* 557 | * Watchdog timer 558 | */ 559 | 560 | __sfr __at 0xc9 WDCTL; 561 | 562 | #define WDCTL_CLEAR_FIRST (0xa << 4) 563 | #define WDCTL_CLEAR_SECOND (0x5 << 4) 564 | #define WDCTL_EN (1 << 3) 565 | #define WDCTL_MODE_WATCHDOG (0 << 2) 566 | #define WDCTL_MODE_TIMER (1 << 2) 567 | #define WDCTL_MODE_MASK (1 << 2) 568 | #define WDCTL_INT_32768 (0 << 0) 569 | #define WDCTL_INT_8192 (1 << 0) 570 | #define WDCTL_INT_512 (2 << 0) 571 | #define WDCTL_INT_64 (3 << 0) 572 | 573 | /* 574 | * Pin selectors, these set which pins are 575 | * using their peripheral function 576 | */ 577 | __sfr __at 0xF3 P0SEL; 578 | __sfr __at 0xF4 P1SEL; 579 | __sfr __at 0xF5 P2SEL; 580 | 581 | #define P2SEL_PRI3P1_USART0 (0 << 6) 582 | #define P2SEL_PRI3P1_USART1 (1 << 6) 583 | #define P2SEL_PRI3P1_MASK (1 << 6) 584 | #define P2SEL_PRI2P1_USART1 (0 << 5) 585 | #define P2SEL_PRI2P1_TIMER3 (1 << 5) 586 | #define P2SEL_PRI1P1_TIMER1 (0 << 4) 587 | #define P2SEL_PRI1P1_TIMER4 (1 << 4) 588 | #define P2SEL_PRI0P1_USART0 (0 << 3) 589 | #define P2SEL_PRI0P1_TIMER1 (1 << 3) 590 | #define P2SEL_SELP2_4_GPIO (0 << 2) 591 | #define P2SEL_SELP2_4_PERIPHERAL (1 << 2) 592 | #define P2SEL_SELP2_3_GPIO (0 << 1) 593 | #define P2SEL_SELP2_3_PERIPHERAL (1 << 1) 594 | #define P2SEL_SELP2_0_GPIO (0 << 0) 595 | #define P2SEL_SELP2_0_PERIPHERAL (1 << 0) 596 | #define P2SEL_SELP2_0_MASK (1 << 0) 597 | 598 | /* 599 | * For pins used as GPIOs, these set which are used as outputs 600 | */ 601 | __sfr __at 0xFD P0DIR; 602 | __sfr __at 0xFE P1DIR; 603 | __sfr __at 0xFF P2DIR; 604 | 605 | __sfr __at 0x8F P0INP; 606 | 607 | /* Select between tri-state and pull up/down 608 | * for pins P0_0 - P0_7. 609 | */ 610 | #define P0INP_MDP0_7_PULL (0 << 7) 611 | #define P0INP_MDP0_7_TRISTATE (1 << 7) 612 | #define P0INP_MDP0_6_PULL (0 << 6) 613 | #define P0INP_MDP0_6_TRISTATE (1 << 6) 614 | #define P0INP_MDP0_5_PULL (0 << 5) 615 | #define P0INP_MDP0_5_TRISTATE (1 << 5) 616 | #define P0INP_MDP0_4_PULL (0 << 4) 617 | #define P0INP_MDP0_4_TRISTATE (1 << 4) 618 | #define P0INP_MDP0_3_PULL (0 << 3) 619 | #define P0INP_MDP0_3_TRISTATE (1 << 3) 620 | #define P0INP_MDP0_2_PULL (0 << 2) 621 | #define P0INP_MDP0_2_TRISTATE (1 << 2) 622 | #define P0INP_MDP0_1_PULL (0 << 1) 623 | #define P0INP_MDP0_1_TRISTATE (1 << 1) 624 | #define P0INP_MDP0_0_PULL (0 << 0) 625 | #define P0INP_MDP0_0_TRISTATE (1 << 0) 626 | 627 | __sfr __at 0xF6 P1INP; 628 | 629 | /* Select between tri-state and pull up/down 630 | * for pins P1_2 - P1_7. Pins P1_0 and P1_1 are 631 | * always tri-stated 632 | */ 633 | #define P1INP_MDP1_7_PULL (0 << 7) 634 | #define P1INP_MDP1_7_TRISTATE (1 << 7) 635 | #define P1INP_MDP1_6_PULL (0 << 6) 636 | #define P1INP_MDP1_6_TRISTATE (1 << 6) 637 | #define P1INP_MDP1_5_PULL (0 << 5) 638 | #define P1INP_MDP1_5_TRISTATE (1 << 5) 639 | #define P1INP_MDP1_4_PULL (0 << 4) 640 | #define P1INP_MDP1_4_TRISTATE (1 << 4) 641 | #define P1INP_MDP1_3_PULL (0 << 3) 642 | #define P1INP_MDP1_3_TRISTATE (1 << 3) 643 | #define P1INP_MDP1_2_PULL (0 << 2) 644 | #define P1INP_MDP1_2_TRISTATE (1 << 2) 645 | 646 | __sfr __at 0xF7 P2INP; 647 | /* P2INP has three extra bits which are used to choose 648 | * between pull-up and pull-down when they are not tri-stated 649 | */ 650 | #define P2INP_PDUP2_PULL_UP (0 << 7) 651 | #define P2INP_PDUP2_PULL_DOWN (1 << 7) 652 | #define P2INP_PDUP1_PULL_UP (0 << 6) 653 | #define P2INP_PDUP1_PULL_DOWN (1 << 6) 654 | #define P2INP_PDUP0_PULL_UP (0 << 5) 655 | #define P2INP_PDUP0_PULL_DOWN (1 << 5) 656 | 657 | /* For the P2 pins, choose between tri-state and pull up/down 658 | * mode 659 | */ 660 | #define P2INP_MDP2_4_PULL (0 << 4) 661 | #define P2INP_MDP2_4_TRISTATE (1 << 4) 662 | #define P2INP_MDP2_3_PULL (0 << 3) 663 | #define P2INP_MDP2_3_TRISTATE (1 << 3) 664 | #define P2INP_MDP2_2_PULL (0 << 2) 665 | #define P2INP_MDP2_2_TRISTATE (1 << 2) 666 | #define P2INP_MDP2_1_PULL (0 << 1) 667 | #define P2INP_MDP2_1_TRISTATE (1 << 1) 668 | #define P2INP_MDP2_0_PULL (0 << 0) 669 | #define P2INP_MDP2_0_TRISTATE (1 << 0) 670 | 671 | /* GPIO interrupt status flags */ 672 | __sfr __at 0x89 P0IFG; 673 | __sfr __at 0x8A P1IFG; 674 | __sfr __at 0x8B P2IFG; 675 | 676 | #define P0IFG_USB_RESUME (1 << 7) 677 | 678 | /* GPIO pins */ 679 | __sfr __at 0x80 P0; 680 | 681 | __sbit __at 0x80 P0_0; 682 | __sbit __at 0x81 P0_1; 683 | __sbit __at 0x82 P0_2; 684 | __sbit __at 0x83 P0_3; 685 | __sbit __at 0x84 P0_4; 686 | __sbit __at 0x85 P0_5; 687 | __sbit __at 0x86 P0_6; 688 | __sbit __at 0x87 P0_7; 689 | 690 | __sfr __at 0x90 P1; 691 | 692 | __sbit __at 0x90 P1_0; 693 | __sbit __at 0x91 P1_1; 694 | __sbit __at 0x92 P1_2; 695 | __sbit __at 0x93 P1_3; 696 | __sbit __at 0x94 P1_4; 697 | __sbit __at 0x95 P1_5; 698 | __sbit __at 0x96 P1_6; 699 | __sbit __at 0x97 P1_7; 700 | 701 | __sfr __at 0xa0 P2; 702 | 703 | __sbit __at 0xa0 P2_0; 704 | __sbit __at 0xa1 P2_1; 705 | __sbit __at 0xa2 P2_2; 706 | __sbit __at 0xa3 P2_3; 707 | __sbit __at 0xa4 P2_4; 708 | 709 | /* DMA controller */ 710 | struct cc_dma_channel { 711 | uint8_t src_high; 712 | uint8_t src_low; 713 | uint8_t dst_high; 714 | uint8_t dst_low; 715 | uint8_t len_high; 716 | uint8_t len_low; 717 | uint8_t cfg0; 718 | uint8_t cfg1; 719 | }; 720 | 721 | # define DMA_LEN_HIGH_VLEN_MASK (7 << 5) 722 | # define DMA_LEN_HIGH_VLEN_LEN (0 << 5) 723 | # define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5) 724 | # define DMA_LEN_HIGH_VLEN (2 << 5) 725 | # define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5) 726 | # define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5) 727 | # define DMA_LEN_HIGH_MASK (0x1f) 728 | 729 | # define DMA_CFG0_WORDSIZE_8 (0 << 7) 730 | # define DMA_CFG0_WORDSIZE_16 (1 << 7) 731 | # define DMA_CFG0_TMODE_MASK (3 << 5) 732 | # define DMA_CFG0_TMODE_SINGLE (0 << 5) 733 | # define DMA_CFG0_TMODE_BLOCK (1 << 5) 734 | # define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5) 735 | # define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5) 736 | 737 | /* 738 | * DMA triggers 739 | */ 740 | # define DMA_CFG0_TRIGGER_NONE 0 741 | # define DMA_CFG0_TRIGGER_PREV 1 742 | # define DMA_CFG0_TRIGGER_T1_CH0 2 743 | # define DMA_CFG0_TRIGGER_T1_CH1 3 744 | # define DMA_CFG0_TRIGGER_T1_CH2 4 745 | # define DMA_CFG0_TRIGGER_T2_OVFL 6 746 | # define DMA_CFG0_TRIGGER_T3_CH0 7 747 | # define DMA_CFG0_TRIGGER_T3_CH1 8 748 | # define DMA_CFG0_TRIGGER_T4_CH0 9 749 | # define DMA_CFG0_TRIGGER_T4_CH1 10 750 | # define DMA_CFG0_TRIGGER_IOC_0 12 751 | # define DMA_CFG0_TRIGGER_IOC_1 13 752 | # define DMA_CFG0_TRIGGER_URX0 14 753 | # define DMA_CFG0_TRIGGER_UTX0 15 754 | # define DMA_CFG0_TRIGGER_URX1 16 755 | # define DMA_CFG0_TRIGGER_UTX1 17 756 | # define DMA_CFG0_TRIGGER_FLASH 18 757 | # define DMA_CFG0_TRIGGER_RADIO 19 758 | # define DMA_CFG0_TRIGGER_ADC_CHALL 20 759 | # define DMA_CFG0_TRIGGER_ADC_CH0 21 760 | # define DMA_CFG0_TRIGGER_ADC_CH1 22 761 | # define DMA_CFG0_TRIGGER_ADC_CH2 23 762 | # define DMA_CFG0_TRIGGER_ADC_CH3 24 763 | # define DMA_CFG0_TRIGGER_ADC_CH4 25 764 | # define DMA_CFG0_TRIGGER_ADC_CH5 26 765 | # define DMA_CFG0_TRIGGER_ADC_CH6 27 766 | # define DMA_CFG0_TRIGGER_I2SRX 27 767 | # define DMA_CFG0_TRIGGER_ADC_CH7 28 768 | # define DMA_CFG0_TRIGGER_I2STX 28 769 | # define DMA_CFG0_TRIGGER_ENC_DW 29 770 | # define DMA_CFG0_TRIGGER_DNC_UP 30 771 | 772 | # define DMA_CFG1_SRCINC_MASK (3 << 6) 773 | # define DMA_CFG1_SRCINC_0 (0 << 6) 774 | # define DMA_CFG1_SRCINC_1 (1 << 6) 775 | # define DMA_CFG1_SRCINC_2 (2 << 6) 776 | # define DMA_CFG1_SRCINC_MINUS_1 (3 << 6) 777 | 778 | # define DMA_CFG1_DESTINC_MASK (3 << 4) 779 | # define DMA_CFG1_DESTINC_0 (0 << 4) 780 | # define DMA_CFG1_DESTINC_1 (1 << 4) 781 | # define DMA_CFG1_DESTINC_2 (2 << 4) 782 | # define DMA_CFG1_DESTINC_MINUS_1 (3 << 4) 783 | 784 | # define DMA_CFG1_IRQMASK (1 << 3) 785 | # define DMA_CFG1_M8 (1 << 2) 786 | 787 | # define DMA_CFG1_PRIORITY_MASK (3 << 0) 788 | # define DMA_CFG1_PRIORITY_LOW (0 << 0) 789 | # define DMA_CFG1_PRIORITY_NORMAL (1 << 0) 790 | # define DMA_CFG1_PRIORITY_HIGH (2 << 0) 791 | 792 | /* 793 | * DMAARM - DMA Channel Arm 794 | */ 795 | 796 | __sfr __at 0xD6 DMAARM; 797 | 798 | # define DMAARM_ABORT (1 << 7) 799 | # define DMAARM_DMAARM4 (1 << 4) 800 | # define DMAARM_DMAARM3 (1 << 3) 801 | # define DMAARM_DMAARM2 (1 << 2) 802 | # define DMAARM_DMAARM1 (1 << 1) 803 | # define DMAARM_DMAARM0 (1 << 0) 804 | 805 | /* 806 | * DMAREQ - DMA Channel Start Request and Status 807 | */ 808 | 809 | __sfr __at 0xD7 DMAREQ; 810 | 811 | # define DMAREQ_DMAREQ4 (1 << 4) 812 | # define DMAREQ_DMAREQ3 (1 << 3) 813 | # define DMAREQ_DMAREQ2 (1 << 2) 814 | # define DMAREQ_DMAREQ1 (1 << 1) 815 | # define DMAREQ_DMAREQ0 (1 << 0) 816 | 817 | /* 818 | * DMA configuration 0 address 819 | */ 820 | 821 | __sfr __at 0xD5 DMA0CFGH; 822 | __sfr __at 0xD4 DMA0CFGL; 823 | 824 | /* 825 | * DMA configuration 1-4 address 826 | */ 827 | 828 | __sfr __at 0xD3 DMA1CFGH; 829 | __sfr __at 0xD2 DMA1CFGL; 830 | 831 | /* 832 | * DMAIRQ - DMA Interrupt Flag 833 | */ 834 | 835 | __sfr __at 0xD1 DMAIRQ; 836 | 837 | # define DMAIRQ_DMAIF4 (1 << 4) 838 | # define DMAIRQ_DMAIF3 (1 << 3) 839 | # define DMAIRQ_DMAIF2 (1 << 2) 840 | # define DMAIRQ_DMAIF1 (1 << 1) 841 | # define DMAIRQ_DMAIF0 (1 << 0) 842 | 843 | /* 844 | * UART registers 845 | */ 846 | 847 | /* USART config/status registers */ 848 | __sfr __at 0x86 U0CSR; 849 | __sfr __at 0xF8 U1CSR; 850 | 851 | # define UxCSR_MODE_UART (1 << 7) 852 | # define UxCSR_MODE_SPI (0 << 7) 853 | # define UxCSR_RE (1 << 6) 854 | # define UxCSR_SLAVE (1 << 5) 855 | # define UxCSR_MASTER (0 << 5) 856 | # define UxCSR_FE (1 << 4) 857 | # define UxCSR_ERR (1 << 3) 858 | # define UxCSR_RX_BYTE (1 << 2) 859 | # define UxCSR_TX_BYTE (1 << 1) 860 | # define UxCSR_ACTIVE (1 << 0) 861 | 862 | /* UART configuration registers */ 863 | __sfr __at 0xc4 U0UCR; 864 | __sfr __at 0xfb U1UCR; 865 | 866 | # define UxUCR_FLUSH (1 << 7) 867 | # define UxUCR_FLOW_DISABLE (0 << 6) 868 | # define UxUCR_FLOW_ENABLE (1 << 6) 869 | # define UxUCR_D9_EVEN_PARITY (0 << 5) 870 | # define UxUCR_D9_ODD_PARITY (1 << 5) 871 | # define UxUCR_BIT9_8_BITS (0 << 4) 872 | # define UxUCR_BIT9_9_BITS (1 << 4) 873 | # define UxUCR_PARITY_DISABLE (0 << 3) 874 | # define UxUCR_PARITY_ENABLE (1 << 3) 875 | # define UxUCR_SPB_1_STOP_BIT (0 << 2) 876 | # define UxUCR_SPB_2_STOP_BITS (1 << 2) 877 | # define UxUCR_STOP_LOW (0 << 1) 878 | # define UxUCR_STOP_HIGH (1 << 1) 879 | # define UxUCR_START_LOW (0 << 0) 880 | # define UxUCR_START_HIGH (1 << 0) 881 | 882 | /* USART General configuration registers (mostly SPI) */ 883 | __sfr __at 0xc5 U0GCR; 884 | __sfr __at 0xfc U1GCR; 885 | 886 | # define UxGCR_CPOL_NEGATIVE (0 << 7) 887 | # define UxGCR_CPOL_POSITIVE (1 << 7) 888 | # define UxGCR_CPHA_FIRST_EDGE (0 << 6) 889 | # define UxGCR_CPHA_SECOND_EDGE (1 << 6) 890 | # define UxGCR_ORDER_LSB (0 << 5) 891 | # define UxGCR_ORDER_MSB (1 << 5) 892 | # define UxGCR_BAUD_E_MASK (0x1f) 893 | # define UxGCR_BAUD_E_SHIFT 0 894 | 895 | /* USART data registers */ 896 | __sfr __at 0xc1 U0DBUF; 897 | __xdata __at (0xDFC1) volatile uint8_t U0DBUFXADDR; 898 | __sfr __at 0xf9 U1DBUF; 899 | __xdata __at (0xDFF9) volatile uint8_t U1DBUFXADDR; 900 | 901 | /* USART baud rate registers, M value */ 902 | __sfr __at 0xc2 U0BAUD; 903 | __sfr __at 0xfa U1BAUD; 904 | 905 | /* Radio */ 906 | 907 | __sfr __at 0xD9 RFD; 908 | __xdata __at (0xDFD9) volatile uint8_t RFDXADDR; 909 | 910 | __sfr __at 0xE9 RFIF; 911 | #define RFIF_IM_TXUNF (1 << 7) 912 | #define RFIF_IM_RXOVF (1 << 6) 913 | #define RFIF_IM_TIMEOUT (1 << 5) 914 | #define RFIF_IM_DONE (1 << 4) 915 | #define RFIF_IM_CS (1 << 3) 916 | #define RFIF_IM_PQT (1 << 2) 917 | #define RFIF_IM_CCA (1 << 1) 918 | #define RFIF_IM_SFD (1 << 0) 919 | 920 | __sfr __at 0x91 RFIM; 921 | #define RFIM_IM_TXUNF (1 << 7) 922 | #define RFIM_IM_RXOVF (1 << 6) 923 | #define RFIM_IM_TIMEOUT (1 << 5) 924 | #define RFIM_IM_DONE (1 << 4) 925 | #define RFIM_IM_CS (1 << 3) 926 | #define RFIM_IM_PQT (1 << 2) 927 | #define RFIM_IM_CCA (1 << 1) 928 | #define RFIM_IM_SFD (1 << 0) 929 | 930 | __sfr __at 0xE1 RFST; 931 | 932 | #define RFST_SFSTXON 0x00 933 | #define RFST_SCAL 0x01 934 | #define RFST_SRX 0x02 935 | #define RFST_STX 0x03 936 | #define RFST_SIDLE 0x04 937 | 938 | __xdata __at (0xdf00) uint8_t RF[0x3c]; 939 | 940 | __xdata __at (0xdf2f) uint8_t RF_IOCFG2; 941 | #define RF_IOCFG2_OFF 0x2f 942 | 943 | __xdata __at (0xdf30) uint8_t RF_IOCFG1; 944 | #define RF_IOCFG1_OFF 0x30 945 | 946 | __xdata __at (0xdf31) uint8_t RF_IOCFG0; 947 | #define RF_IOCFG0_OFF 0x31 948 | 949 | __xdata __at (0xdf00) uint8_t RF_SYNC1; 950 | #define RF_SYNC1_OFF 0x00 951 | 952 | __xdata __at (0xdf01) uint8_t RF_SYNC0; 953 | #define RF_SYNC0_OFF 0x01 954 | 955 | __xdata __at (0xdf02) uint8_t RF_PKTLEN; 956 | #define RF_PKTLEN_OFF 0x02 957 | 958 | __xdata __at (0xdf03) uint8_t RF_PKTCTRL1; 959 | #define RF_PKTCTRL1_OFF 0x03 960 | #define PKTCTRL1_PQT_MASK (0x7 << 5) 961 | #define PKTCTRL1_PQT_SHIFT 5 962 | #define PKTCTRL1_APPEND_STATUS (1 << 2) 963 | #define PKTCTRL1_ADR_CHK_NONE (0 << 0) 964 | #define PKTCTRL1_ADR_CHK_NO_BROADCAST (1 << 0) 965 | #define PKTCTRL1_ADR_CHK_00_BROADCAST (2 << 0) 966 | #define PKTCTRL1_ADR_CHK_00_FF_BROADCAST (3 << 0) 967 | 968 | /* If APPEND_STATUS is used, two bytes will be added to the packet data */ 969 | #define PKT_APPEND_STATUS_0_RSSI_MASK (0xff) 970 | #define PKT_APPEND_STATUS_0_RSSI_SHIFT 0 971 | #define PKT_APPEND_STATUS_1_CRC_OK (1 << 7) 972 | #define PKT_APPEND_STATUS_1_LQI_MASK (0x7f) 973 | #define PKT_APPEND_STATUS_1_LQI_SHIFT 0 974 | 975 | __xdata __at (0xdf04) uint8_t RF_PKTCTRL0; 976 | #define RF_PKTCTRL0_OFF 0x04 977 | #define RF_PKTCTRL0_WHITE_DATA (1 << 6) 978 | #define RF_PKTCTRL0_PKT_FORMAT_NORMAL (0 << 4) 979 | #define RF_PKTCTRL0_PKT_FORMAT_RANDOM (2 << 4) 980 | #define RF_PKTCTRL0_CRC_EN (1 << 2) 981 | #define RF_PKTCTRL0_LENGTH_CONFIG_FIXED (0 << 0) 982 | #define RF_PKTCTRL0_LENGTH_CONFIG_VARIABLE (1 << 0) 983 | 984 | __xdata __at (0xdf05) uint8_t RF_ADDR; 985 | #define RF_ADDR_OFF 0x05 986 | 987 | __xdata __at (0xdf06) uint8_t RF_CHANNR; 988 | #define RF_CHANNR_OFF 0x06 989 | 990 | __xdata __at (0xdf07) uint8_t RF_FSCTRL1; 991 | #define RF_FSCTRL1_OFF 0x07 992 | 993 | #define RF_FSCTRL1_FREQ_IF_SHIFT (0) 994 | 995 | __xdata __at (0xdf08) uint8_t RF_FSCTRL0; 996 | #define RF_FSCTRL0_OFF 0x08 997 | 998 | #define RF_FSCTRL0_FREQOFF_SHIFT (0) 999 | 1000 | __xdata __at (0xdf09) uint8_t RF_FREQ2; 1001 | #define RF_FREQ2_OFF 0x09 1002 | 1003 | __xdata __at (0xdf0a) uint8_t RF_FREQ1; 1004 | #define RF_FREQ1_OFF 0x0a 1005 | 1006 | __xdata __at (0xdf0b) uint8_t RF_FREQ0; 1007 | #define RF_FREQ0_OFF 0x0b 1008 | 1009 | __xdata __at (0xdf0c) uint8_t RF_MDMCFG4; 1010 | #define RF_MDMCFG4_OFF 0x0c 1011 | 1012 | #define RF_MDMCFG4_CHANBW_E_SHIFT 6 1013 | #define RF_MDMCFG4_CHANBW_M_SHIFT 4 1014 | #define RF_MDMCFG4_DRATE_E_SHIFT 0 1015 | 1016 | __xdata __at (0xdf0d) uint8_t RF_MDMCFG3; 1017 | #define RF_MDMCFG3_OFF 0x0d 1018 | 1019 | #define RF_MDMCFG3_DRATE_M_SHIFT 0 1020 | 1021 | __xdata __at (0xdf0e) uint8_t RF_MDMCFG2; 1022 | #define RF_MDMCFG2_OFF 0x0e 1023 | 1024 | #define RF_MDMCFG2_DEM_DCFILT_OFF (1 << 7) 1025 | #define RF_MDMCFG2_DEM_DCFILT_ON (0 << 7) 1026 | 1027 | #define RF_MDMCFG2_MOD_FORMAT_MASK (7 << 4) 1028 | #define RF_MDMCFG2_MOD_FORMAT_2_FSK (0 << 4) 1029 | #define RF_MDMCFG2_MOD_FORMAT_GFSK (1 << 4) 1030 | #define RF_MDMCFG2_MOD_FORMAT_ASK_OOK (3 << 4) 1031 | #define RF_MDMCFG2_MOD_FORMAT_MSK (7 << 4) 1032 | 1033 | #define RF_MDMCFG2_MANCHESTER_EN (1 << 3) 1034 | 1035 | #define RF_MDMCFG2_SYNC_MODE_MASK (0x7 << 0) 1036 | #define RF_MDMCFG2_SYNC_MODE_NONE (0x0 << 0) 1037 | #define RF_MDMCFG2_SYNC_MODE_15_16 (0x1 << 0) 1038 | #define RF_MDMCFG2_SYNC_MODE_16_16 (0x2 << 0) 1039 | #define RF_MDMCFG2_SYNC_MODE_30_32 (0x3 << 0) 1040 | #define RF_MDMCFG2_SYNC_MODE_NONE_THRES (0x4 << 0) 1041 | #define RF_MDMCFG2_SYNC_MODE_15_16_THRES (0x5 << 0) 1042 | #define RF_MDMCFG2_SYNC_MODE_16_16_THRES (0x6 << 0) 1043 | #define RF_MDMCFG2_SYNC_MODE_30_32_THRES (0x7 << 0) 1044 | 1045 | __xdata __at (0xdf0f) uint8_t RF_MDMCFG1; 1046 | #define RF_MDMCFG1_OFF 0x0f 1047 | 1048 | #define RF_MDMCFG1_FEC_EN (1 << 7) 1049 | #define RF_MDMCFG1_FEC_DIS (0 << 7) 1050 | 1051 | #define RF_MDMCFG1_NUM_PREAMBLE_MASK (7 << 4) 1052 | #define RF_MDMCFG1_NUM_PREAMBLE_2 (0 << 4) 1053 | #define RF_MDMCFG1_NUM_PREAMBLE_3 (1 << 4) 1054 | #define RF_MDMCFG1_NUM_PREAMBLE_4 (2 << 4) 1055 | #define RF_MDMCFG1_NUM_PREAMBLE_6 (3 << 4) 1056 | #define RF_MDMCFG1_NUM_PREAMBLE_8 (4 << 4) 1057 | #define RF_MDMCFG1_NUM_PREAMBLE_12 (5 << 4) 1058 | #define RF_MDMCFG1_NUM_PREAMBLE_16 (6 << 4) 1059 | #define RF_MDMCFG1_NUM_PREAMBLE_24 (7 << 4) 1060 | 1061 | #define RF_MDMCFG1_CHANSPC_E_MASK (3 << 0) 1062 | #define RF_MDMCFG1_CHANSPC_E_SHIFT (0) 1063 | 1064 | __xdata __at (0xdf10) uint8_t RF_MDMCFG0; 1065 | #define RF_MDMCFG0_OFF 0x10 1066 | 1067 | #define RF_MDMCFG0_CHANSPC_M_SHIFT (0) 1068 | 1069 | __xdata __at (0xdf11) uint8_t RF_DEVIATN; 1070 | #define RF_DEVIATN_OFF 0x11 1071 | 1072 | #define RF_DEVIATN_DEVIATION_E_SHIFT 4 1073 | #define RF_DEVIATN_DEVIATION_M_SHIFT 0 1074 | 1075 | __xdata __at (0xdf12) uint8_t RF_MCSM2; 1076 | #define RF_MCSM2_OFF 0x12 1077 | #define RF_MCSM2_RX_TIME_RSSI (1 << 4) 1078 | #define RF_MCSM2_RX_TIME_QUAL (1 << 3) 1079 | #define RF_MCSM2_RX_TIME_MASK (0x7) 1080 | #define RF_MCSM2_RX_TIME_SHIFT 0 1081 | #define RF_MCSM2_RX_TIME_END_OF_PACKET (7) 1082 | 1083 | __xdata __at (0xdf13) uint8_t RF_MCSM1; 1084 | #define RF_MCSM1_OFF 0x13 1085 | #define RF_MCSM1_CCA_MODE_ALWAYS (0 << 4) 1086 | #define RF_MCSM1_CCA_MODE_RSSI_BELOW (1 << 4) 1087 | #define RF_MCSM1_CCA_MODE_UNLESS_RECEIVING (2 << 4) 1088 | #define RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING (3 << 4) 1089 | #define RF_MCSM1_RXOFF_MODE_IDLE (0 << 2) 1090 | #define RF_MCSM1_RXOFF_MODE_FSTXON (1 << 2) 1091 | #define RF_MCSM1_RXOFF_MODE_TX (2 << 2) 1092 | #define RF_MCSM1_RXOFF_MODE_RX (3 << 2) 1093 | #define RF_MCSM1_TXOFF_MODE_IDLE (0 << 0) 1094 | #define RF_MCSM1_TXOFF_MODE_FSTXON (1 << 0) 1095 | #define RF_MCSM1_TXOFF_MODE_TX (2 << 0) 1096 | #define RF_MCSM1_TXOFF_MODE_RX (3 << 0) 1097 | 1098 | __xdata __at (0xdf14) uint8_t RF_MCSM0; 1099 | #define RF_MCSM0_OFF 0x14 1100 | #define RF_MCSM0_FS_AUTOCAL_NEVER (0 << 4) 1101 | #define RF_MCSM0_FS_AUTOCAL_FROM_IDLE (1 << 4) 1102 | #define RF_MCSM0_FS_AUTOCAL_TO_IDLE (2 << 4) 1103 | #define RF_MCSM0_FS_AUTOCAL_TO_IDLE_EVERY_4 (3 << 4) 1104 | #define RF_MCSM0_MAGIC_3 (1 << 3) 1105 | #define RF_MCSM0_MAGIC_2 (1 << 2) 1106 | #define RF_MCSM0_CLOSE_IN_RX_0DB (0 << 0) 1107 | #define RF_MCSM0_CLOSE_IN_RX_6DB (1 << 0) 1108 | #define RF_MCSM0_CLOSE_IN_RX_12DB (2 << 0) 1109 | #define RF_MCSM0_CLOSE_IN_RX_18DB (3 << 0) 1110 | 1111 | __xdata __at (0xdf15) uint8_t RF_FOCCFG; 1112 | #define RF_FOCCFG_OFF 0x15 1113 | #define RF_FOCCFG_FOC_BS_CS_GATE (1 << 5) 1114 | #define RF_FOCCFG_FOC_PRE_K_1K (0 << 3) 1115 | #define RF_FOCCFG_FOC_PRE_K_2K (1 << 3) 1116 | #define RF_FOCCFG_FOC_PRE_K_3K (2 << 3) 1117 | #define RF_FOCCFG_FOC_PRE_K_4K (3 << 3) 1118 | #define RF_FOCCFG_FOC_POST_K_PRE_K (0 << 2) 1119 | #define RF_FOCCFG_FOC_POST_K_PRE_K_OVER_2 (1 << 2) 1120 | #define RF_FOCCFG_FOC_LIMIT_0 (0 << 0) 1121 | #define RF_FOCCFG_FOC_LIMIT_BW_OVER_8 (1 << 0) 1122 | #define RF_FOCCFG_FOC_LIMIT_BW_OVER_4 (2 << 0) 1123 | #define RF_FOCCFG_FOC_LIMIT_BW_OVER_2 (3 << 0) 1124 | 1125 | __xdata __at (0xdf16) uint8_t RF_BSCFG; 1126 | #define RF_BSCFG_OFF 0x16 1127 | #define RF_BSCFG_BS_PRE_K_1K (0 << 6) 1128 | #define RF_BSCFG_BS_PRE_K_2K (1 << 6) 1129 | #define RF_BSCFG_BS_PRE_K_3K (2 << 6) 1130 | #define RF_BSCFG_BS_PRE_K_4K (3 << 6) 1131 | #define RF_BSCFG_BS_PRE_KP_1KP (0 << 4) 1132 | #define RF_BSCFG_BS_PRE_KP_2KP (1 << 4) 1133 | #define RF_BSCFG_BS_PRE_KP_3KP (2 << 4) 1134 | #define RF_BSCFG_BS_PRE_KP_4KP (3 << 4) 1135 | #define RF_BSCFG_BS_POST_KI_PRE_KI (0 << 3) 1136 | #define RF_BSCFG_BS_POST_KI_PRE_KI_OVER_2 (1 << 3) 1137 | #define RF_BSCFG_BS_POST_KP_PRE_KP (0 << 2) 1138 | #define RF_BSCFG_BS_POST_KP_PRE_KP_OVER_2 (1 << 2) 1139 | #define RF_BSCFG_BS_LIMIT_0 (0 << 0) 1140 | #define RF_BSCFG_BS_LIMIT_3_125 (1 << 0) 1141 | #define RF_BSCFG_BS_LIMIT_6_25 (2 << 0) 1142 | #define RF_BSCFG_BS_LIMIT_12_5 (3 << 0) 1143 | 1144 | __xdata __at (0xdf17) uint8_t RF_AGCCTRL2; 1145 | #define RF_AGCCTRL2_OFF 0x17 1146 | 1147 | __xdata __at (0xdf18) uint8_t RF_AGCCTRL1; 1148 | #define RF_AGCCTRL1_OFF 0x18 1149 | 1150 | __xdata __at (0xdf19) uint8_t RF_AGCCTRL0; 1151 | #define RF_AGCCTRL0_OFF 0x19 1152 | 1153 | __xdata __at (0xdf1a) uint8_t RF_FREND1; 1154 | #define RF_FREND1_OFF 0x1a 1155 | 1156 | #define RF_FREND1_LNA_CURRENT_SHIFT 6 1157 | #define RF_FREND1_LNA2MIX_CURRENT_SHIFT 4 1158 | #define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT 2 1159 | #define RF_FREND1_MIX_CURRENT_SHIFT 0 1160 | 1161 | __xdata __at (0xdf1b) uint8_t RF_FREND0; 1162 | #define RF_FREND0_OFF 0x1b 1163 | 1164 | #define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK (0x3 << 4) 1165 | #define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT 4 1166 | #define RF_FREND0_PA_POWER_MASK (0x7) 1167 | #define RF_FREND0_PA_POWER_SHIFT 0 1168 | 1169 | __xdata __at (0xdf1c) uint8_t RF_FSCAL3; 1170 | #define RF_FSCAL3_OFF 0x1c 1171 | 1172 | __xdata __at (0xdf1d) uint8_t RF_FSCAL2; 1173 | #define RF_FSCAL2_OFF 0x1d 1174 | 1175 | __xdata __at (0xdf1e) uint8_t RF_FSCAL1; 1176 | #define RF_FSCAL1_OFF 0x1e 1177 | 1178 | __xdata __at (0xdf1f) uint8_t RF_FSCAL0; 1179 | #define RF_FSCAL0_OFF 0x1f 1180 | 1181 | __xdata __at (0xdf23) uint8_t RF_TEST2; 1182 | #define RF_TEST2_OFF 0x23 1183 | 1184 | #define RF_TEST2_NORMAL_MAGIC 0x88 1185 | #define RF_TEST2_RX_LOW_DATA_RATE_MAGIC 0x81 1186 | 1187 | __xdata __at (0xdf24) uint8_t RF_TEST1; 1188 | #define RF_TEST1_OFF 0x24 1189 | 1190 | #define RF_TEST1_TX_MAGIC 0x31 1191 | #define RF_TEST1_RX_LOW_DATA_RATE_MAGIC 0x35 1192 | 1193 | __xdata __at (0xdf25) uint8_t RF_TEST0; 1194 | #define RF_TEST0_OFF 0x25 1195 | 1196 | #define RF_TEST0_7_2_MASK (0xfc) 1197 | #define RF_TEST0_VCO_SEL_CAL_EN (1 << 1) 1198 | #define RF_TEST0_0_MASK (1) 1199 | 1200 | /* These are undocumented, and must be computed 1201 | * using the provided tool. 1202 | */ 1203 | __xdata __at (0xdf27) uint8_t RF_PA_TABLE7; 1204 | #define RF_PA_TABLE7_OFF 0x27 1205 | 1206 | __xdata __at (0xdf28) uint8_t RF_PA_TABLE6; 1207 | #define RF_PA_TABLE6_OFF 0x28 1208 | 1209 | __xdata __at (0xdf29) uint8_t RF_PA_TABLE5; 1210 | #define RF_PA_TABLE5_OFF 0x29 1211 | 1212 | __xdata __at (0xdf2a) uint8_t RF_PA_TABLE4; 1213 | #define RF_PA_TABLE4_OFF 0x2a 1214 | 1215 | __xdata __at (0xdf2b) uint8_t RF_PA_TABLE3; 1216 | #define RF_PA_TABLE3_OFF 0x2b 1217 | 1218 | __xdata __at (0xdf2c) uint8_t RF_PA_TABLE2; 1219 | #define RF_PA_TABLE2_OFF 0x2c 1220 | 1221 | __xdata __at (0xdf2d) uint8_t RF_PA_TABLE1; 1222 | #define RF_PA_TABLE1_OFF 0x2d 1223 | 1224 | __xdata __at (0xdf2e) uint8_t RF_PA_TABLE0; 1225 | #define RF_PA_TABLE0_OFF 0x2e 1226 | 1227 | __xdata __at (0xdf36) uint8_t RF_PARTNUM; 1228 | #define RF_PARTNUM_OFF 0x36 1229 | 1230 | __xdata __at (0xdf37) uint8_t RF_VERSION; 1231 | #define RF_VERSION_OFF 0x37 1232 | 1233 | __xdata __at (0xdf38) uint8_t RF_FREQEST; 1234 | #define RF_FREQEST_OFF 0x38 1235 | 1236 | __xdata __at (0xdf39) uint8_t RF_LQI; 1237 | #define RF_LQI_OFF 0x39 1238 | 1239 | #define RF_LQI_CRC_OK (1 << 7) 1240 | #define RF_LQI_LQI_EST_MASK (0x7f) 1241 | 1242 | __xdata __at (0xdf3a) uint8_t RF_RSSI; 1243 | #define RF_RSSI_OFF 0x3a 1244 | 1245 | __xdata __at (0xdf3b) uint8_t RF_MARCSTATE; 1246 | #define RF_MARCSTATE_OFF 0x3b 1247 | 1248 | #define RF_MARCSTATE_MASK 0x1f 1249 | #define RF_MARCSTATE_SLEEP 0x00 1250 | #define RF_MARCSTATE_IDLE 0x01 1251 | #define RF_MARCSTATE_VCOON_MC 0x03 1252 | #define RF_MARCSTATE_REGON_MC 0x04 1253 | #define RF_MARCSTATE_MANCAL 0x05 1254 | #define RF_MARCSTATE_VCOON 0x06 1255 | #define RF_MARCSTATE_REGON 0x07 1256 | #define RF_MARCSTATE_STARTCAL 0x08 1257 | #define RF_MARCSTATE_BWBOOST 0x09 1258 | #define RF_MARCSTATE_FS_LOCK 0x0a 1259 | #define RF_MARCSTATE_IFADCON 0x0b 1260 | #define RF_MARCSTATE_ENDCAL 0x0c 1261 | #define RF_MARCSTATE_RX 0x0d 1262 | #define RF_MARCSTATE_RX_END 0x0e 1263 | #define RF_MARCSTATE_RX_RST 0x0f 1264 | #define RF_MARCSTATE_TXRX_SWITCH 0x10 1265 | #define RF_MARCSTATE_RX_OVERFLOW 0x11 1266 | #define RF_MARCSTATE_FSTXON 0x12 1267 | #define RF_MARCSTATE_TX 0x13 1268 | #define RF_MARCSTATE_TX_END 0x14 1269 | #define RF_MARCSTATE_RXTX_SWITCH 0x15 1270 | #define RF_MARCSTATE_TX_UNDERFLOW 0x16 1271 | 1272 | 1273 | __xdata __at (0xdf3c) uint8_t RF_PKTSTATUS; 1274 | #define RF_PKTSTATUS_OFF 0x3c 1275 | 1276 | #define RF_PKTSTATUS_CRC_OK (1 << 7) 1277 | #define RF_PKTSTATUS_CS (1 << 6) 1278 | #define RF_PKTSTATUS_PQT_REACHED (1 << 5) 1279 | #define RF_PKTSTATUS_CCA (1 << 4) 1280 | #define RF_PKTSTATUS_SFD (1 << 3) 1281 | 1282 | __xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC; 1283 | #define RF_VCO_VC_DAC_OFF 0x3d 1284 | 1285 | #endif 1286 | --------------------------------------------------------------------------------