From 11cfdfdcdc5520d0712775bf741de22dd7882d0a Mon Sep 17 00:00:00 2001 From: Joby Taffey Date: Wed, 7 Mar 2012 17:08:43 +0000 Subject: [PATCH] Initial version of CCTL, 1KB serial bootloader for CC1110/CC1111 --- LICENSE | 339 ++++++++++ Makefile | 67 ++ README.markdown | 116 ++++ boot/cc1110-ext.h | 1283 ++++++++++++++++++++++++++++++++++++++ boot/main.c | 339 ++++++++++ boot/start.asm | 101 +++ cctl-prog/Makefile | 9 + cctl-prog/cctl-prog.c | 292 +++++++++ cctl-prog/hex.c | 198 ++++++ cctl-prog/hex.h | 7 + example_payload/Makefile | 50 ++ example_payload/main.c | 28 + prebuilt-cctl.hex | 121 ++++ 13 files changed, 2950 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.markdown create mode 100644 boot/cc1110-ext.h create mode 100644 boot/main.c create mode 100644 boot/start.asm create mode 100644 cctl-prog/Makefile create mode 100644 cctl-prog/cctl-prog.c create mode 100644 cctl-prog/hex.c create mode 100644 cctl-prog/hex.h create mode 100644 example_payload/Makefile create mode 100644 example_payload/main.c create mode 100755 prebuilt-cctl.hex diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c827530 --- /dev/null +++ b/Makefile @@ -0,0 +1,67 @@ +PROG = /cygdrive/c/Program\ Files/Texas\ Instruments/SmartRF\ Tools/Flash\ Programmer/bin/SmartRFProgConsole.exe + +TARGET = cctl.hex + +CC = sdcc +AS = sdas8051 + +CFLAGS = --model-small --opt-code-size + +LDFLAGS_FLASH = \ + --out-fmt-ihx \ + --code-loc 0x0000 --code-size 0x400 \ + --xram-loc 0xf000 --xram-size 0x1000 \ + --iram-size 0x100 + +ASFLAGS = -plosgff + +ifdef DEBUG +CFLAGS += --debug +endif + +SRC = boot/main.c + +ASM_SRC = boot/start.asm + +ADB = $(SRC:.c=.c.adb) +ASM = $(SRC:.c=.c.asm) +LNK = $(SRC:.c=.c.lnk) +LST = $(SRC:.c=.c.lst) +REL = $(SRC:.c=.c.rel) +RST = $(SRC:.c=.c.rst) +SYM = $(SRC:.c=.c.sym) + +ASM_ADB = $(ASM_SRC:.asm=.adb) +ASM_LNK = $(ASM_SRC:.asm=.lnk) +ASM_LST = $(ASM_SRC:.asm=.lst) +ASM_REL = $(ASM_SRC:.asm=.rel) +ASM_RST = $(ASM_SRC:.asm=.rst) +ASM_SYM = $(ASM_SRC:.asm=.sym) + +PROGS = $(TARGET) +PCDB = $(PROGS:.hex=.cdb) +PLNK = $(PROGS:.hex=.lnk) +PMAP = $(PROGS:.hex=.map) +PMEM = $(PROGS:.hex=.mem) +PAOM = $(PROGS:.hex=) + +%.c.rel : %.c + $(CC) -c $(CFLAGS) -o$*.c.rel $< + +%.rel : %.asm + $(AS) -c $(ASFLAGS) $< + +all: $(PROGS) + +$(TARGET): $(REL) $(ASM_REL) Makefile + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(TARGET) $(ASM_REL) $(REL) + @echo Binary size `makebin -p < $(TARGET) | wc -c` + + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(ASM_ADB) $(ASM_LNK) $(ASM_LST) $(ASM_REL) $(ASM_RST) $(ASM_SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: $(TARGET) + $(PROG) S EPV F="$(TARGET)" diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..d162e6e --- /dev/null +++ b/README.markdown @@ -0,0 +1,116 @@ +CC Tiny Loader +============== + +CCTL is a serial bootloader for the Chipcon CC1110/CC1111 using only one 1KB page of flash. +It allows update of the the microcontroller firmware over its serial port. + +The bootloader consists of two components, a piece of firmware that is flashed +onto the device and a C utility for downloading code and manipulating the +flash memory. + +Authors +------- + +Joby Taffey (c) 2012 +Portions originally from CC Bootloader, Fergus Noble (c) 2011 + +Usage +----- + +The first step is to flash your device with the `cctl.hex` firmware file. A prebuilt version `prebuilt-cctl.hex` is provided. + +Once the device is flashed with this firmware it will identify itself over the serial interface with the message "CCTL" on reset. + +The microcontroller is configured for 115200, 8N1 transmitting on P0.3, receiving on P0.2. +Note that the CC111x is not 5v tolerant, so be sure to use a 3v serial adapter. + + +You can now use cctl-prog to download your payload code. + +For usage instructions, run cctl-prog with no arguments: + +`./cctl-prog` + +Preparing your user code for usage with the bootloader is very simple. All you +need to do is set your linker to start the code section at 0x400. For an +example of this see the `Makefile` file in the `example_payload` subdirectory. +This is the relevant line: + +`LDFLAGS_FLASH = ... --code-loc 0x400 ...` + +Building +-------- + +This requires [sdcc](http://sdcc.sourceforge.net/) (Small Device C Compiler). +Then it should be as simple as issuing + +`make` + +from the root directory of the project. + +The code has been tested with SDCC version 3.0.0 + + +Serial protocol +--------------- + +CCTL uses a custom binary serial protocol, running at 115200bps, 8 bits, no party, 1 stop bit. + +On reset, the bootloader prints "\r\nCCTL\r\n" followed by "B" up to 8 times with a delay between each. +If the bootloader receives any character before printing "B" 8 times, it will enter upgrade mode. + +If no character is received, the bootloader will attempt to launch user code from 0x400. +The bootloader enables the watchdog with a 1s timeout before jumping to user code, so launching a broken app should cause a reset. + +Once in upgrade mode, the bootloader expects to receive at least one character per second, else it will reset using the hardware watchdog. + +In upgrade mode, the following commands are available: + +### Jump to user code + +Jumps to user code. On failure, the device will reset. + +-> `j` + +## Erase page + +Erase a 1KB page of flash. On completion, `\0` is sent + +-> `e`, `uint8_t page` (0-31) +<- `\0` + +## Read page + +Read a 1KB page from flash. Sends 1024 raw bytes. On completion, '\0' is sent + +-> `r`, `uint8_t page` (0-31) +<- uint8_t data[1024], `\0` + +## Load page + +Loads 1KB page from serial into a RAM buffer. Receives 1024 raw bytes. On completion, '\0' is sent + +-> `l`, `uint8_t data[1024` +<- `\0` + +## Program page + +Program a 1KB page of flash from RAM buffer. On completion, `\0` is sent + +-> `p`, `uint8_t page` (0-31) +<- `\0` + + +Interrupts +---------- + +CCTL resides in the first flash page, 0x0000 to 0x0400. On reset, the CC1110 begins executing from address 0x0000 where it finds the CCTL reset vector. + +CCTL provides a vector table which jumps to the relevant vector in application code at 0x400 + offset. + +For interrupts which are used by both CCTL and application code, CCTL looks at the F1 user flag in the PSW register. When this flag is 0, the bootloader isr is called, when 1, the application isr is called. + +Application code should not modify PSW.F1. + + + diff --git a/boot/cc1110-ext.h b/boot/cc1110-ext.h new file mode 100644 index 0000000..5fec807 --- /dev/null +++ b/boot/cc1110-ext.h @@ -0,0 +1,1283 @@ +/* + Filename: ioCCxx10_bitdef.h + + This file contains the bit definitions of registers in CCxx10 + + Copyright 2008 Texas Instruments, Inc. +*/ +#ifndef _IOCCXX10_BITDEF_H +#define _IOCCXX10_BITDEF_H + + + +/* SEE DATA SHEET FOR DETAILS ABOUT THE FOLLOWING BIT MASKS */ + + + +/* + * Memory Control Registers + */ + +// MPAGE (0x93) - Memory Page Select + +// MEMCTR (0xC7) - Memory Arbiter Control +#define MEMCTR_CACHD 0x02 +#define MEMCTR_PREFD 0x01 + + +/* + * CPU Registers + */ + +// DPH0 (0x83) - Data Pointer 0 High Byte + +// DPL0 (0x82) - Data Pointer 0 Low Byte + +// DPH1 (0x85) - Data Pointer 1 High Byte + +// DPL1 (0x84) - Data Pointer 1 Low Byte + +// DPS (0x92) - Data Pointer Select +#define DPS_VDPS 0x01 + + +// PSW (0xD0) - Progrttus Word - bit accessible SFR register + +// ACC (0xE0) - Accumulator - bit accessible SFR register + +// B (0xF0) - B Register - bit accessible SFR register + +// SP (0x81) - Stack Pointer + + +/* + * Interrupt Control Registers + */ + +// IEN0 (0xA8) - Interrupt Enable 0 Register - bit accessible SFR register + +// IEN1 (0xB8) - Interrupt Enable 1 Register - bit accessible SFR register +#define IEN1_T2IE 0x04 + +// IEN2 (0x9A) - Interrupt Enable 2 Register +#define IEN2_WDTIE 0x20 +#define IEN2_P1IE 0x10 +#define IEN2_UTX1IE 0x08 +#define IEN2_I2STXIE 0x08 +#define IEN2_UTX0IE 0x04 +#define IEN2_P2IE 0x02 +#define IEN2_USBIE 0x02 +#define IEN2_RFIE 0x01 + + +// TCON (0x88) - CPU Interrupt Flag 1 - bit accessible SFR register + +// S0CON (0x98) - CPU Interrupt Flag 2 - bit accessible SFR register + +// S1CON (0x9B) - CPU Interrupt Flag 3 +#define S1CON_RFIF_1 0x02 +#define S1CON_RFIF_0 0x01 + + +// IRCON (0xC0) - CPU Interrupt Flag 4 - bit accessible SFR register + +// IRCON2 (0xE8) - CPU Interrupt Flag 5 - bit accessible SFR register + +// IP1 (0xB9) - Interrupt Priority 1 +#define IP1_IPG5 0x20 +#define IP1_IPG4 0x10 +#define IP1_IPG3 0x08 +#define IP1_IPG2 0x04 +#define IP1_IPG1 0x02 +#define IP1_IPG0 0x01 + +// IP0 (0xA9) - Interrupt Priority 0 +#define IP0_IPG5 0x20 +#define IP0_IPG4 0x10 +#define IP0_IPG3 0x08 +#define IP0_IPG2 0x04 +#define IP0_IPG1 0x02 +#define IP0_IPG0 0x01 + + + +/* + * Power Management and Clocks + */ + +// PCON (0x87) - Power Mode Control +#define PCON_IDLE 0x01 + + +// SLEEP (0xBE) - Sleep Mode Control +#define SLEEP_USB_EN 0x80 +#define SLEEP_XOSC_S 0x40 +#define SLEEP_HFRC_S 0x20 +#define SLEEP_RST 0x18 +#define SLEEP_RST0 0x08 +#define SLEEP_RST1 0x10 +#define SLEEP_OSC_PD 0x04 +#define SLEEP_MODE 0x03 +#define SLEEP_MODE1 0x02 +#define SLEEP_MODE0 0x01 + +#define SLEEP_RST_POR_BOD (0x00 << 3) +#define SLEEP_RST_EXT (0x01 << 3) +#define SLEEP_RST_WDT (0x02 << 3) + +#define SLEEP_MODE_PM0 (0x00) +#define SLEEP_MODE_PM1 (0x01) +#define SLEEP_MODE_PM2 (0x02) +#define SLEEP_MODE_PM3 (0x03) + + +// CLKCON (0xC6) - Clock Control +#define CLKCON_OSC32 0x80 // bit mask, for the slow 32k clock oscillator +#define CLKCON_OSC 0x40 // bit mask, for the system clock oscillator +#define CLKCON_TICKSPD 0x38 // bit mask, for timer ticks output setting +#define CLKCON_TICKSPD0 0x08 // bit mask, for timer ticks output setting +#define CLKCON_TICKSPD1 0x10 // bit mask, for timer ticks output setting +#define CLKCON_TICKSPD2 0x20 // bit mask, for timer ticks output setting +#define CLKCON_CLKSPD 0x07 // bit mask, for the clock speed +#define CLKCON_CLKSPD0 0x01 // bit mask, for the clock speed +#define CLKCON_CLKSPD1 0x02 // bit mask, for the clock speed +#define CLKCON_CLKSPD2 0x04 // bit mask, for the clock speed + +#define TICKSPD_DIV_1 (0x00 << 3) +#define TICKSPD_DIV_2 (0x01 << 3) +#define TICKSPD_DIV_4 (0x02 << 3) +#define TICKSPD_DIV_8 (0x03 << 3) +#define TICKSPD_DIV_16 (0x04 << 3) +#define TICKSPD_DIV_32 (0x05 << 3) +#define TICKSPD_DIV_64 (0x06 << 3) +#define TICKSPD_DIV_128 (0x07 << 3) + +#define CLKSPD_DIV_1 (0x00) +#define CLKSPD_DIV_2 (0x01) +#define CLKSPD_DIV_4 (0x02) +#define CLKSPD_DIV_8 (0x03) +#define CLKSPD_DIV_16 (0x04) +#define CLKSPD_DIV_32 (0x05) +#define CLKSPD_DIV_64 (0x06) +#define CLKSPD_DIV_128 (0x07) + + + +/* + * Flash Controller + */ + +// FCTL (0xAE) - Flash Control +#define FCTL_BUSY 0x80 +#define FCTL_SWBSY 0x40 +#define FCTL_CONTRD 0x10 +#define FCTL_WRITE 0x02 +#define FCTL_ERASE 0x01 + + +// FWDATA (0xAF) - Flash Write Data + +// FADDRH (0xAD) - Flash Address High Byte + +// FADDRL (0xAC) - Flash Address Low Byte + +// FWT (0xAB) - Flash Write Timing (Only bit 0-5 R/W) + + +/* + * I/O Ports + */ + +// P0 (0x80) - Port 0 - bit accessible SFR register + +// P1 (0x90) - Port 1 - bit accessible SFR register + +// P2 (0xA0) - Port 2 - bit accessible SFR register + +// PERCFG (0xF1) - Peripheral Control +#define PERCFG_T1CFG 0x40 +#define PERCFG_T3CFG 0x20 +#define PERCFG_T4CFG 0x10 +#define PERCFG_U1CFG 0x02 +#define PERCFG_U0CFG 0x01 + + + +// ADCCFG (0xF2) - ADC input Configuration +#define ADCCFG_7 0x80 +#define ADCCFG_6 0x40 +#define ADCCFG_5 0x20 +#define ADCCFG_4 0x10 +#define ADCCFG_3 0x08 +#define ADCCFG_2 0x04 +#define ADCCFG_1 0x02 +#define ADCCFG_0 0x01 + + +// P0SEL (0xF3) - Port 0 Function Select (bit 7 not used) + +// P1SEL (0xF4) - Port 1 Function Select + +// P2SEL (0xF5) - Port 2 Function Select +#define P2SEL_PRI3P1 0x40 +#define P2SEL_PRI2P1 0x20 +#define P2SEL_PRI1P1 0x10 +#define P2SEL_PRI0P1 0x08 +#define P2SEL_SELP2_4 0x04 +#define P2SEL_SELP2_3 0x02 +#define P2SEL_SELP2_0 0x01 + + +// P0DIR (0xFD) - Port 0 Direction Select + +// P1DIR (0xFE) - Port 1 Direction Select + +// P2DIR (0xFF) - Port 2 Direction +#define P2DIR_PRIP0 0xC0 +#define P2DIR_0PRIP0 0x40 +#define P2DIR_1PRIP0 0x80 +#define P2DIR_DIRP2 0x1F + +#define P2DIR_PRIP0_0 (0x00 << 6) +#define P2DIR_PRIP0_1 (0x01 << 6) +#define P2DIR_PRIP0_2 (0x02 << 6) +#define P2DIR_PRIP0_3 (0x03 << 6) + +#define P2DIR_DIRP2_4 (0x10) +#define P2DIR_DIRP2_3 (0x08) +#define P2DIR_DIRP2_2 (0x04) +#define P2DIR_DIRP2_1 (0x02) +#define P2DIR_DIRP2_0 (0x01) + + + +// P0INP (0x8F) - Port 0 Input Mode (bit 0 & 1 not used) + +// P1INP (0xF6) - Port 1 Input Mode (bit 0 & 1 not used) + +// P2INP (0xF7) - Port 2 Input Mode +#define P2INP_PDUP2 0x80 +#define P2INP_PDUP1 0x40 +#define P2INP_PDUP0 0x20 +#define P2INP_MDP2 0x1F + +#define P2INP_MDP2_0 (0x01) +#define P2INP_MDP2_1 (0x02) +#define P2INP_MDP2_2 (0x04) +#define P2INP_MDP2_3 (0x08) +#define P2INP_MDP2_4 (0x10) + + + +// P0IFG (0x89) - Port 0 Interrupt Status Flag + +// P1IFG (0x8A) - Port 1 Interrupt Status Flag + +// P2IFG (0x8B) - Port 2 Interrupt Status Flag (bit 7 - 5 not used) + +// PICTL (0x8C) - Port Interrupt Control +#define PICTL_PADSC 0x40 +#define PICTL_P2IEN 0x20 +#define PICTL_P0IENH 0x10 +#define PICTL_P0IENL 0x08 +#define PICTL_P2ICON 0x04 +#define PICTL_P1ICON 0x02 +#define PICTL_P0ICON 0x01 + + +// P1IEN (0x8D) - Port 1 Interrupt Mask + + + +/* + * DMA Controller + */ + +// DMAARM (0xD6) - DMA Channel Arm +#define DMAARM_ABORT 0x80 +#define DMAARM4 0x10 +#define DMAARM3 0x08 +#define DMAARM2 0x04 +#define DMAARM1 0x02 +#define DMAARM0 0x01 + + +// DMAREQ (0xD7) - DMA Channel Start Request and Status +#define DMAREQ4 0x10 +#define DMAREQ3 0x08 +#define DMAREQ2 0x04 +#define DMAREQ1 0x02 +#define DMAREQ0 0x01 + + +// DMA0CFGH (0xD5) - DMA Channel 0 Configuration Address High Byte + +// DMA0CFGL (0xD4) - DMA Channel 0 Configuration Address Low Byte + +// DMA1CFGH (0xD3) - DMA Channel 1 - 4 Configuration Address High By + +// DMA1CFGL (0xD2) - DMA Channel 1 - 4 Configuration Address Low Byte + +// DMAIRQ (0xD1) - DMA Interrupt Flag +#define DMAIRQ_DMAIF4 0x10 +#define DMAIRQ_DMAIF3 0x08 +#define DMAIRQ_DMAIF2 0x04 +#define DMAIRQ_DMAIF1 0x02 +#define DMAIRQ_DMAIF0 0x01 + + +// T1CNTH (0xE3) - Timer 1 Counter High + +// T1CNTL (0xE2) - Timer 1 Counter Low + +// T1CTL (0xE4) - Timer 1 Control and Status +#define T1CTL_CH2IF 0x80 // Timer 1 channel 2 interrupt flag +#define T1CTL_CH1IF 0x40 // Timer 1 channel 1 interrupt flag +#define T1CTL_CH0IF 0x20 // Timer 1 channel 0 interrupt flag +#define T1CTL_OVFIF 0x10 // Timer 1 counter overflow interrupt flag +#define T1CTL_DIV 0x0C +#define T1CTL_DIV0 0x04 +#define T1CTL_DIV1 0x08 +#define T1CTL_MODE 0x03 +#define T1CTL_MODE0 0x01 +#define T1CTL_MODE1 0x02 + +#define T1CTL_DIV_1 (0x00 << 2) // Divide tick frequency by 1 +#define T1CTL_DIV_8 (0x01 << 2) // Divide tick frequency by 8 +#define T1CTL_DIV_32 (0x02 << 2) // Divide tick frequency by 32 +#define T1CTL_DIV_128 (0x03 << 2) // Divide tick frequency by 128 + +#define T1CTL_MODE_SUSPEND (0x00) // Operation is suspended (halt) +#define T1CTL_MODE_FREERUN (0x01) // Free Running mode +#define T1CTL_MODE_MODULO (0x02) // Modulo +#define T1CTL_MODE_UPDOWN (0x03) // Up/down + + +// T1CCTL0 (0xE5) - Timer 1 Channel 0 Capture/Compare Control +#define T1CCTL0_CPSEL 0x80 // Timer 1 channel 0 capture select +#define T1CCTL0_IM 0x40 // Channel 0 Interrupt mask +#define T1CCTL0_CMP 0x38 +#define T1CCTL0_CMP0 0x08 +#define T1CCTL0_CMP1 0x10 +#define T1CCTL0_CMP2 0x20 +#define T1CCTL0_MODE 0x04 // Capture or compare mode +#define T1CCTL0_CAP 0x03 +#define T1CCTL0_CAP0 0x01 +#define T1CCTL0_CAP1 0x02 + +#define T1C0_SET_ON_CMP (0x00 << 3) // Clear output on compare-up set on 0 +#define T1C0_CLR_ON_CMP (0x01 << 3) // Set output on compare-up clear on 0 +#define T1C0_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T1C0_SET_CMP_UP_CLR_0 (0x03 << 3) // Clear output on compare +#define T1C0_CLR_CMP_UP_SET_0 (0x04 << 3) // Set output on compare + +#define T1C0_NO_CAP (0x00) // No capture +#define T1C0_RISE_EDGE (0x01) // Capture on rising edge +#define T1C0_FALL_EDGE (0x02) // Capture on falling edge +#define T1C0_BOTH_EDGE (0x03) // Capture on both edges + + +// T1CC0H (0xDB) - Timer 1 Channel 0 Capture/Compare Value High + +// T1CC0L (0xDA) - Timer 1 Channel 0 Capture/Compare Value Low + +// T1CCTL1 (0xE6) - Timer 1 Channel 1 Capture/Compare Control +#define T1CCTL1_CPSEL 0x80 // Timer 1 channel 1 capture select +#define T1CCTL1_IM 0x40 // Channel 1 Interrupt mask +#define T1CCTL1_CMP 0x38 +#define T1CCTL1_CMP0 0x08 +#define T1CCTL1_CMP1 0x10 +#define T1CCTL1_CMP2 0x20 +#define T1CCTL1_MODE 0x04 // Capture or compare mode +#define T1CCTL1_DSM_SPD 0x04 +#define T1CCTL1_CAP 0x03 +#define T1CCTL1_CAP0 0x01 +#define T1CCTL1_CAP1 0x02 + +#define T1C1_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T1C1_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T1C1_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T1C1_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T1C1_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T1C1_SET_C1_CLR_C0 (0x05 << 3) // Set when equal to T1CC1, clear when equal to T1CC0 +#define T1C1_CLR_C1_SET_C0 (0x06 << 3) // Clear when equal to T1CC1, set when equal to T1CC0 +#define T1C1_DSM_MODE (0x07 << 3) // DSM mode + +#define T1C1_NO_CAP (0x00) // No capture +#define T1C1_RISE_EDGE (0x01) // Capture on rising edge +#define T1C1_FALL_EDGE (0x02) // Capture on falling edge +#define T1C1_BOTH_EDGE (0x03) // Capture on both edges + +#define DSM_IP_ON_OS_ON (0x00) // Interpolator & output shaping enabled +#define DSM_IP_ON_OS_OFF (0x01) // Interpolator enabled & output shaping disabled +#define DSM_IP_OFF_OS_ON (0x02) // Interpolator disabled & output shaping enabled +#define DSM_IP_OFF_OS_OFF (0x03) // Interpolator & output shaping disabled + + + +// T1CC1H (0xDD) - Timer 1 Channel 1 Capture/Compare Value High + +// T1CC1L (0xDC) - Timer 1 Channel 1 Capture/Compare Value Low + +// T1CCTL2 (0xE7) - Timer 1 Channel 2 Capture/Compare Control +#define T1CCTL2_CPSEL 0x80 // Timer 1 channel 2 capture select +#define T1CCTL2_IM 0x40 // Channel 2 Interrupt mask +#define T1CCTL2_CMP 0x38 +#define T1CCTL2_CMP0 0x08 +#define T1CCTL2_CMP1 0x10 +#define T1CCTL2_CMP2 0x20 +#define T1CCTL2_MODE 0x04 // Capture or compare mode +#define T1CCTL2_CAP 0x03 +#define T1CCTL2_CAP0 0x01 +#define T1CCTL2_CAP1 0x02 + +#define T1C2_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T1C2_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T1C2_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T1C2_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T1C2_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T1C2_SET_C2_CLR_C0 (0x05 << 3) // Set when equal to T1CC2, clear when equal to T1CC0 +#define T1C2_CLR_C2_SET_C0 (0x06 << 3) // Clear when equal to T1CC2, set when equal to T1CC0 + +#define T1C2_NO_CAP (0x00) // No capture +#define T1C2_RISE_EDGE (0x01) // Capture on rising edge +#define T1C2_FALL_EDGE (0x02) // Capture on falling edge +#define T1C2_BOTH_EDGE (0x03) // Capture on both edges + + +// T1CC2H (0xDF) - Timer 1 Channel 2 Capture/Compare Value High + +// T1CC2L (0xDE) - Timer 1 Channel 2 Capture/Compare Value Low + +// T2CTL (0x9E) - Timer 2 Control +#define T2CTL_TEX 0x40 +#define T2CTL_INT 0x10 // Enable Timer 2 interrupt +#define T2CTL_TIG 0x04 // Tick generator mode +#define T2CTL_TIP 0x03 +#define T2CTL_TIP0 0x01 +#define T2CTL_TIP1 0x02 + +#define T2CTL_TIP_64 (0x00) +#define T2CTL_TIP_128 (0x01) +#define T2CTL_TIP_256 (0x02) +#define T2CTL_TIP_1024 (0x03) + + +// T2CT (0x9C) - Timer 2 Count + +// T2PR (0x9D) - Timer 2 Prescaler + +// WORTIME0 (0xA5) - Sleep Timer Low Byte + +// WORTIME1 (0xA6) - Sleep Timer High Byte + +// WOREVT1 (0xA4) - Sleep Timer Event0 Timeout High + +// WOREVT0 (0xA3) - Sleep Timer Event0 Timeout Low + +// WORCTL (0xA2) - Sleep Timer Control +#define WORCTL_WOR_RESET 0x04 +#define WORCTL_WOR_RES 0x03 +#define WORCTL_WOR_RES0 0x01 +#define WORCTL_WOR_RES1 0x02 + +#define WORCTL_WOR_RES_1 (0x00) +#define WORCTL_WOR_RES_32 (0x01) +#define WORCTL_WOR_RES_1024 (0x02) +#define WORCTL_WOR_RES_32768 (0x03) + + +// WORIRQ (0xA1) - Sleep Timer Interrupt Control +#define WORIRQ_EVENT0_MASK 0x10 +#define WORIRQ_EVENT0_FLAG 0x01 + + +// T3CNT (0xCA) - Timer 3 Counter + +// T3CTL (0xCB) - Timer 3 Control +#define T3CTL_DIV 0xE0 +#define T3CTL_DIV0 0x20 +#define T3CTL_DIV1 0x40 +#define T3CTL_DIV2 0x80 +#define T3CTL_START 0x10 +#define T3CTL_OVFIM 0x08 +#define T3CTL_CLR 0x04 +#define T3CTL_MODE 0x03 +#define T3CTL_MODE0 0x01 +#define T3CTL_MODE1 0x02 + +#define T3CTL_DIV_1 (0x00 << 5) +#define T3CTL_DIV_2 (0x01 << 5) +#define T3CTL_DIV_4 (0x02 << 5) +#define T3CTL_DIV_8 (0x03 << 5) +#define T3CTL_DIV_16 (0x04 << 5) +#define T3CTL_DIV_32 (0x05 << 5) +#define T3CTL_DIV_64 (0x06 << 5) +#define T3CTL_DIV_128 (0x07 << 5) + +#define T3CTL_MODE_FREERUN (0x00) +#define T3CTL_MODE_DOWN (0x01) +#define T3CTL_MODE_MODULO (0x02) +#define T3CTL_MODE_UPDOWN (0x03) + + + +// T3CCTL0 (0xCC) - Timer 3 Channel 0 Compare Control +#define T3CCTL0_IM 0x40 +#define T3CCTL0_MODE 0x04 +#define T3CCTL0_CMP 0x38 +#define T3CCTL0_CMP0 0x08 +#define T3CCTL0_CMP1 0x10 +#define T3CCTL0_CMP2 0x20 + +#define T3C0_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T3C0_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T3C0_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T3C0_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T3C0_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T3C0_SET_CMP_CLR_255 (0x05 << 3) // Set when equal to T3CC0, clear on 255 +#define T3C0_CLR_CMP_SET_0 (0x06 << 3) // Clear when equal to T3CC0, set on 0 + + + +// T3CC0 (0xCD) - Timer 3 Channel 0 Compare Value + +// T3CCTL1 (0xCE) - Timer 3 Channel 1 Compare Control + +#define T3CCTL1_IM 0x40 +#define T3CCTL1_MODE 0x04 +#define T3CCTL1_CMP 0x38 +#define T3CCTL1_CMP0 0x08 +#define T3CCTL1_CMP1 0x10 +#define T3CCTL1_CMP2 0x20 + +#define T3C1_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T3C1_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T3C1_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T3C1_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T3C1_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T3C1_SET_CMP_CLR_C0 (0x05 << 3) // Set when equal to T3CC1, clear when equal to T3CC0 +#define T3C1_CLR_CMP_SET_C0 (0x06 << 3) // Clear when equal to T3CC1, set when equal to T3CC0 + + +// T3CC1 (0xCF) - Timer 3 Channel 1 Compare Value + +// T4CNT (0xEA) - Timer 4 Counter + +// T4CTL (0xEB) - Timer 4 Control +#define T4CTL_DIV 0xE0 +#define T4CTL_DIV0 0x20 +#define T4CTL_DIV1 0x40 +#define T4CTL_DIV2 0x80 +#define T4CTL_START 0x10 +#define T4CTL_OVFIM 0x08 +#define T4CTL_CLR 0x04 +#define T4CTL_MODE 0x03 +#define T4CTL_MODE0 0x01 +#define T4CTL_MODE1 0x02 + +#define T4CTL_MODE_FREERUN (0x00) +#define T4CTL_MODE_DOWN (0x01) +#define T4CTL_MODE_MODULO (0x02) +#define T4CTL_MODE_UPDOWN (0x03) + +#define T4CTL_DIV_1 (0x00 << 5) +#define T4CTL_DIV_2 (0x01 << 5) +#define T4CTL_DIV_4 (0x02 << 5) +#define T4CTL_DIV_8 (0x03 << 5) +#define T4CTL_DIV_16 (0x04 << 5) +#define T4CTL_DIV_32 (0x05 << 5) +#define T4CTL_DIV_64 (0x06 << 5) +#define T4CTL_DIV_128 (0x07 << 5) + + +// T4CCTL0 (0xEC) - Timer 4 Channel 0 Compare Control +#define T4CCTL0_IM 0x40 +#define T4CCTL0_CMP 0x38 +#define T4CCTL0_CMP0 0x08 +#define T4CCTL0_CMP1 0x10 +#define T4CCTL0_CMP2 0x20 +#define T4CCTL0_MODE 0x04 + +#define T4CCTL0_SET_ON_CMP (0x00 << 3) +#define T4CCTL0_CLR_ON_CMP (0x01 << 3) +#define T4CCTL0_TOG_ON_CMP (0x02 << 3) +#define T4CCTL0_SET_CMP_UP_CLR_0 (0x03 << 3) +#define T4CCTL0_CLR_CMP_UP_SET_0 (0x04 << 3) +#define T4CCTL0_SET_CMP_CLR_255 (0x05 << 3) +#define T4CCTL0_CLR_CMP_SET_0 (0x06 << 3) + + +// T4CC0 (0xED) - Timer 4 Channel 0 Compare Value + +// T4CCTL1 (0xEE) - Timer 4 Channel 1 Compare Control +#define T4CCTL1_IM 0x40 +#define T4CCTL1_CMP 0x38 +#define T4CCTL1_CMP0 0x08 +#define T4CCTL1_CMP1 0x10 +#define T4CCTL1_CMP2 0x20 +#define T4CCTL1_MODE 0x04 + +#define T4CCTL1_SET_ON_CMP (0x00 << 3) +#define T4CCTL1_CLR_ON_CMP (0x01 << 3) +#define T4CCTL1_TOG_ON_CMP (0x02 << 3) +#define T4CCTL1_SET_CMP_UP_CLR_0 (0x03 << 3) +#define T4CCTL1_CLR_CMP_UP_SET_0 (0x04 << 3) +#define T4CCTL1_SET_CMP_CLR_C0 (0x05 << 3) +#define T4CCTL1_CLR_CMP_SET_C0 (0x06 << 3) + + +// TIMIF (0xD8) - Timers 1/3/4 Interrupt Mask/Flag - bit accessible SFR register + + +/* + * ADC + */ + +// ADCL (0xBA) - ADC Data Low (only bit 7-4 used) + +// ADCH (0xBB) - ADC Data High + +// ADCCON1 (0xB4) - ADC Control 1 +#define ADCCON1_EOC 0x80 +#define ADCCON1_ST 0x40 +#define ADCCON1_STSEL 0x30 +#define ADCCON1_STSEL0 0x10 +#define ADCCON1_STSEL1 0x20 +#define ADCCON1_RCTRL 0x0C +#define ADCCON1_RCTRL0 0x04 +#define ADCCON1_RCTRL1 0x08 + +#define STSEL_P2_0 (0x00 << 4) +#define STSEL_FULL_SPEED (0x01 << 4) +#define STSEL_T1C0_CMP_EVT (0x02 << 4) +#define STSEL_ST (0x03 << 4) + +#define ADCCON1_RCTRL_COMPL (0x00 << 2) +#define ADCCON1_RCTRL_LFSR13 (0x01 << 2) + + + +// ADCCON2 (0xB5) - ADC Control 2 +#define ADCCON2_SREF 0xC0 +#define ADCCON2_SREF0 0x40 +#define ADCCON2_SREF1 0x80 +#define ADCCON2_SDIV 0x30 +#define ADCCON2_SDIV0 0x10 +#define ADCCON2_SDIV1 0x20 +#define ADCCON2_SCH 0x0F +#define ADCCON2_SCH0 0x01 +#define ADCCON2_SCH1 0x02 +#define ADCCON2_SCH2 0x04 +#define ADCCON2_SCH3 0x08 + +#define ADCCON2_SREF_1_25V (0x00 << 6) +#define ADCCON2_SREF_P0_7 (0x01 << 6) +#define ADCCON2_SREF_AVDD (0x02 << 6) +#define ADCCON2_SREF_P0_6_P0_7 (0x03 << 6) + +#define ADCCON2_SDIV_64 (0x00 << 4) +#define ADCCON2_SDIV_128 (0x01 << 4) +#define ADCCON2_SDIV_256 (0x02 << 4) +#define ADCCON2_SDIV_512 (0x03 << 4) + +#define ADCCON2_SCH_AIN0 (0x00) +#define ADCCON2_SCH_AIN1 (0x01) +#define ADCCON2_SCH_AIN2 (0x02) +#define ADCCON2_SCH_AIN3 (0x03) +#define ADCCON2_SCH_AIN4 (0x04) +#define ADCCON2_SCH_AIN5 (0x05) +#define ADCCON2_SCH_AIN6 (0x06) +#define ADCCON2_SCH_AIN7 (0x07) +#define ADCCON2_SCH_AIN0_1 (0x08) +#define ADCCON2_SCH_AIN2_3 (0x09) +#define ADCCON2_SCH_AIN4_5 (0x0A) +#define ADCCON2_SCH_AIN6_7 (0x0B) +#define ADCCON2_SCH_GND (0x0C) +#define ADCCON2_SCH_POSVOL (0x0D) +#define ADCCON2_SCH_TEMPR (0x0E) +#define ADCCON2_SCH_VDD_3 (0x0F) + + +// ADCCON3 (0xB6) - ADC Control 3 +#define ADCCON3_EREF 0xC0 +#define ADCCON3_EREF0 0x40 +#define ADCCON3_EREF1 0x80 +#define ADCCON3_EDIV 0x30 +#define ADCCON3_EDIV0 0x10 +#define ADCCON3_EDIV1 0x20 +#define ADCCON2_ECH 0x0F +#define ADCCON2_ECH0 0x01 +#define ADCCON2_ECH1 0x02 +#define ADCCON2_ECH2 0x04 +#define ADCCON2_ECH3 0x08 + +#define ADCCON3_EREF_1_25V (0x00 << 6) +#define ADCCON3_EREF_P0_7 (0x01 << 6) +#define ADCCON3_EREF_AVDD (0x02 << 6) +#define ADCCON3_EREF_P0_6_P0_7 (0x03 << 6) + +#define ADCCON3_EDIV_64 (0x00 << 4) +#define ADCCON3_EDIV_128 (0x01 << 4) +#define ADCCON3_EDIV_256 (0x02 << 4) +#define ADCCON3_EDIV_512 (0x03 << 4) + +#define ADCCON3_ECH_AIN0 (0x00) +#define ADCCON3_ECH_AIN1 (0x01) +#define ADCCON3_ECH_AIN2 (0x02) +#define ADCCON3_ECH_AIN3 (0x03) +#define ADCCON3_ECH_AIN4 (0x04) +#define ADCCON3_ECH_AIN5 (0x05) +#define ADCCON3_ECH_AIN6 (0x06) +#define ADCCON3_ECH_AIN7 (0x07) +#define ADCCON3_ECH_AIN0_1 (0x08) +#define ADCCON3_ECH_AIN2_3 (0x09) +#define ADCCON3_ECH_AIN4_5 (0x0A) +#define ADCCON3_ECH_AIN6_7 (0x0B) +#define ADCCON3_ECH_GND (0x0C) +#define ADCCON3_ECH_POSVOL (0x0D) +#define ADCCON3_ECH_TEMPR (0x0E) +#define ADCCON3_ECH_VDD_3 (0x0F) + + + +/* + * Random Number Generator + */ + +// RNDL (0xBC) - Random Number Generator Data Low Byte + +// RNDH (0xBD) - Random Number Generator Data High Byte + + +/* + * AES + */ + +// ENCCS (0xB3) - Encryption Control and Status +#define ENCCS_MODE 0x70 +#define ENCCS_MODE0 0x10 +#define ENCCS_MODE1 0x20 +#define ENCCS_MODE2 0x40 +#define ENCCS_RDY 0x08 +#define ENCCS_CMD 0x06 +#define ENCCS_CMD0 0x02 +#define ENCCS_CMD1 0x04 +#define ENCCS_ST 0x01 + +#define ENCCS_MODE_CBC (0x00 << 4) +#define ENCCS_MODE_CFB (0x01 << 4) +#define ENCCS_MODE_OFB (0x02 << 4) +#define ENCCS_MODE_CTR (0x03 << 4) +#define ENCCS_MODE_ECB (0x04 << 4) +#define ENCCS_MODE_CBCMAC (0x05 << 4) + +#define ENCCS_CMD_ENC (0x00 << 1) +#define ENCCS_CMD_DEC (0x01 << 1) +#define ENCCS_CMD_LDKEY (0x02 << 1) +#define ENCCS_CMD_LDIV (0x03 << 1) + + +// ENCDI (0xB1) - Encryption Input Data + +// ENCDO (0xB2) - Encryption Output Data + + +/* + * Watchdog Timer + */ + +// WDCTL (0xC9) - Watchdog Timer Control +#define WDCTL_CLR 0xF0 +#define WDCTL_CLR0 0x10 +#define WDCTL_CLR1 0x20 +#define WDCTL_CLR2 0x40 +#define WDCTL_CLR3 0x80 +#define WDCTL_EN 0x08 +#define WDCTL_MODE 0x04 +#define WDCTL_INT 0x03 +#define WDCTL_INT0 0x01 +#define WDCTL_INT1 0x02 + + +#define WDCTL_INT_SEC_1 (0x00) +#define WDCTL_INT1_MSEC_250 (0x01) +#define WDCTL_INT2_MSEC_15 (0x02) +#define WDCTL_INT3_MSEC_2 (0x03) + + + +/* + * USART + */ + +// U0CSR (0x86) - USART 0 Control and Status + +#define U0CSR_MODE 0x80 +#define U0CSR_RE 0x40 +#define U0CSR_SLAVE 0x20 +#define U0CSR_FE 0x10 +#define U0CSR_ERR 0x08 +#define U0CSR_RX_BYTE 0x04 +#define U0CSR_TX_BYTE 0x02 +#define U0CSR_ACTIVE 0x01 + + +// U0UCR (0xC4) - USART 0 UART Control +#define U0UCR_FLUSH 0x80 +#define U0UCR_FLOW 0x40 +#define U0UCR_D9 0x20 +#define U0UCR_BIT9 0x10 +#define U0UCR_PARITY 0x08 +#define U0UCR_SPB 0x04 +#define U0UCR_STOP 0x02 +#define U0UCR_START 0x01 + + +// U0GCR (0xC5) - USART 0 Generic Control +#define U0GCR_CPOL 0x80 +#define U0GCR_CPHA 0x40 +#define U0GCR_ORDER 0x20 +#define U0GCR_BAUD_E 0x1F +#define U0GCR_BAUD_E0 0x01 +#define U0GCR_BAUD_E1 0x02 +#define U0GCR_BAUD_E2 0x04 +#define U0GCR_BAUD_E3 0x08 +#define U0GCR_BAUD_E4 0x10 + + +// U0DBUF (0xC1) - USART 0 Receive/Transmit Data Buffer + +// U0BAUD (0xC2) - USART 0 Baud Rate Control + +// U1CSR (0xF8) - USART 1 Control and Status - bit accessible SFR register +#define U1CSR_MODE 0x80 +#define U1CSR_RE 0x40 +#define U1CSR_SLAVE 0x20 +#define U1CSR_FE 0x10 +#define U1CSR_ERR 0x08 +#define U1CSR_RX_BYTE 0x04 +#define U1CSR_TX_BYTE 0x02 +#define U1CSR_ACTIVE 0x01 + + +// U1UCR (0xFB) - USART 1 UART Control +#define U1UCR_FLUSH 0x80 +#define U1UCR_FLOW 0x40 +#define U1UCR_D9 0x20 +#define U1UCR_BIT9 0x10 +#define U1UCR_PARITY 0x08 +#define U1UCR_SPB 0x04 +#define U1UCR_STOP 0x02 +#define U1UCR_START 0x01 + + +// U1GCR (0xFC) - USART 1 Generic Control +#define U1GCR_CPOL 0x80 +#define U1GCR_CPHA 0x40 +#define U1GCR_ORDER 0x20 +#define U1GCR_BAUD_E 0x1F +#define U1GCR_BAUD_E0 0x01 +#define U1GCR_BAUD_E1 0x02 +#define U1GCR_BAUD_E2 0x04 +#define U1GCR_BAUD_E3 0x08 +#define U1GCR_BAUD_E4 0x10 + + +// U1DBUF (0xF9) - USART 1 Receive/Transmit Data Buffer + +// U1BAUD (0xFA) - USART 1 Baud Rate Control + + +/* + * I2S + */ + +// 0xDF40: I2SCFG0 - I2S Configuration Register 0 +#define I2SCFG0_TXIEN 0x80 +#define I2SCFG0_RXIEN 0x40 +#define I2SCFG0_ULAWE 0x20 +#define I2SCFG0_ULAWC 0x10 +#define I2SCFG0_TXMONO 0x08 +#define I2SCFG0_RXMONO 0x04 +#define I2SCFG0_MASTER 0x02 +#define I2SCFG0_ENAB 0x01 + + +// 0xDF41: I2SCFG1 - I2S Configuration Register 1 +#define I2SCFG1_WORDS 0xF8 +#define I2SCFG1_WORDS0 0x08 +#define I2SCFG1_WORDS1 0x10 +#define I2SCFG1_WORDS2 0x20 +#define I2SCFG1_WORDS3 0x40 +#define I2SCFG1_WORDS4 0x80 +#define I2SCFG1_TRIGNUM 0x06 +#define I2SCFG1_TRIGNUM0 0x02 +#define I2SCFG1_TRIGNUM1 0x04 +#define I2SCFG1_IOLOC 0x01 + +#define I2SCFG1_TRIGNUM_NO_TRIG (0x00 << 1) +#define I2SCFG1_TRIGNUM_USB_SOF (0x01 << 1) +#define I2SCFG1_TRIGNUM_IOC_1 (0x02 << 1) +#define I2SCFG1_TRIGNUM_T1_CH0 (0x03 << 1) + + + +// 0xDF42: I2SDATL - I2S Data Low Byte + +// 0xDF43: I2SDATH - I2S Data High Byte + +// 0xDF44: I2SWCNT - I2S Word Count Register + +// 0xDF45: I2SSTAT - I2S Status Register +#define I2SSTAT_TXUNF 0x80 +#define I2SSTAT_RXOVF 0x40 +#define I2SSTAT_TXLR 0x20 +#define I2SSTAT_RXLR 0x10 +#define I2SSTAT_TXIRQ 0x08 +#define I2SSTAT_RXIRQ 0x04 +#define I2SSTAT_WCNT 0x03 +#define I2SSTAT_WCNT0 0x01 +#define I2SSTAT_WCNT1 0x02 + +#define I2SSTAT_WCNT_10BIT (0x02) +#define I2SSTAT_WCNT_9BIT (0x01) +#define I2SSTAT_WCNT_9_10BIT (0x02) + + +// 0xDF46: I2SCLKF0 - I2S Clock Configuration Register 0 + +// 0xDF47: I2SCLKF1 - I2S Clock Configuration Register 1 + +// 0xDF48: I2SCLKF2 - I2S Clock Configuration Register 2 + + + + +/* + * Radio Registers + */ + +// RFIF (0xE9) - RF Interrupt Flags +#define RFIF_IRQ_TXUNF 0x80 +#define RFIF_IRQ_RXOVF 0x40 +#define RFIF_IRQ_TIMEOUT 0x20 +#define RFIF_IRQ_DONE 0x10 +#define RFIF_IRQ_CS 0x08 +#define RFIF_IRQ_PQT 0x04 +#define RFIF_IRQ_CCA 0x02 +#define RFIF_IRQ_SFD 0x01 + + +// RFIM (0x91) - RF Interrupt Mask +#define RFIM_IM_TXUNF 0x80 +#define RFIM_IM_RXOVF 0x40 +#define RFIM_IM_TIMEOUT 0x20 +#define RFIM_IM_DONE 0x10 +#define RFIM_IM_CS 0x08 +#define RFIM_IM_PQT 0x04 +#define RFIM_IM_CCA 0x02 +#define RFIM_IM_SFD 0x01 + + +// 0xDF2F: IOCFG2 - Radio Test Signal Configuration (P1_7) +#define IOCFG2_GDO2_INV 0x40 +#define IOCFG2_GDO2_CFG 0x3F + + +// 0xDF30: IOCFG1 - Radio Test Signal Configuration (P1_6) +#define IOCFG1_GDO_DS 0x80 +#define IOCFG1_GDO1_INV 0x40 +#define IOCFG1_GDO1_CFG 0x3F + + +// 0xDF31: IOCFG0 - Radio Test Signal Configuration (P1_5) +#define IOCFG0_GDO0_INV 0x40 +#define IOCFG0_GDO0_CFG 0x3F + + +// 0xDF03: PKTCTRL1 - Packet Automation Control +#define PKTCTRL1_PQT 0xE0 +#define PKTCTRL1_PQT0 0x20 +#define PKTCTRL1_PQT1 0x40 +#define PKTCTRL1_PQT2 0x80 +#define PKTCTRL1_APPEND_STATUS 0x04 +#define PKTCTRL1_ADR_CHK 0x03 +#define PKTCTRL1_ADR_CHK0 0x01 +#define PKTCTRL1_ADR_CHK1 0x02 + +#define ADR_CHK_NONE (0x00) +#define ADR_CHK_NO_BRDCST (0x01) +#define ADR_CHK_0_BRDCST (0x02) +#define ADR_CHK_0_255_BRDCST (0x03) + + +// 0xDF04: PKTCTRL0 - Packet Automation Control +#define PKTCTRL0_WHITE_DATA 0x40 +#define PKTCTRL0_PKT_FORMAT 0x30 +#define PKTCTRL0_PKT_FORMAT0 0x10 +#define PKTCTRL0_PKT_FORMAT1 0x20 +#define PKTCTRL0_CC2400_EN 0x08 +#define PKTCTRL0_CRC_EN 0x04 +#define PKTCTRL0_LENGTH_CONFIG 0x03 +#define PKTCTRL0_LENGTH_CONFIG0 0x01 + +#define PKT_FORMAT_NORM (0x00) +#define PKT_FORMAT_RAND (0x02) + +#define PKTCTRL0_LENGTH_CONFIG_FIX (0x00) +#define PKTCTRL0_LENGTH_CONFIG_VAR (0x01) + + +// 0xDF05: ADDR - Device Address + +// 0xDF06: CHANNR - Channel Number + +// 0xDF07: FSCTRL1 - Frequency Synthesizer Control (only bit 0-4 used) + +// 0xDF08: FSCTRL0 - Frequency Synthesizer Control + +// 0xDF09: FREQ2 - Frequency Control Word, High Byte + +// 0xDF0A: FREQ1 - Frequency Control Word, Middle Byte + +// 0xDF0B: FREQ0 - Frequency Control Word, Low Byte + +// 0xDF0C: MDMCFG4 - Modem configuration + +// 0xDF0D: MDMCFG3 - Modem Configuration + +// 0xDF0E: MDMCFG2 - Modem Configuration +#define MDMCFG2_DEM_DCFILT_OFF 0x80 +#define MDMCFG2_MOD_FORMAT 0x70 +#define MDMCFG2_MOD_FORMAT0 0x10 +#define MDMCFG2_MOD_FORMAT1 0x20 +#define MDMCFG2_MOD_FORMAT2 0x40 +#define MDMCFG2_MANCHESTER_EN 0x08 +#define MDMCFG2_SYNC_MODE 0x07 +#define MDMCFG2_SYNC_MODE0 0x01 +#define MDMCFG2_SYNC_MODE1 0x02 +#define MDMCFG2_SYNC_MODE2 0x04 + +#define MOD_FORMAT_2_FSK (0x00 << 4) +#define MOD_FORMAT_GFSK (0x01 << 4) +#define MOD_FORMAT_MSK (0x07 << 4) + +#define SYNC_MODE_NO_PRE (0x00) +#define SYNC_MODE_15_16 (0x01) +#define SYNC_MODE_16_16 (0x02) +#define SYNC_MODE_30_32 (0x03) +#define SYNC_MODE_NO_PRE_CS (0x04) // CS = carrier-sense above threshold +#define SYNC_MODE_15_16_CS (0x05) +#define SYNC_MODE_16_16_CS (0x06) +#define SYNC_MODE_30_32_CS (0x07) + + +// 0xDF0F: MDMCG1 - Modem Configuration +#define MDMCG1_FEC_EN 0x80 +#define MDMCG1_NUM_PREAMBLE 0x70 +#define MDMCG1_NUM_PREAMBLE0 0x10 +#define MDMCG1_NUM_PREAMBLE1 0x20 +#define MDMCG1_NUM_PREAMBLE2 0x40 +#define MDMCG1_CHANSPC_E 0x03 +#define MDMCG1_CHANSPC_E0 0x01 +#define MDMCG1_CHANSPC_E1 0x02 + +#define MDMCG1_NUM_PREAMBLE_2 (0x00 << 4) +#define MDMCG1_NUM_PREAMBLE_3 (0x01 << 4) +#define MDMCG1_NUM_PREAMBLE_4 (0x02 << 4) +#define MDMCG1_NUM_PREAMBLE_6 (0x03 << 4) +#define MDMCG1_NUM_PREAMBLE_8 (0x04 << 4) +#define MDMCG1_NUM_PREAMBLE_12 (0x05 << 4) +#define MDMCG1_NUM_PREAMBLE_16 (0x06 << 4) +#define MDMCG1_NUM_PREAMBLE_24 (0x07 << 4) + + +// 0xDF10: MDMCFG0 - Modem Configuration + +// 0xDF11: DEVIATN - Modem Deviation Setting +#define DEVIATN_DEVIATION_E 0x70 +#define DEVIATN_DEVIATION_E0 0x10 +#define DEVIATN_DEVIATION_E1 0x20 +#define DEVIATN_DEVIATION_E2 0x40 +#define DEVIATN_DEVIATION_M 0x07 +#define DEVIATN_DEVIATION_M0 0x01 +#define DEVIATN_DEVIATION_M1 0x02 +#define DEVIATN_DEVIATION_M2 0x04 + + +// 0xDF12: MCSM2 - Main Radio Control State Machine Configuration +#define MCSM2_RX_TIME_RSSI 0x10 +#define MCSM2_RX_TIME_QUAL 0x08 +#define MCSM2_RX_TIME 0x07 + + +// 0xDF13: MCSM1 - Main Radio Control State Machine Configuration +#define MCSM1_CCA_MODE 0x30 +#define MCSM1_CCA_MODE0 0x10 +#define MCSM1_CCA_MODE1 0x20 +#define MCSM1_RXOFF_MODE 0x0C +#define MCSM1_RXOFF_MODE0 0x04 +#define MCSM1_RXOFF_MODE1 0x08 +#define MCSM1_TXOFF_MODE 0x03 +#define MCSM1_TXOFF_MODE0 0x01 +#define MCSM1_TXOFF_MODE1 0x02 + +#define MCSM1_CCA_MODE_ALWAYS (0x00 << 4) +#define MCSM1_CCA_MODE_RSSI0 (0x01 << 4) +#define MCSM1_CCA_MODE_PACKET (0x02 << 4) +#define MCSM1_CCA_MODE_RSSI1 (0x03 << 4) + +#define MCSM1_RXOFF_MODE_IDLE (0x00 << 2) +#define MCSM1_RXOFF_MODE_FSTXON (0x01 << 2) +#define MCSM1_RXOFF_MODE_TX (0x02 << 2) +#define MCSM1_RXOFF_MODE_RX (0x03 << 2) + +#define MCSM1_TXOFF_MODE_IDLE (0x00 << 0) +#define MCSM1_TXOFF_MODE_FSTXON (0x01 << 0) +#define MCSM1_TXOFF_MODE_TX (0x02 << 0) +#define MCSM1_TXOFF_MODE_RX (0x03 << 0) + + +// 0xDF14: MCSM0 - Main Radio Control State Machine Configuration +#define MCSM0_FS_AUTOCAL 0x30 + +#define FS_AUTOCAL_NEVER (0x00 << 4) +#define FS_AUTOCAL_FROM_IDLE (0x01 << 4) +#define FS_AUTOCAL_TO_IDLE (0x02 << 4) +#define FS_AUTOCAL_4TH_TO_IDLE (0x03 << 4) + + +// 0xDF15: FOCCFG - Frequency Offset Compensation Configuration +#define FOCCFG_FOC_BS_CS_GATE 0x20 +#define FOCCFG_FOC_PRE_K 0x18 +#define FOCCFG_FOC_PRE_K0 0x08 +#define FOCCFG_FOC_PRE_K1 0x10 +#define FOCCFG_FOC_POST_K 0x04 +#define FOCCFG_FOC_LIMIT 0x03 +#define FOCCFG_FOC_LIMIT0 0x01 +#define FOCCFG_FOC_LIMIT1 0x02 + +#define FOC_PRE_K_1K (0x00 << 3) +#define FOC_PRE_K_2K (0x02 << 3) +#define FOC_PRE_K_3K (0x03 << 3) +#define FOC_PRE_K_4K (0x04 << 3) + +#define FOC_LIMIT_0 (0x00) +#define FOC_LIMIT_DIV8 (0x01) +#define FOC_LIMIT_DIV4 (0x02) +#define FOC_LIMIT_DIV2 (0x03) + + +// 0xDF16: BSCFG - Bit Synchronization Configuration +#define BSCFG_BS_PRE_KI 0xC0 +#define BSCFG_BS_PRE_KI0 0x40 +#define BSCFG_BS_PRE_KI1 0x80 +#define BSCFG_BS_PRE_KP 0x30 +#define BSCFG_BS_PRE_KP0 0x10 +#define BSCFG_BS_PRE_KP1 0x20 +#define BSCFG_BS_POST_KI 0x08 +#define BSCFG_BS_POST_KP 0x04 +#define BSCFG_BS_LIMIT 0x03 +#define BSCFG_BS_LIMIT0 0x01 +#define BSCFG_BS_LIMIT1 0x02 + +#define BSCFG_BS_PRE_KI_1K (0x00 << 6) +#define BSCFG_BS_PRE_KI_2K (0x01 << 6) +#define BSCFG_BS_PRE_KI_3K (0x02 << 6) +#define BSCFG_BS_PRE_KI_4K (0x03 << 6) + +#define BSCFG_BS_PRE_KP_1K (0x00 << 4) +#define BSCFG_BS_PRE_KP_2K (0x01 << 4) +#define BSCFG_BS_PRE_KP_3K (0x02 << 4) +#define BSCFG_BS_PRE_KP_4K (0x03 << 4) + +#define BSCFG_BS_LIMIT_0 (0x00) +#define BSCFG_BS_LIMIT_3 (0x01) +#define BSCFG_BS_LIMIT_6 (0x02) +#define BSCFG_BS_LIMIT_12 (0x03) + + +// 0xDF17: AGCCTRL2 - AGC Control +#define AGCCTRL2_MAX_DVGA_GAIN 0xC0 +#define AGCCTRL2_MAX_LNA_GAIN 0x38 +#define AGCCTRL2_MAGN_TARGET 0x07 + + +// 0xDF18: AGCCTRL1 - AGC Control +#define AGCCTRL1_AGC_LNA_PRIORITY 0x40 +#define AGCCTRL1_CARRIER_SENSE_REL_THR 0x30 +#define AGCCTRL1_CARRIER_SENSE_ABS_THR 0x0F + + +// 0xDF19: AGCCTRL0 - AGC Control +#define AGCCTRL0_HYST_LEVEL 0xC0 +#define AGCCTRL0_WAIT_TIME 0x30 +#define AGCCTRL0_AGC_FREEZE 0x0C +#define AGCCTRL0_FILTER_LENGTH 0x03 + + +// 0xDF1A: FREND1 - Front End RX Configuration +#define FREND1_LNA_CURRENT 0xC0 +#define FREND1_LNA2MIX_CURRENT 0x30 +#define FREND1_LODIV_BUF_CURRENT_RX 0x0C +#define FREND1_MIX_CURRENT 0x03 + + +// 0xDF1B: FREND0 - Front End TX Configuration +#define FREND0_LODIV_BUF_CURRENT_TX 0x30 + + +// 0xDF1C: FSCAL3 - Frequency Synthesizer Calibration +#define FSCAL3_FSCAL3 0xC0 +#define FSCAL3_CHP_CURR_CAL_EN 0x30 + + +// 0xDF1D: FSCAL2 - Frequency Synthesizer Calibration +#define FSCAL2_VCO_CORE_H_EN 0x20 +#define FSCAL2_FSCAL2 0x1F + + +// 0xDF1E: FSCAL1 - Frequency Synthesizer Calibration + +// 0xDF1F: FSCAL0 - Frequency Synthesizer Calibration + +// 0xDF25: TEST0 - Various Test Settings + + +// RFST (0xE1) - RF Strobe Commands +#define RFST_SFSTXON 0x00 +#define RFST_SCAL 0x01 +#define RFST_SRX 0x02 +#define RFST_STX 0x03 +#define RFST_SIDLE 0x04 +#define RFST_SNOP 0x05 + +// 0xDF3B: MARCSTATE - Main Radio Control State Machine State +#define MARCSTATE_MARC_STATE 0x1F + +#define MARC_STATE_SLEEP 0x00 +#define MARC_STATE_IDLE 0x01 +#define MARC_STATE_VCOON_MC 0x03 +#define MARC_STATE_REGON_MC 0x04 +#define MARC_STATE_MANCAL 0x05 +#define MARC_STATE_VCOON 0x06 +#define MARC_STATE_REGON 0x07 +#define MARC_STATE_STARTCAL 0x08 +#define MARC_STATE_BWBOOST 0x09 +#define MARC_STATE_FS_LOCK 0x0A +#define MARC_STATE_IFADCON 0x0B +#define MARC_STATE_ENDCAL 0x0C +#define MARC_STATE_RX 0x0D +#define MARC_STATE_RX_END 0x0E +#define MARC_STATE_RX_RST 0x0F +#define MARC_STATE_TXRX_SWITCH 0x10 +#define MARC_STATE_RX_OVERFLOW 0x11 +#define MARC_STATE_FSTXON 0x12 +#define MARC_STATE_TX 0x13 +#define MARC_STATE_TX_END 0x14 +#define MARC_STATE_RXTX_SWITCH 0x15 +#define MARC_STATE_TX_UNDERFLOW 0x16 + + +#endif diff --git a/boot/main.c b/boot/main.c new file mode 100644 index 0000000..ef9540c --- /dev/null +++ b/boot/main.c @@ -0,0 +1,339 @@ +/* + * CCTL - ChipCon Tiny Loader + * A 1KB serial bootloader for the CC1110/CC1111 + * Joby Taffey (c) 2012 + * + * Derived from CC Bootloader + * Fergus Noble (c) 2011 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include "cc1110-ext.h" + +// Flash write timer value: +// FWT = 21000 * FCLK / (16 * 10^9) +// For FCLK = 24MHz, FWT = 0x1F +// For FCLK = 26MHz, FWT = 0x11 +#define FLASH_FWT 0x11 +// Address of flash controller data register +#define FLASH_FWDATA_ADDR 0xDFAF + + +#define RXFIFO_ELEMENTS 2048 +#define RXFIFO_SIZE (RXFIFO_ELEMENTS - 1) +static __xdata uint8_t rxfifo[RXFIFO_SIZE]; +static uint8_t rxfifo_in; +static uint8_t rxfifo_out; +static __xdata struct cc_dma_channel dma0_config; +static const __code uint8_t * __at (0x0000) flashp; +__xdata uint8_t rambuf[1024]; +uint8_t page; + +static const char banner[] = {'\r', '\n', 'C', 'C', 'T', 'L', '\r', '\n'}; + +struct cc_dma_channel +{ + uint8_t src_high; + uint8_t src_low; + uint8_t dst_high; + uint8_t dst_low; + uint8_t len_high; + uint8_t len_low; + uint8_t cfg0; + uint8_t cfg1; +}; + +#define DMA_CFG0_TRIGGER_FLASH 18 +#define DMA_CFG1_SRCINC_1 (1 << 6) +#define DMA_CFG1_DESTINC_0 (0 << 4) +#define DMA_CFG1_PRIORITY_HIGH (2 << 0) +#define DMAARM_DMAARM0 (1 << 0) + +#define DMA_LEN_HIGH_VLEN_MASK (7 << 5) +#define DMA_LEN_HIGH_VLEN_LEN (0 << 5) +#define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5) +#define DMA_LEN_HIGH_VLEN (2 << 5) +#define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5) +#define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5) +#define DMA_LEN_HIGH_MASK (0x1f) + +#define DMA_CFG0_WORDSIZE_8 (0 << 7) +#define DMA_CFG0_WORDSIZE_16 (1 << 7) +#define DMA_CFG0_TMODE_MASK (3 << 5) +#define DMA_CFG0_TMODE_SINGLE (0 << 5) +#define DMA_CFG0_TMODE_BLOCK (1 << 5) +#define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5) +#define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5) + + +void flash_erase_page(void) +{ + while (FCTL & FCTL_BUSY); + + FWT = FLASH_FWT; + FADDRH = page << 1; + FADDRL = 0x00; + + // Erase the page that will be written to + FCTL |= FCTL_ERASE; + __asm nop __endasm; + + // Wait for the erase operation to complete + while (FCTL & FCTL_BUSY) {} +} + +void flash_write_trigger(void) +{ + // Enable flash write. Generates a DMA trigger. Must be aligned on a 2-byte + // boundary and is therefore implemented in assembly. + + // p.s. if this looks a little crazy its because it is, sdcc doesn't currently + // support explicitly specifying code alignment which would make this easier + + __asm + .globl flash_write_trigger_instruction + .globl flash_write_trigger_done + + ; Put our trigger instruction in the HOME segment (shared with some startup code) + ; where it wont move around too much + .area HOME (CODE) + ; Comment or uncomment these lines to adjust if you change the start.asm code + nop ; Padding to get onto 16-bit boundary + flash_write_trigger_instruction: + orl _FCTL, #0x02 ; FCTL |= FCTL_ERASE + nop ; Required, see datasheet. + ljmp flash_write_trigger_done ; Jump back into our function + + ; Meanwhile, back in the main CSEG segment... + .area CSEG (CODE) + ; Jump to the trigger instruction + ljmp flash_write_trigger_instruction + flash_write_trigger_done: + __endasm; +} + +void flash_write(void) +{ + // Setup DMA descriptor + dma0_config.src_high = (((uint16_t)(__xdata uint16_t *)rambuf) >> 8) & 0x00FF; + dma0_config.src_low = ((uint16_t)(__xdata uint16_t *)rambuf) & 0x00FF; + dma0_config.dst_high = (FLASH_FWDATA_ADDR >> 8) & 0x00FF; + dma0_config.dst_low = FLASH_FWDATA_ADDR & 0x00FF; + dma0_config.len_high = DMA_LEN_HIGH_VLEN_LEN; + dma0_config.len_high |= ((1024) >> 8) & DMA_LEN_HIGH_MASK; + dma0_config.len_low = (1024) & 0x00FF; + + dma0_config.cfg0 = \ + DMA_CFG0_WORDSIZE_8 | \ + DMA_CFG0_TMODE_SINGLE | \ + DMA_CFG0_TRIGGER_FLASH; + + dma0_config.cfg1 = \ + DMA_CFG1_SRCINC_1 | \ + DMA_CFG1_DESTINC_0 | \ + DMA_CFG1_PRIORITY_HIGH; + + // Point DMA controller at our DMA descriptor + DMA0CFGH = ((uint16_t)&dma0_config >> 8) & 0x00FF; + DMA0CFGL = (uint16_t)&dma0_config & 0x00FF; + + // Waiting for the flash controller to be ready + while (FCTL & FCTL_BUSY); + + // Configure the flash controller + FWT = FLASH_FWT; + FADDRH = (page << 1) & 0x3F; + //FADDRL = 0;//(page << 9) & 0xFF; // reset value is 0x00 + + // Arm the DMA channel, so that a DMA trigger will initiate DMA writing + DMAARM |= DMAARM_DMAARM0; + + // Enable flash write - triggers the DMA transfer + flash_write_trigger(); + + // Wait for DMA transfer to complete + while (!(DMAIRQ & DMAIRQ_DMAIF0)); + + // Wait until flash controller not busy + while (FCTL & (FCTL_BUSY | FCTL_SWBSY)); + + // By now, the transfer is completed, so the transfer count is reached. + // The DMA channel 0 interrupt flag is then set, so we clear it here. + DMAIRQ &= ~DMAIRQ_DMAIF0; +} + + +uint8_t cons_getch(void) +{ + if (rxfifo_in == rxfifo_out) + return 0; + page = rxfifo[rxfifo_out]; + if (rxfifo_out + 1 == RXFIFO_SIZE) + rxfifo_out = 0; + else + rxfifo_out++; + return 1; +} + + +void cons_putc(uint8_t ch) +{ + U0DBUF = ch; + while(!(U0CSR & U0CSR_TX_BYTE)); // wait for byte to be transmitted + U0CSR &= ~U0CSR_TX_BYTE; // Clear transmit byte status +} + +void uart0_isr(void) __interrupt URX0_VECTOR +{ + URX0IF = 0; + +// HACK we know the buffer is big enough, as client is waiting for our ACK +// if(rxfifo_in != (( rxfifo_out - 1 + RXFIFO_SIZE) % RXFIFO_SIZE)) // not full + { + rxfifo[rxfifo_in] = U0DBUF; + if (rxfifo_in + 1 == RXFIFO_SIZE) + rxfifo_in = 0; + else + rxfifo_in++; + } +} + +void jump_to_user(void) +{ + if (*((__xdata uint8_t*)0x400) != 0xFF) + { + // Disable all interrupts + EA = 0; + IEN0 = IEN1 = IEN2 = 0; + + // bootloader not running + F1 = 0; + + // Jump to user code + __asm + ljmp #0x400 + __endasm; + } +} + + +void bootloader_main(void) +{ + uint16_t i; + uint8_t n; + + // Initialise clocks + SLEEP &= ~SLEEP_OSC_PD; // enable RC oscillator + while( !(SLEEP & SLEEP_XOSC_S) ); // let oscillator stabilise + + CLKCON = CLKCON_OSC32 | CLKCON_OSC | TICKSPD_DIV_32 | CLKSPD_DIV_2; // select internal HS RC oscillator + while (!(CLKCON & CLKCON_OSC)); + + CLKCON = CLKCON_OSC32 | TICKSPD_DIV_32 | CLKSPD_DIV_1; // select external crystal + +// while (CLKCON & CLKCON_OSC); +// SLEEP |= SLEEP_OSC_PD; // Disable RC oscillator now that we have an external crystal + + rxfifo_in = rxfifo_out = 0; + + PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG; + P0SEL |= (1<<3) | (1<<2); + U0CSR = 0x80 | 0x40; // UART, RX on + U0BAUD = 34; // 115200 + U0GCR = 13; // 115k2 baud at 13MHz, useful for coming out of sleep. Assumes clkspd_div2 in clkcon for HSRC osc + URX0IF = 0; // No interrupts pending at start + URX0IE = 1; // Serial Rx irqs enabled in system interrupt register + + F1 = 1; + EA = 1; + + n = 0; + while(n < sizeof(banner)) + cons_putc(banner[n++]); + + n = 8; + i = 65535; + while(!cons_getch() && n > 0) + { + if (i-- == 0) + { + cons_putc('B'); + n--; + } + } + if (n != 0) + goto upgrade_loop; + + jump_to_user(); + +upgrade_loop: + WDCTL = (WDCTL & ~WDCTL_INT) | WDCTL_INT_SEC_1; // watchdog on LS RCOSC, ~1s + WDCTL = (WDCTL & ~WDCTL_MODE) | WDCTL_EN; // start + + while(1) + { + if (cons_getch()) + { + WDCTL = (WDCTL & ~0xF0) | (0xA0); // pat + WDCTL = (WDCTL & ~0xF0) | (0x50); + + switch(page) + { + case 'e': + while(!cons_getch()); + flash_erase_page(); + goto ack; + break; + + case 'p': + while(!cons_getch()); + flash_write(); + goto ack; + break; + + case 'r': + while(!cons_getch()); + for (i=page<<10;i<(page+1)<<10;i++) + cons_putc(flashp[i]); + goto ack; + break; + + case 'l': + i = 0; + while(i<1024) + { + while(!cons_getch()); + rambuf[i] = page; + i++; + } + goto ack; + break; + + case 'j': + jump_to_user(); + break; + + ack: + cons_putc(0); + + } + } + } +} + + + diff --git a/boot/start.asm b/boot/start.asm new file mode 100644 index 0000000..d74fdf8 --- /dev/null +++ b/boot/start.asm @@ -0,0 +1,101 @@ + .globl __start__stack +;-------------------------------------------------------- +; Stack segment in internal ram +;-------------------------------------------------------- + .area SSEG (DATA) +__start__stack: + .ds 1 + +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- + .area VECTOR (CODE) + .globl __interrupt_vect +__interrupt_vect: + ljmp __sdcc_gsinit_startup + + ljmp #(0x400+0x03) + .ds 5 + ljmp #(0x400+0x0B) + .ds 5 + ljmp uart0_isr_forward; + .ds 5 + ljmp #(0x400+0x1B) + .ds 5 + ljmp #(0x400+0x23) + .ds 5 + ljmp #(0x400+0x2B) + .ds 5 + ljmp #(0x400+0x33) + .ds 5 + ljmp #(0x400+0x3B) + .ds 5 + ljmp #(0x400+0x43) + .ds 5 + ljmp #(0x400+0x4B) + .ds 5 + ljmp #(0x400+0x53) + .ds 5 + ljmp #(0x400+0x5B) + .ds 5 + ljmp #(0x400+0x63) + .ds 5 + ljmp #(0x400+0x6B) + .ds 5 + ljmp #(0x400+0x73) + .ds 5 + ljmp #(0x400+0x7B) + .ds 5 + ljmp #(0x400+0x83) + .ds 5 + ljmp #(0x400+0x8B) + .ds 5 + +uart0_isr_forward: + push psw + jnb psw.1, 00001$ + pop psw + ljmp _uart0_isr +00001$: + pop psw + ljmp #(0x400+0x13) + + +;-------------------------------------------------------- +; external initialized ram data +;-------------------------------------------------------- + .area XISEG (XDATA) + .area HOME (CODE) + .area GSINIT0 (CODE) + .area GSINIT1 (CODE) + .area GSINIT2 (CODE) + .area GSINIT3 (CODE) + .area GSINIT4 (CODE) + .area GSINIT5 (CODE) + .area GSINIT (CODE) + .area GSFINAL (CODE) + .area CSEG (CODE) + +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + + .area GSINIT (CODE) + .globl __sdcc_gsinit_startup + .globl __sdcc_program_startup + .globl __start__stack + .globl __mcs51_genXINIT + .globl __mcs51_genXRAMCLEAR + .globl __mcs51_genRAMCLEAR + .area GSFINAL (CODE) + .globl __sdcc_program_startup + ljmp __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- + .area HOME (CODE) + .area HOME (CODE) +__sdcc_program_startup: + lcall _bootloader_main + ; return from main will lock up + sjmp . diff --git a/cctl-prog/Makefile b/cctl-prog/Makefile new file mode 100644 index 0000000..0ad51c0 --- /dev/null +++ b/cctl-prog/Makefile @@ -0,0 +1,9 @@ +CFLAGS=-Wall +TARGET=cctl-prog + +all: + gcc -o $(TARGET) $(CFLAGS) $(TARGET).c hex.c + +clean: + rm -f $(TARGET) $(TARGET).exe + diff --git a/cctl-prog/cctl-prog.c b/cctl-prog/cctl-prog.c new file mode 100644 index 0000000..717b9c6 --- /dev/null +++ b/cctl-prog/cctl-prog.c @@ -0,0 +1,292 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hex.h" + +int serial_open(char *port) +{ + int fd; + struct termios t_opt; + + fd = open(port, O_RDWR | O_NOCTTY); + if (fd == -1) { + fprintf(stderr, "Could not open serial port."); + return -1; + } + + fcntl(fd, F_SETFL, 0); + tcgetattr(fd, &t_opt); + cfsetispeed(&t_opt, B115200); + cfsetospeed(&t_opt, B115200); + t_opt.c_cflag |= (CLOCAL | CREAD); + t_opt.c_cflag &= ~PARENB; + t_opt.c_cflag &= ~CSTOPB; + t_opt.c_cflag &= ~CSIZE; + t_opt.c_cflag |= CS8; + t_opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + t_opt.c_iflag &= ~(IXON | IXOFF | IXANY); + t_opt.c_oflag &= ~OPOST; + t_opt.c_cc[VMIN] = 0; + t_opt.c_cc[VTIME] = 10; + tcflush(fd, TCIFLUSH); + tcsetattr(fd, TCSANOW, &t_opt); + + return fd; +} + +int program_page(int fd, int page) +{ + char cmd = 'p'; + char rsp; + + if (write(fd, &cmd, 1) <= 0) + return 1; + + if (write(fd, &page, 1) <= 0) + return 1; + + if (read(fd, &rsp, 1) <= 0 || rsp != 0) + return 1; + + return 0; +} + +int read_page(int fd, uint8_t page, uint8_t *data) +{ + int remaining; + int rc; + char cmd = 'r'; + char rsp; + + if (write(fd, &cmd, 1) <= 0) + return 1; + + if (write(fd, &page, 1) <= 0) + return 1; + + remaining = 1024; + while(remaining > 0) + { + rc = read(fd, data + (1024 - remaining), remaining); + if (rc <= 0) + return 1; + remaining -= rc; + } + + if (read(fd, &rsp, 1) <= 0 || rsp != 0) + return 1; + + return 0; +} + +int erase_page(int fd, uint8_t page) +{ + char cmd = 'e'; + char rsp; + + if (write(fd, &cmd, 1) <= 0) + return 1; + + if (write(fd, &page, 1) <= 0) + return 1; + + if (read(fd, &rsp, 1) <= 0 || rsp != 0) + { + fprintf(stderr, "erase_page rsp=%02X\n", rsp); + return 1; + } + + return 0; +} + +int load_data(int fd, uint8_t *data) +{ + int remaining; + int rc; + char cmd = 'l'; + char rsp; + + if (write(fd, &cmd, 1) <= 0) + return 1; + + remaining = 1024; + while(remaining > 0) + { + rc = write(fd, data + (1024 - remaining), remaining); + if (rc <= 0) + return 1; + remaining -= rc; + } + + if (read(fd, &rsp, 1) <= 0 || rsp != 0) + return 1; + + return 0; +} + +void dump(uint8_t *p, size_t len) +{ + while(len--) + printf("%02X", *p++); + printf("\n"); +} + +int erase_program_verify_page(int fd, uint8_t *data, uint8_t page) +{ + uint8_t verbuf[1024]; + + if (0 != load_data(fd, data)) + { + fprintf(stderr, "load_data failed\n"); + return 1; + } + + if (0 != erase_page(fd, page)) + { + fprintf(stderr, "erase_page failed\n"); + return 1; + } + + if (0 != program_page(fd, page)) + { + fprintf(stderr, "program_page failed\n"); + return 1; + } + + if (0 != read_page(fd, page, verbuf)) + { + fprintf(stderr, "read_page failed\n"); + return 1; + } + + if (0!=memcmp(verbuf, data, 1024)) + { + fprintf(stderr, "verify failed\n"); + + printf("verbuf = "); + dump(verbuf, 1024); + printf("expected = "); + dump(data, 1024); + + return 1; + } + + return 0; +} + +int wait_for_bootloader(int fd) +{ + uint8_t c; + uint8_t prev_c = 0; + int attempts = 100; + + while(attempts-- > 0) + { + printf("Waiting...\n"); + if (read(fd, &c, 1) < 0) + return 1; + else + { + if (c == 'B' && prev_c == 'B') + break; + prev_c = c; + } + } + + c = 0x00; + if (write(fd, &c, 1) <= 0) + return 1; + + return 0; +} + +int send_jump(int fd) +{ + uint8_t cmd = 'j'; + + if (write(fd, &cmd, 1) <= 0) + return 1; + return 0; +} + +int main(int argc, char *argv[]) +{ + int fd; + uint8_t buf[32*1024]; + int i, j; + + if (argc < 3) + { + fprintf(stderr, "Usage %s \n", argv[0]); + return 1; + } + + fd = serial_open(argv[1]); + if (fd < 0) + { + fprintf(stderr, "Failed to open %s\n", argv[1]); + return 1; + } + + memset(buf, 0xFF, sizeof(buf)); + if (0 != read_hexfile(buf, sizeof(buf), argv[2])) + { + fprintf(stderr, "Failed to read %s\n", argv[2]); + return 1; + } + + if (0 != wait_for_bootloader(fd)) + { + fprintf(stderr, "No bootloader detected\n"); + return 1; + } + + for (i=0x400;i<32*1024;i+=1024) + { + bool all_empty = true; + for (j=i;j +#include +#include +#include +#include +#include +#include +#include +#include + +static uint8_t tolowercase(uint8_t ch) +{ + if ((ch >= 'A') && (ch <= 'Z')) + return ch + 0x20; // Convert uppercase to lowercase + return ch; // Simply return original character if it doesn't require any adjustments +} + +static int8_t parseHexDigit(uint8_t digit) +{ + digit = tolowercase(digit); + if (isdigit(digit)) + return (int8_t)digit - '0'; + if ((digit >= 'a') && (digit <= 'f')) + return (int8_t)digit + 0xA - 'a'; + return -1; // Error case - input wasn't a valid hex digit +} + + +static int hexstring_parse(const char *hexstr, uint8_t *buf, size_t *buflen) +{ + size_t hexstrlen = *buflen * 2; + size_t i; + + if (hexstrlen & 0x1) + { + fprintf(stderr, "hexstring_parse: not even\n"); + return 1; + } + + if (*buflen < hexstrlen/2) + { + fprintf(stderr, "hexstring_parse: buffer too small %d < %d\n", *buflen, hexstrlen/2); + return 1; + } + + for (i=0;i> 8; + sum += addr & 0xFF; + + for (i=0;i buflen) + { + fprintf(stderr, "bad hexfile, too big\n"); + return 1; + } + memcpy(buf + addr, data, record_len); + } + else + if (type == 1) + { + *eof = true; + } + else + { + fprintf(stderr, "bad hexfile: unknown record type %02X\n", type); + } + + return 0; +} + +int read_hexfile(uint8_t *buf, size_t buflen, const char *filename) +{ + FILE *fp; + char line[1024]; + bool eof; + + if (NULL == (fp = fopen(filename, "ro"))) + return 1; + + while (NULL != fgets(line, sizeof(line), fp)) + { + char *p = (line + strlen(line)) - 1; + + while(p > line) + { + if (isspace((int)(*p))) + *p = 0; + p--; + } + + if (0 != read_record(buf, buflen, line, &eof)) + goto fail; + + if (eof) + break; + } + + fclose(fp); + return 0; +fail: + fclose(fp); + return 1; +} + + diff --git a/cctl-prog/hex.h b/cctl-prog/hex.h new file mode 100644 index 0000000..1293874 --- /dev/null +++ b/cctl-prog/hex.h @@ -0,0 +1,7 @@ +#ifndef HEX_H +#define HEX_H 1 + +int read_hexfile(uint8_t *buf, size_t buflen, const char *filename); + +#endif + diff --git a/example_payload/Makefile b/example_payload/Makefile new file mode 100644 index 0000000..4c49a5a --- /dev/null +++ b/example_payload/Makefile @@ -0,0 +1,50 @@ +# +# CC Debugger - Example Payload +# Fergus Noble (c) 2011 +# + +CC = sdcc + +CFLAGS = --model-small --opt-code-speed + +# NOTE: code-loc should be the same as the value specified for +# USER_CODE_BASE in the bootloader! +LDFLAGS_FLASH = \ + --out-fmt-ihx \ + --code-loc 0x400 --code-size 0x8000 \ + --xram-loc 0xf000 --xram-size 0x300 \ + --iram-size 0x100 + +ifdef DEBUG +CFLAGS += --debug +endif + +SRC = main.c + +ADB=$(SRC:.c=.adb) +ASM=$(SRC:.c=.asm) +LNK=$(SRC:.c=.lnk) +LST=$(SRC:.c=.lst) +REL=$(SRC:.c=.rel) +RST=$(SRC:.c=.rst) +SYM=$(SRC:.c=.sym) + +PROGS=example_payload.hex +PCDB=$(PROGS:.hex=.cdb) +PLNK=$(PROGS:.hex=.lnk) +PMAP=$(PROGS:.hex=.map) +PMEM=$(PROGS:.hex=.mem) +PAOM=$(PROGS:.hex=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +example_payload.hex: $(REL) Makefile + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o example_payload.hex $(REL) + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + diff --git a/example_payload/main.c b/example_payload/main.c new file mode 100644 index 0000000..bb6768a --- /dev/null +++ b/example_payload/main.c @@ -0,0 +1,28 @@ +#include "cc1110.h" + +#define nop() __asm nop __endasm; + +void delay (unsigned char n) +{ + unsigned char i = 0; + unsigned char j = 0; + + n <<= 1; + while (--n != 0) + while (--i != 0) + while (--j != 0) + nop(); +} + +void main(void) +{ + // toggle P2_3 + P2DIR |= (1<<3); + P2_3 = 0; + + while (1) + { + P2_3 ^= 1; + delay(3); + } +} diff --git a/prebuilt-cctl.hex b/prebuilt-cctl.hex new file mode 100755 index 0000000..837418d --- /dev/null +++ b/prebuilt-cctl.hex @@ -0,0 +1,121 @@ +:060000000200AF02040340 +:03000B0002040BE1 +:0300130002009355 +:03001B0002041BC1 +:03002300020423B1 +:03002B0002042BA1 +:0300330002043391 +:03003B0002043B81 +:0300430002044371 +:03004B0002044B61 +:0300530002045351 +:03005B0002045B41 +:0300630002046331 +:03006B0002046B21 +:0300730002047311 +:03007B0002047B01 +:03008300020483F1 +:03008B0002048BE1 +:0A009300C0D030D105D0D00201DE4C +:05009D00D0D0020413A5 +:030108000200A250 +:0500A20012023A80FE8D +:0B010B00E5AE20E7FB75AB11E50A250F +:0A0116000AF5AD75AC0043AE010020 +:06012000E5AE20E7FB2222 +:0100A7000058 +:0700A80043AE020002012932 +:030126000200A82C +:0101290022B3 +:07012A007A077BF88B0290BD +:07013100F7FFEAF07A077BFB +:07013800F890F800EAF090D6 +:0C013F00F80174DFF090F80274AFF0904B +:0E014B00F803E4F0E0FA43020490F803EAF04F +:0C01590090F804E4F090F8057412F090A7 +:08016500F8067442F07AFF7BFA +:06016D00F78BD57AFF7B41 +:05017300F77B008AD4B7 +:0B017800E5AE20E7FB75AB11E50A25A2 +:0B0183000AFA743F5AF5AD43D6011292 +:02018E00012648 +:05019000E5D130E0FBA9 +:08019500E5AE54C0600280F8E1 +:04019D0053D1FE221A +:0901A100E509B50804758200228D +:0801AA00E5092400F582E434AC +:0701B200F0F583E0F50AAA55 +:0801B900097B000ABA00010BEA +:0B01C100BAFF08BB07057509008002AB +:0201CC00050923 +:0401CE007582012213 +:0301D2008582C162 +:0901D500E58630E1FB5386FD22B2 +:0E01DE00C0E0C082C083C002C003C0D075D094 +:0A01EC0000C28BE5082400F582E450 +:0A01F60034F0F583E5C1F0AA087BA0 +:06020000000ABA00010B28 +:0B020600BAFF08BB0705750800800266 +:020211000508DE +:0D021300D0D0D003D002D083D082D0E03212 +:09022000900400E0FABAFF01228B +:0E022900C2AF759A0075B80075A800C2D10268 +:030237000400229E +:03023A0053BEFBB5 +:08023D00E5BE30E6FB75C6E9E1 +:0C024500E5C630E6FB75C6A8750900751B +:0C0251000800AAF174FE5A4402F5F143C3 +:0E025D00F30C7586C075C22275C50DC28BD21A +:07026B00AAD2D1D2AF7A0044 +:03027200BA0800C7 +:0E02750050138A030AEB9003B793F582C00280 +:070283001201D2D00280E855 +:06028A007AFF7BFF7C08F7 +:0E029000C002C003C0041201A1E582D004D058 +:0E029E0003D0027025EC60228A058B061ABA86 +:0302AC00FF011B34 +:0E02AF00ED4E70DD758242C002C003C0041225 +:0B02BD0001D2D004D003D0021C80C886 +:0602C800EC70031202209D +:0C02CE0053C9FCAAC974FB5A4408F5C9C6 +:0E02DA001201A1E58260F9AAC9740F5A44A06E +:0C02E800F5C9AAC9740F5A4450F5C9AA00 +:0602F4000ABA6502801D3C +:0802FA00AA0ABA6A030203A478 +:07030200AA0ABA6C02806F29 +:07030900AA0ABA7002801479 +:07031000AA0ABA72C5801AA7 +:0B0317001201A1E58260F912010B0247 +:0203220003AA2C +:0B0324001201A1E58260F912012A021B +:02032F0003AA1F +:0C0331001201A1E58260F9AA0AEA2A255F +:04033D00E0FB7A0067 +:09034100AC0A7D000CBC00010DAA +:0E034A00EC2C25E0FD7C00C3EA9CEB9D50529C +:0E035800EA2500F582EB3501F583E493F5828A +:0E036600C002C0031201D2D003D0020ABA00B6 +:04037400CC0B80C965 +:040378007A007B008C +:05037C0074FC2B402978 +:0E038100C002C0031201A1E582D003D00260C9 +:0A038F00F1EA2407F582EB34F8F5DB +:0B03990083E50AF00ABA00DB0B80D8F5 +:0603A4001202200202DA41 +:0903AA007582001201D20202DA90 +:0803B7000D0A4343544C0D0AEA +:0600DE00E478FFF6D8FDF6 +:0800BC007900E94400601B7AA1 +:0500C400009003BF786D +:0300C9000075932C +:0A00CC0000E493F2A308B800020557 +:0800D60093D9F4DAF27593FFEF +:0800E4007800E84400600A798D +:0300EC0000759309 +:0600EF00F0E4F309D8FC67 +:0800F5007807E8440C600C7967 +:0B00FD000D90F000E4F0A3D8FCD9FA4D +:0300AF0075810A4E +:0A00B2001203B3E58260030200A20E +:0403B300758200222D +:00000001FF