imme-dongle.tar.gz master
authorToby Jaffey <toby@hodgepig.org>
Fri, 23 Aug 2013 12:20:21 +0000 (14:20 +0200)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Fri, 23 Aug 2013 12:20:21 +0000 (14:20 +0200)
15 files changed:
COPYING [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
cc1110/Makefile [new file with mode: 0644]
cc1110/dongle.c [new file with mode: 0644]
cc1110/ioCCxx10_bitdef.h [new file with mode: 0644]
dongle.hex [new file with mode: 0644]
linux/Makefile [new file with mode: 0644]
linux/console.c [new file with mode: 0644]
linux/console.h [new file with mode: 0644]
linux/main.c [new file with mode: 0644]
linux/parse.c [new file with mode: 0644]
linux/parse.h [new file with mode: 0644]
linux/tty_posix.c [new file with mode: 0644]
linux/tty_posix.h [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..9f1e730
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     51 Franklin Street, 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 Library 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.
+\f
+                   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.)
+\f
+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.
+\f
+  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.
+\f
+  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
+\f
+           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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy <name of author>
+
+    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, 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) 19yy 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.
+
+  <signature of Ty Coon>, 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 Library General
+Public License instead of this License.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..582e01b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+all:
+       make -C linux
+       make -C cc1110
+
+clean:
+       make -C linux clean
+       make -C cc1110 clean
+
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..fd634a3
--- /dev/null
+++ b/README
@@ -0,0 +1,77 @@
+This is alternative firmware for the Girl Tech IM-Me USB dongle.
+(http://www.girltech.com/electronics-imMe.aspx) that implements a basic command shell for control of the CC1110.
+
+It is a work-in-progress. A fairly generic messaging framework is provided, but not much actual functionality, yet.
+
+Directories
+===========
+
+/linux
+    PC side application for sending messages to the dongle. Loosely based on im-megpldrivers (http://sourceforge.net/projects/im-megpldrivers/)
+
+/cc1110
+    Dongle firmware
+
+Status
+======
+
+"It works for me".
+All of my testing has been with Debian running under VMWare on OSX - this may be the cause of some of the USB issues.
+My understanding of the protocol between the Cypress and Chipcon chips comes from what I've gleaned using an Open Logic Sniffer.
+There are probably bugs, please help to fix them.
+
+Building and using
+==================
+
+Type make.
+
+You'll need a GoodFET/SmartRF or some other Chipcon flasher to load dongle.hex into your USB dongle.
+(See this picture for where to make the connections: http://www.flickr.com/photos/travisgoodspeed/4323094248/)
+
+Connect the dongle and run ./imme-shell (as root)
+
+Type "led 1"
+Type "led 0"
+
+The dongle LED should respond.
+
+Type "getreg 0xDF36" to read the PARTNUM register. Being a CC1110, it will respond with 0x01.
+
+Load the spectrum analyser firmware onto your IM-me console.
+Type "setchan n" into ./imme-shell where 0 <= n <= 255, see the dongle transmit a modulated carrier wave with a base frequency of 868MHz using the given channel offset
+
+Type "exit" to quit.
+
+Protocols
+=========
+
+CY7C63803 <--> CC1110
+---------------------
+
+The link between the Cypress and Chipcon devices is SPI-like.
+ * The clock is driven by the CC1110 at 100kHz
+ * MISO and MOSI behave as you'd expect
+ * There are two "ready to receive" lines, which go high to request data. Once a valid 3 byte header (0xFA, 0xFB, len) is received, the requester drives the line low
+ * On sending 0xFA in the first header byte, the receiver responds with > 0 if it has data which needs to be polled for
+ * It seems to be important to wait for ~500ms between transmit and receive, else the Cypress device crashes
+
+More pinouts and timing information here:
+http://www.flickr.com/photos/54388270@N04/sets/72157625159026076/
+
+
+PC <--> CC1110
+--------------
+
+Each message starts with a command byte, eg. CMD_LED or CMD_SETCHAN, this is followed by a command specific number of bytes containing the args. When no message is queued to be sent, each end of the link sends CMD_NULL packets repeatedly.
+
+The top bit of the command byte is the ACK request flag. If set, the receiver should respond with a CMD_ACK packet. No sequence numbers are used, so only one message can be "in flight" at a time.
+
+
+Author
+======
+
+Joby Taffey <jrt@hodgepig.org>
+http://blog.hodgepig.org/
+http://twitter.com/jobytaffey
+
+
diff --git a/cc1110/Makefile b/cc1110/Makefile
new file mode 100644 (file)
index 0000000..f9978b4
--- /dev/null
@@ -0,0 +1,18 @@
+TARGET=dongle
+
+libs = 
+CC = sdcc
+CFLAGS = --no-pack-iram
+LFLAGS = --xram-loc 0xF000
+
+all: $(TARGET).hex
+
+%.rel : %.c
+       $(CC) $(CFLAGS) -c $<
+
+$(TARGET).hex: $(TARGET).rel $(libs)
+       sdcc $(LFLAGS) $(TARGET).rel $(libs)
+       packihx <$(TARGET).ihx >$(TARGET).hex
+
+clean:
+       rm -f *.hex *.ihx *.rel *.asm *.lst *.rst *.sym *.lnk *.map *.mem
diff --git a/cc1110/dongle.c b/cc1110/dongle.c
new file mode 100644 (file)
index 0000000..48ba840
--- /dev/null
@@ -0,0 +1,514 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <cc1110.h>
+#include "ioCCxx10_bitdef.h"
+
+/******************************************************************/
+
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+/******************************************************************/
+
+// 230400 bps
+#define SPI_BAUD_M  34
+#define SPI_BAUD_E  13
+
+#define TIMER1_COUNT (26000/2)  // 1ms  // defines the inter-byte gap, this can actually shrink to almost nothing
+#define RX_WAIT_TIME 0 // in timer1_ticks == ms
+#define TX_WAIT_TIME 200 // in timer1_ticks == ms
+
+/******************************************************************/
+
+#define nop()   _asm nop _endasm;
+
+#define LED_ON      P0 &= ~BIT6
+#define LED_OFF     P0 |= BIT6
+
+/******************************************************************/
+
+volatile static __data uint32_t timer1_ticks = 0;   // in ms
+
+/******************************************************************/
+
+enum
+{
+    TX_COMPLETE_WAIT,   // pause at the end of transmission
+    TX_COMPLETE,        // transmission complete
+    TX_WAITING_CYP,     // waiting for cypress to request data
+    TX_SENDING_HDR_FA,  // send 0xFA
+    TX_SENDING_HDR_FB,  // send 0xFB
+    TX_SENDING_HDR_LEN, // send len
+    TX_WAIT_ACK,        // waiting for acknowledgement
+    TX_SENDING_DATA,    // send data
+};
+
+volatile static uint8_t *txbuf = NULL;
+volatile static __data uint8_t txbuf_len = 0;
+volatile static __data uint8_t txbuf_index = 0;
+volatile static __data uint8_t txstate = TX_COMPLETE;
+volatile static __data uint8_t recv_needed = 0;
+volatile static __data uint32_t tx_wait_timer = 0;
+
+static void handle_tx(void);
+
+/******************************************************************/
+
+#define RX_HDR_ATTEMPTS 5   // number of times to search for 0xFA
+
+volatile static __data uint8_t err = 0;
+
+enum
+{
+    RX_WAIT_FA,     // waiting for 0xFA
+    RX_WAIT_FB,     // waiting for 0xFB
+    RX_WAIT_LEN,    // waiting for length byte
+    RX_WAIT_DATA,   // receiving data
+    RX_FAILED_WAIT, // wait a short time before doing anything else
+    RX_FAILED,      // failed to read a valid header
+    RX_COMPLETE,    // received a packet OK
+};
+
+volatile static uint8_t *rxbuf = NULL;
+volatile static __data uint8_t rx_hdr_attempts;
+volatile static __data uint8_t rxstate = RX_COMPLETE;
+volatile static __data uint8_t rxbuf_len;
+volatile static __data uint8_t rx_len;  // length on incoming packet
+volatile static __data uint8_t rx_index;    // index of data read
+volatile static __data uint32_t rx_wait_timer = 0;
+
+
+static void handle_rx(void);
+
+/******************************************************************/
+
+// Set system clock source to 26MHz
+static void clock_init(void)
+{
+    SLEEP &= ~SLEEP_OSC_PD; // Turn both high speed oscillators on
+    while( !(SLEEP & SLEEP_XOSC_S) ); // Wait until xtal oscillator is stable
+
+    CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1; // Select xtal osc, 26MHz
+    while (CLKCON & CLKCON_OSC); // Wait for change to take effect
+
+    SLEEP |= SLEEP_OSC_PD; // Turn off the other high speed oscillator (the RC osc)
+}
+
+/******************************************************************/
+
+static void timer1_init(void)
+{
+    T1CTL = 0;  // stop timer
+
+    T1CC0H = TIMER1_COUNT >> 8;
+    T1CC0L = (uint8_t) TIMER1_COUNT;
+
+    T1CCTL0 = T1CCTL0_MODE;
+    T1CCTL1 = 0;
+    T1CCTL2 = 0;
+
+    T1CNTL = 0; // clear count
+
+    OVFIM = 1;  // interrupt on overflow
+    T1IE = 1;   // timer interrupt
+
+    T1CTL = T1CTL_MODE_MODULO;    // modulo mode
+}
+
+static volatile uint8_t led_ticks = 0;
+
+static void timer1_isr(void) __interrupt 9
+{
+    timer1_ticks++;
+    handle_tx();
+    handle_rx();
+}
+
+/******************************************************************/
+
+static void spi_init(void)
+{
+       U0CSR = 0;              // SPI master
+       U0BAUD =  SPI_BAUD_M;   // SPI baud mantissa
+       U0GCR = U0GCR_ORDER | SPI_BAUD_E;   // Clock on 1st edge, -ve clock polarity, MSB first, and baud exponent
+}
+
+static uint8_t spi_tx(uint8_t ch)
+{
+       U0DBUF = ch;
+       while(!(U0CSR & U0CSR_TX_BYTE)); // wait for byte to be transmitted
+       U0CSR &= ~U0CSR_TX_BYTE;         // Clear transmit byte status
+
+    return U0DBUF;
+}
+
+/******************************************************************/
+
+static void io_init(void)
+{
+       P0SEL |= (BIT5 | BIT3);     // Select SCK and MOSI as SPI
+       P0DIR |= BIT4 | BIT6;       // SSEL and LED as output
+    P0 &= ~(BIT4 | BIT2);       // Drive SSEL and MISO low
+
+    P1IF = 0;           // clear P1 interrupt flag
+    IEN2 |= IEN2_P1IE;  // enable P1 interrupt
+    P1IEN |= BIT1;      // enable interrupt for P1.1
+
+    P1DIR |= BIT0;      // P1.0 as output, attention line to cypress
+    P1 &= ~BIT0;        // not ready to receive
+}
+
+static void p1_isr (void) __interrupt 15
+{
+    if (P1IFG & BIT1)   // cypress says it's ready to receive
+    {
+//        if (txstate == TX_WAITING_CYP)
+//            txstate = TX_SENDING_HDR_FA;
+    }
+    P1IFG = 0;
+}
+
+/******************************************************************/
+
+#if 1
+static void delay2(uint8_t n)
+{
+    uint8_t j = 0;
+    while(--n != 0)
+        while(--j != 0)
+            nop();
+}
+#endif
+
+/******************************************************************/
+
+static void rx(volatile uint8_t *buf, uint8_t len)
+{
+    rx_hdr_attempts = RX_HDR_ATTEMPTS;  // number of times to try and find first byte of header
+    rxbuf = buf;
+    rxbuf_len = len;
+    rxstate = RX_WAIT_FA;
+    rx_len = 0;
+    P1 |= BIT0;     // P1.0 assert attention
+}
+
+static void handle_rx(void)
+{
+    switch(rxstate)
+    {
+        case RX_WAIT_FA:
+            if (0xFA == spi_tx(0x00))
+                rxstate = RX_WAIT_FB;
+            else
+            {
+                rx_hdr_attempts--;
+                if (0 == rx_hdr_attempts)
+                {
+                    err = 1;
+                    rx_wait_timer = timer1_ticks + RX_WAIT_TIME;
+                    rxstate = RX_FAILED_WAIT;
+                }
+            }
+        break;
+
+        case RX_WAIT_FB:
+            if (0xFB == spi_tx(0x00))
+                rxstate = RX_WAIT_LEN;
+            else
+            {
+                err = 2;
+                rx_wait_timer = timer1_ticks + RX_WAIT_TIME;
+                rxstate = RX_FAILED_WAIT;
+            }
+        break;
+
+        case RX_WAIT_LEN:
+            rx_len = spi_tx(0x00);
+            rx_index = 0;
+            P1 &= ~BIT0;    // deassert attention line
+            if (rx_len > 0)
+                rxstate = RX_WAIT_DATA;
+            else
+            {
+                rx_wait_timer = timer1_ticks + RX_WAIT_TIME;
+                rxstate = RX_FAILED_WAIT;
+            }
+        break;
+
+        case RX_WAIT_DATA:
+            rxbuf[rx_index++] = spi_tx(0x00);
+            if (rx_index == rx_len || rx_index == rxbuf_len)
+                rxstate = RX_COMPLETE;
+        break;
+
+        case RX_FAILED_WAIT:
+            if (timer1_ticks >= rx_wait_timer)
+                rxstate = RX_FAILED;
+        break;
+
+        case RX_FAILED:
+        break;
+
+        case RX_COMPLETE:
+            // data sitting in buffer
+        break;
+    }
+}
+
+static void tx(volatile uint8_t *buf, uint8_t len)
+{
+    if (len < 4)
+        len = 4;
+
+    txbuf = buf;
+    txbuf_len = len;
+
+    recv_needed = 0;
+    txstate = TX_WAITING_CYP;    // start
+}
+
+static void handle_tx(void)
+{
+    switch(txstate)
+    {
+        case TX_COMPLETE_WAIT:
+            if (recv_needed)
+            {
+                if (timer1_ticks >= tx_wait_timer)
+                    txstate = TX_COMPLETE;
+            }
+            else
+                txstate = TX_COMPLETE;
+        break;
+
+        case TX_COMPLETE:
+        break;
+
+        case TX_WAITING_CYP:    // P1_isr detects rising edge also
+            if ((P1 & BIT1) == BIT1)
+                txstate = TX_SENDING_HDR_FA;
+        break;
+
+        case TX_SENDING_HDR_FA:
+            recv_needed = spi_tx(0xFA);
+            txstate = TX_SENDING_HDR_FB;
+        break;
+        case TX_SENDING_HDR_FB:
+            spi_tx(0xFB);
+            txstate = TX_SENDING_HDR_LEN;
+        break;
+        case TX_SENDING_HDR_LEN:
+            spi_tx(txbuf_len);
+            txbuf_index = 0;
+            txstate = TX_WAIT_ACK;
+        break;
+        case TX_WAIT_ACK:   // wait for cypress to ack header by lowering attention line
+            if ((P1 & BIT1) != BIT1)
+                txstate = TX_SENDING_DATA;
+            else
+                txstate = TX_SENDING_HDR_FA;
+        break;
+        case TX_SENDING_DATA:
+            spi_tx(txbuf[txbuf_index++]);
+            if (txbuf_index == txbuf_len)
+            {
+                tx_wait_timer = timer1_ticks + TX_WAIT_TIME;
+                txstate = TX_COMPLETE_WAIT;
+            }
+        break;
+    }
+}
+
+/******************************************************************/
+
+/*
+* Each packet is:
+* 0xFA, 0xFB, LEN, CMD, ARGS
+* Top bit of CMD is REQ_ACK flag, receiver should respond with an ACK packet (0xFA, 0xFB, 1, TYPE_ACK)
+*
+* LEDON is 0xFA, 0xFB, LEN, CMD_LED, 1
+*/
+
+#define ACK_REQ_FLAG 0x80
+
+enum
+{
+    CMD_NULL,
+    CMD_ACK,
+    CMD_LED,    // followed by one byte boolean
+    CMD_GETREG_REQ,
+    CMD_GETREG_RSP,
+    CMD_SETCHAN
+};
+
+static volatile uint8_t getreg_pending = 0x00;
+
+static void process_rx(uint8_t *buf, uint8_t *len)
+{
+    switch(*buf & ~ACK_REQ_FLAG)  // cmd
+    {
+        case CMD_ACK:
+            // received an ACK
+        break;
+
+        case CMD_LED:
+            if (buf[1] != 0)
+                LED_ON;
+            else
+                LED_OFF;
+        break;
+
+        case CMD_SETCHAN:
+            RFST = RFST_SIDLE;
+            delay2(0x10);
+            CHANNR = buf[1];
+            RFST = RFST_STX;
+        break;
+
+        case CMD_GETREG_REQ:
+        {
+            __xdata volatile unsigned char *ptr = (__xdata volatile unsigned char *)((buf[1] << 8) | buf[2]) ;
+            getreg_pending = *ptr;
+        }
+        break;
+    }
+
+    // ACK if requested
+    if (*buf & ACK_REQ_FLAG)
+    {   // reuse buf, an ACK is shorter than anything else
+        *buf = CMD_ACK;
+        *len = 1;
+    }
+    else
+    {
+        *buf = CMD_NULL;
+        *len = 1;
+    }
+}
+
+/*************************************/
+
+static void radio_init(void)
+{
+    // from SmartRF, 868MHz
+    SYNC1      =     0xD3;       // Sync Word, High Byte 
+    SYNC0      =     0x91;       // Sync Word, Low Byte 
+    PKTLEN     =     0xFF;       // Packet Length 
+    PKTCTRL1   =     0x04;       // Packet Automation Control 
+    PKTCTRL0   =     0x22;       // Packet Automation Control 
+    ADDR       =     0x00;       // Device Address 
+    CHANNR     =     0x00;       // Channel Number 
+    FSCTRL1    =     0x06;       // Frequency Synthesizer Control 
+    FSCTRL0    =     0x00;       // Frequency Synthesizer Control 
+    FREQ2      =     0x21;       // Frequency Control Word, High Byte 
+    FREQ1      =     0x65;       // Frequency Control Word, Middle Byte 
+    FREQ0      =     0x6A;       // Frequency Control Word, Low Byte 
+    MDMCFG4    =     0xF5;       // Modem configuration 
+    MDMCFG3    =     0x83;       // Modem Configuration 
+    MDMCFG2    =     0x10;       // Modem Configuration 
+    MDMCFG1    =     0x22;       // Modem Configuration 
+    MDMCFG0    =     0xF8;       // Modem Configuration 
+    DEVIATN    =     0x15;       // Modem Deviation Setting 
+    MCSM2      =     0x07;       // Main Radio Control State Machine Configuration 
+    MCSM1      =     0x30;       // Main Radio Control State Machine Configuration 
+    MCSM0      =     0x18;       // Main Radio Control State Machine Configuration 
+    FOCCFG     =     0x17;       // Frequency Offset Compensation Configuration 
+    BSCFG      =     0x6C;       // Bit Synchronization Configuration 
+    AGCCTRL2   =     0x03;       // AGC Control 
+    AGCCTRL1   =     0x40;       // AGC Control 
+    AGCCTRL0   =     0x91;       // AGC Control 
+    FREND1     =     0x56;       // Front End RX Configuration 
+    FREND0     =     0x10;       // Front End TX Configuration 
+    FSCAL3     =     0xE9;       // Frequency Synthesizer Calibration 
+    FSCAL2     =     0x2A;       // Frequency Synthesizer Calibration 
+    FSCAL1     =     0x00;       // Frequency Synthesizer Calibration 
+    FSCAL0     =     0x1F;       // Frequency Synthesizer Calibration 
+    TEST2      =     0x88;       // Various Test Settings 
+    TEST1      =     0x31;       // Various Test Settings 
+    TEST0      =     0x09;       // Various Test Settings 
+    PA_TABLE7  =     0x00;       // PA Power Setting 7 
+    PA_TABLE6  =     0x00;       // PA Power Setting 6 
+    PA_TABLE5  =     0x00;       // PA Power Setting 5 
+    PA_TABLE4  =     0x00;       // PA Power Setting 4 
+    PA_TABLE3  =     0x00;       // PA Power Setting 3 
+    PA_TABLE2  =     0x00;       // PA Power Setting 2 
+    PA_TABLE1  =     0x00;       // PA Power Setting 1 
+    PA_TABLE0  =     0xC2;       // PA Power Setting 0 
+    IOCFG2     =     0x00;       // Radio Test Signal Configuration (P1_7) 
+    IOCFG1     =     0x00;       // Radio Test Signal Configuration (P1_6) 
+    IOCFG0     =     0x00;       // Radio Test Signal Configuration (P1_5) 
+    PARTNUM    =     0x01;       // Chip ID[15:8] 
+    VERSION    =     0x03;       // Chip ID[7:0] 
+    FREQEST    =     0x00;       // Frequency Offset Estimate from Demodulator 
+    LQI        =     0xFF;       // Demodulator Estimate for Link Quality 
+    RSSI       =     0x80;       // Received Signal Strength Indication 
+    MARCSTATE  =     0x01;       // Main Radio Control State Machine State 
+    PKTSTATUS  =     0x80;       // Packet Status 
+    VCO_VC_DAC =     0x94;       // Current Setting from PLL Calibration Module 
+}
+
+void main(void)
+{
+    uint8_t buf[4];
+    uint32_t timeout;
+
+       clock_init();
+       spi_init();
+       io_init();
+    timer1_init();
+    radio_init();
+
+    EA = 1; // enable interrupts
+
+    buf[0] = CMD_NULL;
+    rx_len = 1;
+
+    while(1)
+    {
+        tx(buf, rx_len);
+        timeout = timer1_ticks + 500;
+        while(txstate != TX_COMPLETE)  // block until completion
+        {
+            if (timer1_ticks > timeout)
+                break;
+        }
+        if (getreg_pending != 0x00)
+        {
+            buf[0] = CMD_GETREG_RSP;
+            buf[1] = getreg_pending;
+            rx_len = 2;
+
+            getreg_pending = 0x00;
+        }
+        else
+        {
+            buf[0] = CMD_NULL;
+            rx_len = 1;
+        }
+
+
+
+        if (recv_needed)
+        {
+retry:
+            rx(buf, 4);
+            timeout = timer1_ticks + 500;
+            while(rxstate != RX_COMPLETE)   // block until completion
+            {
+                if (rxstate == RX_FAILED || timer1_ticks > timeout)
+                {
+                    goto retry;
+                }
+            }
+            recv_needed = 0;
+            process_rx(buf, &rx_len);
+        }
+    }
+}
+
diff --git a/cc1110/ioCCxx10_bitdef.h b/cc1110/ioCCxx10_bitdef.h
new file mode 100644 (file)
index 0000000..7c84a0a
--- /dev/null
@@ -0,0 +1,1284 @@
+/******************************************************************************\r
+    Filename: ioCCxx10_bitdef.h\r
+\r
+    This file contains the bit definitions of registers in CCxx10\r
+\r
+    Copyright 2008 Texas Instruments, Inc.\r
+******************************************************************************/\r
+#ifndef _IOCCXX10_BITDEF_H\r
+#define _IOCCXX10_BITDEF_H\r
+\r
+\r
+\r
+/* SEE DATA SHEET FOR DETAILS ABOUT THE FOLLOWING BIT MASKS */\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * Memory Control Registers\r
+ */\r
+\r
+// MPAGE (0x93) - Memory Page Select\r
+\r
+// MEMCTR (0xC7) - Memory Arbiter Control\r
+#define MEMCTR_CACHD                      0x02\r
+#define MEMCTR_PREFD                      0x01\r
+\r
+\r
+/*******************************************************************************\r
+ * CPU Registers\r
+ */\r
+\r
+// DPH0 (0x83) - Data Pointer 0 High Byte\r
+\r
+// DPL0 (0x82) - Data Pointer 0 Low Byte\r
+\r
+// DPH1 (0x85) - Data Pointer 1 High Byte\r
+\r
+// DPL1 (0x84) - Data Pointer 1 Low Byte\r
+\r
+// DPS (0x92) - Data Pointer Select\r
+#define DPS_VDPS                          0x01\r
+\r
+\r
+// PSW (0xD0) - Progrttus Word - bit accessible SFR register\r
+\r
+// ACC (0xE0) - Accumulator - bit accessible SFR register\r
+\r
+// B (0xF0) - B Register - bit accessible SFR register\r
+\r
+// SP (0x81) - Stack Pointer\r
+\r
+\r
+/*******************************************************************************\r
+ * Interrupt Control Registers\r
+ */\r
+\r
+// IEN0 (0xA8) - Interrupt Enable 0 Register - bit accessible SFR register\r
+\r
+// IEN1 (0xB8) - Interrupt Enable 1 Register - bit accessible SFR register\r
+\r
+// IEN2 (0x9A) - Interrupt Enable 2 Register\r
+#define IEN2_WDTIE                        0x20\r
+#define IEN2_P1IE                         0x10\r
+#define IEN2_UTX1IE                       0x08\r
+#define IEN2_I2STXIE                      0x08\r
+#define IEN2_UTX0IE                       0x04\r
+#define IEN2_P2IE                         0x02\r
+#define IEN2_USBIE                        0x02\r
+#define IEN2_RFIE                         0x01\r
+\r
+\r
+// TCON (0x88) - CPU Interrupt Flag 1 - bit accessible SFR register\r
+\r
+// S0CON (0x98) - CPU Interrupt Flag 2 - bit accessible SFR register\r
+\r
+// S1CON (0x9B) - CPU Interrupt Flag 3\r
+#define S1CON_RFIF_1                      0x02\r
+#define S1CON_RFIF_0                      0x01\r
+\r
+\r
+// IRCON (0xC0) - CPU Interrupt Flag 4 - bit accessible SFR register\r
+\r
+// IRCON2 (0xE8) - CPU Interrupt Flag 5 - bit accessible SFR register\r
+\r
+// IP1 (0xB9) - Interrupt Priority 1\r
+#define IP1_IPG5                          0x20\r
+#define IP1_IPG4                          0x10\r
+#define IP1_IPG3                          0x08\r
+#define IP1_IPG2                          0x04\r
+#define IP1_IPG1                          0x02\r
+#define IP1_IPG0                          0x01\r
+\r
+// IP0 (0xA9) - Interrupt Priority 0\r
+#define IP0_IPG5                          0x20\r
+#define IP0_IPG4                          0x10\r
+#define IP0_IPG3                          0x08\r
+#define IP0_IPG2                          0x04\r
+#define IP0_IPG1                          0x02\r
+#define IP0_IPG0                          0x01\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * Power Management and Clocks\r
+ */\r
+\r
+// PCON (0x87) - Power Mode Control\r
+#define PCON_IDLE                         0x01\r
+\r
+\r
+// SLEEP (0xBE) - Sleep Mode Control\r
+#define SLEEP_USB_EN                      0x80\r
+#define SLEEP_XOSC_S                      0x40\r
+#define SLEEP_HFRC_S                      0x20\r
+#define SLEEP_RST                         0x18\r
+#define SLEEP_RST0                        0x08\r
+#define SLEEP_RST1                        0x10\r
+#define SLEEP_OSC_PD                      0x04\r
+#define SLEEP_MODE                        0x03\r
+#define SLEEP_MODE1                       0x02\r
+#define SLEEP_MODE0                       0x01\r
+\r
+#define SLEEP_RST_POR_BOD                 (0x00 << 3)\r
+#define SLEEP_RST_EXT                     (0x01 << 3)\r
+#define SLEEP_RST_WDT                     (0x02 << 3)\r
+\r
+#define SLEEP_MODE_PM0                    (0x00)\r
+#define SLEEP_MODE_PM1                    (0x01)\r
+#define SLEEP_MODE_PM2                    (0x02)\r
+#define SLEEP_MODE_PM3                    (0x03)\r
+\r
+\r
+// CLKCON (0xC6) - Clock Control\r
+#define CLKCON_OSC32                      0x80  // bit mask, for the slow 32k clock oscillator\r
+#define CLKCON_OSC                        0x40  // bit mask, for the system clock oscillator\r
+#define CLKCON_TICKSPD                    0x38  // bit mask, for timer ticks output setting\r
+#define CLKCON_TICKSPD0                   0x08  // bit mask, for timer ticks output setting\r
+#define CLKCON_TICKSPD1                   0x10  // bit mask, for timer ticks output setting\r
+#define CLKCON_TICKSPD2                   0x20  // bit mask, for timer ticks output setting\r
+#define CLKCON_CLKSPD                     0x07  // bit mask, for the clock speed\r
+#define CLKCON_CLKSPD0                    0x01  // bit mask, for the clock speed\r
+#define CLKCON_CLKSPD1                    0x02  // bit mask, for the clock speed\r
+#define CLKCON_CLKSPD2                    0x04  // bit mask, for the clock speed\r
+\r
+#define TICKSPD_DIV_1                     (0x00 << 3)\r
+#define TICKSPD_DIV_2                     (0x01 << 3)\r
+#define TICKSPD_DIV_4                     (0x02 << 3)\r
+#define TICKSPD_DIV_8                     (0x03 << 3)\r
+#define TICKSPD_DIV_16                    (0x04 << 3)\r
+#define TICKSPD_DIV_32                    (0x05 << 3)\r
+#define TICKSPD_DIV_64                    (0x06 << 3)\r
+#define TICKSPD_DIV_128                   (0x07 << 3)\r
+\r
+#define CLKSPD_DIV_1                      (0x00)\r
+#define CLKSPD_DIV_2                      (0x01)\r
+#define CLKSPD_DIV_4                      (0x02)\r
+#define CLKSPD_DIV_8                      (0x03)\r
+#define CLKSPD_DIV_16                     (0x04)\r
+#define CLKSPD_DIV_32                     (0x05)\r
+#define CLKSPD_DIV_64                     (0x06)\r
+#define CLKSPD_DIV_128                    (0x07)\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ *  Flash Controller\r
+ */\r
+\r
+// FCTL (0xAE) - Flash Control\r
+#define FCTL_BUSY                         0x80\r
+#define FCTL_SWBSY                        0x40\r
+#define FCTL_CONTRD                       0x10\r
+#define FCTL_WRITE                        0x02\r
+#define FCTL_ERASE                        0x01\r
+\r
+\r
+// FWDATA (0xAF) - Flash Write Data\r
+\r
+// FADDRH (0xAD) - Flash Address High Byte\r
+\r
+// FADDRL (0xAC) - Flash Address Low Byte\r
+\r
+// FWT (0xAB) - Flash Write Timing (Only bit 0-5 R/W)\r
+\r
+\r
+/*******************************************************************************\r
+ * I/O Ports\r
+ */\r
+\r
+// P0 (0x80) - Port 0 - bit accessible SFR register\r
+\r
+// P1 (0x90) - Port 1 - bit accessible SFR register\r
+\r
+// P2 (0xA0) - Port 2 - bit accessible SFR register\r
+\r
+// PERCFG (0xF1) - Peripheral Control\r
+#define PERCFG_T1CFG                      0x40\r
+#define PERCFG_T3CFG                      0x20\r
+#define PERCFG_T4CFG                      0x10\r
+#define PERCFG_U1CFG                      0x02\r
+#define PERCFG_U0CFG                      0x01\r
+\r
+\r
+\r
+// ADCCFG (0xF2) - ADC input Configuration\r
+#define ADCCFG_7                          0x80\r
+#define ADCCFG_6                          0x40\r
+#define ADCCFG_5                          0x20\r
+#define ADCCFG_4                          0x10\r
+#define ADCCFG_3                          0x08\r
+#define ADCCFG_2                          0x04\r
+#define ADCCFG_1                          0x02\r
+#define ADCCFG_0                          0x01\r
+\r
+\r
+// P0SEL (0xF3) - Port 0 Function Select (bit 7 not used)\r
+\r
+// P1SEL (0xF4) - Port 1 Function Select\r
+\r
+// P2SEL (0xF5) - Port 2 Function Select\r
+#define P2SEL_PRI3P1                      0x40\r
+#define P2SEL_PRI2P1                      0x20\r
+#define P2SEL_PRI1P1                      0x10\r
+#define P2SEL_PRI0P1                      0x08\r
+#define P2SEL_SELP2_4                     0x04\r
+#define P2SEL_SELP2_3                     0x02\r
+#define P2SEL_SELP2_0                     0x01\r
+\r
+\r
+// P0DIR (0xFD) - Port 0 Direction Select\r
+\r
+// P1DIR (0xFE) - Port 1 Direction Select\r
+\r
+// P2DIR (0xFF) - Port 2 Direction\r
+#define P2DIR_PRIP0                       0xC0\r
+#define P2DIR_0PRIP0                      0x40\r
+#define P2DIR_1PRIP0                      0x80\r
+#define P2DIR_DIRP2                       0x1F\r
+\r
+#define P2DIR_PRIP0_0                     (0x00 << 6)\r
+#define P2DIR_PRIP0_1                     (0x01 << 6)\r
+#define P2DIR_PRIP0_2                     (0x02 << 6)\r
+#define P2DIR_PRIP0_3                     (0x03 << 6)\r
+\r
+#define P2DIR_DIRP2_4                     (0x10)\r
+#define P2DIR_DIRP2_3                     (0x08)\r
+#define P2DIR_DIRP2_2                     (0x04)\r
+#define P2DIR_DIRP2_1                     (0x02)\r
+#define P2DIR_DIRP2_0                     (0x01)\r
+\r
+\r
+\r
+// P0INP (0x8F) - Port 0 Input Mode (bit 0 & 1 not used)\r
+\r
+// P1INP (0xF6) - Port 1 Input Mode (bit 0 & 1 not used)\r
+\r
+// P2INP (0xF7) - Port 2 Input Mode\r
+#define P2INP_PDUP2                       0x80\r
+#define P2INP_PDUP1                       0x40\r
+#define P2INP_PDUP0                       0x20\r
+#define P2INP_MDP2                        0x1F\r
+\r
+#define P2INP_MDP2_0                      (0x01)\r
+#define P2INP_MDP2_1                      (0x02)\r
+#define P2INP_MDP2_2                      (0x04)\r
+#define P2INP_MDP2_3                      (0x08)\r
+#define P2INP_MDP2_4                      (0x10)\r
+\r
+\r
+\r
+// P0IFG (0x89) - Port 0 Interrupt Status Flag\r
+\r
+// P1IFG (0x8A) - Port 1 Interrupt Status Flag\r
+\r
+// P2IFG (0x8B) - Port 2 Interrupt Status Flag (bit 7 - 5 not used)\r
+\r
+// PICTL (0x8C) - Port Interrupt Control\r
+#define PICTL_PADSC                       0x40\r
+#define PICTL_P2IEN                       0x20\r
+#define PICTL_P0IENH                      0x10\r
+#define PICTL_P0IENL                      0x08\r
+#define PICTL_P2ICON                      0x04\r
+#define PICTL_P1ICON                      0x02\r
+#define PICTL_P0ICON                      0x01\r
+\r
+\r
+// P1IEN (0x8D) - Port 1 Interrupt Mask\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * DMA Controller\r
+ */\r
+\r
+// DMAARM (0xD6) - DMA Channel Arm\r
+#define DMAARM_ABORT                      0x80\r
+#define DMAARM4                           0x10\r
+#define DMAARM3                           0x08\r
+#define DMAARM2                           0x04\r
+#define DMAARM1                           0x02\r
+#define DMAARM0                           0x01\r
+\r
+\r
+// DMAREQ (0xD7) - DMA Channel Start Request and Status\r
+#define DMAREQ4                           0x10\r
+#define DMAREQ3                           0x08\r
+#define DMAREQ2                           0x04\r
+#define DMAREQ1                           0x02\r
+#define DMAREQ0                           0x01\r
+\r
+\r
+// DMA0CFGH (0xD5) - DMA Channel 0 Configuration Address High Byte\r
+\r
+// DMA0CFGL (0xD4) - DMA Channel 0 Configuration Address Low Byte\r
+\r
+// DMA1CFGH (0xD3) - DMA Channel 1 - 4 Configuration Address High By\r
+\r
+// DMA1CFGL (0xD2) - DMA Channel 1 - 4 Configuration Address Low Byte\r
+\r
+// DMAIRQ (0xD1) - DMA Interrupt Flag\r
+#define DMAIRQ_DMAIF4                     0x10\r
+#define DMAIRQ_DMAIF3                     0x08\r
+#define DMAIRQ_DMAIF2                     0x04\r
+#define DMAIRQ_DMAIF1                     0x02\r
+#define DMAIRQ_DMAIF0                     0x01\r
+\r
+\r
+// T1CNTH (0xE3) - Timer 1 Counter High\r
+\r
+// T1CNTL (0xE2) - Timer 1 Counter Low\r
+\r
+// T1CTL (0xE4) - Timer 1 Control and Status\r
+#define T1CTL_CH2IF                       0x80 // Timer 1 channel 2 interrupt flag\r
+#define T1CTL_CH1IF                       0x40 // Timer 1 channel 1 interrupt flag\r
+#define T1CTL_CH0IF                       0x20 // Timer 1 channel 0 interrupt flag\r
+#define T1CTL_OVFIF                       0x10 // Timer 1 counter overflow interrupt flag\r
+#define T1CTL_DIV                         0x0C\r
+#define T1CTL_DIV0                        0x04\r
+#define T1CTL_DIV1                        0x08\r
+#define T1CTL_MODE                        0x03\r
+#define T1CTL_MODE0                       0x01\r
+#define T1CTL_MODE1                       0x02\r
+\r
+#define T1CTL_DIV_1                       (0x00 << 2) // Divide tick frequency by 1\r
+#define T1CTL_DIV_8                       (0x01 << 2) // Divide tick frequency by 8\r
+#define T1CTL_DIV_32                      (0x02 << 2) // Divide tick frequency by 32\r
+#define T1CTL_DIV_128                     (0x03 << 2) // Divide tick frequency by 128\r
+\r
+#define T1CTL_MODE_SUSPEND                (0x00)    // Operation is suspended (halt)\r
+#define T1CTL_MODE_FREERUN                (0x01)    // Free Running mode\r
+#define T1CTL_MODE_MODULO                 (0x02)    // Modulo\r
+#define T1CTL_MODE_UPDOWN                 (0x03)    // Up/down\r
+\r
+\r
+// T1CCTL0 (0xE5) - Timer 1 Channel 0 Capture/Compare Control\r
+#define T1CCTL0_CPSEL                     0x80    // Timer 1 channel 0 capture select\r
+#define T1CCTL0_IM                        0x40    // Channel 0 Interrupt mask\r
+#define T1CCTL0_CMP                       0x38\r
+#define T1CCTL0_CMP0                      0x08\r
+#define T1CCTL0_CMP1                      0x10\r
+#define T1CCTL0_CMP2                      0x20\r
+#define T1CCTL0_MODE                      0x04    // Capture or compare mode\r
+#define T1CCTL0_CAP                       0x03\r
+#define T1CCTL0_CAP0                      0x01\r
+#define T1CCTL0_CAP1                      0x02\r
+\r
+#define T1C0_SET_ON_CMP                   (0x00 << 3)    // Clear output on compare-up set on 0\r
+#define T1C0_CLR_ON_CMP                   (0x01 << 3)    // Set output on compare-up clear on 0\r
+#define T1C0_TOG_ON_CMP                   (0x02 << 3)    // Toggle output on compare\r
+#define T1C0_SET_CMP_UP_CLR_0             (0x03 << 3)    // Clear output on compare\r
+#define T1C0_CLR_CMP_UP_SET_0             (0x04 << 3)    // Set output on compare\r
+\r
+#define T1C0_NO_CAP                       (0x00)    // No capture\r
+#define T1C0_RISE_EDGE                    (0x01)    // Capture on rising edge\r
+#define T1C0_FALL_EDGE                    (0x02)    // Capture on falling edge\r
+#define T1C0_BOTH_EDGE                    (0x03)    // Capture on both edges\r
+\r
+\r
+// T1CC0H (0xDB) - Timer 1 Channel 0 Capture/Compare Value High\r
+\r
+// T1CC0L (0xDA) - Timer 1 Channel 0 Capture/Compare Value Low\r
+\r
+// T1CCTL1 (0xE6) - Timer 1 Channel 1 Capture/Compare Control\r
+#define T1CCTL1_CPSEL                     0x80    // Timer 1 channel 1 capture select\r
+#define T1CCTL1_IM                        0x40    // Channel 1 Interrupt mask\r
+#define T1CCTL1_CMP                       0x38\r
+#define T1CCTL1_CMP0                      0x08\r
+#define T1CCTL1_CMP1                      0x10\r
+#define T1CCTL1_CMP2                      0x20\r
+#define T1CCTL1_MODE                      0x04    // Capture or compare mode\r
+#define T1CCTL1_DSM_SPD                   0x04\r
+#define T1CCTL1_CAP                       0x03\r
+#define T1CCTL1_CAP0                      0x01\r
+#define T1CCTL1_CAP1                      0x02\r
+\r
+#define T1C1_SET_ON_CMP                   (0x00 << 3)  // Set output on compare\r
+#define T1C1_CLR_ON_CMP                   (0x01 << 3)  // Clear output on compare\r
+#define T1C1_TOG_ON_CMP                   (0x02 << 3)  // Toggle output on compare\r
+#define T1C1_SET_CMP_UP_CLR_0             (0x03 << 3)  // Set output on compare-up clear on 0\r
+#define T1C1_CLR_CMP_UP_SET_0             (0x04 << 3)  // Clear output on compare-up set on 0\r
+#define T1C1_SET_C1_CLR_C0                (0x05 << 3)  // Set when equal to T1CC1, clear when equal to T1CC0\r
+#define T1C1_CLR_C1_SET_C0                (0x06 << 3)  // Clear when equal to T1CC1, set when equal to T1CC0\r
+#define T1C1_DSM_MODE                     (0x07 << 3)  // DSM mode\r
+\r
+#define T1C1_NO_CAP                       (0x00)     // No capture\r
+#define T1C1_RISE_EDGE                    (0x01)    // Capture on rising edge\r
+#define T1C1_FALL_EDGE                    (0x02)    // Capture on falling edge\r
+#define T1C1_BOTH_EDGE                    (0x03)    // Capture on both edges\r
+\r
+#define DSM_IP_ON_OS_ON                   (0x00)    // Interpolator & output shaping enabled\r
+#define DSM_IP_ON_OS_OFF                  (0x01)    // Interpolator enabled & output shaping disabled\r
+#define DSM_IP_OFF_OS_ON                  (0x02)    // Interpolator disabled & output shaping enabled\r
+#define DSM_IP_OFF_OS_OFF                 (0x03)    // Interpolator & output shaping disabled\r
+\r
+\r
+\r
+// T1CC1H (0xDD) - Timer 1 Channel 1 Capture/Compare Value High\r
+\r
+// T1CC1L (0xDC) - Timer 1 Channel 1 Capture/Compare Value Low\r
+\r
+// T1CCTL2 (0xE7) - Timer 1 Channel 2 Capture/Compare Control\r
+#define T1CCTL2_CPSEL                     0x80    // Timer 1 channel 2 capture select\r
+#define T1CCTL2_IM                        0x40    // Channel 2 Interrupt mask\r
+#define T1CCTL2_CMP                       0x38\r
+#define T1CCTL2_CMP0                      0x08\r
+#define T1CCTL2_CMP1                      0x10\r
+#define T1CCTL2_CMP2                      0x20\r
+#define T1CCTL2_MODE                      0x04    // Capture or compare mode\r
+#define T1CCTL2_CAP                       0x03\r
+#define T1CCTL2_CAP0                      0x01\r
+#define T1CCTL2_CAP1                      0x02\r
+\r
+#define T1C2_SET_ON_CMP                   (0x00 << 3)  // Set output on compare\r
+#define T1C2_CLR_ON_CMP                   (0x01 << 3)  // Clear output on compare\r
+#define T1C2_TOG_ON_CMP                   (0x02 << 3)  // Toggle output on compare\r
+#define T1C2_SET_CMP_UP_CLR_0             (0x03 << 3)  // Set output on compare-up clear on 0\r
+#define T1C2_CLR_CMP_UP_SET_0             (0x04 << 3)  // Clear output on compare-up set on 0\r
+#define T1C2_SET_C2_CLR_C0                (0x05 << 3)  // Set when equal to T1CC2, clear when equal to T1CC0\r
+#define T1C2_CLR_C2_SET_C0                (0x06 << 3)  // Clear when equal to T1CC2, set when equal to T1CC0\r
+\r
+#define T1C2_NO_CAP                       (0x00)     // No capture\r
+#define T1C2_RISE_EDGE                    (0x01)    // Capture on rising edge\r
+#define T1C2_FALL_EDGE                    (0x02)    // Capture on falling edge\r
+#define T1C2_BOTH_EDGE                    (0x03)    // Capture on both edges\r
+\r
+\r
+// T1CC2H (0xDF) - Timer 1 Channel 2 Capture/Compare Value High\r
+\r
+// T1CC2L (0xDE) - Timer 1 Channel 2 Capture/Compare Value Low\r
+\r
+// T2CTL (0x9E) - Timer 2 Control\r
+#define T2CTL_TEX                         0x40\r
+#define T2CTL_INT                         0x10    // Enable Timer 2 interrupt\r
+#define T2CTL_TIG                         0x04    // Tick generator mode\r
+#define T2CTL_TIP                         0x03\r
+#define T2CTL_TIP0                        0x01\r
+#define T2CTL_TIP1                        0x02\r
+\r
+#define T2CTL_TIP_64                      (0x00)\r
+#define T2CTL_TIP_128                     (0x01)\r
+#define T2CTL_TIP_256                     (0x02)\r
+#define T2CTL_TIP_1024                    (0x03)\r
+\r
+\r
+// T2CT (0x9C) - Timer 2 Count\r
+\r
+// T2PR (0x9D) - Timer 2 Prescaler\r
+\r
+// WORTIME0 (0xA5) - Sleep Timer Low Byte\r
+\r
+// WORTIME1 (0xA6) - Sleep Timer High Byte\r
+\r
+// WOREVT1 (0xA4) - Sleep Timer Event0 Timeout High\r
+\r
+// WOREVT0 (0xA3) - Sleep Timer Event0 Timeout Low\r
+\r
+// WORCTL (0xA2) - Sleep Timer Control\r
+#define WORCTL_WOR_RESET                  0x04\r
+#define WORCTL_WOR_RES                    0x03\r
+#define WORCTL_WOR_RES0                   0x01\r
+#define WORCTL_WOR_RES1                   0x02\r
+\r
+#define WORCTL_WOR_RES_1                  (0x00)\r
+#define WORCTL_WOR_RES_32                 (0x01)\r
+#define WORCTL_WOR_RES_1024               (0x02)\r
+#define WORCTL_WOR_RES_32768              (0x03)\r
+\r
+\r
+// WORIRQ (0xA1) - Sleep Timer Interrupt Control\r
+#define WORIRQ_EVENT0_MASK                0x10\r
+#define WORIRQ_EVENT0_FLAG                0x01\r
+\r
+\r
+// T3CNT (0xCA) - Timer 3 Counter\r
+\r
+// T3CTL (0xCB) - Timer 3 Control\r
+#define T3CTL_DIV                         0xE0\r
+#define T3CTL_DIV0                        0x20\r
+#define T3CTL_DIV1                        0x40\r
+#define T3CTL_DIV2                        0x80\r
+#define T3CTL_START                       0x10\r
+#define T3CTL_OVFIM                       0x08\r
+#define T3CTL_CLR                         0x04\r
+#define T3CTL_MODE                        0x03\r
+#define T3CTL_MODE0                       0x01\r
+#define T3CTL_MODE1                       0x02\r
+\r
+#define T3CTL_DIV_1                       (0x00 << 5)\r
+#define T3CTL_DIV_2                       (0x01 << 5)\r
+#define T3CTL_DIV_4                       (0x02 << 5)\r
+#define T3CTL_DIV_8                       (0x03 << 5)\r
+#define T3CTL_DIV_16                      (0x04 << 5)\r
+#define T3CTL_DIV_32                      (0x05 << 5)\r
+#define T3CTL_DIV_64                      (0x06 << 5)\r
+#define T3CTL_DIV_128                     (0x07 << 5)\r
+\r
+#define T3CTL_MODE_FREERUN                (0x00)\r
+#define T3CTL_MODE_DOWN                   (0x01)\r
+#define T3CTL_MODE_MODULO                 (0x02)\r
+#define T3CTL_MODE_UPDOWN                 (0x03)\r
+\r
+\r
+\r
+// T3CCTL0 (0xCC) - Timer 3 Channel 0 Compare Control\r
+#define T3CCTL0_IM                        0x40\r
+#define T3CCTL0_MODE                      0x04\r
+#define T3CCTL0_CMP                       0x38\r
+#define T3CCTL0_CMP0                      0x08\r
+#define T3CCTL0_CMP1                      0x10\r
+#define T3CCTL0_CMP2                      0x20\r
+\r
+#define T3C0_SET_ON_CMP                   (0x00 << 3)  // Set output on compare\r
+#define T3C0_CLR_ON_CMP                   (0x01 << 3)  // Clear output on compare\r
+#define T3C0_TOG_ON_CMP                   (0x02 << 3)  // Toggle output on compare\r
+#define T3C0_SET_CMP_UP_CLR_0             (0x03 << 3)  // Set output on compare-up clear on 0\r
+#define T3C0_CLR_CMP_UP_SET_0             (0x04 << 3)  // Clear output on compare-up set on 0\r
+#define T3C0_SET_CMP_CLR_255              (0x05 << 3)  // Set when equal to T3CC0, clear on 255\r
+#define T3C0_CLR_CMP_SET_0                (0x06 << 3)  // Clear when equal to T3CC0, set on 0\r
+\r
+\r
+\r
+// T3CC0 (0xCD) - Timer 3 Channel 0 Compare Value\r
+\r
+// T3CCTL1 (0xCE) - Timer 3 Channel 1 Compare Control\r
+\r
+#define T3CCTL1_IM                        0x40\r
+#define T3CCTL1_MODE                      0x04\r
+#define T3CCTL1_CMP                       0x38\r
+#define T3CCTL1_CMP0                      0x08\r
+#define T3CCTL1_CMP1                      0x10\r
+#define T3CCTL1_CMP2                      0x20\r
+\r
+#define T3C1_SET_ON_CMP                   (0x00 << 3)  // Set output on compare\r
+#define T3C1_CLR_ON_CMP                   (0x01 << 3)  // Clear output on compare\r
+#define T3C1_TOG_ON_CMP                   (0x02 << 3)  // Toggle output on compare\r
+#define T3C1_SET_CMP_UP_CLR_0             (0x03 << 3)  // Set output on compare-up clear on 0\r
+#define T3C1_CLR_CMP_UP_SET_0             (0x04 << 3)  // Clear output on compare-up set on 0\r
+#define T3C1_SET_CMP_CLR_C0               (0x05 << 3)  // Set when equal to T3CC1, clear when equal to T3CC0\r
+#define T3C1_CLR_CMP_SET_C0               (0x06 << 3)  // Clear when equal to T3CC1, set when equal to T3CC0\r
+\r
+\r
+// T3CC1 (0xCF) - Timer 3 Channel 1 Compare Value\r
+\r
+// T4CNT (0xEA) - Timer 4 Counter\r
+\r
+// T4CTL (0xEB) - Timer 4 Control\r
+#define T4CTL_DIV                         0xE0\r
+#define T4CTL_DIV0                        0x20\r
+#define T4CTL_DIV1                        0x40\r
+#define T4CTL_DIV2                        0x80\r
+#define T4CTL_START                       0x10\r
+#define T4CTL_OVFIM                       0x08\r
+#define T4CTL_CLR                         0x04\r
+#define T4CTL_MODE                        0x03\r
+#define T4CTL_MODE0                       0x01\r
+#define T4CTL_MODE1                       0x02\r
+\r
+#define T4CTL_MODE_FREERUN                (0x00)\r
+#define T4CTL_MODE_DOWN                   (0x01)\r
+#define T4CTL_MODE_MODULO                 (0x02)\r
+#define T4CTL_MODE_UPDOWN                 (0x03)\r
+\r
+#define T4CTL_DIV_1                       (0x00 << 5)\r
+#define T4CTL_DIV_2                       (0x01 << 5)\r
+#define T4CTL_DIV_4                       (0x02 << 5)\r
+#define T4CTL_DIV_8                       (0x03 << 5)\r
+#define T4CTL_DIV_16                      (0x04 << 5)\r
+#define T4CTL_DIV_32                      (0x05 << 5)\r
+#define T4CTL_DIV_64                      (0x06 << 5)\r
+#define T4CTL_DIV_128                     (0x07 << 5)\r
+\r
+\r
+// T4CCTL0 (0xEC) - Timer 4 Channel 0 Compare Control\r
+#define T4CCTL0_IM                        0x40\r
+#define T4CCTL0_CMP                       0x38\r
+#define T4CCTL0_CMP0                      0x08\r
+#define T4CCTL0_CMP1                      0x10\r
+#define T4CCTL0_CMP2                      0x20\r
+#define T4CCTL0_MODE                      0x04\r
+\r
+#define T4CCTL0_SET_ON_CMP                (0x00 << 3)\r
+#define T4CCTL0_CLR_ON_CMP                (0x01 << 3)\r
+#define T4CCTL0_TOG_ON_CMP                (0x02 << 3)\r
+#define T4CCTL0_SET_CMP_UP_CLR_0          (0x03 << 3)\r
+#define T4CCTL0_CLR_CMP_UP_SET_0          (0x04 << 3)\r
+#define T4CCTL0_SET_CMP_CLR_255           (0x05 << 3)\r
+#define T4CCTL0_CLR_CMP_SET_0             (0x06 << 3)\r
+\r
+\r
+// T4CC0 (0xED) - Timer 4 Channel 0 Compare Value\r
+\r
+// T4CCTL1 (0xEE) - Timer 4 Channel 1 Compare Control\r
+#define T4CCTL1_IM                        0x40\r
+#define T4CCTL1_CMP                       0x38\r
+#define T4CCTL1_CMP0                      0x08\r
+#define T4CCTL1_CMP1                      0x10\r
+#define T4CCTL1_CMP2                      0x20\r
+#define T4CCTL1_MODE                      0x04\r
+\r
+#define T4CCTL1_SET_ON_CMP                (0x00 << 3)\r
+#define T4CCTL1_CLR_ON_CMP                (0x01 << 3)\r
+#define T4CCTL1_TOG_ON_CMP                (0x02 << 3)\r
+#define T4CCTL1_SET_CMP_UP_CLR_0          (0x03 << 3)\r
+#define T4CCTL1_CLR_CMP_UP_SET_0          (0x04 << 3)\r
+#define T4CCTL1_SET_CMP_CLR_C0            (0x05 << 3)\r
+#define T4CCTL1_CLR_CMP_SET_C0            (0x06 << 3)\r
+\r
+\r
+// TIMIF (0xD8) - Timers 1/3/4 Interrupt Mask/Flag - bit accessible SFR register\r
+\r
+\r
+/*******************************************************************************\r
+ * ADC\r
+ */\r
+\r
+// ADCL (0xBA) - ADC Data Low (only bit 7-4 used)\r
+\r
+// ADCH (0xBB) - ADC Data High\r
+\r
+// ADCCON1 (0xB4) - ADC Control 1\r
+#define ADCCON1_EOC                       0x80\r
+#define ADCCON1_ST                        0x40\r
+#define ADCCON1_STSEL                     0x30\r
+#define ADCCON1_STSEL0                    0x10\r
+#define ADCCON1_STSEL1                    0x20\r
+#define ADCCON1_RCTRL                     0x0C\r
+#define ADCCON1_RCTRL0                    0x04\r
+#define ADCCON1_RCTRL1                    0x08\r
+\r
+#define STSEL_P2_0                        (0x00 << 4)\r
+#define STSEL_FULL_SPEED                  (0x01 << 4)\r
+#define STSEL_T1C0_CMP_EVT                (0x02 << 4)\r
+#define STSEL_ST                          (0x03 << 4)\r
+\r
+#define ADCCON1_RCTRL_COMPL               (0x00 << 2)\r
+#define ADCCON1_RCTRL_LFSR13              (0x01 << 2)\r
+\r
+\r
+\r
+// ADCCON2 (0xB5) - ADC Control 2\r
+#define ADCCON2_SREF                      0xC0\r
+#define ADCCON2_SREF0                     0x40\r
+#define ADCCON2_SREF1                     0x80\r
+#define ADCCON2_SDIV                      0x30\r
+#define ADCCON2_SDIV0                     0x10\r
+#define ADCCON2_SDIV1                     0x20\r
+#define ADCCON2_SCH                       0x0F\r
+#define ADCCON2_SCH0                      0x01\r
+#define ADCCON2_SCH1                      0x02\r
+#define ADCCON2_SCH2                      0x04\r
+#define ADCCON2_SCH3                      0x08\r
+\r
+#define ADCCON2_SREF_1_25V                (0x00 << 6)\r
+#define ADCCON2_SREF_P0_7                 (0x01 << 6)\r
+#define ADCCON2_SREF_AVDD                 (0x02 << 6)\r
+#define ADCCON2_SREF_P0_6_P0_7            (0x03 << 6)\r
+\r
+#define ADCCON2_SDIV_64                   (0x00 << 4)\r
+#define ADCCON2_SDIV_128                  (0x01 << 4)\r
+#define ADCCON2_SDIV_256                  (0x02 << 4)\r
+#define ADCCON2_SDIV_512                  (0x03 << 4)\r
+\r
+#define ADCCON2_SCH_AIN0                  (0x00)\r
+#define ADCCON2_SCH_AIN1                  (0x01)\r
+#define ADCCON2_SCH_AIN2                  (0x02)\r
+#define ADCCON2_SCH_AIN3                  (0x03)\r
+#define ADCCON2_SCH_AIN4                  (0x04)\r
+#define ADCCON2_SCH_AIN5                  (0x05)\r
+#define ADCCON2_SCH_AIN6                  (0x06)\r
+#define ADCCON2_SCH_AIN7                  (0x07)\r
+#define ADCCON2_SCH_AIN0_1                (0x08)\r
+#define ADCCON2_SCH_AIN2_3                (0x09)\r
+#define ADCCON2_SCH_AIN4_5                (0x0A)\r
+#define ADCCON2_SCH_AIN6_7                (0x0B)\r
+#define ADCCON2_SCH_GND                   (0x0C)\r
+#define ADCCON2_SCH_POSVOL                (0x0D)\r
+#define ADCCON2_SCH_TEMPR                 (0x0E)\r
+#define ADCCON2_SCH_VDD_3                 (0x0F)\r
+\r
+\r
+// ADCCON3 (0xB6) - ADC Control 3\r
+#define ADCCON3_EREF                      0xC0\r
+#define ADCCON3_EREF0                     0x40\r
+#define ADCCON3_EREF1                     0x80\r
+#define ADCCON3_EDIV                      0x30\r
+#define ADCCON3_EDIV0                     0x10\r
+#define ADCCON3_EDIV1                     0x20\r
+#define ADCCON2_ECH                       0x0F\r
+#define ADCCON2_ECH0                      0x01\r
+#define ADCCON2_ECH1                      0x02\r
+#define ADCCON2_ECH2                      0x04\r
+#define ADCCON2_ECH3                      0x08\r
+\r
+#define ADCCON3_EREF_1_25V                (0x00 << 6)\r
+#define ADCCON3_EREF_P0_7                 (0x01 << 6)\r
+#define ADCCON3_EREF_AVDD                 (0x02 << 6)\r
+#define ADCCON3_EREF_P0_6_P0_7            (0x03 << 6)\r
+\r
+#define ADCCON3_EDIV_64                   (0x00 << 4)\r
+#define ADCCON3_EDIV_128                  (0x01 << 4)\r
+#define ADCCON3_EDIV_256                  (0x02 << 4)\r
+#define ADCCON3_EDIV_512                  (0x03 << 4)\r
+\r
+#define ADCCON3_ECH_AIN0                  (0x00)\r
+#define ADCCON3_ECH_AIN1                  (0x01)\r
+#define ADCCON3_ECH_AIN2                  (0x02)\r
+#define ADCCON3_ECH_AIN3                  (0x03)\r
+#define ADCCON3_ECH_AIN4                  (0x04)\r
+#define ADCCON3_ECH_AIN5                  (0x05)\r
+#define ADCCON3_ECH_AIN6                  (0x06)\r
+#define ADCCON3_ECH_AIN7                  (0x07)\r
+#define ADCCON3_ECH_AIN0_1                (0x08)\r
+#define ADCCON3_ECH_AIN2_3                (0x09)\r
+#define ADCCON3_ECH_AIN4_5                (0x0A)\r
+#define ADCCON3_ECH_AIN6_7                (0x0B)\r
+#define ADCCON3_ECH_GND                   (0x0C)\r
+#define ADCCON3_ECH_POSVOL                (0x0D)\r
+#define ADCCON3_ECH_TEMPR                 (0x0E)\r
+#define ADCCON3_ECH_VDD_3                 (0x0F)\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * Random Number Generator\r
+ */\r
+\r
+// RNDL (0xBC) - Random Number Generator Data Low Byte\r
+\r
+// RNDH (0xBD) - Random Number Generator Data High Byte\r
+\r
+\r
+/*******************************************************************************\r
+ * AES\r
+ */\r
+\r
+// ENCCS (0xB3) - Encryption Control and Status\r
+#define ENCCS_MODE                        0x70\r
+#define ENCCS_MODE0                       0x10\r
+#define ENCCS_MODE1                       0x20\r
+#define ENCCS_MODE2                       0x40\r
+#define ENCCS_RDY                         0x08\r
+#define ENCCS_CMD                         0x06\r
+#define ENCCS_CMD0                        0x02\r
+#define ENCCS_CMD1                        0x04\r
+#define ENCCS_ST                          0x01\r
+\r
+#define ENCCS_MODE_CBC                    (0x00 << 4)\r
+#define ENCCS_MODE_CFB                    (0x01 << 4)\r
+#define ENCCS_MODE_OFB                    (0x02 << 4)\r
+#define ENCCS_MODE_CTR                    (0x03 << 4)\r
+#define ENCCS_MODE_ECB                    (0x04 << 4)\r
+#define ENCCS_MODE_CBCMAC                 (0x05 << 4)\r
+\r
+#define ENCCS_CMD_ENC                     (0x00 << 1)\r
+#define ENCCS_CMD_DEC                     (0x01 << 1)\r
+#define ENCCS_CMD_LDKEY                   (0x02 << 1)\r
+#define ENCCS_CMD_LDIV                    (0x03 << 1)\r
+\r
+\r
+// ENCDI (0xB1) - Encryption Input Data\r
+\r
+// ENCDO (0xB2) - Encryption Output Data\r
+\r
+\r
+/*******************************************************************************\r
+ * Watchdog Timer\r
+ */\r
+\r
+// WDCTL (0xC9) - Watchdog Timer Control\r
+#define WDCTL_CLR                         0xF0\r
+#define WDCTL_CLR0                        0x10\r
+#define WDCTL_CLR1                        0x20\r
+#define WDCTL_CLR2                        0x40\r
+#define WDCTL_CLR3                        0x80\r
+#define WDCTL_EN                          0x08\r
+#define WDCTL_MODE                        0x04\r
+#define WDCTL_INT                         0x03\r
+#define WDCTL_INT0                        0x01\r
+#define WDCTL_INT1                        0x02\r
+\r
+\r
+#define WDCTL_INT_SEC_1                   (0x00)\r
+#define WDCTL_INT1_MSEC_250               (0x01)\r
+#define WDCTL_INT2_MSEC_15                (0x02)\r
+#define WDCTL_INT3_MSEC_2                 (0x03)\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * USART\r
+ */\r
+\r
+// U0CSR (0x86) - USART 0 Control and Status\r
+\r
+#define U0CSR_MODE                        0x80\r
+#define U0CSR_RE                          0x40\r
+#define U0CSR_SLAVE                       0x20\r
+#define U0CSR_FE                          0x10\r
+#define U0CSR_ERR                         0x08\r
+#define U0CSR_RX_BYTE                     0x04\r
+#define U0CSR_TX_BYTE                     0x02\r
+#define U0CSR_ACTIVE                      0x01\r
+\r
+\r
+// U0UCR (0xC4) - USART 0 UART Control\r
+#define U0UCR_FLUSH                       0x80\r
+#define U0UCR_FLOW                        0x40\r
+#define U0UCR_D9                          0x20\r
+#define U0UCR_BIT9                        0x10\r
+#define U0UCR_PARITY                      0x08\r
+#define U0UCR_SPB                         0x04\r
+#define U0UCR_STOP                        0x02\r
+#define U0UCR_START                       0x01\r
+\r
+\r
+// U0GCR (0xC5) - USART 0 Generic Control\r
+#define U0GCR_CPOL                        0x80\r
+#define U0GCR_CPHA                        0x40\r
+#define U0GCR_ORDER                       0x20\r
+#define U0GCR_BAUD_E                      0x1F\r
+#define U0GCR_BAUD_E0                     0x01\r
+#define U0GCR_BAUD_E1                     0x02\r
+#define U0GCR_BAUD_E2                     0x04\r
+#define U0GCR_BAUD_E3                     0x08\r
+#define U0GCR_BAUD_E4                     0x10\r
+\r
+\r
+// U0DBUF (0xC1) - USART 0 Receive/Transmit Data Buffer\r
+\r
+// U0BAUD (0xC2) - USART 0 Baud Rate Control\r
+\r
+// U1CSR (0xF8) - USART 1 Control and Status - bit accessible SFR register\r
+#define U1CSR_MODE                        0x80\r
+#define U1CSR_RE                          0x40\r
+#define U1CSR_SLAVE                       0x20\r
+#define U1CSR_FE                          0x10\r
+#define U1CSR_ERR                         0x08\r
+#define U1CSR_RX_BYTE                     0x04\r
+#define U1CSR_TX_BYTE                     0x02\r
+#define U1CSR_ACTIVE                      0x01\r
+\r
+\r
+// U1UCR (0xFB) - USART 1 UART Control\r
+#define U1UCR_FLUSH                       0x80\r
+#define U1UCR_FLOW                        0x40\r
+#define U1UCR_D9                          0x20\r
+#define U1UCR_BIT9                        0x10\r
+#define U1UCR_PARITY                      0x08\r
+#define U1UCR_SPB                         0x04\r
+#define U1UCR_STOP                        0x02\r
+#define U1UCR_START                       0x01\r
+\r
+\r
+// U1GCR (0xFC) - USART 1 Generic Control\r
+#define U1GCR_CPOL                        0x80\r
+#define U1GCR_CPHA                        0x40\r
+#define U1GCR_ORDER                       0x20\r
+#define U1GCR_BAUD_E                      0x1F\r
+#define U1GCR_BAUD_E0                     0x01\r
+#define U1GCR_BAUD_E1                     0x02\r
+#define U1GCR_BAUD_E2                     0x04\r
+#define U1GCR_BAUD_E3                     0x08\r
+#define U1GCR_BAUD_E4                     0x10\r
+\r
+\r
+// U1DBUF (0xF9) - USART 1 Receive/Transmit Data Buffer\r
+\r
+// U1BAUD (0xFA) - USART 1 Baud Rate Control\r
+\r
+\r
+/*******************************************************************************\r
+ * I2S\r
+ */\r
+\r
+// 0xDF40: I2SCFG0 - I2S Configuration Register 0\r
+#define I2SCFG0_TXIEN                     0x80\r
+#define I2SCFG0_RXIEN                     0x40\r
+#define I2SCFG0_ULAWE                     0x20\r
+#define I2SCFG0_ULAWC                     0x10\r
+#define I2SCFG0_TXMONO                    0x08\r
+#define I2SCFG0_RXMONO                    0x04\r
+#define I2SCFG0_MASTER                    0x02\r
+#define I2SCFG0_ENAB                      0x01\r
+\r
+\r
+// 0xDF41: I2SCFG1 - I2S Configuration Register 1\r
+#define I2SCFG1_WORDS                     0xF8\r
+#define I2SCFG1_WORDS0                    0x08\r
+#define I2SCFG1_WORDS1                    0x10\r
+#define I2SCFG1_WORDS2                    0x20\r
+#define I2SCFG1_WORDS3                    0x40\r
+#define I2SCFG1_WORDS4                    0x80\r
+#define I2SCFG1_TRIGNUM                   0x06\r
+#define I2SCFG1_TRIGNUM0                  0x02\r
+#define I2SCFG1_TRIGNUM1                  0x04\r
+#define I2SCFG1_IOLOC                     0x01\r
+\r
+#define I2SCFG1_TRIGNUM_NO_TRIG           (0x00 << 1)\r
+#define I2SCFG1_TRIGNUM_USB_SOF           (0x01 << 1)\r
+#define I2SCFG1_TRIGNUM_IOC_1             (0x02 << 1)\r
+#define I2SCFG1_TRIGNUM_T1_CH0            (0x03 << 1)\r
+\r
+\r
+\r
+// 0xDF42: I2SDATL - I2S Data Low Byte\r
+\r
+// 0xDF43: I2SDATH - I2S Data High Byte\r
+\r
+// 0xDF44: I2SWCNT - I2S Word Count Register\r
+\r
+// 0xDF45: I2SSTAT - I2S Status Register\r
+#define I2SSTAT_TXUNF                     0x80\r
+#define I2SSTAT_RXOVF                     0x40\r
+#define I2SSTAT_TXLR                      0x20\r
+#define I2SSTAT_RXLR                      0x10\r
+#define I2SSTAT_TXIRQ                     0x08\r
+#define I2SSTAT_RXIRQ                     0x04\r
+#define I2SSTAT_WCNT                      0x03\r
+#define I2SSTAT_WCNT0                     0x01\r
+#define I2SSTAT_WCNT1                     0x02\r
+\r
+#define I2SSTAT_WCNT_10BIT                (0x02)\r
+#define I2SSTAT_WCNT_9BIT                 (0x01)\r
+#define I2SSTAT_WCNT_9_10BIT              (0x02)\r
+\r
+\r
+// 0xDF46: I2SCLKF0 - I2S Clock Configuration Register 0\r
+\r
+// 0xDF47: I2SCLKF1 - I2S Clock Configuration Register 1\r
+\r
+// 0xDF48: I2SCLKF2 - I2S Clock Configuration Register 2\r
+\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * Radio Registers\r
+ */\r
+\r
+// RFIF (0xE9) - RF Interrupt Flags\r
+#define RFIF_IRQ_TXUNF                    0x80\r
+#define RFIF_IRQ_RXOVF                    0x40\r
+#define RFIF_IRQ_TIMEOUT                  0x20\r
+#define RFIF_IRQ_DONE                     0x10\r
+#define RFIF_IRQ_CS                       0x08\r
+#define RFIF_IRQ_PQT                      0x04\r
+#define RFIF_IRQ_CCA                      0x02\r
+#define RFIF_IRQ_SFD                      0x01\r
+\r
+\r
+// RFIM (0x91) - RF Interrupt Mask\r
+#define RFIM_IM_TXUNF                     0x80\r
+#define RFIM_IM_RXOVF                     0x40\r
+#define RFIM_IM_TIMEOUT                   0x20\r
+#define RFIM_IM_DONE                      0x10\r
+#define RFIM_IM_CS                        0x08\r
+#define RFIM_IM_PQT                       0x04\r
+#define RFIM_IM_CCA                       0x02\r
+#define RFIM_IM_SFD                       0x01\r
+\r
+\r
+// 0xDF2F: IOCFG2 - Radio Test Signal Configuration (P1_7)\r
+#define IOCFG2_GDO2_INV                   0x40\r
+#define IOCFG2_GDO2_CFG                   0x3F\r
+\r
+\r
+// 0xDF30: IOCFG1 - Radio Test Signal Configuration (P1_6)\r
+#define IOCFG1_GDO_DS                     0x80\r
+#define IOCFG1_GDO1_INV                   0x40\r
+#define IOCFG1_GDO1_CFG                   0x3F\r
+\r
+\r
+// 0xDF31: IOCFG0 - Radio Test Signal Configuration (P1_5)\r
+#define IOCFG0_GDO0_INV                   0x40\r
+#define IOCFG0_GDO0_CFG                   0x3F\r
+\r
+\r
+// 0xDF03: PKTCTRL1 - Packet Automation Control\r
+#define PKTCTRL1_PQT                      0xE0\r
+#define PKTCTRL1_PQT0                     0x20\r
+#define PKTCTRL1_PQT1                     0x40\r
+#define PKTCTRL1_PQT2                     0x80\r
+#define PKTCTRL1_APPEND_STATUS            0x04\r
+#define PKTCTRL1_ADR_CHK                  0x03\r
+#define PKTCTRL1_ADR_CHK0                 0x01\r
+#define PKTCTRL1_ADR_CHK1                 0x02\r
+\r
+#define ADR_CHK_NONE                      (0x00)\r
+#define ADR_CHK_NO_BRDCST                 (0x01)\r
+#define ADR_CHK_0_BRDCST                  (0x02)\r
+#define ADR_CHK_0_255_BRDCST              (0x03)\r
+\r
+\r
+// 0xDF04: PKTCTRL0 - Packet Automation Control\r
+#define PKTCTRL0_WHITE_DATA               0x40\r
+#define PKTCTRL0_PKT_FORMAT               0x30\r
+#define PKTCTRL0_PKT_FORMAT0              0x10\r
+#define PKTCTRL0_PKT_FORMAT1              0x20\r
+#define PKTCTRL0_CC2400_EN                0x08\r
+#define PKTCTRL0_CRC_EN                   0x04\r
+#define PKTCTRL0_LENGTH_CONFIG            0x03\r
+#define PKTCTRL0_LENGTH_CONFIG0           0x01\r
+\r
+#define PKT_FORMAT_NORM                   (0x00)\r
+#define PKT_FORMAT_RAND                   (0x02)\r
+\r
+#define PKTCTRL0_LENGTH_CONFIG_FIX        (0x00)\r
+#define PKTCTRL0_LENGTH_CONFIG_VAR        (0x01)\r
+\r
+\r
+// 0xDF05: ADDR - Device Address\r
+\r
+// 0xDF06: CHANNR - Channel Number\r
+\r
+// 0xDF07: FSCTRL1 - Frequency Synthesizer Control (only bit 0-4 used)\r
+\r
+// 0xDF08: FSCTRL0 - Frequency Synthesizer Control\r
+\r
+// 0xDF09: FREQ2 - Frequency Control Word, High Byte\r
+\r
+// 0xDF0A: FREQ1 - Frequency Control Word, Middle Byte\r
+\r
+// 0xDF0B: FREQ0 - Frequency Control Word, Low Byte\r
+\r
+// 0xDF0C: MDMCFG4 - Modem configuration\r
+\r
+// 0xDF0D: MDMCFG3 - Modem Configuration\r
+\r
+// 0xDF0E: MDMCFG2 - Modem Configuration\r
+#define MDMCFG2_DEM_DCFILT_OFF            0x80\r
+#define MDMCFG2_MOD_FORMAT                0x70\r
+#define MDMCFG2_MOD_FORMAT0               0x10\r
+#define MDMCFG2_MOD_FORMAT1               0x20\r
+#define MDMCFG2_MOD_FORMAT2               0x40\r
+#define MDMCFG2_MANCHESTER_EN             0x08\r
+#define MDMCFG2_SYNC_MODE                 0x07\r
+#define MDMCFG2_SYNC_MODE0                0x01\r
+#define MDMCFG2_SYNC_MODE1                0x02\r
+#define MDMCFG2_SYNC_MODE2                0x04\r
+\r
+#define MOD_FORMAT_2_FSK                  (0x00 << 4)\r
+#define MOD_FORMAT_GFSK                   (0x01 << 4)\r
+#define MOD_FORMAT_MSK                    (0x07 << 4)\r
+\r
+#define SYNC_MODE_NO_PRE                  (0x00)\r
+#define SYNC_MODE_15_16                   (0x01)\r
+#define SYNC_MODE_16_16                   (0x02)\r
+#define SYNC_MODE_30_32                   (0x03)\r
+#define SYNC_MODE_NO_PRE_CS               (0x04)    // CS = carrier-sense above threshold\r
+#define SYNC_MODE_15_16_CS                (0x05)\r
+#define SYNC_MODE_16_16_CS                (0x06)\r
+#define SYNC_MODE_30_32_CS                (0x07)\r
+\r
+\r
+// 0xDF0F: MDMCG1 - Modem Configuration\r
+#define MDMCG1_FEC_EN                     0x80\r
+#define MDMCG1_NUM_PREAMBLE               0x70\r
+#define MDMCG1_NUM_PREAMBLE0              0x10\r
+#define MDMCG1_NUM_PREAMBLE1              0x20\r
+#define MDMCG1_NUM_PREAMBLE2              0x40\r
+#define MDMCG1_CHANSPC_E                  0x03\r
+#define MDMCG1_CHANSPC_E0                 0x01\r
+#define MDMCG1_CHANSPC_E1                 0x02\r
+\r
+#define MDMCG1_NUM_PREAMBLE_2             (0x00 << 4)\r
+#define MDMCG1_NUM_PREAMBLE_3             (0x01 << 4)\r
+#define MDMCG1_NUM_PREAMBLE_4             (0x02 << 4)\r
+#define MDMCG1_NUM_PREAMBLE_6             (0x03 << 4)\r
+#define MDMCG1_NUM_PREAMBLE_8             (0x04 << 4)\r
+#define MDMCG1_NUM_PREAMBLE_12            (0x05 << 4)\r
+#define MDMCG1_NUM_PREAMBLE_16            (0x06 << 4)\r
+#define MDMCG1_NUM_PREAMBLE_24            (0x07 << 4)\r
+\r
+\r
+// 0xDF10: MDMCFG0 - Modem Configuration\r
+\r
+// 0xDF11: DEVIATN - Modem Deviation Setting\r
+#define DEVIATN_DEVIATION_E               0x70\r
+#define DEVIATN_DEVIATION_E0              0x10\r
+#define DEVIATN_DEVIATION_E1              0x20\r
+#define DEVIATN_DEVIATION_E2              0x40\r
+#define DEVIATN_DEVIATION_M               0x07\r
+#define DEVIATN_DEVIATION_M0              0x01\r
+#define DEVIATN_DEVIATION_M1              0x02\r
+#define DEVIATN_DEVIATION_M2              0x04\r
+\r
+\r
+// 0xDF12: MCSM2 - Main Radio Control State Machine Configuration\r
+#define MCSM2_RX_TIME_RSSI                0x10\r
+#define MCSM2_RX_TIME_QUAL                0x08\r
+#define MCSM2_RX_TIME                     0x07\r
+\r
+\r
+// 0xDF13: MCSM1 - Main Radio Control State Machine Configuration\r
+#define MCSM1_CCA_MODE                    0x30\r
+#define MCSM1_CCA_MODE0                   0x10\r
+#define MCSM1_CCA_MODE1                   0x20\r
+#define MCSM1_RXOFF_MODE                  0x0C\r
+#define MCSM1_RXOFF_MODE0                 0x04\r
+#define MCSM1_RXOFF_MODE1                 0x08\r
+#define MCSM1_TXOFF_MODE                  0x03\r
+#define MCSM1_TXOFF_MODE0                 0x01\r
+#define MCSM1_TXOFF_MODE1                 0x02\r
+\r
+#define MCSM1_CCA_MODE_ALWAYS             (0x00 << 4)\r
+#define MCSM1_CCA_MODE_RSSI0              (0x01 << 4)\r
+#define MCSM1_CCA_MODE_PACKET             (0x02 << 4)\r
+#define MCSM1_CCA_MODE_RSSI1              (0x03 << 4)\r
+\r
+#define MCSM1_RXOFF_MODE_IDLE             (0x00 << 2)\r
+#define MCSM1_RXOFF_MODE_FSTXON           (0x01 << 2)\r
+#define MCSM1_RXOFF_MODE_TX               (0x02 << 2)\r
+#define MCSM1_RXOFF_MODE_RX               (0x03 << 2)\r
+\r
+#define MCSM1_TXOFF_MODE_IDLE             (0x00 << 0)\r
+#define MCSM1_TXOFF_MODE_FSTXON           (0x01 << 0)\r
+#define MCSM1_TXOFF_MODE_TX               (0x02 << 0)\r
+#define MCSM1_TXOFF_MODE_RX               (0x03 << 0)\r
+\r
+\r
+// 0xDF14: MCSM0 - Main Radio Control State Machine Configuration\r
+#define MCSM0_FS_AUTOCAL                  0x30\r
+\r
+#define FS_AUTOCAL_NEVER                  (0x00 << 4)\r
+#define FS_AUTOCAL_FROM_IDLE              (0x01 << 4)\r
+#define FS_AUTOCAL_TO_IDLE                (0x02 << 4)\r
+#define FS_AUTOCAL_4TH_TO_IDLE            (0x03 << 4)\r
+\r
+\r
+// 0xDF15: FOCCFG - Frequency Offset Compensation Configuration\r
+#define FOCCFG_FOC_BS_CS_GATE             0x20\r
+#define FOCCFG_FOC_PRE_K                  0x18\r
+#define FOCCFG_FOC_PRE_K0                 0x08\r
+#define FOCCFG_FOC_PRE_K1                 0x10\r
+#define FOCCFG_FOC_POST_K                 0x04\r
+#define FOCCFG_FOC_LIMIT                  0x03\r
+#define FOCCFG_FOC_LIMIT0                 0x01\r
+#define FOCCFG_FOC_LIMIT1                 0x02\r
+\r
+#define FOC_PRE_K_1K                      (0x00 << 3)\r
+#define FOC_PRE_K_2K                      (0x02 << 3)\r
+#define FOC_PRE_K_3K                      (0x03 << 3)\r
+#define FOC_PRE_K_4K                      (0x04 << 3)\r
+\r
+#define FOC_LIMIT_0                       (0x00)\r
+#define FOC_LIMIT_DIV8                    (0x01)\r
+#define FOC_LIMIT_DIV4                    (0x02)\r
+#define FOC_LIMIT_DIV2                    (0x03)\r
+\r
+\r
+// 0xDF16: BSCFG - Bit Synchronization Configuration\r
+#define BSCFG_BS_PRE_KI                   0xC0\r
+#define BSCFG_BS_PRE_KI0                  0x40\r
+#define BSCFG_BS_PRE_KI1                  0x80\r
+#define BSCFG_BS_PRE_KP                   0x30\r
+#define BSCFG_BS_PRE_KP0                  0x10\r
+#define BSCFG_BS_PRE_KP1                  0x20\r
+#define BSCFG_BS_POST_KI                  0x08\r
+#define BSCFG_BS_POST_KP                  0x04\r
+#define BSCFG_BS_LIMIT                    0x03\r
+#define BSCFG_BS_LIMIT0                   0x01\r
+#define BSCFG_BS_LIMIT1                   0x02\r
+\r
+#define BSCFG_BS_PRE_KI_1K                (0x00 << 6)\r
+#define BSCFG_BS_PRE_KI_2K                (0x01 << 6)\r
+#define BSCFG_BS_PRE_KI_3K                (0x02 << 6)\r
+#define BSCFG_BS_PRE_KI_4K                (0x03 << 6)\r
+\r
+#define BSCFG_BS_PRE_KP_1K                (0x00 << 4)\r
+#define BSCFG_BS_PRE_KP_2K                (0x01 << 4)\r
+#define BSCFG_BS_PRE_KP_3K                (0x02 << 4)\r
+#define BSCFG_BS_PRE_KP_4K                (0x03 << 4)\r
+\r
+#define BSCFG_BS_LIMIT_0                  (0x00)\r
+#define BSCFG_BS_LIMIT_3                  (0x01)\r
+#define BSCFG_BS_LIMIT_6                  (0x02)\r
+#define BSCFG_BS_LIMIT_12                 (0x03)\r
+\r
+\r
+// 0xDF17: AGCCTRL2 - AGC Control\r
+#define AGCCTRL2_MAX_DVGA_GAIN            0xC0\r
+#define AGCCTRL2_MAX_LNA_GAIN             0x38\r
+#define AGCCTRL2_MAGN_TARGET              0x07\r
+\r
+\r
+// 0xDF18: AGCCTRL1 - AGC Control\r
+#define AGCCTRL1_AGC_LNA_PRIORITY         0x40\r
+#define AGCCTRL1_CARRIER_SENSE_REL_THR    0x30\r
+#define AGCCTRL1_CARRIER_SENSE_ABS_THR    0x0F\r
+\r
+\r
+// 0xDF19: AGCCTRL0 - AGC Control\r
+#define AGCCTRL0_HYST_LEVEL               0xC0\r
+#define AGCCTRL0_WAIT_TIME                0x30\r
+#define AGCCTRL0_AGC_FREEZE               0x0C\r
+#define AGCCTRL0_FILTER_LENGTH            0x03\r
+\r
+\r
+// 0xDF1A: FREND1 - Front End RX Configuration\r
+#define FREND1_LNA_CURRENT                0xC0\r
+#define FREND1_LNA2MIX_CURRENT            0x30\r
+#define FREND1_LODIV_BUF_CURRENT_RX       0x0C\r
+#define FREND1_MIX_CURRENT                0x03\r
+\r
+\r
+// 0xDF1B: FREND0 - Front End TX Configuration\r
+#define FREND0_LODIV_BUF_CURRENT_TX       0x30\r
+\r
+\r
+// 0xDF1C: FSCAL3 - Frequency Synthesizer Calibration\r
+#define FSCAL3_FSCAL3                     0xC0\r
+#define FSCAL3_CHP_CURR_CAL_EN            0x30\r
+\r
+\r
+// 0xDF1D: FSCAL2 - Frequency Synthesizer Calibration\r
+#define FSCAL2_VCO_CORE_H_EN              0x20\r
+#define FSCAL2_FSCAL2                     0x1F\r
+\r
+\r
+// 0xDF1E: FSCAL1 - Frequency Synthesizer Calibration\r
+\r
+// 0xDF1F: FSCAL0 - Frequency Synthesizer Calibration\r
+\r
+// 0xDF25: TEST0 - Various Test Settings\r
+\r
+\r
+// RFST (0xE1) - RF Strobe Commands\r
+#define RFST_SFSTXON                      0x00\r
+#define RFST_SCAL                         0x01\r
+#define RFST_SRX                          0x02\r
+#define RFST_STX                          0x03\r
+#define RFST_SIDLE                        0x04\r
+#define RFST_SNOP                         0x05\r
+\r
+// 0xDF3B: MARCSTATE - Main Radio Control State Machine State\r
+#define MARCSTATE_MARC_STATE              0x1F\r
+\r
+#define MARC_STATE_SLEEP                  0x00\r
+#define MARC_STATE_IDLE                   0x01\r
+#define MARC_STATE_VCOON_MC               0x03\r
+#define MARC_STATE_REGON_MC               0x04\r
+#define MARC_STATE_MANCAL                 0x05\r
+#define MARC_STATE_VCOON                  0x06\r
+#define MARC_STATE_REGON                  0x07\r
+#define MARC_STATE_STARTCAL               0x08\r
+#define MARC_STATE_BWBOOST                0x09\r
+#define MARC_STATE_FS_LOCK                0x0A\r
+#define MARC_STATE_IFADCON                0x0B\r
+#define MARC_STATE_ENDCAL                 0x0C\r
+#define MARC_STATE_RX                     0x0D\r
+#define MARC_STATE_RX_END                 0x0E\r
+#define MARC_STATE_RX_RST                 0x0F\r
+#define MARC_STATE_TXRX_SWITCH            0x10\r
+#define MARC_STATE_RX_OVERFLOW            0x11\r
+#define MARC_STATE_FSTXON                 0x12\r
+#define MARC_STATE_TX                     0x13\r
+#define MARC_STATE_TX_END                 0x14\r
+#define MARC_STATE_RXTX_SWITCH            0x15\r
+#define MARC_STATE_TX_UNDERFLOW           0x16\r
+\r
+\r
+\r
+/***********************************************************************/\r
+#endif\r
diff --git a/dongle.hex b/dongle.hex
new file mode 100644 (file)
index 0000000..5c869cf
--- /dev/null
@@ -0,0 +1,127 @@
+:040000000200833245
+:01000B0032C2
+:0100130032BA
+:01001B0032B2
+:0100230032AA
+:01002B0032A2
+:01003300329A
+:01003B003292
+:01004300328A
+:03004B000201515E
+:01005300327A
+:01005B003272
+:01006300326A
+:01006B003262
+:01007300325A
+:03007B000201D9A6
+:1000DC00E4F521F522F523F524E4F525F526F5279D
+:1000EC00752800752900752A01752B00E4F52CF58F
+:1000FC002DF52EF52F753000E4F531F532F533750D
+:10010C003506E4F539F53AF53BF53C753D00753EA1
+:04011C000002007E5F
+:05007E0012061E80FEC9
+:1001200053BEFBE5BE30E6FB53C6B8E5C620E6FB92
+:1001300043BE042275E40075DB3275DAC875E50448
+:1001400075E60075E70075E200D2DED2B975E4020B
+:1001500022C020C0E0C0F0C082C083C002C003C083
+:1001600004C005C006C007C000C001C0D075D000E3
+:1001700074012521F521E43522F522E43523F52308
+:10018000E43524F524120327120218D0D0D001D070
+:1001900000D007D006D005D004D003D002D083D041
+:1001A00082D0F0D0E0D0203275860075C22275C5AD
+:1001B0002D228582C1E58630E1FB5386FD85C18213
+:1001C0002243F32843FD505380EBC2EB439A104384
+:1001D0008D0243FE015390FE22C0E0E58A758A003D
+:1001E000D0E032AA827B001AEA600A8B041CECFB86
+:1001F00060F50080F82285820985830A85F00B75F9
+:100200003405850931850A32850B33850836753505
+:100210000075370043900122E535FA24F950012298
+:10022000EA2A2A9002277302023C02026502028730
+:100230000202AE0202EA0203010203017582001209
+:1002400001B2AA82BAFA04753501221534E5346088
+:10025000012275300185213985223A85233B852489
+:100260003C753504227582001201B2AA82BAFB04E1
+:100270007535022275300285213985223A85233B66
+:1002800085243C753504227582001201B2858237BF
+:100290007538005390FEE5376004753503228521DB
+:1002A0003985223A85233B85243C75350422AA38BA
+:1002B0000538EA2531FAE43532FBAC33758200C0EB
+:1002C00002C003C0041201B2AD82D004D003D00238
+:1002D0008A828B838CF0ED1206DAE537B53802801E
+:1002E00005E536B5381B75350622C3E5219539E598
+:1002F00022953AE523953BE524953C400475350568
+:10030000222285820985830A85F00B74FC2508402A
+:1003100003750804850925850A26850B2785082885
+:10032000752B00752A0222E52AFA24F8500122EAE8
+:100330002A2A9003367302034E02036E02036F02F1
+:10034000037E02038B0203950203A20203B4E52B92
+:100350006018C3E521952CE522952DE523952EE522
+:1003600024952F500122752A0122752A0122227418
+:10037000025590FABA0202800122752A0322758280
+:10038000FA1201B285822B752A04227582FB1201B2
+:10039000B2752A05228528821201B2752900752AB4
+:1003A000062274025590FABA02028004752A0722C6
+:1003B000752A0322AA290529EA2525FAE43526FB10
+:1003C000AC278A828B838CF01206F3F5821201B27D
+:1003D000E528B5291874C82521F52CE43522F52D1A
+:1003E000E43523F52EE43524F52F752A0022AA8260
+:1003F000AB83ACF01206F3FD7E0053057FBD010612
+:10040000BE00030204ACBD0205BE00028013BD03A2
+:1004100005BE0002805ABD0505BE0002802102040F
+:10042000AC74012AFDE43BFE8C078D828E838FF035
+:100430001206F360055380BF8072438040806D7563
+:10044000E104758210C002C003C0041201E3D004AD
+:10045000D003D00274012AFDE43BFE8C078D828E0E
+:10046000838FF01206F3FD90DF06F075E103803C08
+:1004700074012AFDE43BFE8C078D828E838FF0127F
+:1004800006F3FE7D0074022AFFE43BF88C018F82A4
+:10049000888389F01206F3FF78004205E842068D52
+:1004A000428E43854282854383E0F53E8A828B8378
+:1004B0008CF01206F3FD30E71C8A828B838CF0747B
+:1004C000011206DAAD3FAE40AF418D828E838FF0D0
+:1004D00074010206DA8A828B838CF0E41206DAAAAF
+:1004E0003FAB40AC418A828B838CF074010206DA08
+:1004F00090DF0074D3F090DF017491F090DF02740C
+:10050000FFF090DF037404F090DF047422F090DFBA
+:1005100005E4F090DF06F090DF077406F090DF0846
+:10052000E4F090DF097421F090DF0A7465F090DF49
+:100530000B746AF090DF0C74F5F090DF0D7483F0AB
+:1005400090DF0E7410F090DF0F7422F090DF1074C3
+:10055000F8F090DF117415F090DF127407F090DF5F
+:10056000137430F090DF147418F090DF157417F0E6
+:1005700090DF16746CF090DF177403F090DF18743E
+:1005800040F090DF197491F090DF1A7456F090DF0C
+:100590001B7410F090DF1C74E9F090DF1D742AF0DA
+:1005A00090DF1EE4F090DF1F741FF090DF2374884B
+:1005B000F090DF247431F090DF257409F090DF278C
+:1005C000E4F090DF28F090DF29F090DF2AF090DF50
+:1005D0002BE4F090DF2CF090DF2DF090DF2E74C232
+:1005E000F090DF2FE4F090DF30F090DF31F090DF1B
+:1005F000367401F090DF377403F090DF38E4F09048
+:10060000DF3974FFF090DF3A7480F090DF3B7401C3
+:10061000F090DF3C7480F090DF3D7494F022120182
+:10062000201201A81201C11201341204F0D2AF75D8
+:10063000440075370185370890004475F040120377
+:100640000274F42521FA74013522FBE43523FCE41D
+:100650003524FD7401B52A02800FC3EA9521EB957C
+:1006600022EC9523ED952450EAE53E600E75440496
+:10067000853E45753702753E008006754400753726
+:1006800001E52B60B075080490004475F04012013C
+:10069000F674F42521FA74013522FBE43523FCE4D9
+:1006A0003524FD7406B5350280187405B535028011
+:1006B000D4C3EA9521EB9522EC9523ED952450E3E4
+:1006C00080C3752B00753F37754000754140900021
+:0A06D0004475F0401203EE020635F7
+:0600B200E478FFF6D8FD22
+:100090007900E94400601B7A00900713780075939B
+:1000A000F0E493F2A308B800020593D9F4DAF275EC
+:0200B00093FFBC
+:1006DA0020F71030F6118883A88220F507F6A88340
+:0906EA0075830022F280F7F02272
+:1000B8007800E84400600A79007593F0E4F309D801
+:1000C800FC7800E84400600C790090F000E4F0A3AC
+:0400D800D8FCD9FA7D
+:0D00830075814712070FE582600302007EC1
+:1006F30020F71430F6148883A88220F507E6A88330
+:1007030075830022E280F7E49322E02275820022BF
+:00000001FF
diff --git a/linux/Makefile b/linux/Makefile
new file mode 100644 (file)
index 0000000..a7bd57c
--- /dev/null
@@ -0,0 +1,11 @@
+TARGET=imme-shell
+
+all: $(TARGET)
+
+$(TARGET): main.o
+       gcc -g -Wall -o $(TARGET) main.c tty_posix.c console.c parse.c -lusb 
+
+clean:
+       rm -fv $(TARGET)
+       rm -f *.o
+
diff --git a/linux/console.c b/linux/console.c
new file mode 100644 (file)
index 0000000..ba6f707
--- /dev/null
@@ -0,0 +1,163 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include "console.h"
+#include "tty_posix.h"
+
+#define CMDBUF_SIZ 255
+
+#if CMDBUF_SIZ > 255
+#error Commands over 255 bytes not supported, change type of cmdbuf_len
+#endif
+
+/**************************************************************/
+
+// CONSOLE_MODE_LINE
+static uint8_t cmdbuf_len; // number of bytes in command buf
+static uint8_t cmdbuf[CMDBUF_SIZ+1];    // null terminator space
+static bool got_line = false;
+
+static void prompt(void)
+{
+    console_puts("> ");
+}
+
+void console_init(void)
+{
+    prompt();
+}
+
+bool console_rx_ready_callback(void)
+{
+    return !got_line;
+}
+
+void console_rx_callback(uint8_t c)
+{
+    if (got_line)   // throw away chars until the line is handled
+        return;
+
+    switch(c)
+    {
+        case 0x0D:
+        //case '\r':
+            got_line = true;
+            console_newline();
+            break;
+        case '\b':  // backspace
+        case 0x7F:  // del
+            if (cmdbuf_len > 0)
+            {
+                cmdbuf_len--;
+                console_putc('\b');
+                console_putc(' ');
+                console_putc('\b');
+            }
+            break;
+        default:
+            if (cmdbuf_len < sizeof(cmdbuf)-1)
+            {
+                console_putc(c);
+                cmdbuf[cmdbuf_len++] = c;
+            }
+            else
+                console_putc('\a');  // bell
+            break;
+    }
+}
+
+void console_tick(void)
+{
+    if (got_line)
+    {
+        if (cmdbuf_len > 0)
+        {
+            cmdbuf[cmdbuf_len] = 0; // terminate it
+            shell_eval((char *)cmdbuf);
+        }
+        cmdbuf_len = 0;
+        prompt();
+        got_line = false;
+    }
+}
+
+void console_putc(uint8_t c)
+{
+    tty_putc(c);
+}
+
+void console_newline(void)
+{
+    console_putc('\r');
+    console_putc('\n');
+}
+
+void console_puts(char *str)
+{
+    while(*str!=0)
+        console_putc(*str++);
+}
+
+static char nibble_to_char(uint8_t nibble)
+{
+    if (nibble < 0xA)
+        return nibble + '0';
+    return nibble - 0xA + 'A';
+}
+
+void console_puthex8(uint8_t h)
+{
+    console_putc(nibble_to_char((h & 0xF0)>>4));
+    console_putc(nibble_to_char(h & 0x0F));
+}
+
+void console_puthex16(uint16_t h)
+{
+    console_puthex8((h & 0xFF00) >> 8);
+    console_puthex8(h & 0xFF);
+}
+
+void console_put0x8(uint8_t h)
+{
+    console_putc('0');
+    console_putc('x');
+    console_puthex8(h);
+}
+
+void console_putsmem(const uint8_t *a, const uint8_t *b)
+{
+    while(a != b)
+    {
+        console_putc(*a);
+        a++;
+    }
+}
+
+void console_putdec(uint32_t n)
+{
+    uint32_t m;
+    bool in_leading_zeroes = true;
+
+    for (m = 1000000000; m != 1; m/=10)
+    {
+        if ((n / m) != 0)
+            in_leading_zeroes = false;
+        if (!in_leading_zeroes)
+            console_putc(nibble_to_char(n / m));
+        n = n % m;
+    }
+    console_putc(nibble_to_char(n));
+}
+
+void console_putbin(uint8_t b)
+{
+    console_putc('b');
+    (b & 0x80) ? console_putc('1') : console_putc('0');
+    (b & 0x40) ? console_putc('1') : console_putc('0');
+    (b & 0x20) ? console_putc('1') : console_putc('0');
+    (b & 0x10) ? console_putc('1') : console_putc('0');
+    (b & 0x08) ? console_putc('1') : console_putc('0');
+    (b & 0x04) ? console_putc('1') : console_putc('0');
+    (b & 0x02) ? console_putc('1') : console_putc('0');
+    (b & 0x01) ? console_putc('1') : console_putc('0');
+}
+
diff --git a/linux/console.h b/linux/console.h
new file mode 100644 (file)
index 0000000..7d2899d
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef CONSOLE_H
+#define CONSOLE_H 1
+
+#include <stdint.h>
+#include <stdbool.h>
+
+void shell_eval(char *cmd);
+
+void console_init(void);
+bool console_rx_ready_callback(void);
+void console_rx_callback(uint8_t c);
+void console_tick(void);
+void console_putc(uint8_t c);
+void console_newline(void);
+void console_puts(char *str);
+void console_puthex8(uint8_t h);
+void console_puthex16(uint16_t h);
+void console_put0x8(uint8_t h);
+void console_putsmem(const uint8_t *a, const uint8_t *b);
+void console_putdec(uint32_t n);
+void console_putbin(uint8_t b);
+
+#endif
diff --git a/linux/main.c b/linux/main.c
new file mode 100644 (file)
index 0000000..a943c1b
--- /dev/null
@@ -0,0 +1,396 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <usb.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "console.h"
+#include "tty_posix.h"
+
+#define IM_VENDOR_ID 0x0e4c
+#define IM_DEVICE_ID 0x7272
+
+//#define DATA_DEBUG 1
+
+static struct usb_device *usb_probe(uint16_t vendor, uint16_t product)
+{
+       struct usb_bus *bus; 
+       struct usb_device *dev; 
+       struct usb_bus *busses; 
+
+       if (NULL == (dev = (struct usb_device*) malloc(sizeof(struct usb_device))))
+        return NULL;
+
+       busses = usb_get_busses(); 
+       for (bus = busses; bus; bus = bus->next)
+    {
+               for (dev = bus->devices; dev; dev = dev->next)
+        {
+                       if ((dev->descriptor.idVendor == vendor) && (dev->descriptor.idProduct == product))
+                               return dev; 
+               }
+       }
+
+    free(dev);
+       return NULL; 
+}
+
+static int sendData(usb_dev_handle *dev_handle, uint8_t *data, int len)
+{
+       int i;
+       int result;
+       uint8_t piece[2];
+
+#ifdef DATA_DEBUG
+    console_puts("TX: ");
+#endif
+
+    // send data
+       for(i=-3; i<len; i++)
+    {
+               piece[0] = i+3;
+
+        if (i == -3)
+            piece[1] = 0xFA;
+        else
+        if (i == -2)
+            piece[1] = 0xFB;
+        else
+        if (i == -1)
+            piece[1] = len;
+        else
+        {
+#ifdef DATA_DEBUG
+            console_puthex8(data[i]);
+            console_putc(' ');
+#endif
+                   piece[1] = data[i];
+        }
+
+               result = usb_control_msg(dev_handle, 0x21, 0x09, 0x0200, 0x00, (char *)piece, 2, 5000);
+               if(result < 0)
+        {
+                       printf("error: %d\n", result);
+            fflush(stdout);
+            break;
+               }
+       }
+#ifdef DATA_DEBUG
+    console_newline();
+#endif
+
+       return result;
+}
+
+#ifdef DATA_DEBUG
+void dump_rx(uint8_t *data, uint8_t len)
+{
+       int i;
+
+    console_puts("RX: ");
+    for (i=0; i<len; i++)
+    {
+        console_puthex8(data[i]);
+        console_putc(' ');
+    }
+    console_newline();
+}
+#endif
+
+int receiveMessage(struct usb_dev_handle *dev_handle, uint8_t *buf, size_t buflen)
+{
+       uint8_t piece[2];
+       bool gotFA = false;
+       bool gotFB = false;
+       bool inMessage = false;
+       int length = 0xFF;
+       int index = 0;
+       int result;
+    
+    while(1)
+    {
+           result = usb_interrupt_read(dev_handle, 0x82, (char *)piece, sizeof(piece), 1000);
+
+        if (-ETIMEDOUT == result)
+            return -2;  // caller should try again
+
+               if(result < 0)
+        {
+                       printf("error: %d\n", result);
+            fflush(stdout);
+            // FIXME
+                       return -1;
+               }
+
+               if(!gotFA && piece[0] != 0xFA)
+        {
+                       //ignore this piece, it's not a message, unlock and start listening again
+            return -1;  // caller should call again
+               }
+        else
+        if (piece[0] == 0xFA)
+                       gotFA = true;
+        else
+        if (piece[0] == 0xFB)
+                       gotFB = true;
+               else
+        if (gotFA && gotFB && !inMessage)
+        {
+                       length = piece[0];
+                       inMessage = true;
+                       index = 0;
+               }
+        else
+               if (inMessage)
+                       buf[index++] = piece[0];
+
+               if (inMessage && (index == length || index == buflen))
+                       return length;
+       }
+       return 0;
+}
+
+static uint8_t cmd_pending[256];
+static uint8_t cmd_pending_len = 0;
+static uint8_t cmd_waitack = 0;
+
+#define MAXARGS 16
+
+
+#define ACK_REQ_FLAG 0x80
+
+enum
+{
+    CMD_NULL,
+    CMD_ACK,
+    CMD_LED,    // followed by one byte boolean
+    CMD_GETREG_REQ,
+    CMD_GETREG_RSP,
+    CMD_SETCHAN
+};  
+
+static bool cmd_led(int argc, char *argv[])
+{
+    int on;
+
+    if (argc < 1)
+        return false;
+
+    on = atoi(argv[0]);
+
+    if (on)
+    {
+        cmd_pending[0] = CMD_LED | ACK_REQ_FLAG;
+        cmd_pending[1] = 0x01;
+        cmd_pending[2] = 0x00;  // padding
+        cmd_pending[3] = 0x00;
+        cmd_pending_len = 4;
+        cmd_waitack = 1;
+    }
+    else
+    {
+        cmd_pending[0] = CMD_LED | ACK_REQ_FLAG;
+        cmd_pending[1] = 0x00;
+        cmd_pending[2] = 0x00;  // padding
+        cmd_pending[3] = 0x00;
+        cmd_pending_len = 4;
+        cmd_waitack = 1;
+    }
+    return true;
+}
+
+static bool cmd_setchan(int argc, char *argv[])
+{
+    uint8_t chan;
+
+    if (argc < 1)
+        return false;
+
+    chan = atoi(argv[0]);
+
+    cmd_pending[0] = CMD_SETCHAN | ACK_REQ_FLAG;
+    cmd_pending[1] = chan;
+    cmd_pending[2] = 0x00;  // padding
+    cmd_pending[3] = 0x00;
+    cmd_pending_len = 4;
+    cmd_waitack = 1;
+    return true;
+}
+
+static bool cmd_getreg(int argc, char *argv[])
+{
+    uint16_t reg;
+
+    if (argc < 1)
+        return false;
+
+    reg = strtol(argv[0], NULL, 16);
+
+    cmd_pending[0] = CMD_GETREG_REQ | ACK_REQ_FLAG;
+    cmd_pending[1] = reg >> 8;
+    cmd_pending[2] = reg & 0xFF;
+    cmd_pending[3] = 0x00;
+    cmd_pending_len = 4;
+    cmd_waitack = 1;
+
+    return true;
+}
+
+static bool handle_cmd(int argc, char *argv[])
+{
+    if (strcmp(argv[0], "exit")==0)
+    {
+        exit(0);
+    }
+    else
+    if (strcmp(argv[0], "led")==0)
+    {
+        return cmd_led(argc-1, argv+1);
+    }
+    else
+    if (strcmp(argv[0], "getreg")==0)
+    {
+        return cmd_getreg(argc-1, argv+1);
+    }
+    else
+    if (strcmp(argv[0], "setchan")==0)
+    {
+        return cmd_setchan(argc-1, argv+1);
+    }
+
+    return false;
+}
+
+void shell_eval(char *cmd)
+{    
+    char *argv[MAXARGS];
+    int argc = 0;
+    char c;
+
+#if 0
+    console_puts(cmd);
+    console_newline();
+#endif
+
+    argv[argc++] = cmd;
+    while ((c = *cmd++) != 0)
+    {
+        if (' ' == c)
+        {
+            *(cmd-1) = 0;
+            argv[argc++] = cmd;
+        }
+    }
+
+    if (!handle_cmd(argc, argv))
+    {
+        console_puts("Bad command");
+        console_newline();
+    }
+}
+
+static void mainloop(struct usb_dev_handle *dev_handle)
+{
+       int count;
+    uint8_t rxbuf[256];
+    uint8_t nullpkt[] = {CMD_NULL, 0, 0, 0};
+
+       while(1)
+    {
+        if (!cmd_waitack)
+        {
+            tty_tick();
+            console_tick();
+        }
+
+        if (cmd_pending_len/* > 0 && !cmd_waitack*/)
+        {
+            sendData(dev_handle, cmd_pending, cmd_pending_len);
+        }
+        else
+        {
+            sendData(dev_handle, nullpkt, sizeof(nullpkt));
+        }
+
+        do
+        {
+            count = receiveMessage(dev_handle, rxbuf, sizeof(rxbuf));
+        }
+        while(count == -1);
+
+        if (count != -2)
+        {
+            if (rxbuf[0] == CMD_ACK)
+            {
+#ifdef DATA_DEBUG
+                console_puts("RX: ACK");
+                console_newline();
+#endif
+                cmd_waitack = 0;
+                cmd_pending_len = 0;
+            }
+            else
+            if (rxbuf[0] == CMD_GETREG_RSP)
+            {
+                console_puts("GETREG_RSP: ");
+                console_puthex8(rxbuf[1]);
+                console_newline();
+            }
+#ifdef DATA_DEBUG
+            else
+            {
+                dump_rx(rxbuf, count);
+            }
+#endif
+        }
+        else
+        {
+            printf("Err -2\n");
+            fflush(stdout);
+        }
+       }
+}
+
+
+int main(int argc, char* argv[])
+{
+    struct usb_device *dev;
+    struct usb_dev_handle *dev_handle;
+
+       usb_init(); 
+       usb_find_busses(); 
+       usb_find_devices(); 
+    
+       usb_set_debug(3);
+       if (NULL == (dev = usb_probe(IM_VENDOR_ID, IM_DEVICE_ID)))
+    {
+        fprintf(stderr, "Failed to find device %04X:%04X\n", IM_VENDOR_ID, IM_DEVICE_ID);
+        return 1;
+    }
+
+    if (NULL == (dev_handle = usb_open(dev)))
+    {
+               fprintf(stderr, "Failed to open device\n");
+               return 1;
+       }
+
+    // try to remove HID driver
+       if (usb_detach_kernel_driver_np(dev_handle, 0))
+               fprintf(stderr, "Failed to detach HID driver, continuing anyway...\n");
+
+       usb_set_configuration(dev_handle, 1);
+       usb_claim_interface(dev_handle, 0);
+
+    tty_init();
+    console_init();
+
+    mainloop(dev_handle);
+
+       usb_close(dev_handle);
+    free(dev);
+
+       return 0;
+}
+
diff --git a/linux/parse.c b/linux/parse.c
new file mode 100644 (file)
index 0000000..ea3d82c
--- /dev/null
@@ -0,0 +1,143 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include "parse.h"
+
+#include <string.h>     /* memcmp */
+
+/*******************************************************************************/
+
+bool memstrcmp(const uint8_t *start, const uint8_t *end, const char *str)
+{
+    uint32_t len = strlen(str);
+
+    if (len != end-start)
+        return false;
+
+    return memcmp(start, str, len) == 0;
+}
+
+
+// hex nibble to int
+static uint8_t digit_to_int(uint8_t ch)
+{
+    uint8_t r;
+    if (ch >= 'a')
+        r = 'a' - 10;
+    else
+    {
+        if (ch >= 'A')
+            r = 'A' - 10;
+        else
+        {
+            if (ch <= '9')
+                r = '0';
+            else
+                r = 0;
+        }
+    }
+
+    return ch - r;
+}
+
+// parse binary, hex and decimal numbers
+bool parse_number(const uint8_t *str, uint8_t len, uint32_t *result)
+{
+    uint8_t base = 10;
+    uint8_t i;
+    uint8_t c;
+    uint8_t digit;
+
+    *result = 0;
+
+    for (i=0;i<len;i++)
+    {
+        c = str[i];
+
+        if (*result == 0)
+        {
+            if ((i == 0 || i == 1) && c == 'b')     // 0b/b for binary
+            {
+                if (len < 2)
+                    return false;
+                base = 2;
+                continue;
+            }
+            else
+            if (i==0 && c == 'h')       // h for hex
+            {
+                if (len < 2)
+                    return false;
+                base = 16;
+                continue;
+            }
+            else
+            if (i == 1 && c == 'x')     // 0x for hex
+            {
+                if (len < 3)
+                    return false;
+                base = 16;
+                continue;
+            }
+        }
+
+        digit = digit_to_int(c);
+
+        if (digit < base)
+            *result = (*result) * base + digit;
+        else
+            return false;
+    }
+    return true;
+}
+
+/*******************************************************************************/
+
+// find the next token in the buffer given by *tok_start to line_end
+// on success, returns true, *tok_start points at first byte of found token, *tok_end points at first character after end of token
+bool tok(uint8_t const **tok_start, uint8_t const **tok_end, const uint8_t *line_end)
+{
+    // skip whitespace on front
+    while(*tok_start != line_end)
+    {
+        if (**tok_start == ' ' || **tok_start == '\t')
+            (*tok_start)++;
+        else
+            break;
+    }
+    // *tok_start is now first non-whitespace character in token
+
+    *tok_end = *tok_start;
+    // skip to end of token
+    while(*tok_end != line_end)
+    {
+        if (**tok_end == ' ' || **tok_end == '\t')
+            break;
+        else
+            (*tok_end)++;
+    }
+    // *tok_end is now first whitespace character after token or line_end
+
+    return *tok_end != *tok_start;
+}
+
+// advance tok_start/tok_end to next token and read number value into i
+bool tok_num(const uint8_t **tok_start, const uint8_t **tok_end, const uint8_t *line_end, uint32_t *i)
+{
+    if (tok(tok_start, tok_end, line_end))
+    {
+        if (parse_number(*tok_start, (*tok_end)-(*tok_start), i))
+        {
+            *tok_start = *tok_end;  // skip past token
+            return true;
+        }
+        else
+        {
+//            *tok_start = *tok_end;  // skip past token
+        }
+    }
+
+    return false;
+}
+
+/*******************************************************************************/
+
diff --git a/linux/parse.h b/linux/parse.h
new file mode 100644 (file)
index 0000000..c4d0b41
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef PARSE_H
+#define PARSE_H 1
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/******************************************************************/
+
+bool parse_number(const uint8_t *str, uint8_t len, uint32_t *result);
+
+/******************************************************************/
+
+bool tok(uint8_t const **tok_start, uint8_t const **tok_end, const uint8_t *line_end);
+bool tok_num(const uint8_t **tok_start, const uint8_t **tok_end, const uint8_t *line_end, uint32_t *i);
+
+bool memstrcmp(const uint8_t *start, const uint8_t *end, const char *str);
+
+#endif
+
+
diff --git a/linux/tty_posix.c b/linux/tty_posix.c
new file mode 100644 (file)
index 0000000..7bd0fdf
--- /dev/null
@@ -0,0 +1,75 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "tty_posix.h"
+#include "console.h"
+
+/**************************************************/
+
+static struct termios orig_termios;
+
+/**************************************************/
+
+static void reset_terminal_mode()
+{
+    tcsetattr(0, TCSANOW, &orig_termios);
+}
+
+static void set_conio_terminal_mode()
+{
+    struct termios new_termios;
+
+    /* take two copies - one for now, one for later */
+    tcgetattr(0, &orig_termios);
+    memcpy(&new_termios, &orig_termios, sizeof(new_termios));
+
+    /* register cleanup handler, and set the new terminal mode */
+    atexit(reset_terminal_mode);
+    cfmakeraw(&new_termios);
+    tcsetattr(0, TCSANOW, &new_termios);
+}
+
+static int kbhit(void)
+{
+    struct timeval tv = { 0L, 0L };
+    fd_set fds;
+    FD_SET(0, &fds);
+    return select(1, &fds, NULL, NULL, &tv);
+}
+
+static int getch(void)
+{
+    int r;
+    unsigned char c;
+    if ((r = read(0, &c, 1)) < 0)
+        return r;
+    else
+        return c;
+}
+
+/**************************************************/
+
+void tty_init(void)
+{
+    set_conio_terminal_mode();
+}
+
+void tty_tick(void)
+{
+    if (console_rx_ready_callback())
+    {
+        if (kbhit())
+            console_rx_callback(getch());
+    }
+}
+
+void tty_putc(char c)
+{
+    write(1, &c, 1);
+}
+
+
+
diff --git a/linux/tty_posix.h b/linux/tty_posix.h
new file mode 100644 (file)
index 0000000..3f8e42d
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef TTY_POSIX
+#define TTY_POSIX 1
+
+void tty_init(void);
+void tty_tick(void);
+void tty_putc(char c);
+
+#endif
+