*.sym
.deps
aclocal.m4
-ao_flight_test
+src/ao_flight_test
+src/ao_gps_test
ao-teledongle.h
ao-telemetrum.h
ao-teleterra.h
ao-tidongle.h
-aoload/aoload
-ccdump/ccdump
-ccmanual/ccmanual
-aoview/Makefile
-aoview/aoview
+ao-tools/ao-bitbang/ao-bitbang
+ao-tools/ao-dbg/ao-dbg
+ao-tools/ao-eeprom/ao-eeprom
+ao-tools/ao-load/ao-load
+ao-tools/ao-rawload/ao-rawload
+ao-view/Makefile
+ao-view/ao-view
autom4te.cache
config.*
config.h
-SUBDIRS=src aoview cctools utils
+SUBDIRS=src ao-view ao-tools ao-utils
--- /dev/null
+SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-load
--- /dev/null
+bin_PROGRAMS=ao-bitbang
+
+AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
+AO_BITBANG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
+
+ao_bitbang_DEPENDENCIES = $(AO_BITBANG_LIBS)
+
+ao_bitbang_LDADD=$(AO_BITBANG_LIBS) $(LIBUSB_LIBS)
+
+ao_bitbang_SOURCES = ao-bitbang.c
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+int
+main (int argc, char **argv)
+{
+ struct ccdbg *dbg;
+
+ dbg = ccdbg_open();
+ if (!dbg)
+ exit (1);
+
+ ccdbg_add_debug(CC_DEBUG_BITBANG);
+
+ ccdbg_manual(dbg, stdin);
+}
--- /dev/null
+bin_PROGRAMS=ao-dbg
+
+AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
+AO_DBG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
+
+man_MANS = ao-dbg.1
+
+ao_dbg_DEPENDENCIES = $(AO_DBG_LIBS)
+
+ao_dbg_LDADD=$(AO_DBG_LIBS) $(LIBUSB_LIBS) -lreadline
+
+ao_dbg_SOURCES = ao-dbg-parse.c ao-dbg-command.c ao-dbg-main.c
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao-dbg.h"
+
+static uint16_t start_address;
+
+static enum command_result
+parse_int(char *value, int *result)
+{
+ char *endptr;
+
+ *result = strtol(value, &endptr, 0);
+ if (endptr == value)
+ return command_syntax;
+ return command_success;
+}
+
+static enum command_result
+parse_uint16(char *value, uint16_t *uint16)
+{
+ int v;
+ enum command_result result;
+
+ result = parse_int(value, &v);
+ if (result != command_success)
+ return command_error;
+ if (v < 0 || v > 0xffff)
+ return command_error;
+ *uint16 = v;
+ return command_success;
+}
+
+static enum command_result
+parse_uint8(char *value, uint8_t *uint8)
+{
+ int v;
+ enum command_result result;
+
+ result = parse_int(value, &v);
+ if (result != command_success)
+ return command_error;
+ if (v < 0 || v > 0xff)
+ return command_error;
+ *uint8 = v;
+ return command_success;
+}
+
+enum command_result
+command_quit (int argc, char **argv)
+{
+ ccdbg_reset(s51_dbg);
+ exit(0);
+ return command_error;
+}
+
+static void
+dump_bytes(uint8_t *memory, int length, uint16_t start, char *format)
+{
+ int group, i;
+
+ for (group = 0; group < length; group += 8) {
+ s51_printf(format, start + group);
+ for (i = group; i < length && i < group + 8; i++)
+ s51_printf("%02x ", memory[i]);
+ for (; i < group + 8; i++)
+ s51_printf(" ");
+ for (i = group; i < length && i < group + 8; i++) {
+ if (isascii(memory[i]) && isprint(memory[i]))
+ s51_printf("%c", memory[i]);
+ else
+ s51_printf(".");
+ }
+ s51_printf("\n");
+ }
+}
+
+enum command_result
+command_di (int argc, char **argv)
+{
+ uint16_t start, end;
+ uint8_t memory[65536];
+ uint8_t status;
+ int length;
+
+ if (argc != 3)
+ return command_error;
+ if (parse_uint16(argv[1], &start) != command_success)
+ return command_error;
+ if (parse_uint16(argv[2], &end) != command_success)
+ return command_error;
+ length = (int) end - (int) start + 1;
+ status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
+ dump_bytes(memory, length, start, "0x%02x ");
+ return command_success;
+}
+
+enum command_result
+command_ds (int argc, char **argv)
+{
+ uint8_t start, end;
+ uint8_t memory[0x100];
+ uint8_t status;
+ int length;
+
+ if (argc != 3)
+ return command_error;
+ if (parse_uint8(argv[1], &start) != command_success)
+ return command_error;
+ if (parse_uint8(argv[2], &end) != command_success)
+ return command_error;
+ length = (int) end - (int) start + 1;
+ status = ccdbg_read_sfr(s51_dbg, start, memory, length);
+ dump_bytes(memory, length, start, "0x%02x ");
+ return command_success;
+}
+
+enum command_result
+command_dx (int argc, char **argv)
+{
+ uint16_t start, end;
+ uint8_t memory[65536];
+ uint8_t status;
+ int length;
+
+ if (argc != 3)
+ return command_error;
+ if (parse_uint16(argv[1], &start) != command_success)
+ return command_error;
+ if (parse_uint16(argv[2], &end) != command_success)
+ return command_error;
+ length = (int) end - (int) start + 1;
+ status = ccdbg_read_memory(s51_dbg, start, memory, length);
+ dump_bytes(memory, length, start, "0x%04x ");
+ return command_success;
+}
+
+enum command_result
+command_set (int argc, char **argv)
+{
+ uint16_t address;
+ uint8_t *data;
+ int len = argc - 3;
+ int i;
+ enum command_result ret = command_success;
+
+ if (len < 0)
+ return command_error;
+ if (parse_uint16(argv[2], &address) != command_success)
+ return command_error;
+ if (len == 0)
+ return command_success;
+ data = malloc(len);
+ if (!data)
+ return command_error;
+ for (i = 0; i < len; i++)
+ if (parse_uint8(argv[i+3], &data[i]) != command_success)
+ return command_error;
+
+ if (strcmp(argv[1], "xram") == 0) {
+ ccdbg_write_memory(s51_dbg, address, data, len);
+ } else if (strcmp(argv[1], "iram") == 0) {
+ ccdbg_write_memory(s51_dbg, address + 0xff00, data, len);
+ } else if (strcmp(argv[1], "sfr") == 0) {
+ ccdbg_write_sfr(s51_dbg, (uint8_t) address, data, len);
+ } else
+ ret = command_error;
+ free(data);
+ return ret;
+}
+
+enum command_result
+command_dump (int argc, char **argv)
+{
+ if (argv[1]) {
+ if (strcmp(argv[1], "rom") == 0 ||
+ strcmp(argv[1], "xram") == 0)
+ return command_dx(argc-1, argv+1);
+ if (strcmp(argv[1], "iram") == 0)
+ return command_di(argc-1, argv+1);
+ if (strcmp(argv[1], "sfr") == 0)
+ return command_ds(argc-1, argv+1);
+ }
+ return command_error;
+}
+
+enum command_result
+command_file (int argc, char **argv)
+{
+ struct hex_file *hex;
+ struct hex_image *image;
+ FILE *file;
+
+ if (argc != 2)
+ return command_error;
+ file = fopen (argv[1], "r");
+ if (!file)
+ return command_error;
+ hex = ccdbg_hex_file_read(file, argv[1]);
+ fclose(file);
+ if (!hex)
+ return command_error;
+ if (hex->nrecord == 0) {
+ ccdbg_hex_file_free(hex);
+ return command_error;
+ }
+ image = ccdbg_hex_image_create(hex);
+ ccdbg_hex_file_free(hex);
+ start_address = image->address;
+ ccdbg_set_rom(s51_dbg, image);
+ return command_success;
+}
+
+enum command_result
+command_pc (int argc, char **argv)
+{
+ uint16_t pc;
+ if (argv[1]) {
+ enum command_result result;
+ result = parse_uint16(argv[1], &pc);
+ if (result != command_success)
+ return result;
+ ccdbg_set_pc(s51_dbg, pc);
+ } else {
+ pc = ccdbg_get_pc(s51_dbg);
+ s51_printf(" 0x%04x 00\n", pc);
+ }
+ return command_success;
+}
+
+struct cc_break {
+ int enabled;
+ int temporary;
+ uint16_t address;
+};
+
+#define CC_NUM_BREAKPOINTS 4
+
+static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
+
+static void
+disable_breakpoint(int b)
+{
+ uint8_t status;
+
+ status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
+ if (status != 0x00 && status != 0xff)
+ s51_printf("disable_breakpoint status 0x%02x\n", status);
+}
+
+static void
+enable_breakpoint(int b)
+{
+ uint8_t status;
+
+ status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
+ if (status != 0xff)
+ s51_printf("enable_breakpoint status 0x%02x\n", status);
+}
+
+static void
+enable_breakpoints(void)
+{
+ int b;
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+ if (breakpoints[b].enabled)
+ enable_breakpoint(b);
+}
+
+enum command_result
+set_breakpoint(uint16_t address, int temporary)
+{
+ int b;
+ uint8_t status;
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
+ if (breakpoints[b].enabled == 0)
+ break;
+ if (breakpoints[b].address == address)
+ break;
+ }
+ if (b == CC_NUM_BREAKPOINTS) {
+ s51_printf("Error: too many breakpoints requested\n");
+ return command_success;
+ }
+ if (breakpoints[b].enabled == 0) {
+ breakpoints[b].address = address;
+ enable_breakpoint(b);
+ }
+ ++breakpoints[b].enabled;
+ s51_printf("Breakpoint %d at 0x%04x\n", b, address);
+ breakpoints[b].temporary += temporary;
+ return command_success;
+}
+
+enum command_result
+clear_breakpoint(uint16_t address, int temporary)
+{
+ int b;
+ uint8_t status;
+
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
+ if (breakpoints[b].enabled != 0 &&
+ ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
+ breakpoints[b].address == address)
+ break;
+ }
+ if (b == CC_NUM_BREAKPOINTS) {
+ s51_printf("Error: no matching breakpoint found\n");
+ return command_success;
+ }
+ --breakpoints[b].enabled;
+ breakpoints[b].temporary -= temporary;
+ if (breakpoints[b].enabled == 0) {
+ disable_breakpoint(b);
+ breakpoints[b].address = -1;
+ }
+ return command_success;
+}
+
+
+int
+find_breakpoint(uint16_t address)
+{
+ int b;
+
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+ if (breakpoints[b].enabled && breakpoints[b].address == address)
+ break;
+ if (b == CC_NUM_BREAKPOINTS)
+ return -1;
+ return b;
+}
+
+enum command_result
+command_break (int argc, char **argv)
+{
+ int b;
+ uint16_t address;
+ enum command_result result;
+
+ if (argc == 1) {
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+ if (breakpoints[b].enabled)
+ s51_printf("Breakpoint %d 0x%04x\n",
+ b, breakpoints[b].address);
+ return command_success;
+ }
+ if (argc != 2)
+ return command_error;
+ result = parse_uint16(argv[1], &address);
+ if (result != command_success)
+ return result;
+
+ return set_breakpoint(address, 0);
+}
+
+enum command_result
+command_clear (int argc, char **argv)
+{
+ int b;
+ uint16_t address;
+ enum command_result result;
+
+ if (argc != 2)
+ return command_error;
+ result = parse_uint16(argv[1], &address);
+ if (result != command_success)
+ return result;
+ return clear_breakpoint(address, 0);
+}
+
+void
+cc_stopped(uint8_t status)
+{
+ uint16_t pc;
+ int b;
+ int code;
+ char *reason;
+
+ pc = ccdbg_get_pc(s51_dbg);
+ if (status & CC_STATUS_CPU_HALTED) {
+ if ((status & CC_STATUS_HALT_STATUS) != 0) {
+ pc = pc - 1;
+ code = 104;
+ reason = "Breakpoint";
+ b = find_breakpoint(pc);
+ if (b != -1 && breakpoints[b].temporary)
+ clear_breakpoint(pc, 1);
+ ccdbg_set_pc(s51_dbg, pc);
+ } else {
+ code = 105;
+ reason = "Interrupt";
+ }
+ s51_printf("Stop at 0x%04x: (%d) %s\n",
+ pc, code, reason);
+ }
+}
+
+uint8_t
+cc_step(uint16_t pc)
+{
+ int b;
+ uint8_t status;
+
+ b = find_breakpoint(pc);
+ if (b != -1)
+ disable_breakpoint(b);
+ status = ccdbg_step_instr(s51_dbg);
+ if (b != -1)
+ enable_breakpoint(b);
+ return status;
+}
+
+enum command_result
+command_run (int argc, char **argv)
+{
+ uint16_t start, end;
+ enum command_result result;
+ uint16_t pc;
+ uint8_t status;
+ int b;
+
+ if (argv[1]) {
+ result = parse_uint16(argv[1], &start);
+ if (result != command_success)
+ return result;
+ if (argv[2]) {
+ result = parse_uint16(argv[2], &end);
+ if (result != command_success)
+ return result;
+ }
+ if (start_address && start == 0) {
+ start = start_address;
+ s51_printf("Starting at 0x%04x\n", start);
+ }
+ ccdbg_set_pc(s51_dbg, start);
+ }
+ else
+ start = ccdbg_get_pc(s51_dbg);
+ s51_printf("Resume at 0x%04x\n", start);
+ pc = start;
+ b = find_breakpoint(pc);
+ if (b != -1) {
+ cc_step(pc);
+ pc = ccdbg_get_pc(s51_dbg);
+ if (find_breakpoint(pc) != -1) {
+ status = ccdbg_read_status(s51_dbg);
+ cc_stopped(status);
+ return command_success;
+ }
+ }
+ ccdbg_resume(s51_dbg);
+ result = cc_wait();
+ return result;
+}
+
+enum command_result
+command_next (int argc, char **argv)
+{
+ return command_step(argc, argv);
+}
+
+enum command_result
+command_step (int argc, char **argv)
+{
+ uint16_t pc;
+ uint8_t opcode;
+ uint8_t a;
+
+ a = cc_step(ccdbg_get_pc(s51_dbg));
+ s51_printf(" ACC= 0x%02x\n", a);
+ pc = ccdbg_get_pc(s51_dbg);
+ ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
+ s51_printf(" ? 0x%04x %02x\n", pc, opcode);
+ return command_success;
+}
+
+enum command_result
+command_load (int argc, char **argv)
+{
+ char *filename = argv[1];
+ FILE *file;
+ struct hex_file *hex;
+ struct hex_image *image;
+
+ if (!filename)
+ return command_error;
+ file = fopen(filename, "r");
+ if (!file) {
+ perror(filename);
+ return command_error;
+ }
+ hex = ccdbg_hex_file_read(file, filename);
+ fclose(file);
+ if (!hex) {
+ return command_error;
+ }
+ image = ccdbg_hex_image_create(hex);
+ ccdbg_hex_file_free(hex);
+ if (!image) {
+ fprintf(stderr, "image create failed\n");
+ return command_error;
+ }
+ if (image->address >= 0xf000) {
+ printf("Loading %d bytes to RAM at 0x%04x\n",
+ image->length, image->address);
+ ccdbg_write_hex_image(s51_dbg, image, 0);
+ } else {
+ fprintf(stderr, "Can only load to RAM\n");
+ }
+ ccdbg_hex_image_free(image);
+ return command_success;
+}
+
+enum command_result
+command_halt (int argc, char **argv)
+{
+ uint16_t pc;
+ ccdbg_halt(s51_dbg);
+ pc = ccdbg_get_pc(s51_dbg);
+ s51_printf("Halted at 0x%04x\n", pc);
+ return command_success;
+}
+
+enum command_result
+command_stop (int argc, char **argv)
+{
+ return command_success;
+}
+
+enum command_result
+command_reset (int argc, char **argv)
+{
+ ccdbg_debug_mode(s51_dbg);
+ ccdbg_halt(s51_dbg);
+ enable_breakpoints();
+ return command_success;
+}
+
+enum command_result
+command_status(int argc, char **argv)
+{
+ uint8_t status;
+
+ status = ccdbg_read_status(s51_dbg);
+ if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
+ s51_printf("\tChip erase in progress\n");
+ if (status & CC_STATUS_PCON_IDLE)
+ s51_printf("\tCPU is idle (clock gated)\n");
+ if (status & CC_STATUS_CPU_HALTED)
+ s51_printf("\tCPU halted\n");
+ else
+ s51_printf("\tCPU running\n");
+ if ((status & CC_STATUS_POWER_MODE_0) == 0)
+ s51_printf("\tPower Mode 1-3 selected\n");
+ if (status & CC_STATUS_HALT_STATUS)
+ s51_printf("\tHalted by software or hw breakpoint\n");
+ else
+ s51_printf("\tHalted by debug command\n");
+ if (status & CC_STATUS_DEBUG_LOCKED)
+ s51_printf("\tDebug interface is locked\n");
+ if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
+ s51_printf("\tOscillators are not stable\n");
+ if (status & CC_STATUS_STACK_OVERFLOW)
+ s51_printf("\tStack overflow\n");
+ return command_success;
+}
+
+static enum command_result
+info_breakpoints(int argc, char **argv)
+{
+ int b;
+ uint16_t address;
+ enum command_result result;
+
+ if (argc == 1) {
+ s51_printf("Num Type Disp Hit Cnt Address What\n");
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+ if (breakpoints[b].enabled) {
+ s51_printf("%-3d fetch %s 1 1 0x%04x uc::disass() unimplemented\n",
+ b,
+ breakpoints[b].temporary ? "del " : "keep",
+ breakpoints[b].address);
+ }
+ return command_success;
+ }
+
+}
+
+static enum command_result
+info_help(int argc, char **argv);
+
+static struct command_function infos[] = {
+ { "breakpoints", "b", info_breakpoints, "[b]reakpoints",
+ "List current breakpoints\n" },
+ { "help", "?", info_help, "help",
+ "Print this list\n" },
+
+ { NULL, NULL, NULL, NULL, NULL },
+};
+
+static enum command_result
+info_help(int argc, char **argv)
+{
+ return command_function_help(infos, argc, argv);
+}
+
+enum command_result
+command_info(int argc, char **argv)
+{
+ struct command_function *func;
+
+ if (argc < 2)
+ return command_error;
+ func = command_string_to_function(infos, argv[1]);
+ if (!func)
+ return command_syntax;
+ return (*func->func)(argc-1, argv+1);
+}
+
+enum command_result
+cc_wait(void)
+{
+ for(;;) {
+ uint8_t status;
+ status = ccdbg_read_status(s51_dbg);
+ if (status & CC_STATUS_CPU_HALTED) {
+ cc_stopped(status);
+ return command_success;
+ }
+ if (s51_interrupted || s51_check_input()) {
+
+ ccdbg_halt(s51_dbg);
+ status = ccdbg_read_status(s51_dbg);
+ cc_stopped(status);
+ return command_interrupt;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao-dbg.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <poll.h>
+
+static int s51_port = 0;
+static char *cpu = "8051";
+static double freq = 11059200;
+char *s51_prompt = "> ";
+struct ccdbg *s51_dbg;
+int s51_interrupted = 0;
+int s51_monitor = 0;
+
+static FILE *s51_input;
+static FILE *s51_output;
+
+static void
+usage(void)
+{
+ fprintf(stderr, "You're doing it wrong.\n");
+ exit(1);
+}
+
+void s51_sigint()
+{
+ s51_interrupted = 1;
+}
+
+int
+main(int argc, char **argv)
+{
+ int flags, opt;
+ char *endptr;
+ struct sigvec vec, ovec;
+
+ while ((opt = getopt(argc, argv, "PVvHhmt:X:c:r:Z:s:S:p:")) != -1) {
+ switch (opt) {
+ case 't':
+ cpu = optarg;
+ break;
+ case 'X':
+ freq = strtod(optarg, &endptr);
+ if (endptr == optarg)
+ usage();
+ if (endptr[0] != '\0') {
+ if (!strcmp(endptr, "k"))
+ freq *= 1000;
+ else if (!strcmp(endptr, "M") )
+ freq *= 1000000;
+ else
+ usage ();
+ }
+ break;
+ case 'c':
+ break;
+ case 'r':
+ case 'Z':
+ s51_port = strtol(optarg, &endptr, 0);
+ if (endptr == optarg || strlen(endptr) != 0)
+ usage();
+ break;
+ case 's':
+ break;
+ case 'S':
+ break;
+ case 'p':
+ s51_prompt = optarg;
+ break;
+ case 'P':
+ s51_prompt = NULL;
+ break;
+ case 'V':
+ break;
+ case 'v':
+ break;
+ case 'H':
+ exit (0);
+ break;
+ case 'h':
+ usage ();
+ break;
+ case 'm':
+ s51_monitor = 1;
+ break;
+ }
+ }
+ if (s51_port) {
+ int l, r, one = 1;
+ int s;
+ struct sockaddr_in in;
+
+ l = socket(AF_INET, SOCK_STREAM, 0);
+ if (l < 0) {
+ perror ("socket");
+ exit(1);
+ }
+ r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
+ if (r) {
+ perror("setsockopt");
+ exit(1);
+ }
+ in.sin_family = AF_INET;
+ in.sin_port = htons(s51_port);
+ in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ r = bind(l, (struct sockaddr *) &in, sizeof (in));
+ if (r) {
+ perror("bind");
+ exit(1);
+ }
+ r = listen(l, 5);
+ if (r) {
+ perror("listen");
+ exit(1);
+ }
+ for (;;) {
+ struct sockaddr_in client_addr;
+ socklen_t client_len = sizeof (struct sockaddr_in);
+
+ s = accept(l, (struct sockaddr *)
+ &client_addr, &client_len);
+ if (s < 0) {
+ perror("accept");
+ exit(1);
+ }
+ s51_input = fdopen(s, "r");
+ s51_output = fdopen(s, "w");
+ if (!s51_input || !s51_output) {
+ perror("fdopen");
+ exit(1);
+ }
+ vec.sv_handler = SIG_IGN;
+ vec.sv_mask = 0;
+ vec.sv_flags = 0;
+ sigvec(SIGINT, &vec, &ovec);
+ command_read();
+ sigvec(SIGINT, &ovec, NULL);
+ fclose(s51_input);
+ fclose(s51_output);
+ }
+ } else {
+ s51_input = stdin;
+ s51_output = stdout;
+ vec.sv_handler = s51_sigint;
+ vec.sv_mask = 0;
+ vec.sv_flags = 0;
+ sigvec(SIGINT, &vec, &ovec);
+ command_read();
+ }
+ exit(0);
+}
+
+void
+s51_printf(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(s51_output, format, ap);
+ if (s51_monitor)
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+}
+
+void
+s51_putc(int c)
+{
+ putc(c, s51_output);
+}
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+int
+s51_read_line(char *line, int len)
+{
+ int ret;
+ if (s51_output == stdout && s51_input == stdin && s51_prompt) {
+ char *r;
+
+ r = readline(s51_prompt);
+ if (r == NULL)
+ return 0;
+ strncpy (line, r, len);
+ line[len-1] = '\0';
+ add_history(r);
+ return 1;
+ } else {
+ if (s51_prompt)
+ s51_printf("%s", s51_prompt);
+ else
+ s51_putc('\0');
+ fflush(s51_output);
+ ret = fgets(line, len, s51_input) != NULL;
+ if (s51_monitor)
+ printf("> %s", line);
+ fflush(stdout);
+ }
+ return ret;
+}
+
+int
+s51_check_input(void)
+{
+ struct pollfd input;
+ int r;
+ int c;
+
+ input.fd = fileno(s51_input);
+ input.events = POLLIN;
+ r = poll(&input, 1, 0);
+ if (r > 0) {
+ char line[256];
+ (void) s51_read_line(line, sizeof (line));
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao-dbg.h"
+
+static struct command_function functions[] = {
+ { "help", "?", command_help, "help", "Print this list\n" },
+ { "quit", "q", command_quit, "[q]uit", "Quit\n" },
+ { "di", "di", command_di, "di <start> <end>",
+ "Dump imem\n" },
+ { "ds", "ds", command_ds, "ds <start> <end>",
+ "Dump sprs\n" },
+ { "dx", "dx", command_dx, "dx <start> <end>",
+ "Dump xaddr\n" },
+ { "set", "t", command_set, "se[t] mem <prefix> <address> <data> ...",
+ "Set mem {xram|rom|iram|sfr}\n"
+ "set bit <addr>\n" },
+ { "dump", "d", command_dump, "[d]ump <prefix> <start> <end>",
+ "Dump {xram|rom|iram|sfr} <start> <end>\n" },
+ { "file", "file", command_file, "file <filename>",
+ "Pretend to load executable from <filename>\n" },
+ { "pc", "p", command_pc, "[p]c [addr]",
+ "Get or set pc value\n" },
+ { "break", "b", command_break,"[b]reak <addr>",
+ "Set break point\n" },
+ { "clear", "c", command_clear,"[c]lear <addr>",
+ "Clear break point\n" },
+ { "run", "r", command_run, "[r]un [start] [stop]",
+ "Run with optional start and temp breakpoint addresses\n" },
+ { "go", "g", command_run, "[g]o [start] [stop]",
+ "Run with optional start and temp breakpoint addresses\n" },
+ { "next", "n", command_next, "[n]ext",
+ "Step over one instruction, past any call\n" },
+ { "step", "s", command_step, "[s]tep",
+ "Single step\n" },
+ { "load", "l", command_load, "[l]oad <file>",
+ "Load a hex file into memory or flash" },
+ { "halt", "h", command_halt, "[h]alt",
+ "Halt the processor\n" },
+ { "reset","res",command_reset, "[res]et",
+ "Reset the CPU\n" },
+ { "status","status",command_status, "status",
+ "Display CC1111 debug status\n" },
+ { "info", "i", command_info, "[i]info",
+ "Get information\n" },
+ { "stop", "stop", command_stop, "stop",
+ "Ignored\n" },
+ { NULL, NULL, NULL, NULL, NULL },
+};
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+static int
+string_to_int(char *s, int *v)
+{
+ char *endptr;
+
+ if (isdigit(s[0]) || s[0] == '-' || s[0] == '+') {
+ *v = strtol(s, &endptr, 0);
+ if (endptr == s)
+ return FALSE;
+ } else if (*s == '\'') {
+ s++;
+ if (*s == '\\') {
+ s++;
+ switch (*s) {
+ case 'n':
+ *v = '\n';
+ break;
+ case 't':
+ *v = '\t';
+ break;
+ default:
+ *v = (int) *s;
+ break;
+ }
+ } else
+ *v = (int) *s;
+ s++;
+ if (*s != '\'')
+ return FALSE;
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+struct command_function *
+command_string_to_function(struct command_function *functions, char *name)
+{
+ int i;
+ for (i = 0; functions[i].name; i++)
+ if (!strcmp(name, functions[i].name) ||
+ !strcmp(name, functions[i].alias))
+ return &functions[i];
+ return NULL;
+}
+
+enum command_result
+command_function_help(struct command_function *functions, int argc, char **argv)
+{
+ int i;
+ struct command_function *func;
+
+ if (argc == 1) {
+ for (i = 0; functions[i].name; i++)
+ s51_printf("%-10s%s\n", functions[i].name,
+ functions[i].usage);
+ } else {
+ for (i = 1; i < argc; i++) {
+ func = command_string_to_function(functions, argv[i]);
+ if (!func) {
+ s51_printf("%-10s unknown command\n", argv[i]);
+ return command_syntax;
+ }
+ s51_printf("%-10s %s\n%s", func->name,
+ func->usage, func->help);
+ }
+ }
+ return command_debug;
+}
+
+static int
+command_split_into_words(char *line, char **argv)
+{
+ char quotechar;
+ int argc;
+
+ argc = 0;
+ while (*line) {
+ while (isspace(*line))
+ line++;
+ if (!*line)
+ break;
+ if (*line == '"') {
+ quotechar = *line++;
+ *argv++ = line;
+ argc++;
+ while (*line && *line != quotechar)
+ line++;
+ if (*line)
+ *line++ = '\0';
+ } else {
+ *argv++ = line;
+ argc++;
+ while (*line && !isspace(*line))
+ line++;
+ if (*line)
+ *line++ = '\0';
+ }
+ }
+ *argv = 0;
+ return argc;
+}
+
+enum command_result
+command_help(int argc, char **argv)
+{
+ return command_function_help(functions, argc, argv);
+}
+
+void
+command_syntax_error(int argc, char **argv)
+{
+ s51_printf("Syntax error in:");
+ while (*argv)
+ s51_printf(" %s", *argv++);
+ s51_printf("\n");
+}
+
+void
+command_read (void)
+{
+ int argc;
+ char line[1024];
+ char *argv[20];
+ enum command_result result;
+ struct command_function *func;
+
+ s51_dbg = ccdbg_open ();
+ if (!s51_dbg) {
+ perror("ccdbg_open");
+ exit(1);
+ }
+ ccdbg_debug_mode(s51_dbg);
+ ccdbg_halt(s51_dbg);
+ s51_printf("Welcome to the non-simulated processor\n");
+ for (;;) {
+ if (s51_read_line (line, sizeof line) == 0)
+ break;
+ s51_interrupted = 0;
+ argc = command_split_into_words(line, argv);
+ if (argc > 0) {
+ func = command_string_to_function(functions, argv[0]);
+ if (!func)
+ command_syntax_error(argc, argv);
+ else
+ {
+ result = (*func->func)(argc, argv);
+ if (s51_interrupted)
+ result = command_interrupt;
+ switch (result) {
+ case command_syntax:
+ command_syntax_error(argc, argv);
+ break;
+ case command_error:
+ s51_printf("Error\n");
+ break;
+ case command_success:
+ break;
+ case command_interrupt:
+ ccdbg_halt(s51_dbg);
+ s51_printf("Interrupted\n");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ ccdbg_close(s51_dbg);
+ s51_printf("...\n");
+}
--- /dev/null
+.\"
+.\" Copyright © 2009 Keith Packard <keithp@keithp.com>
+.\"
+.\" 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.,
+.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+.\"
+.\"
+.TH S51 1 "s51" ""
+.SH NAME
+s51 \- hex debugger for cc1111 processors
+.SH SYNOPSIS
+.B "s51"
+[\-t \fIcpu-type\fP]
+[\-X \fIfrequency\fP]
+[\-c]
+[\-r \fIlisten-port\fP]
+[\-Z \fIlisten-port\fP]
+[\-s]
+[\-S]
+[\-p \fIprompt\fP]
+[\-V]
+[\-v]
+[\-H]
+[\-h]
+[\-m]
+.SH DESCRIPTION
+.I s51
+connects to a cc1111 processor through a cp1203-based USB-to-serial
+converter board, using the GPIO pins available on that chip. It provides an
+interface compatible with the 8051 emulator of the same name (s51), but
+communicating with the real chip instead of an emulation. Using a modified
+version of the SDCC debugger (sdcdb), you can control program execution
+on the target machine at source-level.
+
+.SH OPTIONS
+The command line options are designed to be compatible with the 8051
+emulator so that it can be used with sdcdb. As such, they're all one letter
+long.
+.IP "\-t \fIcpu-type\fP"
+The 8051 emulator can operate as one of several different chips. Oddly, the
+real hardware cannot, so this option is ignored.
+.IP "\-X \fIfrequency\fP"
+Similarly, the emulator can pretend to run at an arbitrary frequency
+which the real hardware cannot do. Ignored.
+.IP "\-c"
+.IP "\-s"
+.IP "\-S"
+.IP "\-v"
+.IP "\-V"
+All ignored.
+.IP "\-r \fIlisten-port\fP, -Z \fIlisten-port\fP"
+The emulator and sdcdb communicate through a network socket. This option
+switches the debugger from communicating through stdin/stdout to listening
+on a specific network port instead. Once a connection is made, the debugger
+continues on, using that network port for command input and output. The
+debugger uses port 9756, and attempts to connect before launching s51, so if
+s51 is listening on this port before sdcdb is started, sdcdb will end up
+talking to the existing s51 instance. That's often useful for debugging s51
+itself.
+.IP "\-p \fIprompt\fP"
+This sets the command prompt to the specified string.
+.IP "\-P"
+This sets the command prompt to a single NUL character. This is for use by
+sdcdb.
+.IP "\-h"
+This should print a usage message, but does nothing useful currently.
+.IP "\-m"
+This option is not present in the original 8051 emulator, and causes s51 to
+dump all commands and replies that are received from and sent to sdcdb.
+.SH COMMANDS
+Once started, s51 connects to the cc1111 via the CP2103 using libusb2 and
+then reads and executes commands, either from stdin, or the nework
+connection to sdcdb.
+.PP
+Unlike the command line, s51 contains built-in help for each of these
+commands, via the 'help' command. Most of the commands are available in a
+long form and a single character short form. Below, the short form follows
+the long form after a comma.
+.IP "help, ? {command}"
+Without arguments, prints a list of available commands. With an argument
+prints more detail about the specific command
+.IP "quit, q"
+Terminates the application, without changing the state of the target
+processor.
+.IP "di [start] [end]"
+Dumps imem (256 bytes of "internal" memory) from start to end (inclusive).
+.IP "ds [start] [end]"
+Dumps sprs from start to end (inclusive). Note that while most sprs are
+visible in the global address space, some are not, so use this command
+instead of "dx" to read them.
+.IP "dx [start] [end]"
+Dump external (global) memory from start to end (inclusive).
+.IP "set, t <prefix> [start] {data ...}"
+Store to the memory space specified by prefix where prefix is one of "xram",
+"rom", "iram", or "sfr". Store bytes starting at start.
+.IP "dump, d <prefix> [start] [end]"
+Dump from the memory space specified by prefix, where prefix is one of
+"xram", "rom", "iram" or "sfr". Dumps from start to end (inclusive).
+.IP "file [filename]"
+Specifies an intel-format hex file (ihx) that contains the contents of the
+rom area loaded into the cc1111. This is used to respond to requests to dump
+rom memory contents without getting them from the cc1111 (which is slow).
+.IP "pc, p {address}"
+If the address argument is given, this sets the program counter to the
+specified value. Otherwise, the current program counter value is displayed.
+.IP "break, b [address]"
+Sets a breakpoint at the specified address. This uses the built-in hardware
+breakpoint support in the cc1111. As a result, it supports no more than four
+breakpoints at once. You must therefore use a modified version of sdcdb which
+changes how program execution is controlled to work within this limit.
+.IP "clear, c [address]"
+Clear a breakpoint from the specified address.
+.IP "run, r, go, g {start} {stop}"
+Resumes execution of the program. If the start argument is present, then it
+begins at that address, otherwise it continues running at the current pc. If
+a stop argument is present, then a temporary breakpoint is set at that
+address. This temporary breakpoint will be removed when execution hits it.
+.IP "next, n"
+Step one instruction. In the original s51 program this would ignore
+subroutines, but as sdcdb doesn't require this functionality, it's not
+available here.
+.IP "step, s"
+Step one instruction.
+.IP "load, l [filename]"
+This is not implemented, but it is supposed to load a hex file into flash.
+Use the ccload program instead.
+.IP "halt, h"
+Halt the processor. This is the only command which can be sent while the
+program is running. It is ignored at other times.
+.IP "reset, res"
+Reset the processor. This pulls the reset pin low and re-enables debug mode.
+Check the cc1111 documentation to see precisely what this does.
+.IP "status"
+This dumps the cc1111 debug status register.
+.IP "info, i breakpoints, b"
+List the current breakpoints.
+.IP "info, i help, ?"
+List the things you can get info on.
+.IP "stop"
+This doesn't do anything and is present only to retain compatibility with
+the original 8051 emulator.
+.SH "BOARD BRINGUP DEBUGGING"
+.PP
+While the original purpose for this program was to connect the source
+debugger with the hardware, it can also be used as a low-level hex debugger
+all on its own. In particular, all of the cc1111 peripherals can be
+manipulated directly from the s51 command line.
+.IP "Starting s51"
+If the CP2103 is plugged in, and the CC1111 is connected correctly, the
+\'s51\' command itself should connect to the device without trouble.
+Note that the CP2103 must have the GPIO pins configured correctly as well.
+.IP
+$ s51
+.br
+Welcome to the non-simulated processor
+.br
+> status
+.br
+ CPU halted
+.br
+ Halted by debug command
+.br
+>
+.IP "Turning on LEDs"
+Two of the cc1111 GPIO pins, P1_0 and P1_1 are capable of driving external
+LEDs. To control these, set the Port 1 direction bits to make these output
+pins and then change the Port 1 data to set them high or low:
+.IP
+> set sfr 0xfe 0x02 # set P1DIR to 0x2
+.br
+> set sfr 0x90 0x02 # set P1_1 to high
+.br
+> set sfr 0x90 0x00 # set P1_1 to low
+.IP "Reading the A/D converters"
+The six A/D converter inputs can each be connected to any of the P0 pins,
+ground, the A/D voltage refernece, an internal temperature sensor or VDD/3.
+To read one of these values, select an A/D converter to use then start the
+conversion process. The cc1111 manual has the table for selecting the input
+on page 144.
+.IP
+To configure one of the P0 pins for use by the A/D unit, we program the
+ADCCFG register, setting the bits in that which match the pins desired:
+.IP
+> set sfr 0xf2 0x3f # enable all 6 A/D inputs
+.IP
+To trigger a single conversion, we ask the A/D unit to perform an 'extra'
+conversion, which means to do a single conversion not a whole sequence of
+conversions. This is controlled by the ADCCON3 register at 0xB6:
+.IP
+> set sfr 0xb6 0xb2 # sample P0_2 using 12 bits of precision
+.br
+> ds 0xba 0xbb # dump the ADC data low and high regs
+.br
+> set sfr 0xb6 0xbe # sample internal temperature sensor
+.br
+> ds 0xba 0xbb # dump the ADC data low and high regs
+.SH "SEE ALSO"
+sdcdb(1), ccload(1)
+.SH AUTHOR
+Keith Packard
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ccdbg.h>
+
+extern char *s51_prompt;
+extern struct ccdbg *s51_dbg;
+extern int s51_interrupted;
+extern int s51_monitor;
+
+enum command_result {
+ command_success, command_debug, command_syntax, command_interrupt, command_error,
+};
+
+struct command_function {
+ char *name;
+ char *alias;
+ enum command_result (*func)(int argc, char **argv);
+ char *usage;
+ char *help;
+};
+
+struct command_function *
+command_string_to_function(struct command_function *functions, char *name);
+
+enum command_result
+command_function_help(struct command_function *functions, int argc, char **argv);
+
+void
+command_syntax_error(int argc, char **argv);
+
+enum command_result
+command_quit (int argc, char **argv);
+
+enum command_result
+command_help (int argc, char **argv);
+
+enum command_result
+command_stop (int argc, char **argv);
+
+enum command_result
+command_di (int argc, char **argv);
+
+enum command_result
+command_ds (int argc, char **argv);
+
+enum command_result
+command_dx (int argc, char **argv);
+
+enum command_result
+command_set (int argc, char **argv);
+
+enum command_result
+command_dump (int argc, char **argv);
+
+enum command_result
+command_file (int argc, char **argv);
+
+enum command_result
+command_pc (int argc, char **argv);
+
+enum command_result
+command_break (int argc, char **argv);
+
+enum command_result
+command_clear (int argc, char **argv);
+
+enum command_result
+command_run (int argc, char **argv);
+
+enum command_result
+command_next (int argc, char **argv);
+
+enum command_result
+command_step (int argc, char **argv);
+
+enum command_result
+command_load (int argc, char **argv);
+
+enum command_result
+command_halt (int argc, char **argv);
+
+enum command_result
+command_reset (int argc, char **argv);
+
+enum command_result
+command_status (int argc, char **argv);
+
+enum command_result
+command_info (int argc, char **argv);
+
+enum command_result
+cc_wait(void);
+
+void
+command_read (void);
+
+void
+s51_printf(char *format, ...);
+
+void
+s51_putc(int c);
+
+int
+s51_check_input(void);
+
+int
+s51_read_line(char *line, int len);
--- /dev/null
+Listens on port 9756 for a command stream.
+
+Dump commands:
+ di <start> <end> - dump imem
+ ds <start> <end> - dump sprs
+ dx <start> <end> - dump xaddr
+
+ Returns a string of hex pairs, each preceded by a space,
+ with 8 pairs per line
+
+Memory access commands:
+ set mem <prefix> <start> <end>
+ dump <prefix> <start> <end>
+
+ <prefix> is one of:
+
+ xram - external ram or external stack
+ rom - code space
+ iram - internal ram or stack
+ sfr - special function register
+
+
+ dump <addr>
+ set bit <addr>
+
+ bit addressable space
+
+Set PC:
+
+ pc <addr>
+
+ Sets PC to specified address
+
+ pc
+
+ Returns current PC
+
+Breakpoints
+
+ break <addr>
+ clear <addr>
+
+Load a file
+
+ file "<filename>"
+
+Execution control:
+
+ run <start> - run starting at <start>
+ run <start> <stop> - set temporary bp at <stop>
+ run - continue
+ next - step over calls(?)
+ step - step one instruction
+
+ reset - reset the simulator
+ res - synonym?
+
+Error messages:
+
+ start with "Error:"
--- /dev/null
+bin_PROGRAMS=ao-eeprom
+
+AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
+AO_EEPROM_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
+
+ao_eeprom_DEPENDENCIES = $(AO_EEPROM_LIBS)
+
+ao_eeprom_LDADD=$(AO_EEPROM_LIBS) $(LIBUSB_LIBS)
+
+ao_eeprom_SOURCES = ao-eeprom.c
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cc-usb.h"
+
+#define NUM_BLOCK 512
+
+int
+main (int argc, char **argv)
+{
+ struct cc_usb *cc;
+ int block;
+ uint8_t bytes[32 * (2 + 8)];
+ uint8_t *b;
+ int i, j;
+ uint32_t addr;
+ char *tty;
+
+ tty = getenv("CCDBG_TTY");
+ cc = cc_usb_open(tty);
+ for (block = 0; block < NUM_BLOCK; block++) {
+ cc_queue_read(cc, bytes, sizeof (bytes));
+ cc_usb_printf(cc, "e %x\n", block);
+ cc_usb_sync(cc);
+ for (i = 0; i < 32; i++) {
+ b = bytes + (i * 10);
+ addr = block * 256 + i * 8;
+ printf ("%06x", addr);
+ for (j = 0; j < 8; j++) {
+ printf (" %02x", b[j+2]);
+ }
+ printf ("\n");
+ }
+ }
+ cc_usb_close(cc);
+ exit (0);
+}
--- /dev/null
+bin_PROGRAMS=ao-load
+
+AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
+AO_LOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
+
+ao_load_DEPENDENCIES = $(AO_LOAD_LIBS)
+
+ao_load_LDADD=$(AO_LOAD_LIBS) $(LIBUSB_LIBS)
+
+ao_load_SOURCES = ao-load.c
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include "ccdbg.h"
+
+#define AO_USB_DESC_STRING 3
+
+void
+usage(char *program)
+{
+ fprintf(stderr, "usage: %s <filename.ihx> <serial>\n", program);
+ exit(1);
+}
+
+struct sym {
+ unsigned addr;
+ char *name;
+} serial_symbols[] = {
+ { 0, "_ao_serial_number" },
+#define AO_SERIAL_NUMBER (serial_symbols[0].addr)
+ { 0, "_ao_usb_descriptors" },
+#define AO_USB_DESCRIPTORS (serial_symbols[1].addr)
+};
+
+#define NUM_SERIAL_SYMBOLS (sizeof(serial_symbols)/sizeof(serial_symbols[0]))
+
+static int
+find_symbols(FILE *map)
+{
+ char line[2048];
+ char *addr, *addr_end;
+ char *name;
+ char *save;
+ char *colon;
+ unsigned long a;
+ int s;
+ int found = 0;
+
+ while (fgets(line, sizeof(line), map) != NULL) {
+ line[sizeof(line)-1] = '\0';
+ addr = strtok_r(line, " \t\n", &save);
+ if (!addr)
+ continue;
+ name = strtok_r(NULL, " \t\n", &save);
+ if (!name)
+ continue;
+ colon = strchr (addr, ':');
+ if (!colon)
+ continue;
+ a = strtoul(colon+1, &addr_end, 16);
+ if (a == ULONG_MAX || addr_end == addr)
+ continue;
+ for (s = 0; s < NUM_SERIAL_SYMBOLS; s++)
+ if (!strcmp(serial_symbols[s].name, name)) {
+ serial_symbols[s].addr = (unsigned) a;
+ ++found;
+ break;
+ }
+ }
+ return found == NUM_SERIAL_SYMBOLS;
+}
+
+static int
+rewrite(struct hex_image *image, unsigned addr, char *data, int len)
+{
+ int i;
+ if (addr < image->address || image->address + image->length < addr + len)
+ return 0;
+ printf("rewrite %04x:", addr);
+ for (i = 0; i < len; i++)
+ printf (" %02x", image->data[addr - image->address + i]);
+ printf(" ->");
+ for (i = 0; i < len; i++)
+ printf (" %02x", data[i]);
+ printf("\n");
+ memcpy(image->data + addr - image->address, data, len);
+}
+
+int
+main (int argc, char **argv)
+{
+ struct ccdbg *dbg;
+ uint8_t status;
+ uint16_t pc;
+ struct hex_file *hex;
+ struct hex_image *image;
+ char *filename;
+ FILE *file;
+ FILE *map;
+ char *serial_string;
+ unsigned int serial;
+ char *mapname, *dot;
+ char *serial_ucs2;
+ int serial_ucs2_len;
+ char serial_int[2];
+ unsigned int s;
+ int i;
+ unsigned usb_descriptors;
+ int string_num;
+
+ filename = argv[1];
+ if (filename == NULL)
+ usage(argv[0]);
+ mapname = strdup(filename);
+ dot = strrchr(mapname, '.');
+ if (!dot || strcmp(dot, ".ihx") != 0)
+ usage(argv[0]);
+ strcpy(dot, ".map");
+
+ serial_string = argv[2];
+ if (serial_string == NULL)
+ usage(argv[0]);
+
+ file = fopen(filename, "r");
+ if (!file) {
+ perror(filename);
+ exit(1);
+ }
+ map = fopen(mapname, "r");
+ if (!map) {
+ perror(mapname);
+ exit(1);
+ }
+ if (!find_symbols(map)) {
+ fprintf(stderr, "Cannot find symbols in \"%s\"\n", mapname);
+ exit(1);
+ }
+ fclose(map);
+
+ hex = ccdbg_hex_file_read(file, filename);
+ fclose(file);
+ if (!hex) {
+ perror(filename);
+ exit (1);
+ }
+ image = ccdbg_hex_image_create(hex);
+ if (!image) {
+ fprintf(stderr, "image create failed\n");
+ exit (1);
+ }
+ ccdbg_hex_file_free(hex);
+
+ serial = strtoul(serial_string, NULL, 0);
+ if (!serial)
+ usage(argv[0]);
+
+ serial_int[0] = serial & 0xff;
+ serial_int[1] = (serial >> 8) & 0xff;
+
+ if (!rewrite(image, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) {
+ fprintf(stderr, "Cannot rewrite serial integer at %04x\n",
+ AO_SERIAL_NUMBER);
+ exit(1);
+ }
+
+ usb_descriptors = AO_USB_DESCRIPTORS - image->address;
+ string_num = 0;
+ while (image->data[usb_descriptors] != 0 && usb_descriptors < image->length) {
+ if (image->data[usb_descriptors+1] == AO_USB_DESC_STRING) {
+ ++string_num;
+ if (string_num == 4)
+ break;
+ }
+ usb_descriptors += image->data[usb_descriptors];
+ }
+ if (usb_descriptors >= image->length || image->data[usb_descriptors] == 0 ) {
+ fprintf(stderr, "Cannot rewrite serial string at %04x\n", AO_USB_DESCRIPTORS);
+ exit(1);
+ }
+
+ serial_ucs2_len = image->data[usb_descriptors] - 2;
+ serial_ucs2 = malloc(serial_ucs2_len);
+ if (!serial_ucs2) {
+ fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len);
+ exit(1);
+ }
+ s = serial;
+ for (i = serial_ucs2_len / 2; i; i--) {
+ serial_ucs2[i * 2 - 1] = 0;
+ serial_ucs2[i * 2 - 2] = (s % 10) + '0';
+ s /= 10;
+ }
+ if (!rewrite(image, usb_descriptors + 2 + image->address, serial_ucs2, serial_ucs2_len))
+ usage(argv[0]);
+
+ dbg = ccdbg_open();
+ if (!dbg)
+ exit (1);
+
+ ccdbg_add_debug(CC_DEBUG_FLASH);
+
+ ccdbg_debug_mode(dbg);
+ ccdbg_halt(dbg);
+ if (image->address == 0xf000) {
+ printf("Loading %d bytes to execute from RAM\n",
+ image->length);
+ ccdbg_write_hex_image(dbg, image, 0);
+ } else if (image->address == 0x0000) {
+ printf("Loading %d bytes to execute from FLASH\n",
+ image->length);
+ ccdbg_flash_hex_image(dbg, image);
+ } else {
+ printf("Cannot load code to 0x%04x\n",
+ image->address);
+ ccdbg_hex_image_free(image);
+ ccdbg_close(dbg);
+ exit(1);
+ }
+ ccdbg_set_pc(dbg, image->address);
+ ccdbg_resume(dbg);
+ ccdbg_close(dbg);
+ exit (0);
+}
--- /dev/null
+bin_PROGRAMS=ao-rawload
+
+AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
+AO_RAWLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
+
+ao_rawload_DEPENDENCIES = $(AO_RAWLOAD_LIBS)
+
+ao_rawload_LDADD=$(AO_RAWLOAD_LIBS) $(LIBUSB_LIBS)
+
+ao_rawload_SOURCES = ao-rawload.c
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+int
+main (int argc, char **argv)
+{
+ struct ccdbg *dbg;
+ uint8_t status;
+ uint16_t pc;
+ struct hex_file *hex;
+ struct hex_image *image;
+ char *filename;
+ FILE *file;
+
+ filename = argv[1];
+ if (filename == NULL) {
+ fprintf(stderr, "usage: %s <filename.ihx>\n", argv[0]);
+ exit(1);
+ }
+ file = fopen(filename, "r");
+ if (!file) {
+ perror(filename);
+ exit(1);
+ }
+ hex = ccdbg_hex_file_read(file, filename);
+ fclose(file);
+ if (!hex)
+ exit (1);
+ image = ccdbg_hex_image_create(hex);
+ if (!image) {
+ fprintf(stderr, "image create failed\n");
+ exit (1);
+ }
+
+ ccdbg_hex_file_free(hex);
+ dbg = ccdbg_open();
+ if (!dbg)
+ exit (1);
+
+ ccdbg_add_debug(CC_DEBUG_FLASH);
+
+ ccdbg_debug_mode(dbg);
+ ccdbg_halt(dbg);
+ if (image->address == 0xf000) {
+ printf("Loading %d bytes to execute from RAM\n",
+ image->length);
+ ccdbg_write_hex_image(dbg, image, 0);
+ } else if (image->address == 0x0000) {
+ printf("Loading %d bytes to execute from FLASH\n",
+ image->length);
+ ccdbg_flash_hex_image(dbg, image);
+ } else {
+ printf("Cannot load code to 0x%04x\n",
+ image->address);
+ ccdbg_hex_image_free(image);
+ ccdbg_close(dbg);
+ exit(1);
+ }
+ ccdbg_set_pc(dbg, image->address);
+ ccdbg_resume(dbg);
+ ccdbg_close(dbg);
+ exit (0);
+}
--- /dev/null
+noinst_LIBRARIES = libao-tools.a
+
+AM_CFLAGS=$(WARN_CFLAGS) $(LIBUSB_CFLAGS)
+
+libao_tools_a_SOURCES = \
+ ccdbg-command.c \
+ ccdbg-debug.c \
+ ccdbg-debug.h \
+ ccdbg-flash.c \
+ ccdbg.h \
+ ccdbg-hex.c \
+ ccdbg-io.c \
+ ccdbg-manual.c \
+ ccdbg-memory.c \
+ ccdbg-rom.c \
+ ccdbg-state.c \
+ cc-usb.c \
+ cc-usb.h \
+ cc-bitbang.c \
+ cc-bitbang.h \
+ cp-usb-async.c \
+ cp-usb-async.h
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "ccdbg-debug.h"
+#include "cc-bitbang.h"
+
+#include "cp-usb-async.h"
+
+struct cc_bitbang {
+ struct cp_usb_async *cp_async;
+};
+
+static uint32_t cc_clock_us = CC_CLOCK_US;
+static uint32_t cc_reset_us = CC_RESET_US;
+
+void
+cc_bitbang_set_clock(uint32_t us)
+{
+ cc_clock_us = us;
+}
+
+void
+cc_bitbang_half_clock(struct cc_bitbang *bb)
+{
+ struct timespec req, rem;
+ req.tv_sec = (cc_clock_us / 2) / 1000000;
+ req.tv_nsec = ((cc_clock_us / 2) % 1000000) * 1000;
+ nanosleep(&req, &rem);
+}
+
+void
+cc_bitbang_wait_reset(struct cc_bitbang *bb)
+{
+ struct timespec req, rem;
+
+ cc_bitbang_sync(bb);
+ req.tv_sec = (cc_reset_us) / 1000000;
+ req.tv_nsec = ((cc_reset_us) % 1000000) * 1000;
+ nanosleep(&req, &rem);
+}
+
+struct cc_bitbang *
+cc_bitbang_open(void)
+{
+ struct cc_bitbang *bb;
+
+ bb = calloc(sizeof (struct cc_bitbang), 1);
+ if (!bb) {
+ perror("calloc");
+ return NULL;
+ }
+ bb->cp_async = cp_usb_async_open();
+ if (!bb->cp_async) {
+ free (bb);
+ return NULL;
+ }
+ return bb;
+}
+
+void
+cc_bitbang_close(struct cc_bitbang *bb)
+{
+ cp_usb_async_close(bb->cp_async);
+ free (bb);
+}
+
+void
+cc_bitbang_debug_mode(struct cc_bitbang *bb)
+{
+ /* force two rising clocks while holding RESET_N low */
+ ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
+ ccdbg_debug(CC_DEBUG_COMMAND, "# Debug mode\n");
+ ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA );
+ cc_bitbang_wait_reset(bb);
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA );
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N);
+ cc_bitbang_wait_reset(bb);
+}
+
+void
+cc_bitbang_reset(struct cc_bitbang *bb)
+{
+ ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
+ ccdbg_debug(CC_DEBUG_COMMAND, "# Reset\n");
+ ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
+ cc_bitbang_wait_reset(bb);
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
+ cc_bitbang_wait_reset(bb);
+}
+
+int
+cc_bitbang_write(struct cc_bitbang *bb, uint8_t mask, uint8_t value)
+{
+ cp_usb_async_write(bb->cp_async, mask, value);
+ return 0;
+}
+
+void
+cc_bitbang_read(struct cc_bitbang *bb, uint8_t *valuep)
+{
+ cp_usb_async_read(bb->cp_async, valuep);
+}
+
+void
+cc_bitbang_sync(struct cc_bitbang *bb)
+{
+ cp_usb_async_sync(bb->cp_async);
+}
+
+static char
+is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit)
+{
+ if (mask&bit) {
+ if (get&bit)
+ return on;
+ else
+ return '.';
+ } else
+ return '-';
+}
+
+void
+cc_bitbang_print(char *format, uint8_t mask, uint8_t set)
+{
+ ccdbg_debug (CC_DEBUG_BITBANG, format,
+ is_bit(set, mask, 'C', CC_CLOCK),
+ is_bit(set, mask, 'D', CC_DATA),
+ is_bit(set, mask, 'R', CC_RESET_N));
+}
+
+void
+cc_bitbang_send(struct cc_bitbang *bb, uint8_t mask, uint8_t set)
+{
+ cc_bitbang_write(bb, mask, set);
+ cc_bitbang_print("%c %c %c\n", mask, set);
+ cc_bitbang_half_clock(bb);
+}
+
+void
+cc_bitbang_send_bit(struct cc_bitbang *bb, uint8_t bit)
+{
+ if (bit) bit = CC_DATA;
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|bit|CC_RESET_N);
+ cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, bit|CC_RESET_N);
+}
+
+void
+cc_bitbang_send_byte(struct cc_bitbang *bb, uint8_t byte)
+{
+ int bit;
+ ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Send Byte 0x%02x\n#\n", byte);
+ for (bit = 7; bit >= 0; bit--) {
+ cc_bitbang_send_bit(bb, (byte >> bit) & 1);
+ if (bit == 3)
+ ccdbg_debug(CC_DEBUG_BITBANG, "\n");
+ }
+ cc_bitbang_sync(bb);
+}
+
+void
+cc_bitbang_send_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes)
+{
+ while (nbytes--)
+ cc_bitbang_send_byte(bb, *bytes++);
+}
+
+void
+cc_bitbang_recv_bit(struct cc_bitbang *bb, int first, uint8_t *bit)
+{
+ uint8_t mask = first ? CC_DATA : 0;
+
+ cc_bitbang_send(bb, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
+ cc_bitbang_read(bb, bit);
+ cc_bitbang_send(bb, CC_CLOCK| CC_RESET_N, CC_RESET_N);
+}
+
+void
+cc_bitbang_recv_byte(struct cc_bitbang *bb, int first, uint8_t *bytep)
+{
+ uint8_t byte = 0;
+ uint8_t bits[8];
+ int bit;
+
+ ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n");
+ for (bit = 0; bit < 8; bit++) {
+ cc_bitbang_recv_bit(bb, first, &bits[bit]);
+ first = 0;
+ }
+ cc_bitbang_sync(bb);
+ for (bit = 0; bit < 8; bit++) {
+ byte = byte << 1;
+ byte |= (bits[bit] & CC_DATA) ? 1 : 0;
+ cc_bitbang_print("#\t%c %c %c\n", CC_DATA, bits[bit]);
+ if (bit == 3)
+ ccdbg_debug(CC_DEBUG_BITBANG, "\n");
+ }
+ ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte);
+ *bytep = byte;
+}
+
+void
+cc_bitbang_recv_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes)
+{
+ int i;
+ int first = 1;
+ for (i = 0; i < nbytes; i++) {
+ cc_bitbang_recv_byte(bb, first, &bytes[i]);
+ first = 0;
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _CC_BITBANG_H_
+#define _CC_BITBANG_H_
+
+#include <stdint.h>
+
+#define CC_CLOCK 0x1
+#define CC_DATA 0x2
+#define CC_RESET_N 0x4
+#define CC_CLOCK_US (2)
+
+/* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground
+ * and a 2.7k resistor to the reset line. This takes about 6us
+ * to settle, so we'll wait longer than that after changing the reset line
+ */
+#define CC_RESET_US (12)
+
+struct cc_bitbang;
+
+void
+cc_bitbang_set_clock(uint32_t us);
+
+void
+cc_bitbang_half_clock(struct cc_bitbang *bb);
+
+void
+cc_bitbang_wait_reset(struct cc_bitbang *bb);
+
+struct cc_bitbang *
+cc_bitbang_open(void);
+
+void
+cc_bitbang_close(struct cc_bitbang *bb);
+
+void
+cc_bitbang_debug_mode(struct cc_bitbang *bb);
+
+void
+cc_bitbang_reset(struct cc_bitbang *bb);
+
+int
+cc_bitbang_write(struct cc_bitbang *bb, uint8_t mask, uint8_t value);
+
+void
+cc_bitbang_read(struct cc_bitbang *bb, uint8_t *valuep);
+
+void
+cc_bitbang_sync(struct cc_bitbang *bb);
+
+void
+cc_bitbang_print(char *format, uint8_t mask, uint8_t set);
+
+void
+cc_bitbang_print(char *format, uint8_t mask, uint8_t set);
+
+void
+cc_bitbang_send(struct cc_bitbang *bb, uint8_t mask, uint8_t set);
+
+void
+cc_bitbang_send_bit(struct cc_bitbang *bb, uint8_t bit);
+
+void
+cc_bitbang_send_byte(struct cc_bitbang *bb, uint8_t byte);
+
+void
+cc_bitbang_send_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes);
+
+void
+cc_bitbang_recv_bit(struct cc_bitbang *bb, int first, uint8_t *bit);
+
+void
+cc_bitbang_recv_byte(struct cc_bitbang *bb, int first, uint8_t *bytep);
+
+void
+cc_bitbang_recv_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes);
+
+#endif /* _CC_BITBANG_H_ */
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <termios.h>
+#include "ccdbg-debug.h"
+#include "cc-usb.h"
+
+
+#define CC_NUM_READ 16
+/*
+ * AltOS has different buffer sizes for in/out packets
+ */
+#define CC_IN_BUF 256
+#define CC_OUT_BUF 64
+#define DEFAULT_TTY "/dev/ttyACM0"
+
+struct cc_read {
+ uint8_t *buf;
+ int len;
+};
+
+struct cc_usb {
+ int fd;
+ uint8_t in_buf[CC_IN_BUF];
+ int in_count;
+ uint8_t out_buf[CC_OUT_BUF];
+ int out_count;
+ struct cc_read read_buf[CC_NUM_READ];
+ int read_count;
+};
+
+#define NOT_HEX 0xff
+
+static uint8_t
+cc_hex_nibble(uint8_t c)
+{
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ return NOT_HEX;
+}
+
+/*
+ * Take raw input bytes, parse them as hex
+ * and write them to the waiting buffer
+ */
+static void
+cc_handle_in(struct cc_usb *cc)
+{
+ uint8_t h, l;
+ int in_pos;
+ int read_pos;
+
+ in_pos = 0;
+ read_pos = 0;
+ while (read_pos < cc->read_count && in_pos < cc->in_count) {
+ /*
+ * Skip to next hex character
+ */
+ while (in_pos < cc->in_count &&
+ cc_hex_nibble(cc->in_buf[in_pos]) == NOT_HEX)
+ in_pos++;
+ /*
+ * Make sure we have two characters left
+ */
+ if (cc->in_count - in_pos < 2)
+ break;
+ /*
+ * Parse hex number
+ */
+ h = cc_hex_nibble(cc->in_buf[in_pos]);
+ l = cc_hex_nibble(cc->in_buf[in_pos+1]);
+ if (h == NOT_HEX || l == NOT_HEX) {
+ fprintf(stderr, "hex read error\n");
+ break;
+ }
+ in_pos += 2;
+ /*
+ * Store hex number
+ */
+ *cc->read_buf[read_pos].buf++ = (h << 4) | l;
+ if (--cc->read_buf[read_pos].len <= 0)
+ read_pos++;
+ }
+
+ /* Move remaining bytes to the start of the input buffer */
+ if (in_pos) {
+ memmove(cc->in_buf, cc->in_buf + in_pos,
+ cc->in_count - in_pos);
+ cc->in_count -= in_pos;
+ }
+
+ /* Move pending reads to the start of the array */
+ if (read_pos) {
+ memmove(cc->read_buf, cc->read_buf + read_pos,
+ (cc->read_count - read_pos) * sizeof (cc->read_buf[0]));
+ cc->read_count -= read_pos;
+ }
+
+ /* Once we're done reading, flush any pending input */
+ if (cc->read_count == 0)
+ cc->in_count = 0;
+}
+
+static void
+cc_usb_dbg(int indent, uint8_t *bytes, int len)
+{
+ int eol = 1;
+ int i;
+ uint8_t c;
+ while (len--) {
+ c = *bytes++;
+ if (eol) {
+ for (i = 0; i < indent; i++)
+ ccdbg_debug(CC_DEBUG_BITBANG, " ");
+ eol = 0;
+ }
+ switch (c) {
+ case '\r':
+ ccdbg_debug(CC_DEBUG_BITBANG, "^M");
+ break;
+ case '\n':
+ eol = 1;
+ default:
+ ccdbg_debug(CC_DEBUG_BITBANG, "%c", c);
+ }
+ }
+}
+
+/*
+ * Flush pending writes, fill pending reads
+ */
+void
+cc_usb_sync(struct cc_usb *cc)
+{
+ int ret;
+ struct pollfd fds;
+ int timeout;
+
+ fds.fd = cc->fd;
+ for (;;) {
+ if (cc->read_count || cc->out_count)
+ timeout = -1;
+ else
+ timeout = 0;
+ fds.events = 0;
+ if (cc->in_count < CC_IN_BUF)
+ fds.events |= POLLIN;
+ if (cc->out_count)
+ fds.events |= POLLOUT;
+ ret = poll(&fds, 1, timeout);
+ if (ret == 0)
+ break;
+ if (ret < 0) {
+ perror("poll");
+ break;
+ }
+ if (fds.revents & POLLIN) {
+ ret = read(cc->fd, cc->in_buf + cc->in_count,
+ CC_IN_BUF - cc->in_count);
+ if (ret > 0) {
+ cc_usb_dbg(24, cc->in_buf + cc->in_count, ret);
+ cc->in_count += ret;
+ cc_handle_in(cc);
+ } else if (ret < 0)
+ perror("read");
+ }
+ if (fds.revents & POLLOUT) {
+ ret = write(cc->fd, cc->out_buf,
+ cc->out_count);
+ if (ret > 0) {
+ cc_usb_dbg(0, cc->out_buf, ret);
+ memmove(cc->out_buf,
+ cc->out_buf + ret,
+ cc->out_count - ret);
+ cc->out_count -= ret;
+ } else if (ret < 0)
+ perror("write");
+ }
+ }
+}
+
+void
+cc_usb_printf(struct cc_usb *cc, char *format, ...)
+{
+ char buf[1024], *b;
+ va_list ap;
+ int ret, this_time;
+
+ /* sprintf to a local buffer */
+ va_start(ap, format);
+ ret = vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+ if (ret > sizeof(buf)) {
+ fprintf(stderr, "printf overflow for format %s\n",
+ format);
+ }
+
+ /* flush local buffer to the wire */
+ b = buf;
+ while (ret > 0) {
+ this_time = ret;
+ if (this_time > CC_OUT_BUF - cc->out_count)
+ this_time = CC_OUT_BUF - cc->out_count;
+ memcpy(cc->out_buf + cc->out_count, b, this_time);
+ cc->out_count += this_time;
+ ret -= this_time;
+ b += this_time;
+ while (cc->out_count >= CC_OUT_BUF)
+ cc_usb_sync(cc);
+ }
+}
+
+int
+cc_usb_send_bytes(struct cc_usb *cc, uint8_t *bytes, int len)
+{
+ int this_len;
+ int ret = len;
+
+ while (len) {
+ this_len = len;
+ if (this_len > 8)
+ this_len = 8;
+ len -= this_len;
+ cc_usb_printf(cc, "P");
+ while (this_len--)
+ cc_usb_printf (cc, " %02x", (*bytes++) & 0xff);
+ cc_usb_printf(cc, "\n");
+ }
+ return ret;
+}
+
+void
+cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len)
+{
+ struct cc_read *read_buf;
+ while (cc->read_count >= CC_NUM_READ)
+ cc_usb_sync(cc);
+ read_buf = &cc->read_buf[cc->read_count++];
+ read_buf->buf = buf;
+ read_buf->len = len;
+}
+
+int
+cc_usb_recv_bytes(struct cc_usb *cc, uint8_t *buf, int len)
+{
+ cc_queue_read(cc, buf, len);
+ cc_usb_printf(cc, "G %x\n", len);
+ return len;
+}
+
+int
+cc_usb_write_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len)
+{
+ cc_usb_printf(cc, "O %x %x\n", len, addr);
+ while (len--)
+ cc_usb_printf(cc, "%02x", *bytes++);
+ cc_usb_sync(cc);
+ return 0;
+}
+
+int
+cc_usb_read_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len)
+{
+ int i;
+ cc_queue_read(cc, bytes, len);
+ cc_usb_printf(cc, "I %x %x\n", len, addr);
+ cc_usb_sync(cc);
+ for (i = 0; i < len; i++) {
+ if ((i & 15) == 0) {
+ if (i)
+ ccdbg_debug(CC_DEBUG_MEMORY, "\n");
+ ccdbg_debug(CC_DEBUG_MEMORY, "\t%04x", addr + i);
+ }
+ ccdbg_debug(CC_DEBUG_MEMORY, " %02x", bytes[i]);
+ }
+ ccdbg_debug(CC_DEBUG_MEMORY, "\n");
+ return 0;
+}
+
+int
+cc_usb_debug_mode(struct cc_usb *cc)
+{
+ cc_usb_sync(cc);
+ cc_usb_printf(cc, "D\n");
+ return 1;
+}
+
+int
+cc_usb_reset(struct cc_usb *cc)
+{
+ cc_usb_sync(cc);
+ cc_usb_printf(cc, "R\n");
+ return 1;
+}
+
+static struct termios save_termios;
+
+struct cc_usb *
+cc_usb_open(char *tty)
+{
+ struct cc_usb *cc;
+ struct termios termios;
+
+ if (!tty)
+ tty = DEFAULT_TTY;
+ cc = calloc (sizeof (struct cc_usb), 1);
+ if (!cc)
+ return NULL;
+ cc->fd = open(tty, O_RDWR | O_NONBLOCK);
+ if (cc->fd < 0) {
+ perror(tty);
+ free (cc);
+ return NULL;
+ }
+ tcgetattr(cc->fd, &termios);
+ save_termios = termios;
+ cfmakeraw(&termios);
+ tcsetattr(cc->fd, TCSAFLUSH, &termios);
+ cc_usb_printf(cc, "E 0\nm 0\n");
+ cc_usb_sync(cc);
+ sleep(1);
+ cc_usb_sync(cc);
+ return cc;
+}
+
+void
+cc_usb_close(struct cc_usb *cc)
+{
+ tcsetattr(cc->fd, TCSAFLUSH, &save_termios);
+ close (cc->fd);
+ free (cc);
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _CC_USB_H_
+#define _CC_USB_H_
+
+#include <stdint.h>
+
+struct cc_usb;
+
+struct cc_usb *
+cc_usb_open(char *tty);
+
+void
+cc_usb_close(struct cc_usb *cc);
+
+int
+cc_usb_send_bytes(struct cc_usb *cc, uint8_t *bytes, int len);
+
+int
+cc_usb_recv_bytes(struct cc_usb *cc, uint8_t *bytes, int len);
+
+int
+cc_usb_write_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len);
+
+int
+cc_usb_read_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len);
+
+int
+cc_usb_debug_mode(struct cc_usb *cc);
+
+int
+cc_usb_reset(struct cc_usb *cc);
+
+void
+cc_usb_sync(struct cc_usb *cc);
+
+void
+cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len);
+
+void
+cc_usb_printf(struct cc_usb *cc, char *format, ...);
+
+#endif /* _CC_USB_H_ */
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+uint8_t
+ccdbg_chip_erase(struct ccdbg *dbg)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_CHIP_ERASE, NULL, 0);
+}
+
+uint8_t
+ccdbg_wr_config(struct ccdbg *dbg, uint8_t config)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_WR_CONFIG, &config, 1);
+}
+
+uint8_t
+ccdbg_rd_config(struct ccdbg *dbg)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0);
+}
+
+uint16_t
+ccdbg_get_pc(struct ccdbg *dbg)
+{
+ uint16_t pc1, pc2;
+
+ pc1 = ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0);
+ pc2 = ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0);
+ if (pc1 != pc2)
+ fprintf (stderr, "Invalid pc %04x != %04x\n",
+ pc1, pc2);
+ return pc2;
+}
+
+uint8_t
+ccdbg_read_status(struct ccdbg *dbg)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_READ_STATUS, NULL, 0);
+}
+
+uint8_t
+ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr)
+{
+ uint8_t data[3];
+
+ data[0] = (number << 3) | (enable << 2);
+ data[1] = (addr >> 8);
+ data[2] = addr;
+ return ccdbg_cmd_write_read8(dbg, CC_SET_HW_BRKPNT, data, 3);
+}
+
+uint8_t
+ccdbg_halt(struct ccdbg *dbg)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_HALT, NULL, 0);
+}
+
+uint8_t
+ccdbg_resume(struct ccdbg *dbg)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_RESUME, NULL, 0);
+}
+
+uint8_t
+ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_DEBUG_INSTR(nbytes), instr, nbytes);
+}
+
+void
+ccdbg_debug_instr_discard(struct ccdbg *dbg, uint8_t *instr, int nbytes)
+{
+ static uint8_t discard;
+ ccdbg_cmd_write_queue8(dbg, CC_DEBUG_INSTR(nbytes),
+ instr, nbytes, &discard);
+}
+
+void
+ccdbg_debug_instr_queue(struct ccdbg *dbg, uint8_t *instr, int nbytes,
+ uint8_t *reply)
+{
+ return ccdbg_cmd_write_queue8(dbg, CC_DEBUG_INSTR(nbytes),
+ instr, nbytes, reply);
+}
+
+uint8_t
+ccdbg_step_instr(struct ccdbg *dbg)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_STEP_INSTR, NULL, 0);
+}
+
+uint8_t
+ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes)
+{
+ return ccdbg_cmd_write_read8(dbg, CC_STEP_REPLACE(nbytes), instr, nbytes);
+}
+
+uint16_t
+ccdbg_get_chip_id(struct ccdbg *dbg)
+{
+ return ccdbg_cmd_write_read16(dbg, CC_GET_CHIP_ID, NULL, 0);
+}
+
+/*
+ * Execute a sequence of instructions
+ */
+uint8_t
+ccdbg_execute(struct ccdbg *dbg, uint8_t *inst)
+{
+ uint8_t status = 0;
+ while(inst[0] != 0) {
+ uint8_t len = inst[0];
+ int i;
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, "\t%02x", inst[1]);
+ for (i = 0; i < len - 1; i++)
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " %02x", inst[i+2]);
+ ccdbg_debug_instr_queue(dbg, inst+1, len, &status);
+ for (; i < 3; i++)
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " ");
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " -> %02x\n", status);
+ inst += len + 1;
+ }
+ ccdbg_sync(dbg);
+ return status;
+}
+
+static uint8_t jump_mem[] = {
+ 3, LJMP, 0xf0, 0x00,
+#define PC_HIGH 2
+#define PC_LOW 3
+ 0
+};
+
+uint8_t
+ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc)
+{
+ jump_mem[PC_HIGH] = pc >> 8;
+ jump_mem[PC_LOW] = pc & 0xff;
+ return ccdbg_execute(dbg, jump_mem);
+}
+
+uint8_t
+ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image)
+{
+ uint16_t pc;
+ uint8_t status;
+
+ if (image->address < 0xf000) {
+ fprintf(stderr, "Cannot execute program starting at 0x%04x\n", image->address);
+ return -1;
+ }
+ ccdbg_write_hex_image(dbg, image, 0);
+ ccdbg_set_pc(dbg, image->address);
+ pc = ccdbg_get_pc(dbg);
+ ccdbg_debug(CC_DEBUG_EXECUTE, "pc starts at 0x%04x\n", pc);
+ status = ccdbg_resume(dbg);
+ ccdbg_debug(CC_DEBUG_EXECUTE, "resume status: 0x%02x\n", status);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+#include <stdarg.h>
+
+int
+ccdbg_level = 0;
+
+void
+ccdbg_add_debug(int level)
+{
+ ccdbg_level |= level;
+}
+
+void
+ccdbg_clear_debug(int level)
+{
+ ccdbg_level &= ~level;
+}
+
+static int initialized;
+
+void
+ccdbg_debug(int level, char *format, ...)
+{
+ va_list ap;
+
+ if (!initialized) {
+ char *level;
+ initialized = 1;
+ level = getenv("CCDEBUG");
+ if (level)
+ ccdbg_level |= strtoul(level, NULL, 0);
+ }
+ if (ccdbg_level & level) {
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+ }
+}
+
+void
+ccdbg_flush(int level)
+{
+ if (ccdbg_level & level)
+ fflush(stdout);
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _CCDBG_DEBUG_H_
+#define _CCDBG_DEBUG_H_
+/* Debug levels
+ */
+#define CC_DEBUG_BITBANG 0x00000001
+#define CC_DEBUG_COMMAND 0x00000002
+#define CC_DEBUG_INSTRUCTIONS 0x00000004
+#define CC_DEBUG_EXECUTE 0x00000008
+#define CC_DEBUG_FLASH 0x00000010
+#define CC_DEBUG_MEMORY 0x00000020
+#define CC_DEBUG_USB_ASYNC 0x00000040
+
+/* ccdbg-debug.c */
+void
+ccdbg_debug(int level, char *format, ...);
+
+void
+ccdbg_add_debug(int level);
+
+void
+ccdbg_clear_debug(int level);
+
+void
+ccdbg_flush(int level);
+
+#endif /* _CCDBG_DEBUG_H_ */
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+/* From SWRA124 section 3.1.6 */
+
+static uint8_t flash_page[] = {
+
+ MOV_direct_data, P1DIR, 0x02,
+ MOV_direct_data, P1, 0xFF,
+
+ MOV_direct_data, FADDRH, 0,
+#define FLASH_ADDR_HIGH 8
+
+ MOV_direct_data, FADDRL, 0,
+#define FLASH_ADDR_LOW 11
+
+ MOV_DPTR_data16, 0, 0,
+#define RAM_ADDR_HIGH 13
+#define RAM_ADDR_LOW 14
+
+ MOV_Rn_data(7), 0,
+#define FLASH_WORDS_HIGH 16
+
+ MOV_Rn_data(6), 0,
+#define FLASH_WORDS_LOW 18
+
+ MOV_direct_data, FWT, 0x20,
+#define FLASH_TIMING 21
+
+ MOV_direct_data, FCTL, FCTL_ERASE,
+/* eraseWaitLoop: */
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_BUSY_BIT), 0xfb,
+
+ MOV_direct_data, P1, 0xfd,
+
+ MOV_direct_data, FCTL, FCTL_WRITE,
+/* writeLoop: */
+ MOV_Rn_data(5), 2,
+/* writeWordLoop: */
+ MOVX_A_atDPTR,
+ INC_DPTR,
+ MOV_direct_A, FWDATA,
+ DJNZ_Rn_rel(5), 0xfa, /* writeWordLoop */
+/* writeWaitLoop: */
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_SWBSY_BIT), 0xfb, /* writeWaitLoop */
+ DJNZ_Rn_rel(6), 0xf1, /* writeLoop */
+ DJNZ_Rn_rel(7), 0xef, /* writeLoop */
+
+ MOV_direct_data, P1DIR, 0x00,
+ MOV_direct_data, P1, 0xFF,
+ TRAP,
+};
+
+#define FLASH_RAM 0xf000
+
+#if 0
+static uint8_t flash_erase_page[] = {
+ 3, MOV_direct_data, FADDRH, 0,
+#define ERASE_PAGE_HIGH 3
+
+ 3, MOV_direct_data, FADDRL, 0,
+#define ERASE_PAGE_LOW 7
+
+ 3, MOV_direct_data, FWT, 0x2A,
+ 3, MOV_direct_data, FCTL, FCTL_ERASE,
+ 0
+};
+
+static uint8_t flash_read_control[] = {
+ 2, MOV_A_direct, FCTL,
+ 0
+};
+#endif
+
+#if 0
+static uint8_t flash_control_clear[] = {
+ 3, MOV_direct_data, FCTL, 0,
+ 2, MOV_A_direct, FCTL,
+ 0
+};
+#endif
+
+#if 0
+static uint8_t
+ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr)
+{
+ uint16_t page_addr = addr >> 1;
+ uint8_t status;
+ uint8_t old[0x10], new[0x10];
+ int i;
+
+ ccdbg_read_memory(dbg, addr, old, 0x10);
+ flash_erase_page[ERASE_PAGE_HIGH] = page_addr >> 8;
+ flash_erase_page[ERASE_PAGE_LOW] = page_addr & 0xff;
+ status = ccdbg_execute(dbg, flash_erase_page);
+ ccdbg_debug(CC_DEBUG_FLASH, "erase status 0x%02x\n", status);
+ do {
+ status = ccdbg_execute(dbg, flash_read_control);
+ ccdbg_debug(CC_DEBUG_FLASH, "fctl 0x%02x\n", status);
+ } while (status & FCTL_BUSY);
+ ccdbg_read_memory(dbg, addr, new, 0x10);
+ for (i = 0; i < 0x10; i++)
+ ccdbg_debug(CC_DEBUG_FLASH, "0x%02x -> 0x%02x\n", old[i], new[i]);
+ status = ccdbg_execute(dbg, flash_control_clear);
+ ccdbg_debug(CC_DEBUG_FLASH, "clear fctl 0x%02x\n", status);
+ return 0;
+}
+#endif
+
+#if 0
+static uint8_t flash_write[] = {
+ MOV_direct_data, P1DIR, 0x02,
+ MOV_direct_data, P1, 0xFD,
+
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_BUSY_BIT), 0xf1,
+
+ MOV_direct_data, FCTL, 0x20,
+
+ MOV_direct_data, FADDRH, 0,
+#define WRITE_PAGE_HIGH 16
+
+ MOV_direct_data, FADDRL, 0,
+#define WRITE_PAGE_LOW 19
+
+ MOV_direct_data, FCTL, FCTL_WRITE,
+ MOV_direct_data, FWDATA, 0,
+#define WRITE_BYTE_0 25
+ MOV_direct_data, FWDATA, 0,
+#define WRITE_BYTE_1 28
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_SWBSY_BIT), 0xf1,
+
+ MOV_direct_data, P1, 0xFF,
+ TRAP,
+};
+#endif
+
+static uint8_t
+ccdbg_clock_init(struct ccdbg *dbg)
+{
+ static uint8_t set_clkcon_fast[] = {
+ 3, MOV_direct_data, CLKCON, 0x00,
+ 0
+ };
+
+ static uint8_t get_sleep[] = {
+ 2, MOV_A_direct, SLEEP,
+ 0
+ };
+
+ uint8_t status;
+
+ ccdbg_execute(dbg, set_clkcon_fast);
+ do {
+ status = ccdbg_execute(dbg, get_sleep);
+ } while (!(status & 0x40));
+ return 0;
+}
+
+#if 0
+static uint8_t
+ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2])
+{
+ uint16_t page_addr = addr >> 1;
+ uint8_t check[2];
+ uint8_t status;
+ int i;
+
+ flash_write[WRITE_PAGE_HIGH] = page_addr >> 8;
+ flash_write[WRITE_PAGE_LOW] = page_addr & 0xff;
+ flash_write[WRITE_BYTE_0] = data[0];
+ flash_write[WRITE_BYTE_1] = data[1];
+ ccdbg_debug(CC_DEBUG_FLASH, "upload flash write\n");
+ ccdbg_write_memory(dbg, 0xf000, flash_write, sizeof(flash_write));
+ ccdbg_set_pc(dbg, 0xf000);
+ ccdbg_resume(dbg);
+ for (;;) {
+ status = ccdbg_read_status(dbg);
+ ccdbg_debug(CC_DEBUG_FLASH, "waiting for write 0x%02x\n", status);
+ if ((status & CC_STATUS_CPU_HALTED) != 0)
+ break;
+ sleep (1);
+ }
+ status = ccdbg_execute(dbg, flash_control_clear);
+ ccdbg_debug(CC_DEBUG_FLASH, "clear fctl 0x%02x\n", status);
+ ccdbg_read_memory(dbg, addr, check, 2);
+ for (i = 0; i < 2; i++)
+ ccdbg_debug(CC_DEBUG_FLASH, "0x%02x : 0x%02x\n", data[i], check[i]);
+ return 0;
+}
+#endif
+
+#define TIMERS_OFF 0x08
+#define DMA_PAUSE 0x04
+#define TIMER_SUSPEND 0x02
+#define SEL_FLASH_INFO_PAGE 0x01
+
+#if 0
+static uint8_t
+ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock)
+{
+ uint8_t config;
+ uint8_t bytes[2];
+ uint8_t old[1], new[1];
+
+ config = ccdbg_rd_config(dbg);
+ ccdbg_wr_config(dbg, config|SEL_FLASH_INFO_PAGE);
+ bytes[0] = lock;
+ bytes[1] = 0;
+ ccdbg_flash_erase_page(dbg, 0);
+ ccdbg_read_memory(dbg, 0, old, 1);
+ ccdbg_flash_write_word(dbg, 0, bytes);
+ ccdbg_read_memory(dbg, 0, new, 1);
+ ccdbg_debug(CC_DEBUG_FLASH, "flash lock 0x%02x -> 0x%02x\n", old[0], new[0]);
+ ccdbg_wr_config(dbg, config & ~SEL_FLASH_INFO_PAGE);
+ return 0;
+}
+#endif
+
+uint8_t
+ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)
+{
+ uint16_t offset;
+ uint16_t flash_prog;
+ uint16_t flash_len;
+ uint8_t fwt;
+ uint16_t flash_addr;
+ uint16_t flash_word_addr;
+ uint16_t flash_words;
+ uint8_t flash_words_high, flash_words_low;
+ uint16_t ram_addr;
+ uint16_t pc;
+ uint8_t status;
+ uint16_t remain, this_time, start;
+ uint8_t verify[0x400];
+ int times;
+
+ ccdbg_clock_init(dbg);
+ if (image->address + image->length > 0x8000) {
+ fprintf(stderr, "cannot flash image from 0x%04x to 0x%04x\n",
+ image->address, image->address + image->length);
+ return 1;
+ }
+ if (image->address & 0x3ff) {
+ fprintf(stderr, "flash image must start on page boundary\n");
+ return 1;
+ }
+ ram_addr = 0xf000;
+
+
+ flash_prog = 0xf400;
+
+ fwt = 0x20;
+
+ flash_page[FLASH_TIMING] = fwt;
+ ccdbg_debug(CC_DEBUG_FLASH, "Upload %d flash program bytes to 0x%04x\n",
+ sizeof (flash_page), flash_prog);
+ ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page));
+
+ remain = image->length;
+ start = 0;
+ while (remain) {
+ this_time = remain;
+ if (this_time > 0x400)
+ this_time = 0x400;
+
+ offset = ram_addr - (image->address + start);
+
+ ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr);
+ ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time);
+#if 0
+ ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in ram\n", this_time);
+ ccdbg_read_memory(dbg, ram_addr, verify, this_time);
+ if (memcmp (image->data + start, verify, this_time) != 0) {
+ fprintf(stderr, "ram verify failed\n");
+ return 1;
+ }
+#endif
+
+ flash_addr = image->address + start;
+ flash_word_addr = flash_addr >> 1;
+ flash_len = this_time + (this_time & 1);
+ flash_words = flash_len >> 1;
+
+ flash_words_low = flash_words & 0xff;
+ flash_words_high = flash_words >> 8;
+
+ /* The flash code above is lame */
+ if (flash_words_low)
+ flash_words_high++;
+
+ ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_HIGH, flash_word_addr >> 8);
+ ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_LOW, flash_word_addr & 0xff);
+
+ ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_HIGH, ram_addr >> 8);
+ ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_LOW, ram_addr & 0xff);
+
+ ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words_high);
+ ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words_low);
+
+ ccdbg_set_pc(dbg, flash_prog);
+ pc = ccdbg_get_pc(dbg);
+ ccdbg_debug(CC_DEBUG_FLASH, "Flashing %d bytes at 0x%04x\n",
+ this_time, flash_addr);
+ status = ccdbg_resume(dbg);
+ for (times = 0; times < 10; times++) {
+ status = ccdbg_read_status(dbg);
+ ccdbg_debug(CC_DEBUG_FLASH, ".");
+ ccdbg_flush(CC_DEBUG_FLASH);
+ if ((status & CC_STATUS_CPU_HALTED) != 0)
+ break;
+ usleep(10000);
+ }
+ ccdbg_debug(CC_DEBUG_FLASH, "\n");
+ if (times == 10) {
+ fprintf(stderr, "flash page timed out\n");
+ return 1;
+ }
+
+ ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in flash\n", this_time);
+ ccdbg_read_memory(dbg, flash_addr, verify, this_time);
+ if (memcmp (image->data + start, verify, this_time) != 0) {
+ int i;
+ fprintf(stderr, "flash verify failed\n");
+ for (i = 0; i < this_time; i++) {
+ if (image->data[start + i] != verify[i])
+ fprintf(stderr, "0x%04x: 0x%02x != 0x%02x\n",
+ start + i, image->data[start+i], verify[i]);
+ }
+ return 1;
+ }
+ remain -= this_time;
+ start += this_time;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+struct hex_input {
+ FILE *file;
+ int line;
+ char *name;
+};
+
+enum hex_read_state {
+ read_marker,
+ read_length,
+ read_address,
+ read_type,
+ read_data,
+ read_checksum,
+ read_newline,
+ read_white,
+ read_done,
+};
+
+
+static void
+ccdbg_hex_error(struct hex_input *input, char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ fprintf(stderr, "Hex error %s:%d: ", input->name, input->line);
+ vfprintf(stderr, format, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+static void
+ccdbg_hex_free(struct hex_record *record)
+{
+ if (!record) return;
+ free(record);
+}
+
+static struct hex_record *
+ccdbg_hex_alloc(uint8_t length)
+{
+ struct hex_record *record;
+
+ record = calloc(1, sizeof(struct hex_record) + length);
+ record->length = length;
+ return record;
+}
+
+static int
+ishex(char c)
+{
+ return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
+}
+
+static int
+fromhex(char c)
+{
+ if (isdigit(c))
+ return c - '0';
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ abort();
+ return 0;
+}
+
+static uint8_t
+ccdbg_hex_checksum(struct hex_record *record)
+{
+ uint8_t checksum = 0;
+ int i;
+
+ checksum += record->length;
+ checksum += record->address >> 8;
+ checksum += record->address & 0xff;
+ checksum += record->type;
+ for (i = 0; i < record->length; i++)
+ checksum += record->data[i];
+ return -checksum;
+}
+
+static struct hex_record *
+ccdbg_hex_read_record(struct hex_input *input)
+{
+ struct hex_record *record = NULL;
+ enum hex_read_state state = read_marker;
+ char c;
+ int nhexbytes;
+ uint32_t hex;
+ uint32_t ndata;
+ uint8_t checksum;
+
+ while (state != read_done) {
+ c = getc(input->file);
+ if (c == EOF && state != read_white) {
+ ccdbg_hex_error(input, "Unexpected EOF");
+ goto bail;
+ }
+ if (c == ' ')
+ continue;
+ if (c == '\n')
+ input->line++;
+ switch (state) {
+ case read_marker:
+ if (c != ':') {
+ ccdbg_hex_error(input, "Missing ':'");
+ goto bail;
+ }
+ state = read_length;
+ nhexbytes = 2;
+ hex = 0;
+ break;
+ case read_length:
+ case read_address:
+ case read_type:
+ case read_data:
+ case read_checksum:
+ if (!ishex(c)) {
+ ccdbg_hex_error(input, "Non-hex char '%c'",
+ c);
+ goto bail;
+ }
+ hex = hex << 4 | fromhex(c);
+ --nhexbytes;
+ if (nhexbytes != 0)
+ break;
+
+ switch (state) {
+ case read_length:
+ record = ccdbg_hex_alloc(hex);
+ if (!record) {
+ ccdbg_hex_error(input, "Out of memory");
+ goto bail;
+ }
+ state = read_address;
+ nhexbytes = 4;
+ break;
+ case read_address:
+ record->address = hex;
+ state = read_type;
+ nhexbytes = 2;
+ break;
+ case read_type:
+ record->type = hex;
+ state = read_data;
+ nhexbytes = 2;
+ ndata = 0;
+ break;
+ case read_data:
+ record->data[ndata] = hex;
+ ndata++;
+ nhexbytes = 2;
+ break;
+ case read_checksum:
+ record->checksum = hex;
+ state = read_newline;
+ break;
+ default:
+ break;
+ }
+ if (state == read_data)
+ if (ndata == record->length) {
+ nhexbytes = 2;
+ state = read_checksum;
+ }
+ hex = 0;
+ break;
+ case read_newline:
+ if (c != '\n' && c != '\r') {
+ ccdbg_hex_error(input, "Missing newline");
+ goto bail;
+ }
+ state = read_white;
+ break;
+ case read_white:
+ if (!isspace(c)) {
+ if (c == '\n')
+ input->line--;
+ if (c != EOF)
+ ungetc(c, input->file);
+ state = read_done;
+ }
+ break;
+ case read_done:
+ break;
+ }
+ }
+ checksum = ccdbg_hex_checksum(record);
+ if (checksum != record->checksum) {
+ ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n",
+ record->checksum, checksum);
+ goto bail;
+ }
+ return record;
+
+bail:
+ ccdbg_hex_free(record);
+ return NULL;
+}
+
+void
+ccdbg_hex_file_free(struct hex_file *hex)
+{
+ int i;
+
+ if (!hex)
+ return;
+ for (i = 0; i < hex->nrecord; i++)
+ ccdbg_hex_free(hex->records[i]);
+ free(hex);
+}
+
+static int
+ccdbg_hex_record_compar(const void *av, const void *bv)
+{
+ const struct hex_record *a = *(struct hex_record **) av;
+ const struct hex_record *b = *(struct hex_record **) bv;
+
+ return (int) a->address - (int) b->address;
+}
+
+struct hex_file *
+ccdbg_hex_file_read(FILE *file, char *name)
+{
+ struct hex_input input;
+ struct hex_file *hex = NULL, *newhex;
+ struct hex_record *record;
+ int srecord = 1;
+ int done = 0;
+
+ hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1);
+ input.name = name;
+ input.line = 1;
+ input.file = file;
+ while (!done) {
+ record = ccdbg_hex_read_record(&input);
+ if (!record)
+ goto bail;
+ if (hex->nrecord == srecord) {
+ srecord *= 2;
+ newhex = realloc(hex,
+ sizeof (struct hex_file) +
+ srecord * sizeof (struct hex_record *));
+ if (!newhex)
+ goto bail;
+ hex = newhex;
+ }
+ hex->records[hex->nrecord++] = record;
+ if (record->type == HEX_RECORD_EOF)
+ done = 1;
+ }
+ /*
+ * Sort them into increasing addresses, except for EOF
+ */
+ qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *),
+ ccdbg_hex_record_compar);
+ return hex;
+
+bail:
+ ccdbg_hex_file_free(hex);
+ return NULL;
+}
+
+struct hex_image *
+ccdbg_hex_image_create(struct hex_file *hex)
+{
+ struct hex_image *image;
+ struct hex_record *first, *last, *record;
+ int i;
+ uint32_t base, bound;
+ uint32_t offset;
+ int length;
+
+ first = hex->records[0];
+ last = hex->records[hex->nrecord - 2]; /* skip EOF */
+ base = (uint32_t) first->address;
+ bound = (uint32_t) last->address + (uint32_t) last->length;
+ length = bound - base;
+ image = calloc(sizeof(struct hex_image) + length, 1);
+ if (!image)
+ return NULL;
+ image->address = base;
+ image->length = length;
+ memset(image->data, 0xff, length);
+ for (i = 0; i < hex->nrecord - 1; i++) {
+ record = hex->records[i];
+ offset = record->address - base;
+ memcpy(image->data + offset, record->data, record->length);
+ }
+ return image;
+}
+
+void
+ccdbg_hex_image_free(struct hex_image *image)
+{
+ free(image);
+}
+
+int
+ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b)
+{
+ if (a->length != b->length)
+ return 0;
+ if (memcmp(a->data, b->data, a->length) != 0)
+ return 0;
+ return 1;
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+#include <time.h>
+#include "cc-usb.h"
+#include "cc-bitbang.h"
+
+struct ccdbg *
+ccdbg_open(void)
+{
+ struct ccdbg *dbg;
+ char *tty;
+
+ dbg = calloc(sizeof (struct ccdbg), 1);
+ if (!dbg) {
+ perror("calloc");
+ return NULL;
+ }
+ tty = getenv("CCDBG_TTY");
+ if (!tty || tty[0] == '/')
+ dbg->usb = cc_usb_open(tty);
+ if (!dbg->usb) {
+ dbg->bb = cc_bitbang_open();
+ if (!dbg->bb) {
+ free(dbg);
+ return NULL;
+ }
+ }
+ return dbg;
+}
+
+void
+ccdbg_close(struct ccdbg *dbg)
+{
+ if (dbg->usb)
+ cc_usb_close(dbg->usb);
+ if (dbg->bb)
+ cc_bitbang_close(dbg->bb);
+ free (dbg);
+}
+
+void
+ccdbg_debug_mode(struct ccdbg *dbg)
+{
+ if (dbg->usb)
+ cc_usb_debug_mode(dbg->usb);
+ else if (dbg->bb)
+ cc_bitbang_debug_mode(dbg->bb);
+}
+
+void
+ccdbg_reset(struct ccdbg *dbg)
+{
+ if (dbg->usb)
+ cc_usb_reset(dbg->usb);
+ else if (dbg->bb)
+ cc_bitbang_reset(dbg->bb);
+}
+
+void
+ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes)
+{
+ if (dbg->usb)
+ cc_usb_send_bytes(dbg->usb, bytes, nbytes);
+ else if (dbg->bb)
+ cc_bitbang_send_bytes(dbg->bb, bytes, nbytes);
+}
+
+void
+ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes)
+{
+ if (dbg->usb)
+ cc_usb_recv_bytes(dbg->usb, bytes, nbytes);
+ else if (dbg->bb)
+ cc_bitbang_recv_bytes(dbg->bb, bytes, nbytes);
+}
+
+void
+ccdbg_sync(struct ccdbg *dbg)
+{
+ if (dbg->usb)
+ cc_usb_sync(dbg->usb);
+ else if (dbg->bb)
+ cc_bitbang_sync(dbg->bb);
+}
+
+void
+ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
+{
+ ccdbg_send_bytes(dbg, &cmd, 1);
+ ccdbg_send_bytes(dbg, data, len);
+}
+
+uint8_t
+ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
+{
+ uint8_t byte[1];
+ ccdbg_cmd_write(dbg, cmd, data, len);
+ ccdbg_recv_bytes(dbg, byte, 1);
+ ccdbg_sync(dbg);
+ return byte[0];
+}
+
+uint16_t
+ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
+{
+ uint8_t byte[2];
+ ccdbg_cmd_write(dbg, cmd, data, len);
+ ccdbg_recv_bytes(dbg, byte, 2);
+ ccdbg_sync(dbg);
+ return (byte[0] << 8) | byte[1];
+}
+
+void
+ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd,
+ uint8_t *data, int len,
+ uint8_t *reply)
+{
+ ccdbg_cmd_write(dbg, cmd, data, len);
+ ccdbg_recv_bytes(dbg, reply, 1);
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+#include "cc-bitbang.h"
+
+/*
+ * Manual bit-banging to debug the low level protocol
+ */
+
+static void
+get_bit(char *line, int i, char on, uint8_t bit, uint8_t *bits, uint8_t *masks)
+{
+ if (line[i] == on) {
+ *bits |= bit;
+ *masks |= bit;
+ return;
+ }
+ if (line[i] == '.') {
+ *masks |= bit;
+ return;
+ }
+ if (line[i] == '-') {
+ return;
+ }
+ fprintf(stderr, "bad line %s\n", line);
+ exit (1);
+}
+
+void
+ccdbg_manual(struct ccdbg *dbg, FILE *input)
+{
+ char line[80];
+ uint8_t set, mask;
+
+ if (dbg->bb == NULL) {
+ fprintf(stderr, "Must use bitbang API for manual mode\n");
+ return;
+ }
+ while (fgets(line, sizeof line, input)) {
+ if (line[0] == '#' || line[0] == '\n') {
+ printf ("%s", line);
+ continue;
+ }
+ set = 0;
+ mask = 0;
+ get_bit(line, 0, 'C', CC_CLOCK, &set, &mask);
+ get_bit(line, 2, 'D', CC_DATA, &set, &mask);
+ get_bit(line, 4, 'R', CC_RESET_N, &set, &mask);
+ if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) {
+ uint8_t read;
+ cc_bitbang_read(dbg->bb, &read);
+ cc_bitbang_sync(dbg->bb);
+ cc_bitbang_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read);
+ if ((set & CC_CLOCK) == 0)
+ printf ("\t%d", (read&CC_DATA) ? 1 : 0);
+ printf ("\n");
+ }
+ cc_bitbang_send(dbg->bb, mask, set);
+ cc_bitbang_sync(dbg->bb);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+/*
+ * Read and write arbitrary memory through the debug port
+ */
+
+static uint8_t memory_init[] = {
+ 3, MOV_DPTR_data16, 0, 0,
+#define HIGH_START 2
+#define LOW_START 3
+ 0,
+};
+
+
+static uint8_t write8[] = {
+ 2, MOV_A_data, 0,
+#define DATA_BYTE 2
+ 1, MOVX_atDPTR_A,
+ 1, INC_DPTR,
+ 0
+};
+
+static uint8_t read8[] = {
+ 1, MOVX_A_atDPTR,
+ 1, INC_DPTR,
+ 0,
+};
+
+uint8_t
+ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
+{
+ int i, nl = 0;
+ struct ccstate state;
+
+ if (dbg->usb)
+ return cc_usb_write_memory(dbg->usb, addr, bytes, nbytes);
+ ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP);
+ memory_init[HIGH_START] = addr >> 8;
+ memory_init[LOW_START] = addr;
+ (void) ccdbg_execute(dbg, memory_init);
+ for (i = 0; i < nbytes; i++) {
+ write8[DATA_BYTE] = *bytes++;
+ ccdbg_execute(dbg, write8);
+ if ((i & 0xf) == 0xf) {
+ ccdbg_debug(CC_DEBUG_MEMORY, ".");
+ ccdbg_flush(CC_DEBUG_MEMORY);
+ nl = 1;
+ }
+ if ((i & 0xff) == 0xff) {
+ ccdbg_debug(CC_DEBUG_MEMORY, "\n");
+ nl = 0;
+ }
+ }
+ ccdbg_state_restore(dbg, &state);
+ if (nl)
+ ccdbg_debug(CC_DEBUG_MEMORY, "\n");
+ return 0;
+}
+
+uint8_t
+ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
+{
+ int i, nl = 0;
+ struct ccstate state;
+
+ if (ccdbg_rom_contains(dbg, addr, nbytes)) {
+ ccdbg_rom_replace_xmem(dbg, addr, bytes, nbytes);
+ return 0;
+ }
+ if (dbg->usb)
+ return cc_usb_read_memory(dbg->usb, addr, bytes, nbytes);
+ ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP);
+ memory_init[HIGH_START] = addr >> 8;
+ memory_init[LOW_START] = addr;
+ (void) ccdbg_execute(dbg, memory_init);
+ for (i = 0; i < nbytes; i++) {
+ *bytes++ = ccdbg_execute(dbg, read8);
+ if ((i & 0xf) == 0xf) {
+ ccdbg_debug(CC_DEBUG_MEMORY, ".");
+ ccdbg_flush(CC_DEBUG_MEMORY);
+ nl = 1;
+ }
+ if ((i & 0xff) == 0xff) {
+ ccdbg_debug(CC_DEBUG_MEMORY, "\n");
+ nl = 0;
+ }
+ }
+ ccdbg_state_replace_xmem(dbg, &state, addr, bytes, nbytes);
+ ccdbg_state_restore(dbg, &state);
+ if (nl)
+ ccdbg_debug(CC_DEBUG_MEMORY, "\n");
+ return 0;
+}
+
+uint8_t
+ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte)
+{
+ return ccdbg_write_memory(dbg, addr, &byte, 1);
+}
+
+uint8_t
+ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset)
+{
+ ccdbg_write_memory(dbg, image->address + offset, image->data, image->length);
+ return 0;
+}
+
+struct hex_image *
+ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length)
+{
+ struct hex_image *image;
+
+ image = calloc(sizeof(struct hex_image) + length, 1);
+ image->address = address;
+ image->length = length;
+ memset(image->data, 0xff, length);
+ ccdbg_read_memory(dbg, address, image->data, length);
+ return image;
+}
+
+static uint8_t sfr_read[] = {
+ 2, MOV_A_direct, 0,
+#define SFR_READ_ADDR 2
+ 0,
+};
+
+static uint8_t sfr_write[] = {
+ 3, MOV_direct_data, 0, 0,
+#define SFR_WRITE_ADDR 2
+#define SFR_WRITE_DATA 3
+ 0,
+};
+
+uint8_t
+ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes)
+{
+ int i;
+ struct ccstate state;
+
+ ccdbg_state_save(dbg, &state, CC_STATE_ACC);
+ for (i = 0; i < nbytes; i++) {
+ sfr_read[SFR_READ_ADDR] = addr + i;
+ *bytes++ = ccdbg_execute(dbg, sfr_read);
+ }
+ ccdbg_state_replace_sfr(dbg, &state, addr, bytes, nbytes);
+ ccdbg_state_restore(dbg, &state);
+ return 0;
+}
+
+uint8_t
+ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes)
+{
+ int i;
+
+ for (i = 0; i < nbytes; i++) {
+ sfr_write[SFR_WRITE_ADDR] = addr + i;
+ sfr_write[SFR_WRITE_DATA] = *bytes++;
+ ccdbg_execute(dbg, sfr_write);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+uint8_t
+ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom)
+{
+ if (dbg->rom)
+ ccdbg_hex_image_free(dbg->rom);
+ dbg->rom = rom;
+ return 0;
+}
+
+uint8_t
+ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes)
+{
+ struct hex_image *rom = dbg->rom;
+ if (!rom)
+ return 0;
+ if (addr < rom->address || rom->address + rom->length < addr + nbytes)
+ return 0;
+ return 1;
+}
+
+uint8_t
+ccdbg_rom_replace_xmem(struct ccdbg *dbg,
+ uint16_t addr, uint8_t *bytes, int nbytes)
+{
+ struct hex_image *rom = dbg->rom;
+ if (!rom)
+ return 0;
+
+ if (rom->address < addr + nbytes && addr < rom->address + rom->length) {
+ int start, stop;
+
+ start = addr;
+ if (addr < rom->address)
+ start = rom->address;
+ stop = addr + nbytes;
+ if (rom->address + rom->length < stop)
+ stop = rom->address + rom->length;
+ memcpy(bytes + start - addr, rom->data + start - rom->address,
+ stop - start);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+static uint8_t save_acc[] = {
+ 1, NOP,
+ 0
+};
+
+static uint8_t save_sfr[] = {
+ 2, MOV_A_direct, 0,
+#define SAVE_SFR_ADDR 2
+ 0,
+};
+
+struct sfr_state {
+ uint8_t address;
+ uint16_t mask;
+ char *name;
+};
+
+static struct sfr_state sfrs[CC_STATE_NSFR] = {
+ { SFR_DPL0, CC_STATE_DP, "dpl0" },
+ { SFR_DPH0, CC_STATE_DP, "dph0" },
+ { SFR_DPL1, CC_STATE_DP, "dpl1" },
+ { SFR_DPH1, CC_STATE_DP, "dph1" },
+ { PSW(0), CC_STATE_PSW, "psw" },
+};
+
+uint8_t
+ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask)
+{
+ int i;
+
+ mask |= CC_STATE_ACC;
+ if (mask & CC_STATE_ACC)
+ state->acc = ccdbg_execute(dbg, save_acc);
+ for (i = 0; i < CC_STATE_NSFR; i++) {
+ if (sfrs[i].mask & mask) {
+ save_sfr[SAVE_SFR_ADDR] = sfrs[i].address;
+ state->sfr[i] = ccdbg_execute(dbg, save_sfr);
+ }
+ }
+ state->mask = mask;
+ return 0;
+}
+
+static uint8_t restore_sfr[] = {
+ 3, MOV_direct_data, 0, 0,
+#define RESTORE_SFR_ADDR 2
+#define RESTORE_SFR_DATA 3
+ 0
+};
+
+static uint8_t restore_acc[] = {
+ 2, MOV_A_data, 0,
+#define RESTORE_ACC_DATA 2
+ 0
+};
+
+uint8_t
+ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state)
+{
+ int i;
+ for (i = CC_STATE_NSFR - 1; i >= 0; i--) {
+ if (sfrs[i].mask & state->mask) {
+ restore_sfr[RESTORE_SFR_ADDR] = sfrs[i].address;
+ restore_sfr[RESTORE_SFR_DATA] = state->sfr[i];
+ ccdbg_execute(dbg, restore_sfr);
+ }
+ }
+ if (state->mask & CC_STATE_ACC) {
+ restore_acc[RESTORE_ACC_DATA] = state->acc;
+ ccdbg_execute(dbg, restore_acc);
+ }
+ state->mask = 0;
+ return 0;
+}
+
+static void
+ccdbg_state_replace(uint16_t sfr_addr, uint8_t sfr, char *name,
+ uint16_t addr, uint8_t *bytes, int nbytes)
+{
+ sfr_addr += 0xdf00;
+
+ if (addr <= sfr_addr && sfr_addr < addr + nbytes) {
+ fprintf(stderr, "replacing %s at 0x%04x - read 0x%02x saved 0x%02x\n",
+ name, sfr_addr, bytes[sfr_addr - addr], sfr);
+ bytes[sfr_addr - addr] = sfr;
+ }
+}
+
+void
+ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state,
+ uint16_t addr, uint8_t *bytes, int nbytes)
+{
+ int i;
+ if (state->mask & CC_STATE_ACC)
+ ccdbg_state_replace(ACC(0), state->acc, "acc",
+ addr, bytes, nbytes);
+ for (i = 0; i < CC_STATE_NSFR; i++)
+ if (state->mask & sfrs[i].mask)
+ ccdbg_state_replace(sfrs[i].address, state->sfr[i],
+ sfrs[i].name, addr, bytes, nbytes);
+}
+
+void
+ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state,
+ uint8_t addr, uint8_t *bytes, int nbytes)
+{
+ ccdbg_state_replace_xmem(dbg, state, (uint16_t) addr + 0xdf00, bytes, nbytes);
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _CCDBG_H_
+#define _CCDBG_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include "ccdbg-debug.h"
+#include "cc-bitbang.h"
+#include "cc-usb.h"
+
+/* 8051 instructions
+ */
+#define NOP 0x00
+#define MOV_direct_data 0x75
+#define LJMP 0x02
+#define MOV_Rn_data(n) (0x78 | (n))
+#define DJNZ_Rn_rel(n) (0xd8 | (n))
+#define MOV_A_direct 0xe5
+#define MOV_direct1_direct2 0x85
+#define MOV_direct_A 0xf5
+#define MOV_DPTR_data16 0x90
+#define MOV_A_data 0x74
+#define MOVX_atDPTR_A 0xf0
+#define MOVX_A_atDPTR 0xe0
+#define INC_DPTR 0xa3
+#define TRAP 0xa5
+#define SJMP 0x80
+#define JB 0x20
+
+/* 8051 special function registers
+ */
+
+#define SFR_P0 0x80
+#define SFR_SP 0x81
+#define SFR_DPL0 0x82
+#define SFR_DPH0 0x83
+#define SFR_DPL1 0x84
+#define SFR_DPH1 0x85
+
+/* flash controller */
+#define FWT 0xAB
+#define FADDRL 0xAC
+#define FADDRH 0xAD
+#define FCTL 0xAE
+# define FCTL_BUSY 0x80
+# define FCTL_BUSY_BIT 7
+# define FCTL_SWBSY 0x40
+# define FCTL_SWBSY_BIT 6
+# define FCTL_CONTRD 0x10
+# define FCTL_WRITE 0x02
+# define FCTL_ERASE 0x01
+#define FWDATA 0xAF
+
+#define SLEEP 0xBE
+
+/* clock controller */
+#define CLKCON 0xC6
+#define CLKCON_OSC32K 0x80
+#define CLKCON_OSC 0x40
+#define CLKCON_TICKSPD 0x38
+#define CLKCON_CLKSPD 0x07
+
+/* I/O pins */
+#define P0 0x80
+#define P1 0x90
+#define P2 0xA0
+#define P0DIR 0xFD
+#define P1DIR 0xFE
+#define P2DIR 0xFF
+
+/* Bit-addressable accumulator */
+#define ACC(bit) (0xE0 | (bit))
+
+/* Bit-addressable status word */
+#define PSW(bit) (0xD0 | (bit))
+
+struct ccdbg {
+ struct cc_bitbang *bb;
+ struct cc_usb *usb;
+ struct hex_image *rom;
+};
+
+/* Intel hex file format data
+ */
+struct hex_record {
+ uint8_t length;
+ uint16_t address;
+ uint8_t type;
+ uint8_t checksum;
+ uint8_t data[0];
+};
+
+struct hex_file {
+ int nrecord;
+ struct hex_record *records[0];
+};
+
+struct hex_image {
+ uint16_t address;
+ uint16_t length;
+ uint8_t data[0];
+};
+
+#define CC_STATE_ACC 0x1
+#define CC_STATE_PSW 0x2
+#define CC_STATE_DP 0x4
+
+#define CC_STATE_NSFR 5
+
+struct ccstate {
+ uint16_t mask;
+ uint8_t acc;
+ uint8_t sfr[CC_STATE_NSFR];
+};
+
+#define HEX_RECORD_NORMAL 0x00
+#define HEX_RECORD_EOF 0x01
+#define HEX_RECORD_EXTENDED_ADDRESS 0x02
+
+/* CC1111 debug port commands
+ */
+#define CC_CHIP_ERASE 0x14
+
+#define CC_WR_CONFIG 0x1d
+#define CC_RD_CONFIG 0x24
+# define CC_CONFIG_TIMERS_OFF (1 << 3)
+# define CC_CONFIG_DMA_PAUSE (1 << 2)
+# define CC_CONFIG_TIMER_SUSPEND (1 << 1)
+# define CC_SET_FLASH_INFO_PAGE (1 << 0)
+
+#define CC_GET_PC 0x28
+#define CC_READ_STATUS 0x34
+# define CC_STATUS_CHIP_ERASE_DONE (1 << 7)
+# define CC_STATUS_PCON_IDLE (1 << 6)
+# define CC_STATUS_CPU_HALTED (1 << 5)
+# define CC_STATUS_POWER_MODE_0 (1 << 4)
+# define CC_STATUS_HALT_STATUS (1 << 3)
+# define CC_STATUS_DEBUG_LOCKED (1 << 2)
+# define CC_STATUS_OSCILLATOR_STABLE (1 << 1)
+# define CC_STATUS_STACK_OVERFLOW (1 << 0)
+
+#define CC_SET_HW_BRKPNT 0x3b
+# define CC_HW_BRKPNT_N(n) ((n) << 3)
+# define CC_HW_BRKPNT_N_MASK (0x3 << 3)
+# define CC_HW_BRKPNT_ENABLE (1 << 2)
+
+#define CC_HALT 0x44
+#define CC_RESUME 0x4c
+#define CC_DEBUG_INSTR(n) (0x54|(n))
+#define CC_STEP_INSTR 0x5c
+#define CC_STEP_REPLACE(n) (0x64|(n))
+#define CC_GET_CHIP_ID 0x68
+
+/* ccdbg-command.c */
+void
+ccdbg_debug_mode(struct ccdbg *dbg);
+
+void
+ccdbg_reset(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_chip_erase(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_wr_config(struct ccdbg *dbg, uint8_t config);
+
+uint8_t
+ccdbg_rd_config(struct ccdbg *dbg);
+
+uint16_t
+ccdbg_get_pc(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_read_status(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr);
+
+uint8_t
+ccdbg_halt(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_resume(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes);
+
+void
+ccdbg_debug_instr_discard(struct ccdbg *dbg, uint8_t *instr, int nbytes);
+
+void
+ccdbg_debug_instr_queue(struct ccdbg *dbg, uint8_t *instr, int nbytes,
+ uint8_t *reply);
+
+uint8_t
+ccdbg_step_instr(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes);
+
+uint16_t
+ccdbg_get_chip_id(struct ccdbg *dbg);
+
+uint8_t
+ccdbg_execute(struct ccdbg *dbg, uint8_t *inst);
+
+uint8_t
+ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc);
+
+uint8_t
+ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image);
+
+/* ccdbg-flash.c */
+uint8_t
+ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image);
+
+/* ccdbg-hex.c */
+struct hex_file *
+ccdbg_hex_file_read(FILE *file, char *name);
+
+void
+ccdbg_hex_file_free(struct hex_file *hex);
+
+struct hex_image *
+ccdbg_hex_image_create(struct hex_file *hex);
+
+void
+ccdbg_hex_image_free(struct hex_image *image);
+
+int
+ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b);
+
+/* ccdbg-io.c */
+struct ccdbg *
+ccdbg_open(void);
+
+void
+ccdbg_close(struct ccdbg *dbg);
+
+void
+ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len);
+
+uint8_t
+ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len);
+
+void
+ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd,
+ uint8_t *data, int len, uint8_t *reply);
+
+uint16_t
+ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len);
+
+void
+ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes);
+
+void
+ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes);
+
+void
+ccdbg_sync(struct ccdbg *dbg);
+
+/* ccdbg-manual.c */
+
+void
+ccdbg_manual(struct ccdbg *dbg, FILE *input);
+
+/* ccdbg-memory.c */
+uint8_t
+ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
+
+uint8_t
+ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
+
+uint8_t
+ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte);
+
+uint8_t
+ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset);
+
+struct hex_image *
+ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length);
+
+uint8_t
+ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);
+
+uint8_t
+ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);
+
+/* ccdbg-rom.c */
+uint8_t
+ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom);
+
+uint8_t
+ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes);
+
+uint8_t
+ccdbg_rom_replace_xmem(struct ccdbg *dbg,
+ uint16_t addrp, uint8_t *bytesp, int nbytes);
+
+/* ccdbg-state.c */
+uint8_t
+ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask);
+
+uint8_t
+ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state);
+
+void
+ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state,
+ uint16_t addr, uint8_t *bytes, int nbytes);
+
+void
+ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state,
+ uint8_t addr, uint8_t *bytes, int nbytes);
+
+#endif /* _CCDBG_H_ */
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "cp-usb-async.h"
+#include "ccdbg-debug.h"
+
+#define MAX_OUTSTANDING 256
+#define CP_TIMEOUT 1000 /* ms */
+
+struct cp_usb_packet {
+ struct libusb_transfer *transfer;
+ enum { packet_read, packet_write } direction;
+ unsigned char data[9];
+ uint8_t *valuep;
+};
+
+struct cp_usb_async {
+ libusb_context *ctx;
+ libusb_device_handle *handle;
+ struct cp_usb_packet packet[MAX_OUTSTANDING];
+ int p, ack;
+ uint8_t value;
+ uint8_t set;
+};
+
+struct cp_usb_async *
+cp_usb_async_open(void)
+{
+ struct cp_usb_async *cp;
+ int ret;
+
+ cp = calloc(sizeof (struct cp_usb_async), 1);
+ if (!cp)
+ return NULL;
+ ret = libusb_init(&cp->ctx);
+ if (ret) {
+ free(cp);
+ return NULL;
+ }
+ cp->handle = libusb_open_device_with_vid_pid(cp->ctx,
+ 0x10c4, 0xea60);
+ cp->ack = -1;
+ if (!cp->handle) {
+ libusb_exit(cp->ctx);
+ free(cp);
+ return NULL;
+ }
+ cp->value = 0;
+ cp->set = 0;
+ return cp;
+}
+
+void
+cp_usb_async_close(struct cp_usb_async *cp)
+{
+ libusb_close(cp->handle);
+ libusb_exit(cp->ctx);
+ free(cp);
+}
+
+static void
+cp_usb_async_transfer_callback(struct libusb_transfer *transfer)
+{
+ struct cp_usb_async *cp = transfer->user_data;
+ int p;
+
+ for (p = 0; p < cp->p; p++)
+ if (cp->packet[p].transfer == transfer)
+ break;
+ if (p == cp->p) {
+ fprintf(stderr, "unknown transfer\n");
+ return;
+ }
+ switch (cp->packet[p].direction) {
+ case packet_read:
+ ccdbg_debug(CC_DEBUG_USB_ASYNC, "ack read %d 0x%02x\n",
+ p, cp->packet[p].data[8]);
+ *cp->packet[p].valuep = cp->packet[p].data[8];
+ break;
+ case packet_write:
+ ccdbg_debug(CC_DEBUG_USB_ASYNC, "ack write %d\n", p);
+ break;
+ }
+ if (p > cp->ack)
+ cp->ack = p;
+}
+
+void
+cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value)
+{
+ int p;
+ uint16_t gpio_set;
+ int ret;
+
+ if (cp->set) {
+ value = (cp->value & ~mask) | (value & mask);
+ mask = value ^ cp->value;
+ }
+ cp->set = 1;
+ cp->value = value;
+ gpio_set = ((uint16_t) value << 8) | mask;
+ if (cp->p == MAX_OUTSTANDING)
+ cp_usb_async_sync(cp);
+ p = cp->p;
+ if (!cp->packet[p].transfer)
+ cp->packet[p].transfer = libusb_alloc_transfer(0);
+ cp->packet[p].direction = packet_write;
+ libusb_fill_control_setup(cp->packet[p].data,
+ 0x40, /* request */
+ 0xff, /* request type */
+ 0x37e1, /* value */
+ gpio_set, /* index */
+ 0); /* length */
+
+ libusb_fill_control_transfer(cp->packet[p].transfer,
+ cp->handle,
+ cp->packet[p].data,
+ cp_usb_async_transfer_callback,
+ cp,
+ CP_TIMEOUT);
+ ccdbg_debug(CC_DEBUG_USB_ASYNC, "Write packet %d 0x%x 0x%x\n", p, mask, value);
+ ret = libusb_submit_transfer(cp->packet[p].transfer);
+ if (ret)
+ fprintf(stderr, "libusb_submit_transfer failed %d\n", ret);
+ cp->p++;
+}
+
+void
+cp_usb_async_read(struct cp_usb_async *cp, uint8_t *valuep)
+{
+ int p;
+ int ret;
+
+ if (cp->p == MAX_OUTSTANDING)
+ cp_usb_async_sync(cp);
+ p = cp->p;
+ if (!cp->packet[p].transfer)
+ cp->packet[p].transfer = libusb_alloc_transfer(0);
+ cp->packet[p].valuep = valuep;
+ cp->packet[p].direction = packet_read;
+ libusb_fill_control_setup(cp->packet[p].data,
+ 0xc0, /* request */
+ 0xff, /* request type */
+ 0x00c2, /* value */
+ 0, /* index */
+ 1); /* length */
+
+ libusb_fill_control_transfer(cp->packet[p].transfer,
+ cp->handle,
+ cp->packet[p].data,
+ cp_usb_async_transfer_callback,
+ cp,
+ CP_TIMEOUT);
+ ccdbg_debug(CC_DEBUG_USB_ASYNC, "Read packet %d\n", p);
+ ret = libusb_submit_transfer(cp->packet[p].transfer);
+ if (ret)
+ fprintf(stderr, "libusb_submit_transfer failed %d\n", ret);
+ cp->p++;
+}
+
+void
+cp_usb_async_sync(struct cp_usb_async *cp)
+{
+ while (cp->ack < cp->p - 1) {
+ libusb_handle_events(cp->ctx);
+ }
+ cp->p = 0;
+ cp->ack = -1;
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _CP_USB_ASYNC_H_
+#define _CP_USB_ASYNC_H_
+#include <libusb.h>
+
+struct cp_usb_async *
+cp_usb_async_open(void);
+
+void
+cp_usb_async_close(struct cp_usb_async *cp);
+
+void
+cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value);
+
+void
+cp_usb_async_read(struct cp_usb_async *cp, uint8_t *valuep);
+
+void
+cp_usb_async_sync(struct cp_usb_async *cp);
+
+#endif
--- /dev/null
+PROG=adc_serial
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --stack-auto --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=$(PROG).c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=$(PROG)-flash.ihx $(PROG)-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+$(PROG)-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL)
+
+$(PROG)-flash.ihx: $(PROG)-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdint.h>
+
+/*
+ * Test ADC in DMA mode
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN (1 << 7)
+# define SLEEP_XOSC_STB (1 << 6)
+
+sfr at 0xF1 PERCFG;
+#define PERCFG_T1CFG_ALT_1 (0 << 6)
+#define PERCFG_T1CFG_ALT_2 (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1 (0 << 5)
+#define PERCFG_T3CFG_ALT_2 (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1 (0 << 4)
+#define PERCFG_T4CFG_ALT_2 (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1 (0 << 1)
+#define PERCFG_U1CFG_ALT_2 (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1 (0 << 0)
+#define PERCFG_U0CFG_ALT_2 (1 << 0)
+
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+/*
+ * UART registers
+ */
+
+sfr at 0x86 U0CSR;
+sfr at 0xF8 U1CSR;
+
+/*
+ * IRCON2
+ */
+sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
+
+sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
+sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
+sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
+sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
+sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
+sbit at 0xEB P1IF; /* Port1 interrupt flag */
+sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
+
+# define UxCSR_MODE_UART (1 << 7)
+# define UxCSR_MODE_SPI (0 << 7)
+# define UxCSR_RE (1 << 6)
+# define UxCSR_SLAVE (1 << 5)
+# define UxCSR_MASTER (0 << 5)
+# define UxCSR_FE (1 << 4)
+# define UxCSR_ERR (1 << 3)
+# define UxCSR_RX_BYTE (1 << 2)
+# define UxCSR_TX_BYTE (1 << 1)
+# define UxCSR_ACTIVE (1 << 0)
+
+sfr at 0xc4 U0UCR;
+sfr at 0xfb U1UCR;
+
+# define UxUCR_FLUSH (1 << 7)
+# define UxUCR_FLOW_DISABLE (0 << 6)
+# define UxUCR_FLOW_ENABLE (1 << 6)
+# define UxUCR_D9_EVEN_PARITY (0 << 5)
+# define UxUCR_D9_ODD_PARITY (1 << 5)
+# define UxUCR_BIT9_8_BITS (0 << 4)
+# define UxUCR_BIT9_9_BITS (1 << 4)
+# define UxUCR_PARITY_DISABLE (0 << 3)
+# define UxUCR_PARITY_ENABLE (1 << 3)
+# define UxUCR_SPB_1_STOP_BIT (0 << 2)
+# define UxUCR_SPB_2_STOP_BITS (1 << 2)
+# define UxUCR_STOP_LOW (0 << 1)
+# define UxUCR_STOP_HIGH (1 << 1)
+# define UxUCR_START_LOW (0 << 0)
+# define UxUCR_START_HIGH (1 << 0)
+
+sfr at 0xc5 U0GCR;
+sfr at 0xfc U1GCR;
+
+# define UxGCR_CPOL_NEGATIVE (0 << 7)
+# define UxGCR_CPOL_POSITIVE (1 << 7)
+# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
+# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
+# define UxGCR_ORDER_LSB (0 << 5)
+# define UxGCR_ORDER_MSB (1 << 5)
+# define UxGCR_BAUD_E_MASK (0x1f)
+# define UxGCR_BAUD_E_SHIFT 0
+
+sfr at 0xc1 U0DBUF;
+sfr at 0xf9 U1DBUF;
+sfr at 0xc2 U0BAUD;
+sfr at 0xfa U1BAUD;
+
+#define DEBUG P1_1
+
+
+# define DMA_LEN_HIGH_VLEN_MASK (7 << 5)
+# define DMA_LEN_HIGH_VLEN_LEN (0 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5)
+# define DMA_LEN_HIGH_VLEN (2 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5)
+# define DMA_LEN_HIGH_MASK (0x1f)
+
+# define DMA_CFG0_WORDSIZE_8 (0 << 7)
+# define DMA_CFG0_WORDSIZE_16 (1 << 7)
+# define DMA_CFG0_TMODE_MASK (3 << 5)
+# define DMA_CFG0_TMODE_SINGLE (0 << 5)
+# define DMA_CFG0_TMODE_BLOCK (1 << 5)
+# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5)
+# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
+
+/*
+ * DMA triggers
+ */
+# define DMA_CFG0_TRIGGER_NONE 0
+# define DMA_CFG0_TRIGGER_PREV 1
+# define DMA_CFG0_TRIGGER_T1_CH0 2
+# define DMA_CFG0_TRIGGER_T1_CH1 3
+# define DMA_CFG0_TRIGGER_T1_CH2 4
+# define DMA_CFG0_TRIGGER_T2_OVFL 6
+# define DMA_CFG0_TRIGGER_T3_CH0 7
+# define DMA_CFG0_TRIGGER_T3_CH1 8
+# define DMA_CFG0_TRIGGER_T4_CH0 9
+# define DMA_CFG0_TRIGGER_T4_CH1 10
+# define DMA_CFG0_TRIGGER_IOC_0 12
+# define DMA_CFG0_TRIGGER_IOC_1 13
+# define DMA_CFG0_TRIGGER_URX0 14
+# define DMA_CFG0_TRIGGER_UTX0 15
+# define DMA_CFG0_TRIGGER_URX1 16
+# define DMA_CFG0_TRIGGER_UTX1 17
+# define DMA_CFG0_TRIGGER_FLASH 18
+# define DMA_CFG0_TRIGGER_RADIO 19
+# define DMA_CFG0_TRIGGER_ADC_CHALL 20
+# define DMA_CFG0_TRIGGER_ADC_CH0 21
+# define DMA_CFG0_TRIGGER_ADC_CH1 22
+# define DMA_CFG0_TRIGGER_ADC_CH2 23
+# define DMA_CFG0_TRIGGER_ADC_CH3 24
+# define DMA_CFG0_TRIGGER_ADC_CH4 25
+# define DMA_CFG0_TRIGGER_ADC_CH5 26
+# define DMA_CFG0_TRIGGER_ADC_CH6 27
+# define DMA_CFG0_TRIGGER_I2SRX 27
+# define DMA_CFG0_TRIGGER_ADC_CH7 28
+# define DMA_CFG0_TRIGGER_I2STX 28
+# define DMA_CFG0_TRIGGER_ENC_DW 29
+# define DMA_CFG0_TRIGGER_DNC_UP 30
+
+# define DMA_CFG1_SRCINC_MASK (3 << 6)
+# define DMA_CFG1_SRCINC_0 (0 << 6)
+# define DMA_CFG1_SRCINC_1 (1 << 6)
+# define DMA_CFG1_SRCINC_2 (2 << 6)
+# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6)
+
+# define DMA_CFG1_DESTINC_MASK (3 << 4)
+# define DMA_CFG1_DESTINC_0 (0 << 4)
+# define DMA_CFG1_DESTINC_1 (1 << 4)
+# define DMA_CFG1_DESTINC_2 (2 << 4)
+# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4)
+
+# define DMA_CFG1_IRQMASK (1 << 3)
+# define DMA_CFG1_M8 (1 << 2)
+
+# define DMA_CFG1_PRIORITY_MASK (3 << 0)
+# define DMA_CFG1_PRIORITY_LOW (0 << 0)
+# define DMA_CFG1_PRIORITY_NORMAL (1 << 0)
+# define DMA_CFG1_PRIORITY_HIGH (2 << 0)
+
+/*
+ * DMAARM - DMA Channel Arm
+ */
+
+sfr at 0xD6 DMAARM;
+
+# define DMAARM_ABORT (1 << 7)
+# define DMAARM_DMAARM4 (1 << 4)
+# define DMAARM_DMAARM3 (1 << 3)
+# define DMAARM_DMAARM2 (1 << 2)
+# define DMAARM_DMAARM1 (1 << 1)
+# define DMAARM_DMAARM0 (1 << 0)
+
+/*
+ * DMAREQ - DMA Channel Start Request and Status
+ */
+
+sfr at 0xD7 DMAREQ;
+
+# define DMAREQ_DMAREQ4 (1 << 4)
+# define DMAREQ_DMAREQ3 (1 << 3)
+# define DMAREQ_DMAREQ2 (1 << 2)
+# define DMAREQ_DMAREQ1 (1 << 1)
+# define DMAREQ_DMAREQ0 (1 << 0)
+
+/*
+ * DMA configuration 0 address
+ */
+
+sfr at 0xD5 DMA0CFGH;
+sfr at 0xD4 DMA0CFGL;
+
+/*
+ * DMA configuration 1-4 address
+ */
+
+sfr at 0xD3 DMA1CFGH;
+sfr at 0xD2 DMA1CFGL;
+
+/*
+ * DMAIRQ - DMA Interrupt Flag
+ */
+
+sfr at 0xD1 DMAIRQ;
+
+# define DMAIRQ_DMAIF4 (1 << 4)
+# define DMAIRQ_DMAIF3 (1 << 3)
+# define DMAIRQ_DMAIF2 (1 << 2)
+# define DMAIRQ_DMAIF1 (1 << 1)
+# define DMAIRQ_DMAIF0 (1 << 0)
+
+struct cc_dma_channel {
+ uint8_t src_high;
+ uint8_t src_low;
+ uint8_t dst_high;
+ uint8_t dst_low;
+ uint8_t len_high;
+ uint8_t len_low;
+ uint8_t cfg0;
+ uint8_t cfg1;
+};
+
+/*
+ * ADC Data register, low and high
+ */
+sfr at 0xBA ADCL;
+sfr at 0xBB ADCH;
+__xdata __at (0xDFBA) volatile uint16_t ADCXDATA;
+
+/*
+ * ADC Control Register 1
+ */
+sfr at 0xB4 ADCCON1;
+
+# define ADCCON1_EOC (1 << 7) /* conversion complete */
+# define ADCCON1_ST (1 << 6) /* start conversion */
+
+# define ADCCON1_STSEL_MASK (3 << 4) /* start select */
+# define ADCCON1_STSEL_EXTERNAL (0 << 4) /* P2_0 pin triggers */
+# define ADCCON1_STSEL_FULLSPEED (1 << 4) /* full speed, no waiting */
+# define ADCCON1_STSEL_TIMER1 (2 << 4) /* timer 1 channel 0 */
+# define ADCCON1_STSEL_START (3 << 4) /* set start bit */
+
+# define ADCCON1_RCTRL_MASK (3 << 2) /* random number control */
+# define ADCCON1_RCTRL_COMPLETE (0 << 2) /* operation completed */
+# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2) /* Clock the LFSR once */
+
+/*
+ * ADC Control Register 2
+ */
+sfr at 0xB5 ADCCON2;
+
+# define ADCCON2_SREF_MASK (3 << 6) /* reference voltage */
+# define ADCCON2_SREF_1_25V (0 << 6) /* internal 1.25V */
+# define ADCCON2_SREF_EXTERNAL (1 << 6) /* external on AIN7 cc1110 */
+# define ADCCON2_SREF_VDD (2 << 6) /* VDD on the AVDD pin */
+# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6) /* external on AIN6-7 cc1110 */
+
+# define ADCCON2_SDIV_MASK (3 << 4) /* decimation rate */
+# define ADCCON2_SDIV_64 (0 << 4) /* 7 bits */
+# define ADCCON2_SDIV_128 (1 << 4) /* 9 bits */
+# define ADCCON2_SDIV_256 (2 << 4) /* 10 bits */
+# define ADCCON2_SDIV_512 (3 << 4) /* 12 bits */
+
+# define ADCCON2_SCH_MASK (0xf << 0) /* Sequence channel select */
+# define ADCCON2_SCH_SHIFT 0
+# define ADCCON2_SCH_AIN0 (0 << 0)
+# define ADCCON2_SCH_AIN1 (1 << 0)
+# define ADCCON2_SCH_AIN2 (2 << 0)
+# define ADCCON2_SCH_AIN3 (3 << 0)
+# define ADCCON2_SCH_AIN4 (4 << 0)
+# define ADCCON2_SCH_AIN5 (5 << 0)
+# define ADCCON2_SCH_AIN6 (6 << 0)
+# define ADCCON2_SCH_AIN7 (7 << 0)
+# define ADCCON2_SCH_AIN0_AIN1 (8 << 0)
+# define ADCCON2_SCH_AIN2_AIN3 (9 << 0)
+# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0)
+# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0)
+# define ADCCON2_SCH_GND (0xc << 0)
+# define ADCCON2_SCH_VREF (0xd << 0)
+# define ADCCON2_SCH_TEMP (0xe << 0)
+# define ADCCON2_SCH_VDD_3 (0xf << 0)
+
+
+/*
+ * ADC Control Register 3
+ */
+
+sfr at 0xB6 ADCCON3;
+
+# define ADCCON3_EREF_MASK (3 << 6) /* extra conversion reference */
+# define ADCCON3_EREF_1_25 (0 << 6) /* internal 1.25V */
+# define ADCCON3_EREF_EXTERNAL (1 << 6) /* external AIN7 cc1110 */
+# define ADCCON3_EREF_VDD (2 << 6) /* VDD on the AVDD pin */
+# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6) /* external AIN6-7 cc1110 */
+# define ADCCON2_EDIV_MASK (3 << 4) /* extral decimation */
+# define ADCCON2_EDIV_64 (0 << 4) /* 7 bits */
+# define ADCCON2_EDIV_128 (1 << 4) /* 9 bits */
+# define ADCCON2_EDIV_256 (2 << 4) /* 10 bits */
+# define ADCCON2_EDIV_512 (3 << 4) /* 12 bits */
+# define ADCCON3_ECH_MASK (0xf << 0) /* Sequence channel select */
+# define ADCCON3_ECH_SHIFT 0
+# define ADCCON3_ECH_AIN0 (0 << 0)
+# define ADCCON3_ECH_AIN1 (1 << 0)
+# define ADCCON3_ECH_AIN2 (2 << 0)
+# define ADCCON3_ECH_AIN3 (3 << 0)
+# define ADCCON3_ECH_AIN4 (4 << 0)
+# define ADCCON3_ECH_AIN5 (5 << 0)
+# define ADCCON3_ECH_AIN6 (6 << 0)
+# define ADCCON3_ECH_AIN7 (7 << 0)
+# define ADCCON3_ECH_AIN0_AIN1 (8 << 0)
+# define ADCCON3_ECH_AIN2_AIN3 (9 << 0)
+# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0)
+# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0)
+# define ADCCON3_ECH_GND (0xc << 0)
+# define ADCCON3_ECH_VREF (0xd << 0)
+# define ADCCON3_ECH_TEMP (0xe << 0)
+# define ADCCON3_ECH_VDD_3 (0xf << 0)
+
+sfr at 0xF2 ADCCFG;
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0;
+ unsigned char j = 0;
+
+ n++;
+ while (--n != 0)
+ while (--i != 0)
+ while (--j != 0)
+ nop();
+}
+
+void
+debug_byte(uint8_t byte)
+{
+ uint8_t s;
+
+ for (s = 0; s < 8; s++) {
+ DEBUG = byte & 1;
+ delay(5);
+ byte >>= 1;
+ }
+}
+
+struct cc_dma_channel __xdata dma_config;
+
+#define ADC_LEN 6
+
+/* The DMA engine writes to XDATA in MSB order */
+struct dma_xdata16 {
+ uint8_t high;
+ uint8_t low;
+};
+
+struct dma_xdata16 adc_output[ADC_LEN];
+
+#define DMA_XDATA16(a,n) ((uint16_t) ((a)[n].high << 8) | (uint16_t) (a[n].low))
+
+#define ADDRH(a) (((uint16_t) (a)) >> 8)
+#define ADDRL(a) (((uint16_t) (a)))
+
+void
+adc_init(void)
+{
+ dma_config.cfg0 = (DMA_CFG0_WORDSIZE_16 |
+ DMA_CFG0_TMODE_REPEATED_SINGLE |
+ DMA_CFG0_TRIGGER_ADC_CHALL);
+ dma_config.cfg1 = (DMA_CFG1_SRCINC_0 |
+ DMA_CFG1_DESTINC_1 |
+ DMA_CFG1_PRIORITY_NORMAL);
+
+ dma_config.src_high = ADDRH(&ADCXDATA);
+ dma_config.src_low = ADDRL(&ADCXDATA);
+ dma_config.dst_high = ADDRH(adc_output);
+ dma_config.dst_low = ADDRL(adc_output);
+ dma_config.len_high = 0;
+ dma_config.len_low = ADC_LEN;
+ DMA0CFGH = ADDRH(&dma_config);
+ DMA0CFGL = ADDRL(&dma_config);
+ ADCCFG = ((1 << 0) | /* acceleration */
+ (1 << 1) | /* pressure */
+ (1 << 2) | /* temperature */
+ (1 << 3) | /* battery voltage */
+ (1 << 4) | /* drogue sense */
+ (1 << 5)); /* main sense */
+
+ ADCCON1 = (ADCCON1_STSEL_START); /* ST bit triggers */
+ ADCCON2 = (ADCCON2_SREF_VDD | /* reference voltage is VDD */
+ ADCCON2_SDIV_512 | /* 12 bit ADC results */
+ ADCCON2_SCH_AIN5); /* sample all 6 inputs */
+}
+
+void
+adc_run(void)
+{
+ DMAIRQ &= ~1;
+ DMAARM |= 1;
+ ADCCON1 |= ADCCON1_ST;
+ while ((DMAIRQ & 1) == 0)
+ ;
+}
+
+/*
+ * This version uses the USART in UART mode
+ */
+void
+usart_init(void)
+{
+ P1DIR |= (1 << 2);
+ /*
+ * Configure the peripheral pin choices
+ * for both of the serial ports
+ *
+ * Note that telemetrum will use U1CFG_ALT_2
+ * but that overlaps with SPI ALT_2, so until
+ * we can test that this works, we'll set this
+ * to ALT_1
+ */
+ PERCFG = (PERCFG_U1CFG_ALT_2 |
+ PERCFG_U0CFG_ALT_1);
+
+ /*
+ * Make the UART pins controlled by the UART
+ * hardware
+ */
+ P1SEL |= ((1 << 6) | (1 << 7));
+
+ /*
+ * UART mode with the receiver enabled
+ */
+ U1CSR = (UxCSR_MODE_UART |
+ UxCSR_RE);
+ /*
+ * Pick a 38.4kbaud rate
+ */
+ U1BAUD = 163;
+ U1GCR = 10 << UxGCR_BAUD_E_SHIFT; /* 38400 */
+// U1GCR = 3 << UxGCR_BAUD_E_SHIFT; /* 300 */
+ /*
+ * Reasonable serial parameters
+ */
+ U1UCR = (UxUCR_FLUSH |
+ UxUCR_FLOW_DISABLE |
+ UxUCR_D9_ODD_PARITY |
+ UxUCR_BIT9_8_BITS |
+ UxUCR_PARITY_DISABLE |
+ UxUCR_SPB_2_STOP_BITS |
+ UxUCR_STOP_HIGH |
+ UxUCR_START_LOW);
+}
+
+void
+usart_out_byte(uint8_t byte)
+{
+ U1DBUF = byte;
+ while (!UTX1IF)
+ ;
+ UTX1IF = 0;
+}
+
+void
+usart_out_string(uint8_t *string)
+{
+ uint8_t b;
+
+ while (b = *string++)
+ usart_out_byte(b);
+}
+
+#define NUM_LEN 6
+
+uint8_t __xdata num_buffer[NUM_LEN];
+uint8_t __xdata * __xdata num_ptr;
+
+void
+usart_out_number(uint16_t v)
+{
+
+ num_ptr = num_buffer + NUM_LEN;
+ *--num_ptr = '\0';
+ do {
+ *--num_ptr = '0' + v % 10;
+ v /= 10;
+ } while (v);
+ while (num_ptr != num_buffer)
+ *--num_ptr = ' ';
+ usart_out_string(num_buffer);
+}
+
+#define ADC(n) DMA_XDATA16(adc_output,n)
+
+main ()
+{
+ P1DIR = 3;
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+
+ adc_init();
+ P1_0 = 1;
+ usart_init();
+ for (;;) {
+ adc_run();
+ usart_out_string("accel: ");
+ usart_out_number(ADC(0));
+ usart_out_string(" pres: ");
+ usart_out_number(ADC(1));
+ usart_out_string(" temp: ");
+ usart_out_number(ADC(2));
+ usart_out_string(" batt: ");
+ usart_out_number(ADC(3));
+ usart_out_string(" drogue: ");
+ usart_out_number(ADC(4));
+ usart_out_string(" main: ");
+ usart_out_number(ADC(5));
+ usart_out_string("\r\n");
+ delay(10);
+ }
+}
--- /dev/null
+PROG=adc
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=$(PROG).c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=$(PROG)-flash.ihx $(PROG)-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+$(PROG)-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL)
+
+$(PROG)-flash.ihx: $(PROG)-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdint.h>
+
+/*
+ * Test ADC in DMA mode
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN (1 << 7)
+# define SLEEP_XOSC_STB (1 << 6)
+
+sfr at 0xF1 PERCFG;
+#define PERCFG_T1CFG_ALT_1 (0 << 6)
+#define PERCFG_T1CFG_ALT_2 (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1 (0 << 5)
+#define PERCFG_T3CFG_ALT_2 (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1 (0 << 4)
+#define PERCFG_T4CFG_ALT_2 (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1 (0 << 1)
+#define PERCFG_U1CFG_ALT_2 (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1 (0 << 0)
+#define PERCFG_U0CFG_ALT_2 (1 << 0)
+
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+/*
+ * UART registers
+ */
+
+sfr at 0x86 U0CSR;
+sfr at 0xF8 U1CSR;
+
+/*
+ * IRCON2
+ */
+sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
+
+sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
+sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
+sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
+sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
+sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
+sbit at 0xEB P1IF; /* Port1 interrupt flag */
+sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
+
+# define UxCSR_MODE_UART (1 << 7)
+# define UxCSR_MODE_SPI (0 << 7)
+# define UxCSR_RE (1 << 6)
+# define UxCSR_SLAVE (1 << 5)
+# define UxCSR_MASTER (0 << 5)
+# define UxCSR_FE (1 << 4)
+# define UxCSR_ERR (1 << 3)
+# define UxCSR_RX_BYTE (1 << 2)
+# define UxCSR_TX_BYTE (1 << 1)
+# define UxCSR_ACTIVE (1 << 0)
+
+sfr at 0xc4 U0UCR;
+sfr at 0xfb U1UCR;
+
+# define UxUCR_FLUSH (1 << 7)
+# define UxUCR_FLOW_DISABLE (0 << 6)
+# define UxUCR_FLOW_ENABLE (1 << 6)
+# define UxUCR_D9_EVEN_PARITY (0 << 5)
+# define UxUCR_D9_ODD_PARITY (1 << 5)
+# define UxUCR_BIT9_8_BITS (0 << 4)
+# define UxUCR_BIT9_9_BITS (1 << 4)
+# define UxUCR_PARITY_DISABLE (0 << 3)
+# define UxUCR_PARITY_ENABLE (1 << 3)
+# define UxUCR_SPB_1_STOP_BIT (0 << 2)
+# define UxUCR_SPB_2_STOP_BITS (1 << 2)
+# define UxUCR_STOP_LOW (0 << 1)
+# define UxUCR_STOP_HIGH (1 << 1)
+# define UxUCR_START_LOW (0 << 0)
+# define UxUCR_START_HIGH (1 << 0)
+
+sfr at 0xc5 U0GCR;
+sfr at 0xfc U1GCR;
+
+# define UxGCR_CPOL_NEGATIVE (0 << 7)
+# define UxGCR_CPOL_POSITIVE (1 << 7)
+# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
+# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
+# define UxGCR_ORDER_LSB (0 << 5)
+# define UxGCR_ORDER_MSB (1 << 5)
+# define UxGCR_BAUD_E_MASK (0x1f)
+# define UxGCR_BAUD_E_SHIFT 0
+
+sfr at 0xc1 U0DBUF;
+sfr at 0xf9 U1DBUF;
+sfr at 0xc2 U0BAUD;
+sfr at 0xfa U1BAUD;
+
+#define DEBUG P1_1
+
+
+# define DMA_LEN_HIGH_VLEN_MASK (7 << 5)
+# define DMA_LEN_HIGH_VLEN_LEN (0 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5)
+# define DMA_LEN_HIGH_VLEN (2 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5)
+# define DMA_LEN_HIGH_MASK (0x1f)
+
+# define DMA_CFG0_WORDSIZE_8 (0 << 7)
+# define DMA_CFG0_WORDSIZE_16 (1 << 7)
+# define DMA_CFG0_TMODE_MASK (3 << 5)
+# define DMA_CFG0_TMODE_SINGLE (0 << 5)
+# define DMA_CFG0_TMODE_BLOCK (1 << 5)
+# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5)
+# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
+
+/*
+ * DMA triggers
+ */
+# define DMA_CFG0_TRIGGER_NONE 0
+# define DMA_CFG0_TRIGGER_PREV 1
+# define DMA_CFG0_TRIGGER_T1_CH0 2
+# define DMA_CFG0_TRIGGER_T1_CH1 3
+# define DMA_CFG0_TRIGGER_T1_CH2 4
+# define DMA_CFG0_TRIGGER_T2_OVFL 6
+# define DMA_CFG0_TRIGGER_T3_CH0 7
+# define DMA_CFG0_TRIGGER_T3_CH1 8
+# define DMA_CFG0_TRIGGER_T4_CH0 9
+# define DMA_CFG0_TRIGGER_T4_CH1 10
+# define DMA_CFG0_TRIGGER_IOC_0 12
+# define DMA_CFG0_TRIGGER_IOC_1 13
+# define DMA_CFG0_TRIGGER_URX0 14
+# define DMA_CFG0_TRIGGER_UTX0 15
+# define DMA_CFG0_TRIGGER_URX1 16
+# define DMA_CFG0_TRIGGER_UTX1 17
+# define DMA_CFG0_TRIGGER_FLASH 18
+# define DMA_CFG0_TRIGGER_RADIO 19
+# define DMA_CFG0_TRIGGER_ADC_CHALL 20
+# define DMA_CFG0_TRIGGER_ADC_CH0 21
+# define DMA_CFG0_TRIGGER_ADC_CH1 22
+# define DMA_CFG0_TRIGGER_ADC_CH2 23
+# define DMA_CFG0_TRIGGER_ADC_CH3 24
+# define DMA_CFG0_TRIGGER_ADC_CH4 25
+# define DMA_CFG0_TRIGGER_ADC_CH5 26
+# define DMA_CFG0_TRIGGER_ADC_CH6 27
+# define DMA_CFG0_TRIGGER_I2SRX 27
+# define DMA_CFG0_TRIGGER_ADC_CH7 28
+# define DMA_CFG0_TRIGGER_I2STX 28
+# define DMA_CFG0_TRIGGER_ENC_DW 29
+# define DMA_CFG0_TRIGGER_DNC_UP 30
+
+# define DMA_CFG1_SRCINC_MASK (3 << 6)
+# define DMA_CFG1_SRCINC_0 (0 << 6)
+# define DMA_CFG1_SRCINC_1 (1 << 6)
+# define DMA_CFG1_SRCINC_2 (2 << 6)
+# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6)
+
+# define DMA_CFG1_DESTINC_MASK (3 << 4)
+# define DMA_CFG1_DESTINC_0 (0 << 4)
+# define DMA_CFG1_DESTINC_1 (1 << 4)
+# define DMA_CFG1_DESTINC_2 (2 << 4)
+# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4)
+
+# define DMA_CFG1_IRQMASK (1 << 3)
+# define DMA_CFG1_M8 (1 << 2)
+
+# define DMA_CFG1_PRIORITY_MASK (3 << 0)
+# define DMA_CFG1_PRIORITY_LOW (0 << 0)
+# define DMA_CFG1_PRIORITY_NORMAL (1 << 0)
+# define DMA_CFG1_PRIORITY_HIGH (2 << 0)
+
+/*
+ * DMAARM - DMA Channel Arm
+ */
+
+sfr at 0xD6 DMAARM;
+
+# define DMAARM_ABORT (1 << 7)
+# define DMAARM_DMAARM4 (1 << 4)
+# define DMAARM_DMAARM3 (1 << 3)
+# define DMAARM_DMAARM2 (1 << 2)
+# define DMAARM_DMAARM1 (1 << 1)
+# define DMAARM_DMAARM0 (1 << 0)
+
+/*
+ * DMAREQ - DMA Channel Start Request and Status
+ */
+
+sfr at 0xD7 DMAREQ;
+
+# define DMAREQ_DMAREQ4 (1 << 4)
+# define DMAREQ_DMAREQ3 (1 << 3)
+# define DMAREQ_DMAREQ2 (1 << 2)
+# define DMAREQ_DMAREQ1 (1 << 1)
+# define DMAREQ_DMAREQ0 (1 << 0)
+
+/*
+ * DMA configuration 0 address
+ */
+
+sfr at 0xD5 DMA0CFGH;
+sfr at 0xD4 DMA0CFGL;
+
+/*
+ * DMA configuration 1-4 address
+ */
+
+sfr at 0xD3 DMA1CFGH;
+sfr at 0xD2 DMA1CFGL;
+
+/*
+ * DMAIRQ - DMA Interrupt Flag
+ */
+
+sfr at 0xD1 DMAIRQ;
+
+# define DMAIRQ_DMAIF4 (1 << 4)
+# define DMAIRQ_DMAIF3 (1 << 3)
+# define DMAIRQ_DMAIF2 (1 << 2)
+# define DMAIRQ_DMAIF1 (1 << 1)
+# define DMAIRQ_DMAIF0 (1 << 0)
+
+struct cc_dma_channel {
+ uint8_t src_high;
+ uint8_t src_low;
+ uint8_t dst_high;
+ uint8_t dst_low;
+ uint8_t len_high;
+ uint8_t len_low;
+ uint8_t cfg0;
+ uint8_t cfg1;
+};
+
+/*
+ * ADC Data register, low and high
+ */
+sfr at 0xBA ADCL;
+sfr at 0xBB ADCH;
+__xdata __at (0xDFBA) volatile uint16_t ADCXDATA;
+
+/*
+ * ADC Control Register 1
+ */
+sfr at 0xB4 ADCCON1;
+
+# define ADCCON1_EOC (1 << 7) /* conversion complete */
+# define ADCCON1_ST (1 << 6) /* start conversion */
+
+# define ADCCON1_STSEL_MASK (3 << 4) /* start select */
+# define ADCCON1_STSEL_EXTERNAL (0 << 4) /* P2_0 pin triggers */
+# define ADCCON1_STSEL_FULLSPEED (1 << 4) /* full speed, no waiting */
+# define ADCCON1_STSEL_TIMER1 (2 << 4) /* timer 1 channel 0 */
+# define ADCCON1_STSEL_START (3 << 4) /* set start bit */
+
+# define ADCCON1_RCTRL_MASK (3 << 2) /* random number control */
+# define ADCCON1_RCTRL_COMPLETE (0 << 2) /* operation completed */
+# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2) /* Clock the LFSR once */
+
+/*
+ * ADC Control Register 2
+ */
+sfr at 0xB5 ADCCON2;
+
+# define ADCCON2_SREF_MASK (3 << 6) /* reference voltage */
+# define ADCCON2_SREF_1_25V (0 << 6) /* internal 1.25V */
+# define ADCCON2_SREF_EXTERNAL (1 << 6) /* external on AIN7 cc1110 */
+# define ADCCON2_SREF_VDD (2 << 6) /* VDD on the AVDD pin */
+# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6) /* external on AIN6-7 cc1110 */
+
+# define ADCCON2_SDIV_MASK (3 << 4) /* decimation rate */
+# define ADCCON2_SDIV_64 (0 << 4) /* 7 bits */
+# define ADCCON2_SDIV_128 (1 << 4) /* 9 bits */
+# define ADCCON2_SDIV_256 (2 << 4) /* 10 bits */
+# define ADCCON2_SDIV_512 (3 << 4) /* 12 bits */
+
+# define ADCCON2_SCH_MASK (0xf << 0) /* Sequence channel select */
+# define ADCCON2_SCH_SHIFT 0
+# define ADCCON2_SCH_AIN0 (0 << 0)
+# define ADCCON2_SCH_AIN1 (1 << 0)
+# define ADCCON2_SCH_AIN2 (2 << 0)
+# define ADCCON2_SCH_AIN3 (3 << 0)
+# define ADCCON2_SCH_AIN4 (4 << 0)
+# define ADCCON2_SCH_AIN5 (5 << 0)
+# define ADCCON2_SCH_AIN6 (6 << 0)
+# define ADCCON2_SCH_AIN7 (7 << 0)
+# define ADCCON2_SCH_AIN0_AIN1 (8 << 0)
+# define ADCCON2_SCH_AIN2_AIN3 (9 << 0)
+# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0)
+# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0)
+# define ADCCON2_SCH_GND (0xc << 0)
+# define ADCCON2_SCH_VREF (0xd << 0)
+# define ADCCON2_SCH_TEMP (0xe << 0)
+# define ADCCON2_SCH_VDD_3 (0xf << 0)
+
+
+/*
+ * ADC Control Register 3
+ */
+
+sfr at 0xB6 ADCCON3;
+
+# define ADCCON3_EREF_MASK (3 << 6) /* extra conversion reference */
+# define ADCCON3_EREF_1_25 (0 << 6) /* internal 1.25V */
+# define ADCCON3_EREF_EXTERNAL (1 << 6) /* external AIN7 cc1110 */
+# define ADCCON3_EREF_VDD (2 << 6) /* VDD on the AVDD pin */
+# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6) /* external AIN6-7 cc1110 */
+# define ADCCON2_EDIV_MASK (3 << 4) /* extral decimation */
+# define ADCCON2_EDIV_64 (0 << 4) /* 7 bits */
+# define ADCCON2_EDIV_128 (1 << 4) /* 9 bits */
+# define ADCCON2_EDIV_256 (2 << 4) /* 10 bits */
+# define ADCCON2_EDIV_512 (3 << 4) /* 12 bits */
+# define ADCCON3_ECH_MASK (0xf << 0) /* Sequence channel select */
+# define ADCCON3_ECH_SHIFT 0
+# define ADCCON3_ECH_AIN0 (0 << 0)
+# define ADCCON3_ECH_AIN1 (1 << 0)
+# define ADCCON3_ECH_AIN2 (2 << 0)
+# define ADCCON3_ECH_AIN3 (3 << 0)
+# define ADCCON3_ECH_AIN4 (4 << 0)
+# define ADCCON3_ECH_AIN5 (5 << 0)
+# define ADCCON3_ECH_AIN6 (6 << 0)
+# define ADCCON3_ECH_AIN7 (7 << 0)
+# define ADCCON3_ECH_AIN0_AIN1 (8 << 0)
+# define ADCCON3_ECH_AIN2_AIN3 (9 << 0)
+# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0)
+# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0)
+# define ADCCON3_ECH_GND (0xc << 0)
+# define ADCCON3_ECH_VREF (0xd << 0)
+# define ADCCON3_ECH_TEMP (0xe << 0)
+# define ADCCON3_ECH_VDD_3 (0xf << 0)
+
+sfr at 0xF2 ADCCFG;
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0;
+ unsigned char j = 0;
+
+ n++;
+ while (--n != 0)
+ while (--i != 0)
+ while (--j != 0)
+ nop();
+}
+
+void
+debug_byte(uint8_t byte)
+{
+ uint8_t s;
+
+ for (s = 0; s < 8; s++) {
+ DEBUG = byte & 1;
+ delay(5);
+ byte >>= 1;
+ }
+}
+
+struct cc_dma_channel __xdata dma_config;
+
+#define ADC_LEN 6
+
+uint16_t __xdata adc_output[ADC_LEN];
+
+#define ADDRH(a) (((uint16_t) (a)) >> 8)
+#define ADDRL(a) (((uint16_t) (a)))
+
+void
+adc_init(void)
+{
+ dma_config.cfg0 = (DMA_CFG0_WORDSIZE_16 |
+ DMA_CFG0_TMODE_REPEATED_SINGLE |
+ DMA_CFG0_TRIGGER_ADC_CHALL);
+ dma_config.cfg1 = (DMA_CFG1_SRCINC_0 |
+ DMA_CFG1_DESTINC_1 |
+ DMA_CFG1_PRIORITY_NORMAL);
+
+ dma_config.src_high = ADDRH(&ADCXDATA);
+ dma_config.src_low = ADDRL(&ADCXDATA);
+ dma_config.dst_high = ADDRH(adc_output);
+ dma_config.dst_low = ADDRL(adc_output);
+ dma_config.len_high = 0;
+ dma_config.len_low = ADC_LEN;
+ DMA0CFGH = ADDRH(&dma_config);
+ DMA0CFGL = ADDRL(&dma_config);
+ ADCCFG = ((1 << 0) | /* acceleration */
+ (1 << 1) | /* pressure */
+ (1 << 2) | /* temperature */
+ (1 << 3) | /* battery voltage */
+ (1 << 4) | /* drogue sense */
+ (1 << 5)); /* main sense */
+
+ ADCCON1 = (ADCCON1_STSEL_START); /* ST bit triggers */
+ ADCCON2 = (ADCCON2_SREF_VDD | /* reference voltage is VDD */
+ ADCCON2_SDIV_512 | /* 12 bit ADC results */
+ ADCCON2_SCH_AIN5); /* sample all 6 inputs */
+}
+
+void
+adc_run(void)
+{
+ DMAIRQ &= ~1;
+ DMAARM |= 1;
+ ADCCON1 |= ADCCON1_ST;
+ while ((DMAIRQ & 1) == 0)
+ ;
+}
+
+main ()
+{
+ int i;
+ P1DIR |= 2;
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+ while (P1 & 0x4)
+ ;
+
+ adc_init();
+ for (;;) {
+ adc_run();
+ for (i = 0; i < ADC_LEN; i++)
+ debug_byte(adc_output[i]);
+ }
+}
--- /dev/null
+PROG=beep_timer
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=$(PROG).c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=$(PROG)-flash.ihx $(PROG)-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+$(PROG)-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL)
+
+$(PROG)-flash.ihx: $(PROG)-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN (1 << 7)
+# define SLEEP_XOSC_STB (1 << 6)
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+sfr at 0xF1 PERCFG;
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+#define P2SEL_PRI3P1_USART0 (0 << 6)
+#define P2SEL_PRI3P1_USART1 (1 << 6)
+#define P2SEL_PRI2P1_USART1 (0 << 5)
+#define P2SEL_PRI2P1_TIMER3 (1 << 5)
+#define P2SEL_PRI1P1_TIMER1 (0 << 4)
+#define P2SEL_PRI1P1_TIMER4 (1 << 4)
+#define P2SEL_PRI0P1_USART0 (0 << 3)
+#define P2SEL_PRI0P1_TIMER1 (1 << 3)
+#define P2SEL_SELP2_4_GPIO (0 << 2)
+#define P2SEL_SELP2_4_PERIPHERAL (1 << 2)
+#define P2SEL_SELP2_3_GPIO (0 << 1)
+#define P2SEL_SELP2_3_PERIPHERAL (1 << 1)
+#define P2SEL_SELP2_0_GPIO (0 << 0)
+#define P2SEL_SELP2_0_PERIPHERAL (1 << 0)
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sfr at 0xF1 PERCFG;
+#define PERCFG_T1CFG_ALT_1 (0 << 6)
+#define PERCFG_T1CFG_ALT_2 (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1 (0 << 5)
+#define PERCFG_T3CFG_ALT_2 (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1 (0 << 4)
+#define PERCFG_T4CFG_ALT_2 (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1 (0 << 1)
+#define PERCFG_U1CFG_ALT_2 (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1 (0 << 0)
+#define PERCFG_U0CFG_ALT_2 (1 << 0)
+
+/* Timer count */
+sfr at 0xCA T3CNT;
+sfr at 0xEA T4CNT;
+
+/* Timer control */
+
+sfr at 0xCB T3CTL;
+sfr at 0xEB T4CTL;
+
+#define TxCTL_DIV_1 (0 << 5)
+#define TxCTL_DIV_2 (1 << 5)
+#define TxCTL_DIV_4 (2 << 5)
+#define TxCTL_DIV_8 (3 << 5)
+#define TxCTL_DIV_16 (4 << 5)
+#define TxCTL_DIV_32 (5 << 5)
+#define TxCTL_DIV_64 (6 << 5)
+#define TxCTL_DIV_128 (7 << 5)
+#define TxCTL_START (1 << 4)
+#define TxCTL_OVFIM (1 << 3)
+#define TxCTL_CLR (1 << 2)
+#define TxCTL_MODE_FREE (0 << 0)
+#define TxCTL_MODE_DOWN (1 << 0)
+#define TxCTL_MODE_MODULO (2 << 0)
+#define TxCTL_MODE_UP_DOWN (3 << 0)
+
+/* Timer 4 channel 0 compare control */
+
+sfr at 0xCC T3CCTL0;
+sfr at 0xCE T3CCTL1;
+sfr at 0xEC T4CCTL0;
+sfr at 0xEE T4CCTL1;
+
+#define TxCCTLy_IM (1 << 6)
+#define TxCCTLy_CMP_SET (0 << 3)
+#define TxCCTLy_CMP_CLEAR (1 << 3)
+#define TxCCTLy_CMP_TOGGLE (2 << 3)
+#define TxCCTLy_CMP_SET_UP_CLEAR_DOWN (3 << 3)
+#define TxCCTLy_CMP_CLEAR_UP_SET_DOWN (4 << 3)
+#define TxCCTLy_CMP_SET_CLEAR_FF (5 << 3)
+#define TxCCTLy_CMP_CLEAR_SET_00 (6 << 3)
+#define TxCCTLy_CMP_MODE_ENABLE (1 << 2)
+
+/* Timer compare value */
+sfr at 0xCD T3CC0;
+sfr at 0xCF T3CC1;
+sfr at 0xED T4CC0;
+sfr at 0xEF T4CC1;
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0, j = 0;
+
+ n <<= 1;
+ while (--n != 0)
+ while (--j != 0)
+ while (--i != 0)
+ nop();
+}
+
+void
+dit() {
+ T4CTL |= TxCTL_START;
+ delay(1);
+ T4CTL &= ~TxCTL_START;
+ delay(1);
+}
+
+void
+dah () {
+ T4CTL |= TxCTL_START;
+ delay(3);
+ T4CTL &= ~TxCTL_START;
+ delay(1);
+}
+
+void
+charspace () {
+ delay(2);
+}
+
+void
+wordspace () {
+ delay(8);
+}
+
+#define _ dit();
+#define ___ dah();
+#define C charspace();
+#define W wordspace();
+
+main ()
+{
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+
+ /* Use timer 4 alternate config 2 */
+ PERCFG = PERCFG_T4CFG_ALT_2;
+ /* Use P2_4 for timer 4 output */
+ P2SEL = P2SEL_SELP2_0_PERIPHERAL;
+
+ T4CCTL0 = TxCCTLy_CMP_TOGGLE|TxCCTLy_CMP_MODE_ENABLE;
+ T4CC0 = 125;
+ T4CTL = TxCTL_DIV_32 | TxCTL_MODE_MODULO;
+
+ for (;;) {
+ ___ _ ___ _ C ___ ___ _ ___ W /* cq */
+ ___ _ _ C _ W /* de */
+ ___ _ ___ C ___ _ _ C /* kd */
+ ___ ___ _ _ _ C _ _ _ C /* 7s */
+ ___ ___ _ ___ C ___ ___ _ W /* qg */
+ if (T4CC0 == 94)
+ T4CC0 = 125;
+ else
+ T4CC0 = 94;
+ }
+}
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=beep.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=beep-flash.ihx beep-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+beep-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o beep-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o beep-flash.ihx $(REL)
+
+beep-flash.ihx: beep-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+
+sfr at 0xF1 PERCFG;
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0;
+
+ n <<= 1;
+ while (--n != 0) {
+ i = 211;
+ while (--i != 0)
+ nop();
+ }
+}
+
+void
+tone (unsigned char n, unsigned char m)
+{
+ unsigned char i = 0;
+ while (--m != 0) {
+ while (--i != 0) {
+ P2 = 0xff;
+ delay(n);
+ P2 = 0xfe;
+ delay(n);
+ }
+ }
+}
+
+void
+high() {
+ tone(1, 2);
+}
+
+void
+low() {
+ tone(2, 1);
+}
+
+main ()
+{
+ CLKCON = 0;
+ /* Set P2_0 to output */
+ P2DIR = 0x01;
+ P1INP = 0x00;
+ P2INP = 0x00;
+ for (;;) {
+ high();
+/* low(); */
+ }
+}
--- /dev/null
+*.ihx
+*.adb
+*.asm
+*.cdb
+*.lnk
+*.lst
+*.map
+*.mem
+*.rel
+*.rst
+*.sym
+blink-flash
+blink-ram
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=blink.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=blink-flash.ihx blink-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+blink-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink-flash.ihx $(REL)
+
+blink-flash.ihx: blink-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+
+sfr at 0xF1 PERCFG;
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0, j = 0;
+
+ n <<= 1;
+ while (--n != 0)
+ while (--j != 0)
+ while (--i != 0)
+ nop();
+}
+
+void
+dit() {
+ P1 = 0xff;
+ delay(1);
+ P1 = 0xfd;
+ delay(1);
+}
+
+void
+dah () {
+ P1 = 0xff;
+ delay(3);
+ P1 = 0xfd;
+ delay(1);
+}
+
+void
+charspace () {
+ delay(2);
+}
+
+void
+wordspace () {
+ delay(8);
+}
+
+#define _ dit();
+#define ___ dah();
+#define C charspace();
+#define W wordspace();
+
+main ()
+{
+ CLKCON = 0;
+ /* Set p1_1 to output */
+ P1DIR = 0x02;
+ P1INP = 0x00;
+ P2INP = 0x00;
+ for (;;) {
+ ___ _ ___ _ C ___ ___ _ ___ W /* cq */
+ ___ _ _ C _ W /* de */
+ ___ _ ___ C ___ _ _ C /* kd */
+ ___ ___ _ _ _ C _ _ _ C /* 7s */
+ ___ ___ _ ___ C ___ ___ _ W /* qg */
+ }
+}
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=dma.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=dma-flash.ihx dma-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+dma-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o dma-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o dma-flash.ihx $(REL)
+
+dma-flash.ihx: dma-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdint.h>
+
+/*
+ * Test DMA
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN (1 << 7)
+# define SLEEP_XOSC_STB (1 << 6)
+
+sfr at 0xF1 PERCFG;
+#define PERCFG_T1CFG_ALT_1 (0 << 6)
+#define PERCFG_T1CFG_ALT_2 (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1 (0 << 5)
+#define PERCFG_T3CFG_ALT_2 (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1 (0 << 4)
+#define PERCFG_T4CFG_ALT_2 (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1 (0 << 1)
+#define PERCFG_U1CFG_ALT_2 (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1 (0 << 0)
+#define PERCFG_U0CFG_ALT_2 (1 << 0)
+
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+/*
+ * UART registers
+ */
+
+sfr at 0x86 U0CSR;
+sfr at 0xF8 U1CSR;
+
+/*
+ * IRCON2
+ */
+sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
+
+sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
+sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
+sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
+sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
+sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
+sbit at 0xEB P1IF; /* Port1 interrupt flag */
+sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
+
+# define UxCSR_MODE_UART (1 << 7)
+# define UxCSR_MODE_SPI (0 << 7)
+# define UxCSR_RE (1 << 6)
+# define UxCSR_SLAVE (1 << 5)
+# define UxCSR_MASTER (0 << 5)
+# define UxCSR_FE (1 << 4)
+# define UxCSR_ERR (1 << 3)
+# define UxCSR_RX_BYTE (1 << 2)
+# define UxCSR_TX_BYTE (1 << 1)
+# define UxCSR_ACTIVE (1 << 0)
+
+sfr at 0xc4 U0UCR;
+sfr at 0xfb U1UCR;
+
+# define UxUCR_FLUSH (1 << 7)
+# define UxUCR_FLOW_DISABLE (0 << 6)
+# define UxUCR_FLOW_ENABLE (1 << 6)
+# define UxUCR_D9_EVEN_PARITY (0 << 5)
+# define UxUCR_D9_ODD_PARITY (1 << 5)
+# define UxUCR_BIT9_8_BITS (0 << 4)
+# define UxUCR_BIT9_9_BITS (1 << 4)
+# define UxUCR_PARITY_DISABLE (0 << 3)
+# define UxUCR_PARITY_ENABLE (1 << 3)
+# define UxUCR_SPB_1_STOP_BIT (0 << 2)
+# define UxUCR_SPB_2_STOP_BITS (1 << 2)
+# define UxUCR_STOP_LOW (0 << 1)
+# define UxUCR_STOP_HIGH (1 << 1)
+# define UxUCR_START_LOW (0 << 0)
+# define UxUCR_START_HIGH (1 << 0)
+
+sfr at 0xc5 U0GCR;
+sfr at 0xfc U1GCR;
+
+# define UxGCR_CPOL_NEGATIVE (0 << 7)
+# define UxGCR_CPOL_POSITIVE (1 << 7)
+# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
+# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
+# define UxGCR_ORDER_LSB (0 << 5)
+# define UxGCR_ORDER_MSB (1 << 5)
+# define UxGCR_BAUD_E_MASK (0x1f)
+# define UxGCR_BAUD_E_SHIFT 0
+
+sfr at 0xc1 U0DBUF;
+sfr at 0xf9 U1DBUF;
+sfr at 0xc2 U0BAUD;
+sfr at 0xfa U1BAUD;
+
+#define DEBUG P1_1
+
+
+# define DMA_LEN_HIGH_VLEN_MASK (7 << 5)
+# define DMA_LEN_HIGH_VLEN_LEN (0 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5)
+# define DMA_LEN_HIGH_VLEN (2 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5)
+# define DMA_LEN_HIGH_MASK (0x1f)
+
+# define DMA_CFG0_WORDSIZE_8 (0 << 7)
+# define DMA_CFG0_WORDSIZE_16 (1 << 7)
+# define DMA_CFG0_TMODE_MASK (3 << 5)
+# define DMA_CFG0_TMODE_SINGLE (0 << 5)
+# define DMA_CFG0_TMODE_BLOCK (1 << 5)
+# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5)
+# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
+
+/*
+ * DMA triggers
+ */
+# define DMA_CFG0_TRIGGER_NONE 0
+# define DMA_CFG0_TRIGGER_PREV 1
+# define DMA_CFG0_TRIGGER_T1_CH0 2
+# define DMA_CFG0_TRIGGER_T1_CH1 3
+# define DMA_CFG0_TRIGGER_T1_CH2 4
+# define DMA_CFG0_TRIGGER_T2_OVFL 6
+# define DMA_CFG0_TRIGGER_T3_CH0 7
+# define DMA_CFG0_TRIGGER_T3_CH1 8
+# define DMA_CFG0_TRIGGER_T4_CH0 9
+# define DMA_CFG0_TRIGGER_T4_CH1 10
+# define DMA_CFG0_TRIGGER_IOC_0 12
+# define DMA_CFG0_TRIGGER_IOC_1 13
+# define DMA_CFG0_TRIGGER_URX0 14
+# define DMA_CFG0_TRIGGER_UTX0 15
+# define DMA_CFG0_TRIGGER_URX1 16
+# define DMA_CFG0_TRIGGER_UTX1 17
+# define DMA_CFG0_TRIGGER_FLASH 18
+# define DMA_CFG0_TRIGGER_RADIO 19
+# define DMA_CFG0_TRIGGER_ADC_CHALL 20
+# define DMA_CFG0_TRIGGER_ADC_CH0 21
+# define DMA_CFG0_TRIGGER_ADC_CH1 22
+# define DMA_CFG0_TRIGGER_ADC_CH2 23
+# define DMA_CFG0_TRIGGER_ADC_CH3 24
+# define DMA_CFG0_TRIGGER_ADC_CH4 25
+# define DMA_CFG0_TRIGGER_ADC_CH5 26
+# define DMA_CFG0_TRIGGER_ADC_CH6 27
+# define DMA_CFG0_TRIGGER_I2SRX 27
+# define DMA_CFG0_TRIGGER_ADC_CH7 28
+# define DMA_CFG0_TRIGGER_I2STX 28
+# define DMA_CFG0_TRIGGER_ENC_DW 29
+# define DMA_CFG0_TRIGGER_DNC_UP 30
+
+# define DMA_CFG1_SRCINC_MASK (3 << 6)
+# define DMA_CFG1_SRCINC_0 (0 << 6)
+# define DMA_CFG1_SRCINC_1 (1 << 6)
+# define DMA_CFG1_SRCINC_2 (2 << 6)
+# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6)
+
+# define DMA_CFG1_DESTINC_MASK (3 << 4)
+# define DMA_CFG1_DESTINC_0 (0 << 4)
+# define DMA_CFG1_DESTINC_1 (1 << 4)
+# define DMA_CFG1_DESTINC_2 (2 << 4)
+# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4)
+
+# define DMA_CFG1_IRQMASK (1 << 3)
+# define DMA_CFG1_M8 (1 << 2)
+
+# define DMA_CFG1_PRIORITY_MASK (3 << 0)
+# define DMA_CFG1_PRIORITY_LOW (0 << 0)
+# define DMA_CFG1_PRIORITY_NORMAL (1 << 0)
+# define DMA_CFG1_PRIORITY_HIGH (2 << 0)
+
+/*
+ * DMAARM - DMA Channel Arm
+ */
+
+sfr at 0xD6 DMAARM;
+
+# define DMAARM_ABORT (1 << 7)
+# define DMAARM_DMAARM4 (1 << 4)
+# define DMAARM_DMAARM3 (1 << 3)
+# define DMAARM_DMAARM2 (1 << 2)
+# define DMAARM_DMAARM1 (1 << 1)
+# define DMAARM_DMAARM0 (1 << 0)
+
+/*
+ * DMAREQ - DMA Channel Start Request and Status
+ */
+
+sfr at 0xD7 DMAREQ;
+
+# define DMAREQ_DMAREQ4 (1 << 4)
+# define DMAREQ_DMAREQ3 (1 << 3)
+# define DMAREQ_DMAREQ2 (1 << 2)
+# define DMAREQ_DMAREQ1 (1 << 1)
+# define DMAREQ_DMAREQ0 (1 << 0)
+
+/*
+ * DMA configuration 0 address
+ */
+
+sfr at 0xD5 DMA0CFGH;
+sfr at 0xD4 DMA0CFGL;
+
+/*
+ * DMA configuration 1-4 address
+ */
+
+sfr at 0xD3 DMA1CFGH;
+sfr at 0xD2 DMA1CFGL;
+
+/*
+ * DMAIRQ - DMA Interrupt Flag
+ */
+
+sfr at 0xD1 DMAIRQ;
+
+# define DMAIRQ_DMAIF4 (1 << 4)
+# define DMAIRQ_DMAIF3 (1 << 3)
+# define DMAIRQ_DMAIF2 (1 << 2)
+# define DMAIRQ_DMAIF1 (1 << 1)
+# define DMAIRQ_DMAIF0 (1 << 0)
+
+struct cc_dma_channel {
+ uint8_t src_high;
+ uint8_t src_low;
+ uint8_t dst_high;
+ uint8_t dst_low;
+ uint8_t len_high;
+ uint8_t len_low;
+ uint8_t cfg0;
+ uint8_t cfg1;
+};
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0;
+ unsigned char j = 0;
+
+ n++;
+ while (--n != 0)
+ while (--i != 0)
+ while (--j != 0)
+ nop();
+}
+
+void
+debug_byte(uint8_t byte)
+{
+ uint8_t s;
+
+ for (s = 0; s < 8; s++) {
+ DEBUG = byte & 1;
+ delay(5);
+ byte >>= 1;
+ }
+}
+
+struct cc_dma_channel __xdata config;
+
+#define DMA_LEN 8
+
+uint8_t __xdata dma_input[DMA_LEN];
+uint8_t __xdata dma_output[DMA_LEN];
+
+#define ADDRH(a) (((uint16_t) (a)) >> 8)
+#define ADDRL(a) (((uint16_t) (a)))
+
+void
+dma_init(void)
+{
+ int i;
+ config.cfg0 = (DMA_CFG0_WORDSIZE_8 |
+ DMA_CFG0_TMODE_BLOCK |
+ DMA_CFG0_TRIGGER_NONE);
+ config.cfg1 = (DMA_CFG1_SRCINC_1 |
+ DMA_CFG1_DESTINC_1 |
+ DMA_CFG1_PRIORITY_NORMAL);
+
+ config.src_high = ADDRH(dma_input);
+ config.src_low = ADDRL(dma_input);
+ config.dst_high = ADDRH(dma_output);
+ config.dst_low = ADDRL(dma_output);
+ config.len_high = 0;
+ config.len_low = DMA_LEN;
+ DMA0CFGH = ADDRH(&config);
+ DMA0CFGL = ADDRL(&config);
+ for (i = 0; i < DMA_LEN; i++)
+ dma_input[i] = i + 1;
+}
+
+void
+dma_run(void)
+{
+ DMAREQ |= 1;
+ DMAARM |= 1;
+ while (DMAARM & 1)
+ ;
+}
+
+main ()
+{
+ int i;
+ P1DIR |= 2;
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+
+ dma_init();
+ dma_run();
+ for (;;) {
+ for (i = 0; i < DMA_LEN; i++)
+ debug_byte(dma_output[i]);
+ }
+}
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=ee.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=ee-flash.ihx ee-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+ee-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o ee-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o ee-flash.ihx $(REL)
+
+ee-flash.ihx: ee-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdint.h>
+
+/*
+ * Validate the SPI-connected EEPROM
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN (1 << 7)
+# define SLEEP_XOSC_STB (1 << 6)
+
+sfr at 0xF1 PERCFG;
+#define PERCFG_T1CFG_ALT_1 (0 << 6)
+#define PERCFG_T1CFG_ALT_2 (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1 (0 << 5)
+#define PERCFG_T3CFG_ALT_2 (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1 (0 << 4)
+#define PERCFG_T4CFG_ALT_2 (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1 (0 << 1)
+#define PERCFG_U1CFG_ALT_2 (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1 (0 << 0)
+#define PERCFG_U0CFG_ALT_2 (1 << 0)
+
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+/*
+ * UART registers
+ */
+
+sfr at 0x86 U0CSR;
+sfr at 0xF8 U1CSR;
+
+# define UxCSR_MODE_UART (1 << 7)
+# define UxCSR_MODE_SPI (0 << 7)
+# define UxCSR_RE (1 << 6)
+# define UxCSR_SLAVE (1 << 5)
+# define UxCSR_MASTER (0 << 5)
+# define UxCSR_FE (1 << 4)
+# define UxCSR_ERR (1 << 3)
+# define UxCSR_RX_BYTE (1 << 2)
+# define UxCSR_TX_BYTE (1 << 1)
+# define UxCSR_ACTIVE (1 << 0)
+
+sfr at 0xc4 U0UCR;
+sfr at 0xfb U1UCR;
+
+sfr at 0xc5 U0GCR;
+sfr at 0xfc U1GCR;
+
+# define UxGCR_CPOL_NEGATIVE (0 << 7)
+# define UxGCR_CPOL_POSITIVE (1 << 7)
+# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
+# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
+# define UxGCR_ORDER_LSB (0 << 5)
+# define UxGCR_ORDER_MSB (1 << 5)
+# define UxGCR_BAUD_E_MASK (0x1f)
+# define UxGCR_BAUD_E_SHIFT 0
+
+sfr at 0xc1 U0DBUF;
+sfr at 0xf9 U1DBUF;
+sfr at 0xc2 U0BAUD;
+sfr at 0xfa U1BAUD;
+
+#define MOSI P1_5
+#define MISO P1_4
+#define SCK P1_3
+#define CS P1_2
+
+#define DEBUG P1_1
+
+#define BITBANG 0
+#define USART 1
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0;
+ unsigned char j = 0;
+
+ while (--n != 0)
+ while (--i != 0)
+ while (--j != 0)
+ nop();
+}
+
+#if BITBANG
+
+/*
+ * This version directly manipulates the GPIOs to synthesize SPI
+ */
+
+void
+bitbang_cs(uint8_t b)
+{
+ SCK = 0;
+ CS = b;
+ delay(1);
+}
+
+void
+bitbang_out_bit(uint8_t b)
+{
+ MOSI = b;
+ delay(1);
+ SCK = 1;
+ delay(1);
+ SCK = 0;
+}
+
+void
+bitbang_out_byte(uint8_t byte)
+{
+ uint8_t s;
+
+ for (s = 0; s < 8; s++) {
+ uint8_t b = (byte & 0x80) ? 1 : 0;
+ bitbang_out_bit(b);
+ byte <<= 1;
+ }
+}
+
+uint8_t
+bitbang_in_bit(void)
+{
+ uint8_t b;
+
+ delay(1);
+ SCK = 1;
+ delay(1);
+ b = MISO;
+ SCK = 0;
+ return b;
+}
+
+uint8_t
+bitbang_in_byte(void)
+{
+ uint8_t byte = 0;
+ uint8_t s;
+ uint8_t b;
+
+ for (s = 0; s < 8; s++) {
+ b = bitbang_in_bit();
+ byte = byte << 1;
+ byte |= b;
+ }
+ return byte;
+}
+
+void
+bit_bang_init(void)
+{
+ CS = 1;
+ SCK = 0;
+ P1DIR = ((1 << 5) |
+ (0 << 4) |
+ (1 << 3) |
+ (1 << 2) |
+ (1 << 1));
+}
+
+#define spi_init() bitbang_init()
+#define spi_out_byte(b) bitbang_out_byte(b)
+#define spi_in_byte() bitbang_in_byte()
+#define spi_cs(b) bitbang_cs(b)
+#endif
+
+#if USART
+
+/*
+ * This version uses the USART in SPI mode
+ */
+void
+usart_init(void)
+{
+ /*
+ * Configure our chip select line
+ */
+ CS = 1;
+ P1DIR |= (1 << 2);
+ /*
+ * Configure the peripheral pin choices
+ * for both of the serial ports
+ *
+ * Note that telemetrum will use U1CFG_ALT_2
+ * but that overlaps with SPI ALT_2, so until
+ * we can test that this works, we'll set this
+ * to ALT_1
+ */
+ PERCFG = (PERCFG_U1CFG_ALT_1 |
+ PERCFG_U0CFG_ALT_2);
+
+ /*
+ * Make the SPI pins controlled by the SPI
+ * hardware
+ */
+ P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3));
+
+ /*
+ * SPI in master mode
+ */
+ U0CSR = (UxCSR_MODE_SPI |
+ UxCSR_MASTER);
+
+ /*
+ * The cc1111 is limited to a 24/8 MHz SPI clock,
+ * while the 25LC1024 is limited to 20MHz. So,
+ * use the 3MHz clock (BAUD_E 17, BAUD_M 0)
+ */
+ U0BAUD = 0;
+ U0GCR = (UxGCR_CPOL_NEGATIVE |
+ UxGCR_CPHA_FIRST_EDGE |
+ UxGCR_ORDER_MSB |
+ (17 << UxGCR_BAUD_E_SHIFT));
+}
+
+void
+usart_cs(uint8_t b)
+{
+ CS = b;
+}
+
+uint8_t
+usart_in_out(uint8_t byte)
+{
+ U0DBUF = byte;
+ while ((U0CSR & UxCSR_TX_BYTE) == 0)
+ ;
+ U0CSR &= ~UxCSR_TX_BYTE;
+ return U0DBUF;
+}
+
+void
+usart_out_byte(uint8_t byte)
+{
+ (void) usart_in_out(byte);
+}
+
+uint8_t
+usart_in_byte(void)
+{
+ return usart_in_out(0xff);
+}
+
+#define spi_init() usart_init()
+#define spi_out_byte(b) usart_out_byte(b)
+#define spi_in_byte() usart_in_byte()
+#define spi_cs(b) usart_cs(b)
+
+#endif
+
+uint8_t
+rdsr(void)
+{
+ uint8_t status;
+ spi_cs(0);
+ spi_out_byte(0x05);
+ status = spi_in_byte();
+ spi_cs(1);
+ return status;
+}
+
+void
+wrsr(uint8_t status)
+{
+ spi_cs(0);
+ spi_out_byte(0x01);
+ spi_out_byte(status);
+ spi_cs(1);
+}
+
+void
+wren(void)
+{
+ spi_cs(0);
+ spi_out_byte(0x06);
+ spi_cs(1);
+}
+
+void
+write(uint32_t addr, uint8_t *bytes, uint16_t len)
+{
+ wren();
+ spi_cs(0);
+ spi_out_byte(0x02);
+ spi_out_byte(addr >> 16);
+ spi_out_byte(addr >> 8);
+ spi_out_byte(addr);
+ while (len-- > 0)
+ spi_out_byte(*bytes++);
+ spi_cs(1);
+ for (;;) {
+ uint8_t status = rdsr();
+ if ((status & (1 << 0)) == 0)
+ break;
+ }
+}
+
+void
+read(uint32_t addr, uint8_t *bytes, uint16_t len)
+{
+ spi_cs(0);
+ spi_out_byte(0x03);
+ spi_out_byte(addr >> 16);
+ spi_out_byte(addr >> 8);
+ spi_out_byte(addr);
+ while (len-- > 0)
+ *bytes++ = spi_in_byte();
+ spi_cs(1);
+}
+
+void
+debug_byte(uint8_t byte)
+{
+ uint8_t s;
+
+ for (s = 0; s < 8; s++) {
+ DEBUG = byte & 1;
+ delay(5);
+ byte >>= 1;
+ }
+}
+
+#define STRING "\360\252"
+#define LENGTH 2
+
+main ()
+{
+ uint8_t status;
+ uint8_t buf[LENGTH];
+ int i;
+
+ P1DIR |= 2;
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+
+ spi_init();
+
+ status = rdsr();
+ /*
+ * Turn off both block-protect bits
+ */
+ status &= ~((1 << 3) | (1 << 2));
+ /*
+ * Turn off write protect enable
+ */
+ status &= ~(1 << 7);
+ wrsr(status);
+ write(0x0, STRING, LENGTH);
+ for (;;) {
+ read(0x0, buf, LENGTH);
+ for (i = 0; i < LENGTH; i++)
+ debug_byte(buf[i]);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+void rftxrx_isr (void) __interrupt(0) __using(1)
+{
+}
+
+void adc_isr (void) __interrupt(1) __using(1)
+{
+}
+
+void urx0_isr (void) __interrupt(2) __using(1)
+{
+}
+
+void urx1_isr (void) __interrupt(3) __using(1)
+{
+}
+
+void enc_isr (void) __interrupt(4) __using(1)
+{
+}
+
+void st_isr (void) __interrupt(5) __using(1)
+{
+}
+
+void usb_isr (void) __interrupt(6) __using(1)
+{
+}
+
+void utx0_isr (void) __interrupt(7) __using(1)
+{
+}
+
+void dma_isr (void) __interrupt(8) __using(1)
+{
+}
+
+void t1_isr (void) __interrupt(9) __using(1)
+{
+}
+
+void t2_isr (void) __interrupt(10) __using(1)
+{
+}
+
+void t3_isr (void) __interrupt(11) __using(1)
+{
+}
+
+void t4_isr (void) __interrupt(12) __using(1)
+{
+}
+
+void p0int_isr (void) __interrupt(13) __using(1)
+{
+}
+
+void utx1_isr (void) __interrupt(14) __using(1)
+{
+}
+
+void p1int_isr (void) __interrupt(15) __using(1)
+{
+}
+
+void rf_isr (void) __interrupt(16) __using(1)
+{
+}
+
+void wdt_isr (void) __interrupt(17) __using(1)
+{
+}
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=xmit.c recv.c init.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=xmit-flash.ihx xmit-ram.ihx recv-flash.ihx recv-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+xmit-ram.ihx: xmit.rel init.rel Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o xmit-ram.ihx xmit.rel init.rel
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o xmit-flash.ihx xmit.rel init.rel
+
+xmit-flash.ihx: xmit-ram.ihx
+
+recv-ram.ihx: recv.rel init.rel Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o recv-ram.ihx recv.rel init.rel
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o recv-flash.ihx recv.rel init.rel
+
+recv-flash.ihx: recv-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "radio.h"
+
+/* Values from SmartRF® Studio for:
+ *
+ * Deviation: 20.507812 kHz
+ * Datarate: 38.360596 kBaud
+ * Modulation: GFSK
+ * RF Freq: 434.549927 MHz
+ * Channel: 99.975586 kHz
+ * Channel: 0
+ * RX filter: 93.75 kHz
+ */
+
+/*
+ * For 434.550MHz, the frequency value is:
+ *
+ * 434.550e6 / (24e6 / 2**16) = 1186611.2
+ */
+
+#define FREQ_CONTROL 1186611
+
+/*
+ * For IF freq of 140.62kHz, the IF value is:
+ *
+ * 140.62e3 / (24e6 / 2**10) = 6
+ */
+
+#define IF_FREQ_CONTROL 6
+
+/*
+ * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are
+ *
+ * BW = 24e6 / (8 * (4 + M) * 2 ** E)
+ *
+ * So, M = 0 and E = 3
+ */
+
+#define CHANBW_M 0
+#define CHANBW_E 3
+
+/*
+ * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are:
+ *
+ * R = (256 + M) * 2** E * 24e6 / 2**28
+ *
+ * So M is 163 and E is 10
+ */
+
+#define DRATE_E 10
+#define DRATE_M 163
+
+/*
+ * For a channel deviation of 20.5kHz, the DEVIATION_E and DEVIATION_M values are:
+ *
+ * F = 24e6/2**17 * (8 + DEVIATION_M) * 2**DEVIATION_E
+ *
+ * So M is 6 and E is 3
+ */
+
+#define DEVIATION_M 6
+#define DEVIATION_E 3
+
+#define PACKET_LEN 128
+
+/* This are from the table for 433MHz */
+
+#define RF_POWER_M30_DBM 0x12
+#define RF_POWER_M20_DBM 0x0e
+#define RF_POWER_M15_DBM 0x1d
+#define RF_POWER_M10_DBM 0x34
+#define RF_POWER_M5_DBM 0x2c
+#define RF_POWER_0_DBM 0x60
+#define RF_POWER_5_DBM 0x84
+#define RF_POWER_7_DBM 0xc8
+#define RF_POWER_10_DBM 0xc0
+
+#define RF_POWER RF_POWER_0_DBM
+
+static __code uint8_t radio_setup[] = {
+ RF_PA_TABLE7_OFF, RF_POWER,
+ RF_PA_TABLE6_OFF, RF_POWER,
+ RF_PA_TABLE5_OFF, RF_POWER,
+ RF_PA_TABLE4_OFF, RF_POWER,
+ RF_PA_TABLE3_OFF, RF_POWER,
+ RF_PA_TABLE2_OFF, RF_POWER,
+ RF_PA_TABLE1_OFF, RF_POWER,
+ RF_PA_TABLE0_OFF, RF_POWER,
+
+ RF_FREQ2_OFF, FREQ_CONTROL >> 16,
+ RF_FREQ1_OFF, FREQ_CONTROL >> 8,
+ RF_FREQ0_OFF, FREQ_CONTROL >> 0,
+
+ RF_FSCTRL1_OFF, (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT),
+ RF_FSCTRL0_OFF, (0 << RF_FSCTRL0_FREQOFF_SHIFT),
+
+ RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
+ (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
+ (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
+ RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
+ RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF |
+ RF_MDMCFG2_MOD_FORMAT_GFSK |
+ RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+ RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_EN |
+ RF_MDMCFG1_NUM_PREAMBLE_4 |
+ (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
+ RF_MDMCFG0_OFF, (17 << RF_MDMCFG0_CHANSPC_M_SHIFT),
+
+ RF_CHANNR_OFF, 0,
+
+ RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) |
+ (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
+
+ /* SmartRF says set LODIV_BUF_CURRENT_TX to 0
+ * And, we're not using power ramping, so use PA_POWER 0
+ */
+ RF_FREND0_OFF, ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) |
+ (0 << RF_FREND0_PA_POWER_SHIFT)),
+
+ RF_FREND1_OFF, ((1 << RF_FREND1_LNA_CURRENT_SHIFT) |
+ (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) |
+ (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) |
+ (2 << RF_FREND1_MIX_CURRENT_SHIFT)),
+
+ RF_FSCAL3_OFF, 0xE9,
+ RF_FSCAL2_OFF, 0x0A,
+ RF_FSCAL1_OFF, 0x00,
+ RF_FSCAL0_OFF, 0x1F,
+
+ RF_TEST2_OFF, 0x88,
+ RF_TEST1_OFF, 0x31,
+ RF_TEST0_OFF, 0x09,
+
+ /* default sync values */
+ RF_SYNC1_OFF, 0xD3,
+ RF_SYNC0_OFF, 0x91,
+
+ /* max packet length */
+ RF_PKTLEN_OFF, PACKET_LEN,
+
+ RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)|
+ PKTCTRL1_APPEND_STATUS|
+ PKTCTRL1_ADR_CHK_NONE),
+ RF_PKTCTRL0_OFF, (RF_PKTCTRL0_WHITE_DATA|
+ RF_PKTCTRL0_PKT_FORMAT_NORMAL|
+ RF_PKTCTRL0_CRC_EN|
+ RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
+ RF_ADDR_OFF, 0x00,
+ RF_MCSM2_OFF, (RF_MCSM2_RX_TIME_END_OF_PACKET),
+ RF_MCSM1_OFF, (RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING|
+ RF_MCSM1_RXOFF_MODE_IDLE|
+ RF_MCSM1_TXOFF_MODE_IDLE),
+ RF_MCSM0_OFF, (RF_MCSM0_FS_AUTOCAL_FROM_IDLE|
+ RF_MCSM0_MAGIC_3|
+ RF_MCSM0_CLOSE_IN_RX_18DB),
+ RF_FOCCFG_OFF, (RF_FOCCFG_FOC_PRE_K_3K,
+ RF_FOCCFG_FOC_POST_K_PRE_K,
+ RF_FOCCFG_FOC_LIMIT_BW_OVER_4),
+ RF_BSCFG_OFF, (RF_BSCFG_BS_PRE_K_2K|
+ RF_BSCFG_BS_PRE_KP_3KP|
+ RF_BSCFG_BS_POST_KI_PRE_KI|
+ RF_BSCFG_BS_POST_KP_PRE_KP|
+ RF_BSCFG_BS_LIMIT_0),
+ RF_AGCCTRL2_OFF, 0x43,
+ RF_AGCCTRL1_OFF, 0x40,
+ RF_AGCCTRL0_OFF, 0x91,
+
+ RF_IOCFG2_OFF, 0x00,
+ RF_IOCFG1_OFF, 0x00,
+ RF_IOCFG0_OFF, 0x00,
+};
+
+void
+radio_init(void) {
+ uint8_t i;
+ for (i = 0; i < sizeof (radio_setup); i += 2)
+ RF[radio_setup[i]] = radio_setup[i+1];
+}
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0;
+
+ n <<= 1;
+ while (--n != 0)
+ while (--i != 0)
+ nop();
+}
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdint.h>
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+
+sfr at 0xF1 PERCFG;
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sfr at 0xD9 RFD;
+sfr at 0xE9 RFIF;
+#define RFIF_IM_TXUNF (1 << 7)
+#define RFIF_IM_RXOVF (1 << 6)
+#define RFIF_IM_TIMEOUT (1 << 5)
+#define RFIF_IM_DONE (1 << 4)
+#define RFIF_IM_CS (1 << 3)
+#define RFIF_IM_PQT (1 << 2)
+#define RFIF_IM_CCA (1 << 1)
+#define RFIF_IM_SFD (1 << 0)
+
+sfr at 0xE1 RFST;
+
+sfr at 0x88 TCON;
+
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN (1 << 7)
+# define SLEEP_XOSC_STB (1 << 6)
+
+sbit at 0x89 RFTXRXIF;
+
+#define TCON_RFTXRXIF (1 << 1)
+
+#define RFST_SFSTXON 0x00
+#define RFST_SCAL 0x01
+#define RFST_SRX 0x02
+#define RFST_STX 0x03
+#define RFST_SIDLE 0x04
+
+__xdata __at (0xdf00) uint8_t RF[0x3c];
+
+__xdata __at (0xdf2f) uint8_t RF_IOCFG2;
+#define RF_IOCFG2_OFF 0x2f
+
+__xdata __at (0xdf30) uint8_t RF_IOCFG1;
+#define RF_IOCFG1_OFF 0x30
+
+__xdata __at (0xdf31) uint8_t RF_IOCFG0;
+#define RF_IOCFG0_OFF 0x31
+
+__xdata __at (0xdf00) uint8_t RF_SYNC1;
+#define RF_SYNC1_OFF 0x00
+
+__xdata __at (0xdf01) uint8_t RF_SYNC0;
+#define RF_SYNC0_OFF 0x01
+
+__xdata __at (0xdf02) uint8_t RF_PKTLEN;
+#define RF_PKTLEN_OFF 0x02
+
+__xdata __at (0xdf03) uint8_t RF_PKTCTRL1;
+#define RF_PKTCTRL1_OFF 0x03
+#define PKTCTRL1_PQT_MASK (0x7 << 5)
+#define PKTCTRL1_PQT_SHIFT 5
+#define PKTCTRL1_APPEND_STATUS (1 << 2)
+#define PKTCTRL1_ADR_CHK_NONE (0 << 0)
+#define PKTCTRL1_ADR_CHK_NO_BROADCAST (1 << 0)
+#define PKTCTRL1_ADR_CHK_00_BROADCAST (2 << 0)
+#define PKTCTRL1_ADR_CHK_00_FF_BROADCAST (3 << 0)
+
+/* If APPEND_STATUS is used, two bytes will be added to the packet data */
+#define PKT_APPEND_STATUS_0_RSSI_MASK (0xff)
+#define PKT_APPEND_STATUS_0_RSSI_SHIFT 0
+#define PKT_APPEND_STATUS_1_CRC_OK (1 << 7)
+#define PKT_APPEND_STATUS_1_LQI_MASK (0x7f)
+#define PKT_APPEND_STATUS_1_LQI_SHIFT 0
+
+__xdata __at (0xdf04) uint8_t RF_PKTCTRL0;
+#define RF_PKTCTRL0_OFF 0x04
+#define RF_PKTCTRL0_WHITE_DATA (1 << 6)
+#define RF_PKTCTRL0_PKT_FORMAT_NORMAL (0 << 4)
+#define RF_PKTCTRL0_PKT_FORMAT_RANDOM (2 << 4)
+#define RF_PKTCTRL0_CRC_EN (1 << 2)
+#define RF_PKTCTRL0_LENGTH_CONFIG_FIXED (0 << 0)
+#define RF_PKTCTRL0_LENGTH_CONFIG_VARIABLE (1 << 0)
+
+__xdata __at (0xdf05) uint8_t RF_ADDR;
+#define RF_ADDR_OFF 0x05
+
+__xdata __at (0xdf06) uint8_t RF_CHANNR;
+#define RF_CHANNR_OFF 0x06
+
+__xdata __at (0xdf07) uint8_t RF_FSCTRL1;
+#define RF_FSCTRL1_OFF 0x07
+
+#define RF_FSCTRL1_FREQ_IF_SHIFT (0)
+
+__xdata __at (0xdf08) uint8_t RF_FSCTRL0;
+#define RF_FSCTRL0_OFF 0x08
+
+#define RF_FSCTRL0_FREQOFF_SHIFT (0)
+
+__xdata __at (0xdf09) uint8_t RF_FREQ2;
+#define RF_FREQ2_OFF 0x09
+
+__xdata __at (0xdf0a) uint8_t RF_FREQ1;
+#define RF_FREQ1_OFF 0x0a
+
+__xdata __at (0xdf0b) uint8_t RF_FREQ0;
+#define RF_FREQ0_OFF 0x0b
+
+__xdata __at (0xdf0c) uint8_t RF_MDMCFG4;
+#define RF_MDMCFG4_OFF 0x0c
+
+#define RF_MDMCFG4_CHANBW_E_SHIFT 6
+#define RF_MDMCFG4_CHANBW_M_SHIFT 4
+#define RF_MDMCFG4_DRATE_E_SHIFT 0
+
+__xdata __at (0xdf0d) uint8_t RF_MDMCFG3;
+#define RF_MDMCFG3_OFF 0x0d
+
+#define RF_MDMCFG3_DRATE_M_SHIFT 0
+
+__xdata __at (0xdf0e) uint8_t RF_MDMCFG2;
+#define RF_MDMCFG2_OFF 0x0e
+
+#define RF_MDMCFG2_DEM_DCFILT_OFF (1 << 7)
+#define RF_MDMCFG2_DEM_DCFILT_ON (0 << 7)
+
+#define RF_MDMCFG2_MOD_FORMAT_MASK (7 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_2_FSK (0 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_GFSK (1 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_ASK_OOK (3 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_MSK (7 << 4)
+
+#define RF_MDMCFG2_MANCHESTER_EN (1 << 3)
+
+#define RF_MDMCFG2_SYNC_MODE_MASK (0x7 << 0)
+#define RF_MDMCFG2_SYNC_MODE_NONE (0x0 << 0)
+#define RF_MDMCFG2_SYNC_MODE_15_16 (0x1 << 0)
+#define RF_MDMCFG2_SYNC_MODE_16_16 (0x2 << 0)
+#define RF_MDMCFG2_SYNC_MODE_30_32 (0x3 << 0)
+#define RF_MDMCFG2_SYNC_MODE_NONE_THRES (0x4 << 0)
+#define RF_MDMCFG2_SYNC_MODE_15_16_THRES (0x5 << 0)
+#define RF_MDMCFG2_SYNC_MODE_16_16_THRES (0x6 << 0)
+#define RF_MDMCFG2_SYNC_MODE_30_32_THRES (0x7 << 0)
+
+__xdata __at (0xdf0f) uint8_t RF_MDMCFG1;
+#define RF_MDMCFG1_OFF 0x0f
+
+#define RF_MDMCFG1_FEC_EN (1 << 7)
+#define RF_MDMCFG1_FEC_DIS (0 << 7)
+
+#define RF_MDMCFG1_NUM_PREAMBLE_MASK (7 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_2 (0 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_3 (1 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_4 (2 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_6 (3 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_8 (4 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_12 (5 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_16 (6 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_24 (7 << 4)
+
+#define RF_MDMCFG1_CHANSPC_E_MASK (3 << 0)
+#define RF_MDMCFG1_CHANSPC_E_SHIFT (0)
+
+__xdata __at (0xdf10) uint8_t RF_MDMCFG0;
+#define RF_MDMCFG0_OFF 0x10
+
+#define RF_MDMCFG0_CHANSPC_M_SHIFT (0)
+
+__xdata __at (0xdf11) uint8_t RF_DEVIATN;
+#define RF_DEVIATN_OFF 0x11
+
+#define RF_DEVIATN_DEVIATION_E_SHIFT 4
+#define RF_DEVIATN_DEVIATION_M_SHIFT 0
+
+__xdata __at (0xdf12) uint8_t RF_MCSM2;
+#define RF_MCSM2_OFF 0x12
+#define RF_MCSM2_RX_TIME_RSSI (1 << 4)
+#define RF_MCSM2_RX_TIME_QUAL (1 << 3)
+#define RF_MCSM2_RX_TIME_MASK (0x7)
+#define RF_MCSM2_RX_TIME_SHIFT 0
+#define RF_MCSM2_RX_TIME_END_OF_PACKET (7)
+
+__xdata __at (0xdf13) uint8_t RF_MCSM1;
+#define RF_MCSM1_OFF 0x13
+#define RF_MCSM1_CCA_MODE_ALWAYS (0 << 4)
+#define RF_MCSM1_CCA_MODE_RSSI_BELOW (1 << 4)
+#define RF_MCSM1_CCA_MODE_UNLESS_RECEIVING (2 << 4)
+#define RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING (3 << 4)
+#define RF_MCSM1_RXOFF_MODE_IDLE (0 << 2)
+#define RF_MCSM1_RXOFF_MODE_FSTXON (1 << 2)
+#define RF_MCSM1_RXOFF_MODE_TX (2 << 2)
+#define RF_MCSM1_RXOFF_MODE_RX (3 << 2)
+#define RF_MCSM1_TXOFF_MODE_IDLE (0 << 0)
+#define RF_MCSM1_TXOFF_MODE_FSTXON (1 << 0)
+#define RF_MCSM1_TXOFF_MODE_TX (2 << 0)
+#define RF_MCSM1_TXOFF_MODE_RX (3 << 0)
+
+__xdata __at (0xdf14) uint8_t RF_MCSM0;
+#define RF_MCSM0_OFF 0x14
+#define RF_MCSM0_FS_AUTOCAL_NEVER (0 << 4)
+#define RF_MCSM0_FS_AUTOCAL_FROM_IDLE (1 << 4)
+#define RF_MCSM0_FS_AUTOCAL_TO_IDLE (2 << 4)
+#define RF_MCSM0_FS_AUTOCAL_TO_IDLE_EVERY_4 (3 << 4)
+#define RF_MCSM0_MAGIC_3 (1 << 3)
+#define RF_MCSM0_MAGIC_2 (1 << 2)
+#define RF_MCSM0_CLOSE_IN_RX_0DB (0 << 0)
+#define RF_MCSM0_CLOSE_IN_RX_6DB (1 << 0)
+#define RF_MCSM0_CLOSE_IN_RX_12DB (2 << 0)
+#define RF_MCSM0_CLOSE_IN_RX_18DB (3 << 0)
+
+__xdata __at (0xdf15) uint8_t RF_FOCCFG;
+#define RF_FOCCFG_OFF 0x15
+#define RF_FOCCFG_FOC_BS_CS_GATE (1 << 5)
+#define RF_FOCCFG_FOC_PRE_K_1K (0 << 3)
+#define RF_FOCCFG_FOC_PRE_K_2K (1 << 3)
+#define RF_FOCCFG_FOC_PRE_K_3K (2 << 3)
+#define RF_FOCCFG_FOC_PRE_K_4K (3 << 3)
+#define RF_FOCCFG_FOC_POST_K_PRE_K (0 << 2)
+#define RF_FOCCFG_FOC_POST_K_PRE_K_OVER_2 (1 << 2)
+#define RF_FOCCFG_FOC_LIMIT_0 (0 << 0)
+#define RF_FOCCFG_FOC_LIMIT_BW_OVER_8 (1 << 0)
+#define RF_FOCCFG_FOC_LIMIT_BW_OVER_4 (2 << 0)
+#define RF_FOCCFG_FOC_LIMIT_BW_OVER_2 (3 << 0)
+
+__xdata __at (0xdf16) uint8_t RF_BSCFG;
+#define RF_BSCFG_OFF 0x16
+#define RF_BSCFG_BS_PRE_K_1K (0 << 6)
+#define RF_BSCFG_BS_PRE_K_2K (1 << 6)
+#define RF_BSCFG_BS_PRE_K_3K (2 << 6)
+#define RF_BSCFG_BS_PRE_K_4K (3 << 6)
+#define RF_BSCFG_BS_PRE_KP_1KP (0 << 4)
+#define RF_BSCFG_BS_PRE_KP_2KP (1 << 4)
+#define RF_BSCFG_BS_PRE_KP_3KP (2 << 4)
+#define RF_BSCFG_BS_PRE_KP_4KP (3 << 4)
+#define RF_BSCFG_BS_POST_KI_PRE_KI (0 << 3)
+#define RF_BSCFG_BS_POST_KI_PRE_KI_OVER_2 (1 << 3)
+#define RF_BSCFG_BS_POST_KP_PRE_KP (0 << 2)
+#define RF_BSCFG_BS_POST_KP_PRE_KP_OVER_2 (1 << 2)
+#define RF_BSCFG_BS_LIMIT_0 (0 << 0)
+#define RF_BSCFG_BS_LIMIT_3_125 (1 << 0)
+#define RF_BSCFG_BS_LIMIT_6_25 (2 << 0)
+#define RF_BSCFG_BS_LIMIT_12_5 (3 << 0)
+
+__xdata __at (0xdf17) uint8_t RF_AGCCTRL2;
+#define RF_AGCCTRL2_OFF 0x17
+
+__xdata __at (0xdf18) uint8_t RF_AGCCTRL1;
+#define RF_AGCCTRL1_OFF 0x18
+
+__xdata __at (0xdf19) uint8_t RF_AGCCTRL0;
+#define RF_AGCCTRL0_OFF 0x19
+
+__xdata __at (0xdf1a) uint8_t RF_FREND1;
+#define RF_FREND1_OFF 0x1a
+
+#define RF_FREND1_LNA_CURRENT_SHIFT 6
+#define RF_FREND1_LNA2MIX_CURRENT_SHIFT 4
+#define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT 2
+#define RF_FREND1_MIX_CURRENT_SHIFT 0
+
+__xdata __at (0xdf1b) uint8_t RF_FREND0;
+#define RF_FREND0_OFF 0x1b
+
+#define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK (0x3 << 4)
+#define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT 4
+#define RF_FREND0_PA_POWER_MASK (0x7)
+#define RF_FREND0_PA_POWER_SHIFT 0
+
+__xdata __at (0xdf1c) uint8_t RF_FSCAL3;
+#define RF_FSCAL3_OFF 0x1c
+
+__xdata __at (0xdf1d) uint8_t RF_FSCAL2;
+#define RF_FSCAL2_OFF 0x1d
+
+__xdata __at (0xdf1e) uint8_t RF_FSCAL1;
+#define RF_FSCAL1_OFF 0x1e
+
+__xdata __at (0xdf1f) uint8_t RF_FSCAL0;
+#define RF_FSCAL0_OFF 0x1f
+
+__xdata __at (0xdf23) uint8_t RF_TEST2;
+#define RF_TEST2_OFF 0x23
+
+#define RF_TEST2_NORMAL_MAGIC 0x88
+#define RF_TEST2_RX_LOW_DATA_RATE_MAGIC 0x81
+
+__xdata __at (0xdf24) uint8_t RF_TEST1;
+#define RF_TEST1_OFF 0x24
+
+#define RF_TEST1_TX_MAGIC 0x31
+#define RF_TEST1_RX_LOW_DATA_RATE_MAGIC 0x35
+
+__xdata __at (0xdf25) uint8_t RF_TEST0;
+#define RF_TEST0_OFF 0x25
+
+#define RF_TEST0_7_2_MASK (0xfc)
+#define RF_TEST0_VCO_SEL_CAL_EN (1 << 1)
+#define RF_TEST0_0_MASK (1)
+
+/* These are undocumented, and must be computed
+ * using the provided tool.
+ */
+__xdata __at (0xdf27) uint8_t RF_PA_TABLE7;
+#define RF_PA_TABLE7_OFF 0x27
+
+__xdata __at (0xdf28) uint8_t RF_PA_TABLE6;
+#define RF_PA_TABLE6_OFF 0x28
+
+__xdata __at (0xdf29) uint8_t RF_PA_TABLE5;
+#define RF_PA_TABLE5_OFF 0x29
+
+__xdata __at (0xdf2a) uint8_t RF_PA_TABLE4;
+#define RF_PA_TABLE4_OFF 0x2a
+
+__xdata __at (0xdf2b) uint8_t RF_PA_TABLE3;
+#define RF_PA_TABLE3_OFF 0x2b
+
+__xdata __at (0xdf2c) uint8_t RF_PA_TABLE2;
+#define RF_PA_TABLE2_OFF 0x2c
+
+__xdata __at (0xdf2d) uint8_t RF_PA_TABLE1;
+#define RF_PA_TABLE1_OFF 0x2d
+
+__xdata __at (0xdf2e) uint8_t RF_PA_TABLE0;
+#define RF_PA_TABLE0_OFF 0x2e
+
+__xdata __at (0xdf36) uint8_t RF_PARTNUM;
+#define RF_PARTNUM_OFF 0x36
+
+__xdata __at (0xdf37) uint8_t RF_VERSION;
+#define RF_VERSION_OFF 0x37
+
+__xdata __at (0xdf38) uint8_t RF_FREQEST;
+#define RF_FREQEST_OFF 0x38
+
+__xdata __at (0xdf39) uint8_t RF_LQI;
+#define RF_LQI_OFF 0x39
+
+#define RF_LQI_CRC_OK (1 << 7)
+#define RF_LQI_LQI_EST_MASK (0x7f)
+
+__xdata __at (0xdf3a) uint8_t RF_RSSI;
+#define RF_RSSI_OFF 0x3a
+
+__xdata __at (0xdf3b) uint8_t RF_MARCSTATE;
+#define RF_MARCSTATE_OFF 0x3b
+
+#define RF_MARCSTATE_MASK 0x0f
+#define RF_MARCSTATE_SLEEP 0x00
+#define RF_MARCSTATE_IDLE 0x01
+#define RF_MARCSTATE_VCOON_MC 0x03
+#define RF_MARCSTATE_REGON_MC 0x04
+#define RF_MARCSTATE_MANCAL 0x05
+#define RF_MARCSTATE_VCOON 0x06
+#define RF_MARCSTATE_REGON 0x07
+#define RF_MARCSTATE_STARTCAL 0x08
+#define RF_MARCSTATE_BWBOOST 0x09
+#define RF_MARCSTATE_FS_LOCK 0x0a
+#define RF_MARCSTATE_IFADCON 0x0b
+#define RF_MARCSTATE_ENDCAL 0x0c
+#define RF_MARCSTATE_RX 0x0d
+#define RF_MARCSTATE_RX_END 0x0e
+#define RF_MARCSTATE_RX_RST 0x0f
+#define RF_MARCSTATE_TXRX_SWITCH 0x10
+#define RF_MARCSTATE_RX_OVERFLOW 0x11
+#define RF_MARCSTATE_FSTXON 0x12
+#define RF_MARCSTATE_TX 0x13
+#define RF_MARCSTATE_TX_END 0x14
+#define RF_MARCSTATE_RXTX_SWITCH 0x15
+#define RF_MARCSTATE_TX_UNDERFLOW 0x16
+
+
+__xdata __at (0xdf3c) uint8_t RF_PKTSTATUS;
+#define RF_PKTSTATUS_OFF 0x3c
+
+#define RF_PKTSTATUS_CRC_OK (1 << 7)
+#define RF_PKTSTATUS_CS (1 << 6)
+#define RF_PKTSTATUS_PQT_REACHED (1 << 5)
+#define RF_PKTSTATUS_CCA (1 << 4)
+#define RF_PKTSTATUS_SFD (1 << 3)
+
+__xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC;
+#define RF_VCO_VC_DAC_OFF 0x3d
+
+#define PACKET_LEN 128
+
+void
+radio_init(void);
+
+void
+delay (unsigned char n);
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "radio.h"
+
+main ()
+{
+ static uint8_t packet[PACKET_LEN + 2];
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+ /* Set P2_0 to output */
+ P1 = 0;
+ P1DIR = 0x02;
+ radio_init ();
+ delay(100);
+
+ for (;;) {
+ uint8_t i;
+ RFST = RFST_SIDLE;
+ RFIF = 0;
+ delay(100);
+ RFST = RFST_SRX;
+// while (!(RFIF & RFIF_IM_CS));
+// P1 = 2;
+ for (i = 0; i < PACKET_LEN + 2; i++) {
+ while (!RFTXRXIF)
+ ;
+ P1=2;
+ RFTXRXIF = 0;
+ packet[i] = RFD;
+ }
+ P1 = 0;
+
+ /* check packet contents */
+ for (i = 0; i < PACKET_LEN; i++)
+ if (packet[i] != i)
+ break;
+
+ /* get excited if the packet came through correctly */
+ if (i == PACKET_LEN &&
+ packet[PACKET_LEN+1] & PKT_APPEND_STATUS_1_CRC_OK)
+ {
+ for (i = 0; i < 5; i++){
+ P1 = 2;
+ delay(100);
+ P1 = 0;
+ delay(100);
+ }
+ }
+ delay(100);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "radio.h"
+
+main ()
+{
+ int16_t j;
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+ P1 = 0;
+ P1DIR = 3;
+ radio_init ();
+ delay(100);
+
+ for (;;) {
+ uint8_t i;
+
+ for (j = 0; j < 100; j++)
+ delay(100);
+ P1 = 2;
+ RFST = RFST_SIDLE;
+ delay(1);
+ RFST = RFST_STX;
+ for (i = 0; i < PACKET_LEN; i++) {
+ while (!RFTXRXIF);
+ RFTXRXIF = 0;
+ RFD = i;
+ }
+ P1 = 0;
+ }
+}
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=--out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=serial.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=serial-flash.ihx serial-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+serial-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o serial-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o serial-flash.ihx $(REL)
+
+serial-flash.ihx: serial-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+
+install:
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdint.h>
+
+/*
+ * Validate UART1
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN (1 << 7)
+# define SLEEP_XOSC_STB (1 << 6)
+
+sfr at 0xF1 PERCFG;
+#define PERCFG_T1CFG_ALT_1 (0 << 6)
+#define PERCFG_T1CFG_ALT_2 (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1 (0 << 5)
+#define PERCFG_T3CFG_ALT_2 (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1 (0 << 4)
+#define PERCFG_T4CFG_ALT_2 (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1 (0 << 1)
+#define PERCFG_U1CFG_ALT_2 (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1 (0 << 0)
+#define PERCFG_U0CFG_ALT_2 (1 << 0)
+
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+/*
+ * UART registers
+ */
+
+sfr at 0x86 U0CSR;
+sfr at 0xF8 U1CSR;
+
+/*
+ * IRCON2
+ */
+sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
+
+sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
+sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
+sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
+sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
+sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
+sbit at 0xEB P1IF; /* Port1 interrupt flag */
+sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
+
+# define UxCSR_MODE_UART (1 << 7)
+# define UxCSR_MODE_SPI (0 << 7)
+# define UxCSR_RE (1 << 6)
+# define UxCSR_SLAVE (1 << 5)
+# define UxCSR_MASTER (0 << 5)
+# define UxCSR_FE (1 << 4)
+# define UxCSR_ERR (1 << 3)
+# define UxCSR_RX_BYTE (1 << 2)
+# define UxCSR_TX_BYTE (1 << 1)
+# define UxCSR_ACTIVE (1 << 0)
+
+sfr at 0xc4 U0UCR;
+sfr at 0xfb U1UCR;
+
+# define UxUCR_FLUSH (1 << 7)
+# define UxUCR_FLOW_DISABLE (0 << 6)
+# define UxUCR_FLOW_ENABLE (1 << 6)
+# define UxUCR_D9_EVEN_PARITY (0 << 5)
+# define UxUCR_D9_ODD_PARITY (1 << 5)
+# define UxUCR_BIT9_8_BITS (0 << 4)
+# define UxUCR_BIT9_9_BITS (1 << 4)
+# define UxUCR_PARITY_DISABLE (0 << 3)
+# define UxUCR_PARITY_ENABLE (1 << 3)
+# define UxUCR_SPB_1_STOP_BIT (0 << 2)
+# define UxUCR_SPB_2_STOP_BITS (1 << 2)
+# define UxUCR_STOP_LOW (0 << 1)
+# define UxUCR_STOP_HIGH (1 << 1)
+# define UxUCR_START_LOW (0 << 0)
+# define UxUCR_START_HIGH (1 << 0)
+
+sfr at 0xc5 U0GCR;
+sfr at 0xfc U1GCR;
+
+# define UxGCR_CPOL_NEGATIVE (0 << 7)
+# define UxGCR_CPOL_POSITIVE (1 << 7)
+# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
+# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
+# define UxGCR_ORDER_LSB (0 << 5)
+# define UxGCR_ORDER_MSB (1 << 5)
+# define UxGCR_BAUD_E_MASK (0x1f)
+# define UxGCR_BAUD_E_SHIFT 0
+
+sfr at 0xc1 U0DBUF;
+sfr at 0xf9 U1DBUF;
+sfr at 0xc2 U0BAUD;
+sfr at 0xfa U1BAUD;
+
+#define MOSI P1_5
+#define MISO P1_4
+#define SCK P1_3
+#define CS P1_2
+
+#define DEBUG P1_1
+
+#define USART 1
+
+#define nop() _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+ unsigned char i = 0;
+ unsigned char j = 0;
+
+ n++;
+ while (--n != 0)
+ while (--i != 0)
+ while (--j != 0)
+ nop();
+}
+
+/*
+ * This version uses the USART in SPI mode
+ */
+void
+usart_init(void)
+{
+ P1DIR |= (1 << 2);
+ /*
+ * Configure the peripheral pin choices
+ * for both of the serial ports
+ *
+ * Note that telemetrum will use U1CFG_ALT_2
+ * but that overlaps with SPI ALT_2, so until
+ * we can test that this works, we'll set this
+ * to ALT_1
+ */
+ PERCFG = (PERCFG_U1CFG_ALT_2 |
+ PERCFG_U0CFG_ALT_1);
+
+ /*
+ * Make the UART pins controlled by the UART
+ * hardware
+ */
+ P1SEL |= ((1 << 6) | (1 << 7));
+
+ /*
+ * UART mode with the receiver enabled
+ */
+ U1CSR = (UxCSR_MODE_UART |
+ UxCSR_RE);
+ /*
+ * Pick a 38.4kbaud rate
+ */
+ U1BAUD = 163;
+ U1GCR = 10 << UxGCR_BAUD_E_SHIFT; /* 38400 */
+// U1GCR = 3 << UxGCR_BAUD_E_SHIFT; /* 300 */
+ /*
+ * Reasonable serial parameters
+ */
+ U1UCR = (UxUCR_FLUSH |
+ UxUCR_FLOW_DISABLE |
+ UxUCR_D9_ODD_PARITY |
+ UxUCR_BIT9_8_BITS |
+ UxUCR_PARITY_DISABLE |
+ UxUCR_SPB_2_STOP_BITS |
+ UxUCR_STOP_HIGH |
+ UxUCR_START_LOW);
+}
+
+void
+usart_out_byte(uint8_t byte)
+{
+ U1DBUF = byte;
+ while (!UTX1IF)
+ ;
+ UTX1IF = 0;
+}
+
+void
+usart_out_string(uint8_t *string)
+{
+ uint8_t b;
+
+ while (b = *string++)
+ usart_out_byte(b);
+}
+
+uint8_t
+usart_in_byte(void)
+{
+ uint8_t b;
+ while ((U1CSR & UxCSR_RX_BYTE) == 0)
+ ;
+ b = U1DBUF;
+ U1CSR &= ~UxCSR_RX_BYTE;
+ return b;
+}
+
+void
+debug_byte(uint8_t byte)
+{
+ uint8_t s;
+
+ for (s = 0; s < 8; s++) {
+ DEBUG = byte & 1;
+ delay(5);
+ byte >>= 1;
+ }
+}
+
+main ()
+{
+ P1DIR |= 2;
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+
+ usart_init();
+
+ for (;;) {
+ usart_out_string("hello world\r\n");
+ debug_byte(usart_in_byte());
+ }
+
+}
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=-L/local/share/sdcc/lib/large --out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=simple.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=simple-flash.ihx simple-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+simple-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o simple-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o simple-flash.ihx $(REL)
+
+simple-flash.ihx: simple-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+sfr at 0x90 P1;
+sfr at 0xC6 CLKCON;
+
+sfr at 0xFE P1DIR;
+sfr at 0xF6 P1INP;
+
+void delay(int n) __reentrant
+{
+ while (n--)
+ _asm nop _endasm;
+}
+int
+main (void) __reentrant
+{
+ long i;
+ CLKCON = 0;
+ /* Set p1_1 to output */
+ P1DIR = 0x02;
+ for (;;) {
+ P1 ^= 0x2;
+ for (i = 0; i < 1000; i++)
+ delay(1000);
+ }
+}
--- /dev/null
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic \
+ --no-peep --int-long-reent --float-reent \
+ --data-loc 0x30
+
+LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
+
+SRC=timer.c
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=timer-flash.ihx timer-ram.ihx
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+all: $(PROGS)
+
+timer-ram.ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o timer-ram.ihx $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o timer-flash.ihx $(REL)
+
+timer-flash.ihx: timer-ram.ihx
+
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
--- /dev/null
+/*-------------------------------------------------------------------------
+ Register Declarations for the ChipCon CC1111 Processor Range
+
+ Copyright © 2008 Keith Packard <keithp@keithp.com>
+
+ 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.,
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+ Adapted from the Cygnal C8051F12x config file which is:
+
+ Copyright (C) 2003 - Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-------------------------------------------------------------------------*/
+
+#ifndef _CC1111_H_
+#define _CC1111_H_
+
+
+/* BYTE Registers */
+
+sfr at 0x80 P0 ; /* PORT 0 */
+sfr at 0x81 SP ; /* STACK POINTER */
+sfr at 0x82 DPL ; /* DATA POINTER - LOW BYTE */
+sfr at 0x83 DPH ; /* DATA POINTER - HIGH BYTE */
+sfr at 0x84 DPL1 ; /* DATA POINTER 1 - LOW BYTE */
+sfr at 0x85 DPH1 ; /* DATA POINTER 1 - HIGH BYTE */
+sfr at 0x86 U0CSR ; /* USART 0 Control and status */
+sfr at 0x87 PCON ; /* POWER CONTROL */
+sfr at 0x88 TCON ; /* TIMER CONTROL */
+sfr at 0x89 P0IFG ; /* TIMER MODE */
+sfr at 0x8A P1IFG ; /* TIMER 0 - LOW BYTE */
+sfr at 0x8B P2IFG ; /* TIMER 1 - LOW BYTE */
+sfr at 0x8C PICTL ; /* TIMER 0 - HIGH BYTE */
+sfr at 0x8D P1IEN ; /* TIMER 1 - HIGH BYTE */
+
+sfr at 0x8F P0INP ; /* FLASH WRITE/ERASE CONTROL */
+sfr at 0x90 P1 ; /* PORT 1 */
+sfr at 0x91 RFIM ; /* UART 0 STATUS */
+sfr at 0x92 DPS ; /* */
+sfr at 0x93 MPAGE ; /* */
+sfr at 0x94 _SFR94_ ; /* */
+sfr at 0x95 ENDIAN ; /* */
+sfr at 0x96 _SFR96_ ; /* */
+sfr at 0x97 _SFR97_ ; /* */
+sfr at 0x98 S0CON ; /* UART 0 CONTROL */
+sfr at 0x99 _SFR99_ ; /* UART 0 BUFFER */
+sfr at 0x9A IEN2 ; /* SPI 0 CONFIGURATION */
+sfr at 0x9B S1CON ; /* SPI 0 DATA */
+sfr at 0x9C T2CT ; /* SPI 0 DATA */
+sfr at 0x9D T2PR ; /* SPI 0 CLOCK RATE CONTROL */
+sfr at 0x9E T2CTL ; /* SPI 0 CLOCK RATE CONTROL */
+sfr at 0x9F _SFR9F_ ; /* SPI 0 CLOCK RATE CONTROL */
+sfr at 0xA0 P2 ; /* PORT 2 */
+sfr at 0xA1 WORIRQ ; /* EMIF TIMING CONTROL */
+sfr at 0xA2 WORCTRL ; /* EMIF CONTROL */
+sfr at 0xA3 WOREVT0 ; /* EMIF CONFIGURATION */
+sfr at 0xA4 WOREVT1 ; /* EMIF CONFIGURATION */
+sfr at 0xA5 WORTIME0 ; /* EMIF CONFIGURATION */
+sfr at 0xA6 WORTIME1 ; /* EMIF CONFIGURATION */
+sfr at 0xA7 _SFRA7_ ; /* EMIF CONFIGURATION */
+sfr at 0xA8 IEN0 ; /* INTERRUPT ENABLE */
+sfr at 0xA9 IP0 ; /* UART 0 SLAVE ADDRESS */
+sfr at 0xAA _SFRAA_ ; /* */
+sfr at 0xAB FWT ; /* */
+sfr at 0xAC FADDRL ; /* */
+sfr at 0xAD FADDRH ; /* */
+sfr at 0xAE FCTL ; /* */
+sfr at 0xAF FWDATA ; /* */
+sfr at 0xB0 _SFRB0_ ; /* */
+sfr at 0xB1 ENCDI ; /* FLASH BANK SELECT */
+sfr at 0xB2 ENCDO ; /* */
+sfr at 0xB3 ENCCS ; /* */
+sfr at 0xB4 ADCCON1 ; /* */
+sfr at 0xB5 ADCCON2 ; /* */
+sfr at 0xB6 ADCCON3 ; /* */
+sfr at 0xB8 IEN1 ; /* INTERRUPT PRIORITY */
+sfr at 0xB9 IP1 ; /* */
+sfr at 0xBA ADCL ; /* */
+sfr at 0xBB ADCH ; /* */
+sfr at 0xBC RNDL ; /* */
+sfr at 0xBD RNDH ; /* */
+sfr at 0xBE SLEEP ; /* */
+sfr at 0xC0 IRCON ; /* */
+sfr at 0xC1 U0DBUF ; /* */
+sfr at 0xC2 U0BAUD ; /* */
+sfr at 0xC4 U0UCR ; /* */
+sfr at 0xC5 U0GCR ; /* */
+sfr at 0xC6 CLKCON ; /* */
+sfr at 0xC7 MEMCTR ; /* */
+sfr at 0xC9 WDCTL ; /* */
+sfr at 0xCA T3CNT ; /* */
+sfr at 0xCB T3CTL ; /* */
+sfr at 0xCC T3CCTL0 ; /* */
+sfr at 0xCD T3CC0 ; /* */
+sfr at 0xCE T3CCTL1 ; /* */
+sfr at 0xCF T3CC1 ; /* */
+sfr at 0xD0 PSW ; /* */
+sfr at 0xD1 DMAIRQ ; /* */
+sfr at 0xD2 DMA1CFGL ; /* */
+sfr at 0xD3 DMA1CFGH ; /* */
+sfr at 0xD4 DMA0CFGL ; /* */
+sfr at 0xD5 DMA0CFGH ; /* */
+sfr at 0xD6 DMAARM ; /* */
+sfr at 0xD7 DMAREQ ; /* */
+sfr at 0xD8 TIMIF ; /* */
+sfr at 0xD9 RFD ; /* */
+sfr at 0xDA T1CC0L ; /* */
+sfr at 0xDB T1CC0H ; /* */
+sfr at 0xDC T1CC1L ; /* */
+sfr at 0xDD T1CC1H ; /* */
+sfr at 0xDE T1CC2L ; /* */
+sfr at 0xDF T1CC2H ; /* */
+sfr at 0xE0 ACC ; /* ACCUMULATOR */
+sfr at 0xE1 RFST ; /* */
+sfr at 0xE2 T1CNTL ; /* */
+sfr at 0xE3 T1CNTH ; /* */
+sfr at 0xE4 T1CTL ; /* */
+sfr at 0xE5 T1CCTL0 ; /* */
+sfr at 0xE6 T1CCTL1 ; /* */
+sfr at 0xE7 T1CCTL2 ; /* */
+sfr at 0xE8 IRCON2 ; /* */
+sfr at 0xE9 RFIF ; /* */
+sfr at 0xEA T4CNT ; /* */
+sfr at 0xEB T4CTL ; /* */
+sfr at 0xEC T4CCTL0 ; /* */
+sfr at 0xED T4CC0 ; /* */
+sfr at 0xEE T4CCTL1 ; /* */
+sfr at 0xEF T4CC1 ; /* */
+sfr at 0xF0 B ; /* */
+sfr at 0xF1 PERCFG ; /* */
+sfr at 0xF2 ADCCFG ; /* */
+sfr at 0xF3 P0SEL ; /* */
+sfr at 0xF4 P1SEL ; /* */
+sfr at 0xF5 P2SEL ; /* */
+sfr at 0xF6 P1INP ; /* */
+sfr at 0xF7 P2INP ; /* */
+sfr at 0xF8 U1CSR ; /* */
+sfr at 0xF9 U1DBUF ; /* */
+sfr at 0xFA U1BAUD ; /* */
+sfr at 0xFB U1UCR ; /* */
+sfr at 0xFC U1GCR ; /* */
+sfr at 0xFD P0DIR ; /* */
+sfr at 0xFE P1DIR ; /* */
+sfr at 0xFF P2DIR ; /* */
+
+/* BIT Registers */
+
+/* P0 0x80 */
+sbit at 0x80 P0_0 ;
+sbit at 0x81 P0_1 ;
+sbit at 0x82 P0_2 ;
+sbit at 0x83 P0_3 ;
+sbit at 0x84 P0_4 ;
+sbit at 0x85 P0_5 ;
+sbit at 0x86 P0_6 ;
+sbit at 0x87 P0_7 ;
+
+/* TCON 0x88 */
+sbit at 0x89 RFTXRXIF; /* */
+sbit at 0x8B URX0IF ; /* */
+sbit at 0x8D ADCIF ; /* */
+sbit at 0x8F URX1IF ; /* */
+sbit at 0x8F I2SRXIF ; /* */
+
+/* SCON0 0x98 */
+sbit at 0x98 ENCIF_0 ; /* UART 0 RX INTERRUPT FLAG */
+sbit at 0x99 ENCIF_1 ; /* UART 0 RX INTERRUPT FLAG */
+
+/* IEN0 0xA8 */
+sbit at 0xA8 RFTXRXIE; /* RF TX/RX done interrupt enable */
+sbit at 0xA9 ADCIE ; /* ADC interrupt enable */
+sbit at 0xAA URX0IE ; /* USART0 RX interrupt enable */
+sbit at 0xAB URX1IE ; /* USART1 RX interrupt enable */
+sbit at 0xAB I2SRXIE ; /* I2S RX interrupt enable */
+sbit at 0xAC ENCIE ; /* AES interrupt enable */
+sbit at 0xAD STIE ; /* Sleep Timer interrupt enable */
+sbit at 0xAF EA ; /* GLOBAL INTERRUPT ENABLE */
+
+/* IEN1 0xB8 */
+sbit at 0xB8 DMAIE ; /* DMA transfer interrupt enable */
+sbit at 0xB9 T1IE ; /* Timer 1 interrupt enable */
+sbit at 0xBA T2IE ; /* Timer 2 interrupt enable */
+sbit at 0xBB T3IE ; /* Timer 3 interrupt enable */
+sbit at 0xBC T4IE ; /* Timer 4 interrupt enable */
+sbit at 0xBD P0IE ; /* Port 0 interrupt enable */
+
+/* IRCON 0xC0 */
+sbit at 0xC0 DMAIF ; /* */
+sbit at 0xC1 T1IF ; /* */
+sbit at 0xC2 T2IF ; /* */
+sbit at 0xC3 T3IF ; /* */
+sbit at 0xC4 T4IF ; /* */
+sbit at 0xC5 P0IF ; /* */
+sbit at 0xC7 STIF ; /* */
+
+/* PSW 0xD0 */
+sbit at 0xD0 P ; /* ACCUMULATOR PARITY FLAG */
+sbit at 0xD1 F1 ; /* USER FLAG 1 */
+sbit at 0xD2 OV ; /* OVERFLOW FLAG */
+sbit at 0xD3 RS0 ; /* REGISTER BANK SELECT 0 */
+sbit at 0xD4 RS1 ; /* REGISTER BANK SELECT 1 */
+sbit at 0xD5 F0 ; /* USER FLAG 0 */
+sbit at 0xD6 AC ; /* AUXILIARY CARRY FLAG */
+sbit at 0xD7 CY ; /* CARRY FLAG */
+
+/* TIMIF D8H */
+sbit at 0xD8 T3OVFIF ; /* */
+sbit at 0xD9 T3CH0IF ; /* */
+sbit at 0xDA T3CH1IF ; /* */
+sbit at 0xDB T4OVFIF ; /* */
+sbit at 0xDC T4CH0IF ; /* */
+sbit at 0xDD T4CH1IF ; /* */
+sbit at 0xDE OVFIM ; /* */
+
+/* IRCON2 E8H */
+sbit at 0xE8 P2IF ; /* */
+sbit at 0xE8 USBIF ; /* */
+sbit at 0xE9 UTX0IF ; /* */
+sbit at 0xEA UTX1IF ; /* */
+sbit at 0xEA I2STXIF ; /* */
+sbit at 0xEB P1IF ; /* */
+sbit at 0xEC WDTIF ; /* */
+
+/* U1CSR F8H */
+sbit at 0xF8 U1_ACTIVE ; /* */
+sbit at 0xF9 U1_TX_BYTE ; /* */
+sbit at 0xFA U1_RX_BYTE ; /* */
+sbit at 0xFB U1_ERR ; /* */
+sbit at 0xFC U1_FE ; /* */
+sbit at 0xFD U1_SLAVE ; /* */
+sbit at 0xFE U1_RE ; /* */
+sbit at 0xFF U1_MODE ; /* */
+
+#define T1CTL_MODE_SUSPENDED (0 << 0)
+#define T1CTL_MODE_FREE (1 << 0)
+#define T1CTL_MODE_MODULO (2 << 0)
+#define T1CTL_MODE_UP_DOWN (3 << 0)
+#define T1CTL_MODE_MASK (3 << 0)
+#define T1CTL_DIV_1 (0 << 2)
+#define T1CTL_DIV_8 (1 << 2)
+#define T1CTL_DIV_32 (2 << 2)
+#define T1CTL_DIV_128 (3 << 2)
+#define T1CTL_DIV_MASK (3 << 2)
+#define T1CTL_OVFIF (1 << 4)
+#define T1CTL_CH0IF (1 << 5)
+#define T1CTL_CH1IF (1 << 6)
+#define T1CTL_CH2IF (1 << 7)
+
+#define T1CCTL_NO_CAPTURE (0 << 0)
+#define T1CCTL_CAPTURE_RISING (1 << 0)
+#define T1CCTL_CAPTURE_FALLING (2 << 0)
+#define T1CCTL_CAPTURE_BOTH (3 << 0)
+#define T1CCTL_CAPTURE_MASK (3 << 0)
+
+#define T1CCTL_MODE_CAPTURE (0 << 2)
+#define T1CCTL_MODE_COMPARE (1 << 2)
+
+#define T1CTL_CMP_SET (0 << 3)
+#define T1CTL_CMP_CLEAR (1 << 3)
+#define T1CTL_CMP_TOGGLE (2 << 3)
+#define T1CTL_CMP_SET_CLEAR (3 << 3)
+#define T1CTL_CMP_CLEAR_SET (4 << 3)
+
+#define T1CTL_IM_DISABLED (0 << 6)
+#define T1CTL_IM_ENABLED (1 << 6)
+
+#define T1CTL_CPSEL_NORMAL (0 << 7)
+#define T1CTL_CPSEL_RF (1 << 7)
+
+#endif
--- /dev/null
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "cc1111.h"
+
+unsigned char irqs;
+
+void timer1_isr(void) interrupt 9 __reentrant
+{
+ ++irqs;
+ if (irqs == 100) {
+ P1 ^= 0x2;
+ irqs = 0;
+ }
+}
+
+int
+main (void) __reentrant
+{
+ CLKCON = 0;
+ P1DIR = 0x2;
+ P1 = 0xff;
+
+ T1CTL = 0;
+
+ /* 30000 */
+ T1CC0H = 0x75;
+ T1CC0L = 0x30;
+ T1CCTL0 = T1CCTL_MODE_COMPARE;
+ T1CCTL1 = 0;
+ T1CCTL2 = 0;
+
+ /* clear timer value */
+ T1CNTL = 0;
+ OVFIM = 1;
+ T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
+ T1IE = 1;
+ EA = 1;
+ for (;;);
+}
--- /dev/null
+:03 0000 00 75 FE 02 88
+:03 0003 00 75 90 FF F6
+:02 0006 00 80 FE 7A
+:02 0008 00 80 FE 78
+:00 0000 01 FF
--- /dev/null
+:03 F000 00 75 FE 02 98
+:03 F003 00 75 90 FF 06
+:02 F006 00 80 FE 8A
+:00000001FF
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_CHIP_ID
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# start reading again
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# Halt 0x44
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# status byte
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+# Resume 0x4c
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# status byte
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# READ_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# status
+#
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# READ_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# status
+#
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# READ_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# status
+#
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# Halt 0x44
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# status byte
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# READ_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# status
+#
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D .
+
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+
+#
+# Ok, we're in debug mode now
+#
+
+#
+# GET_CHIP_ID
+
+#C . R 0
+#. . R
+#C D R 1
+#. D R
+#C D R 1
+#. D R
+#C . R 0
+#. . R
+#
+#C D R 1
+#. D R
+#C . R 0
+#. . R
+#C . R 0
+#. . R
+#C . R 0
+#. . R
+#
+##
+## Read the chip id
+##
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# Halt 0x44
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# status byte
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# DEBUG_INSTR
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# MOV 0xfe, 0x02
+
+# 0x75 0x02 0xfe
+
+# 0x75
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# 0xfe
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+
+# 0x02
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+
+# status byte
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# DEBUG_INSTR
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# MOV 0x90, 0xfd
+# 0x75 0xfd 0x90
+
+# 0x75
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# 0x90
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# 0xff
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# status byte
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+#
+# DEBUG_INSTR
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# MOV 0x90, 0xfd
+# 0x75 0xfd 0x90
+
+# 0x75
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# 0x90
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# 0xfd
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# status byte
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# RD_CONFIG
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# READ_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+C - R
+. - R
+
+C D R
--- /dev/null
+# reset
+C D R
+C D R
+C D R
+C D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# WR_CONFIG
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+
+#
+# RD_CONFIG
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+dist_bin_SCRIPTS = ao-ejection
--- /dev/null
+#!/usr/bin/env nickle
+
+void main () {
+ real R = 22.16 * 12; /* in lbf / lbm (gas constant for ffff powder */
+ real T = 3307; /* combustion temperature for BP */
+ real d_mm; /* diameter(mm) */
+ real l_mm; /* length(mm) */
+ real f_N; /* force(N) */
+ real f_lb;
+ real A_mm²; /* area of bulkhead (mm²) */
+ real A_in²;
+ real V_mm³; /* free volume (mm³) */
+ real V_in³;
+ real M_lb; /* mass of BP in lb */
+ real M_g;
+ real P_Nmm²; /* pressure (N/mm²) */
+ real P_lbin²; /* pressure (psi) */
+
+ if (dim(argv) != 4) {
+ File::fprintf(stderr,
+ "usage: %s diameter(mm) length(mm) force(N)\n",
+ argv[0]);
+ exit(1);
+ }
+
+ d_mm = string_to_real(argv[1]);
+ l_mm = string_to_real(argv[2]);
+ f_N = string_to_real(argv[3]);
+ f_lb = f_N * 0.22480894;
+
+ A_mm² = pi * (d_mm/2) ** 2;
+ V_mm³ = A_mm² * l_mm;
+
+ A_in² = A_mm² / (25.4**2);
+ V_in³ = V_mm³ / (25.4**3);
+
+ P_Nmm² = f_N / A_mm²;
+
+ P_lbin² = P_Nmm² * 0.22480894 * (25.4 ** 2);
+
+ M_lb = (P_lbin² * V_in³) / (R * T);
+ M_g = M_lb * 453.59237;
+
+ printf ("Input parameters:\n");
+ printf (" Diameter: %.1g (mm) %.3g (in)\n",
+ d_mm, d_mm / 25.4);
+ printf (" Length: %.1g (mm) %.3g (in)\n",
+ l_mm, l_mm / 25.4);
+ printf (" Force: %.1g (N) %.3g (lb)\n",
+ f_N, f_lb);
+
+ printf ("Chamber values:\n");
+ printf (" Area: %.0f (mm²) %.3g (in²)\n",
+ A_mm², A_in²);
+ printf (" Volume: %.0f (mm³) %.3g (in³)\n",
+ V_mm³, V_in³);
+ printf (" Pressure: %.2g (lb/in²) %.5g (N/mm²)\n",
+ P_lbin², P_Nmm²);
+
+ printf ("Results:\n");
+ printf (" FFFF powder: %.3g (g)\n", M_g);
+}
+
+main();
--- /dev/null
+*.o
+aoview
+aoview_glade.h
+aoview_flite
--- /dev/null
+VERSION=$(shell git describe)
+
+AM_CFLAGS=$(GNOME_CFLAGS) $(ALSA_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\" @FLITE_INCS@
+
+bin_PROGRAMS=ao-view
+
+ao_view_LDADD=$(GNOME_LIBS) $(FLITE_LIBS) $(ALSA_LIBS)
+
+ao_view_SOURCES = \
+ aoview_main.c \
+ aoview_dev.c \
+ aoview_dev_dialog.c \
+ aoview_serial.c \
+ aoview_monitor.c \
+ aoview_state.c \
+ aoview_convert.c \
+ aoview_log.c \
+ aoview_table.c \
+ aoview_util.c \
+ aoview_file.c \
+ aoview_eeprom.c \
+ aoview_voice.c \
+ aoview_replay.c \
+ aoview_label.c \
+ aoview_flite.c \
+ aoview.h
+
+BUILT_SOURCES = aoview_glade.h
+
+CLEANFILES = aoview_glade.h
+
+aoview_glade.h: aoview.glade
+ sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/"/' $< > $@
--- /dev/null
+<?xml version="1.0"?>
+<glade-interface>
+ <!-- interface-requires gtk+ 2.16 -->
+ <!-- interface-naming-policy project-wide -->
+ <widget class="GtkWindow" id="aoview">
+ <property name="width_request">550</property>
+ <property name="height_request">700</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">AltOS View</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem1">
+ <property name="label">gtk-new</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem2">
+ <property name="label">gtk-open</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem3">
+ <property name="label">gtk-save</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem4">
+ <property name="label">gtk-save-as</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem5">
+ <property name="label">gtk-quit</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="gtk_main_quit"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem6">
+ <property name="label">gtk-cut</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem7">
+ <property name="label">gtk-copy</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem8">
+ <property name="label">gtk-paste</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem9">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Device</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu4">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="ao_connect">
+ <property name="label" translatable="yes">_Connect to device</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">False</property>
+ <signal name="activate_item" handler="gtk_widget_show" object="device_connect_dialog" after="yes"/>
+ <signal name="activate" handler="gtk_widget_show" object="device_connect_dialog" after="yes"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-connect</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="ao_disconnect">
+ <property name="label" translatable="yes">_Disconnect</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">False</property>
+ <child internal-child="image">
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-disconnect</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="seperator">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="ao_savelog">
+ <property name="label" translatable="yes">_Save EEPROM data</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">False</property>
+ <signal name="activate_item" handler="gtk_widget_show" object="device_connect_dialog" after="yes"/>
+ <signal name="activate" handler="gtk_widget_show" object="device_connect_dialog"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="image5">
+ <property name="visible">True</property>
+ <property name="stock">gtk-save</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="ao_replay">
+ <property name="label" translatable="yes">_Replay</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">False</property>
+ <signal name="activate_item" handler="gtk_widget_show" object="ao_replay_dialog" after="yes"/>
+ <signal name="activate" handler="gtk_widget_show" object="ao_replay_dialog"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="image6">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-play</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Log</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu5">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="log_new">
+ <property name="label" translatable="yes">_New log</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">False</property>
+ <child internal-child="image">
+ <widget class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-new</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="file_configure">
+ <property name="label" translatable="yes">_Configure Log</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">False</property>
+ <signal name="activate" handler="gtk_widget_show" object="file_chooser_dialog" after="yes"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-preferences</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Voice</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu6">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckMenuItem" id="voice_enable">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Enable _Voice</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem10">
+ <property name="label">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="gtk_widget_show" object="about_dialog" after="yes"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">4</property>
+ <property name="row_spacing">3</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <widget class="GtkLabel" id="height_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Height (m)</property>
+ <property name="justify">center</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="state_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">State</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="rssi_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">RSSI (dBm)</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="height_value">
+ <property name="visible">True</property>
+ <property name="ypad">2</property>
+ <property name="label" translatable="yes">0</property>
+ <property name="selectable">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="state_value">
+ <property name="visible">True</property>
+ <property name="ypad">2</property>
+ <property name="label" translatable="yes">pad</property>
+ <property name="selectable">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="rssi_value">
+ <property name="visible">True</property>
+ <property name="ypad">2</property>
+ <property name="label" translatable="yes">-50</property>
+ <property name="selectable">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="speed_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Speed (m/s)</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="speed_value">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">0</property>
+ <property name="selectable">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkTreeView" id="dataview_0">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_expanders">False</property>
+ <property name="enable_grid_lines">both</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTreeView" id="dataview_1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_expanders">False</property>
+ <property name="enable_grid_lines">both</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkDialog" id="device_connect_dialog">
+ <property name="border_width">5</property>
+ <property name="type_hint">normal</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkTreeView" id="dev_list">
+ <property name="width_request">300</property>
+ <property name="height_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_clickable">False</property>
+ <property name="rules_hint">True</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <property name="level_indentation">1</property>
+ <property name="enable_grid_lines">both</property>
+ <property name="enable_tree_lines">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <widget class="GtkButton" id="cancel_button">
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="response_id">1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gtk_widget_hide" object="device_connect_dialog" after="yes"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="connect_button">
+ <property name="label" translatable="yes">gtk-connect</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkFileChooserDialog" id="file_chooser_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Configure Log Directory</property>
+ <property name="type_hint">dialog</property>
+ <property name="has_separator">False</property>
+ <property name="action">select-folder</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area2">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <widget class="GtkButton" id="file_configure_cancel">
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gtk_widget_hide" object="file_chooser_dialog"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="file_configure_ok">
+ <property name="label" translatable="yes">gtk-ok</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkMessageDialog" id="file_fail_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Failed to create log</property>
+ <property name="type_hint">normal</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="transient_for">aoview</property>
+ <property name="message_type">error</property>
+ <property name="buttons">close</property>
+ <property name="text">Cannot create log file</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox4">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area4">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkMessageDialog" id="dev_open_fail_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Failed to open device</property>
+ <property name="type_hint">normal</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="transient_for">aoview</property>
+ <property name="message_type">error</property>
+ <property name="buttons">close</property>
+ <property name="text">Cannot open device</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox6">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area6">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkAboutDialog" id="about_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">About AoView</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">normal</property>
+ <property name="transient_for">aoview</property>
+ <property name="has_separator">False</property>
+ <property name="program_name">AoView</property>
+ <property name="copyright" translatable="yes">Copyright © 2009 Keith Packard</property>
+ <property name="comments" translatable="yes">AltOS data capture and display.</property>
+ <property name="website">http://altusmetrum.org</property>
+ <property name="license" translatable="yes">AoView is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
+
+AoView 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 AoView; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</property>
+ <property name="authors">Keith Packard <keithp@keithp.com></property>
+ <property name="wrap_license">True</property>
+ <signal name="close" handler="gtk_widget_hide" object="about_dialog" after="yes"/>
+ <signal name="response" handler="gtk_widget_hide" object="about_dialog" after="yes"/>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox7">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area7">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkMessageDialog" id="ao_save_done">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">EEPROM save complete</property>
+ <property name="type_hint">normal</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="transient_for">aoview</property>
+ <property name="has_separator">False</property>
+ <property name="buttons">close</property>
+ <property name="text">Saving EEPROM data as</property>
+ <property name="secondary_text"><filename></property>
+ <signal name="close" handler="gtk_widget_hide" object="ao_save_done"/>
+ <signal name="response" handler="gtk_widget_hide" object="ao_save_done"/>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox11">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area11">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkFileChooserDialog" id="ao_replay_dialog">
+ <property name="border_width">5</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="transient_for">aoview</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox10">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area10">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <widget class="GtkButton" id="ao_replay_cancel">
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gtk_widget_hide" object="ao_replay_dialog"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="ao_replay_ok">
+ <property name="label" translatable="yes">gtk-ok</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AOVIEW_H_
+#define _AOVIEW_H_
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <err.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <math.h>
+
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+#include <gconf/gconf-client.h>
+
+struct usbdev {
+ char *sys;
+ char *tty;
+ char *manufacturer;
+ char *product;
+ char *serial;
+ int idProduct;
+ int idVendor;
+};
+
+struct aogps_time {
+ int hour;
+ int minute;
+ int second;
+};
+
+struct aogps {
+ int nsat;
+ int gps_locked;
+ int gps_connected;
+ struct aogps_time gps_time;
+ double lat; /* degrees (+N -S) */
+ double lon; /* degrees (+E -W) */
+ int alt; /* m */
+
+ int gps_extended; /* has extra data */
+ double ground_speed; /* m/s */
+ int course; /* degrees */
+ double climb_rate; /* m/s */
+ double hdop; /* unitless? */
+ int h_error; /* m */
+ int v_error; /* m */
+};
+
+struct aodata {
+ char callsign[16];
+ int serial;
+ int rssi;
+ char state[16];
+ int tick;
+ int accel;
+ int pres;
+ int temp;
+ int batt;
+ int drogue;
+ int main;
+ int flight_accel;
+ int ground_accel;
+ int flight_vel;
+ int flight_pres;
+ int ground_pres;
+ struct aogps gps;
+};
+
+struct aostate {
+ struct aodata data;
+
+ /* derived data */
+
+ struct aodata prev_data;
+
+ double report_time;
+
+ gboolean ascent; /* going up? */
+
+ int ground_altitude;
+ int height;
+ double speed;
+ double acceleration;
+ double battery;
+ double temperature;
+ double main_sense;
+ double drogue_sense;
+ double baro_speed;
+
+ int max_height;
+ double max_acceleration;
+ double max_speed;
+
+ struct aogps gps;
+
+ int gps_valid;
+ double pad_lat;
+ double pad_lon;
+ double pad_alt;
+ double pad_lat_total;
+ double pad_lon_total;
+ double pad_alt_total;
+ int npad;
+ int prev_npad;
+
+ double distance;
+ double bearing;
+ int gps_height;
+
+ int speak_tick;
+ int speak_altitude;
+};
+
+extern struct aostate aostate;
+
+/* GPS is 'stable' when we've seen at least this many samples */
+#define MIN_PAD_SAMPLES 10
+
+void
+aoview_monitor_disconnect(void);
+
+gboolean
+aoview_monitor_connect(char *tty);
+
+gboolean
+aoview_monitor_parse(const char *line);
+
+void
+aoview_monitor_reset(void);
+
+struct aoview_serial *
+aoview_serial_open(const char *tty);
+
+void
+aoview_serial_close(struct aoview_serial *serial);
+
+typedef void (*aoview_serial_callback)(gpointer user_data, struct aoview_serial *serial, gint revents);
+
+void
+aoview_serial_set_callback(struct aoview_serial *serial,
+ aoview_serial_callback func);
+
+void
+aoview_serial_printf(struct aoview_serial *serial, char *format, ...);
+
+int
+aoview_serial_read(struct aoview_serial *serial, char *buf, int len);
+
+int
+aoview_serial_getc(struct aoview_serial *serial);
+
+void
+aoview_dev_dialog_init(GladeXML *xml);
+
+int
+aoview_usb_scan(struct usbdev ***devs_ret);
+
+void
+aoview_usbdev_free(struct usbdev *usbdev);
+
+void
+aoview_state_notify(struct aodata *data);
+
+void
+aoview_state_new(void);
+
+void
+aoview_state_init(GladeXML *xml);
+
+int16_t
+aoview_pres_to_altitude(int16_t pres);
+
+int16_t
+aoview_altitude_to_pres(int16_t alt);
+
+char *
+aoview_fullname (char *dir, char *file);
+
+char *
+aoview_basename(char *file);
+
+GtkTreeViewColumn *
+aoview_add_plain_text_column (GtkTreeView *view, const gchar *title, gint model_column, gint width);
+
+int
+aoview_mkdir(char *dir);
+
+void
+aoview_log_init(GladeXML *xml);
+
+void
+aoview_log_set_serial(int serial);
+
+int
+aoview_log_get_serial(void);
+
+void
+aoview_log_printf(char *format, ...);
+
+void
+aoview_log_new(void);
+
+void
+aoview_table_start(void);
+
+void
+aoview_table_add_row(int column, char *label, char *format, ...);
+
+void
+aoview_table_finish(void);
+
+void
+aoview_table_init(GladeXML *xml);
+
+void
+aoview_table_clear(void);
+
+struct aoview_file;
+
+extern char *aoview_file_dir;
+
+void
+aoview_file_finish(struct aoview_file *file);
+
+gboolean
+aoview_file_start(struct aoview_file *file);
+
+const char *
+aoview_file_name(struct aoview_file *file);
+
+void
+aoview_file_set_serial(struct aoview_file *file, int serial);
+
+int
+aoview_file_get_serial(struct aoview_file *file);
+
+void
+aoview_file_printf(struct aoview_file *file, char *format, ...);
+
+void
+aoview_file_vprintf(struct aoview_file *file, char *format, va_list ap);
+
+struct aoview_file *
+aoview_file_new(char *ext);
+
+void
+aoview_file_destroy(struct aoview_file *file);
+
+void
+aoview_file_init(GladeXML *xml);
+
+/* aoview_eeprom.c */
+
+gboolean
+aoview_eeprom_save(const char *device);
+
+void
+aoview_eeprom_init(GladeXML *xml);
+
+/* aoview_voice.c */
+void aoview_voice_open(void);
+
+void aoview_voice_close(void);
+
+void aoview_voice_speak(char *format, ...);
+
+/* aoview_label.c */
+
+void aoview_label_init(GladeXML *xml);
+
+void
+aoview_label_show(struct aostate *state);
+
+/* aoview_flite.c */
+
+FILE *
+aoview_flite_start(void);
+
+void
+aoview_flite_stop(void);
+
+#endif /* _AOVIEW_H_ */
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+static int16_t altitude_table[2048] = {
+#include "altitude.h"
+};
+
+int16_t
+aoview_pres_to_altitude(int16_t pres)
+{
+ pres = pres >> 4;
+ if (pres < 0) pres = 0;
+ if (pres > 2047) pres = 2047;
+ return altitude_table[pres];
+}
+
+int16_t
+aoview_altitude_to_pres(int16_t alt)
+{
+ int16_t pres;
+
+ for (pres = 0; pres < 2047; pres++)
+ if (altitude_table[pres] <= alt)
+ break;
+ return pres << 4;
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+#include <ctype.h>
+#include <dirent.h>
+
+static char *
+load_string(char *dir, char *file)
+{
+ char *full = aoview_fullname(dir, file);
+ char line[4096];
+ char *r;
+ FILE *f;
+ int rlen;
+
+ f = fopen(full, "r");
+ free(full);
+ if (!f)
+ return NULL;
+ r = fgets(line, sizeof (line), f);
+ fclose(f);
+ if (!r)
+ return NULL;
+ rlen = strlen(r);
+ if (r[rlen-1] == '\n')
+ r[rlen-1] = '\0';
+ return strdup(r);
+}
+
+static int
+load_hex(char *dir, char *file)
+{
+ char *line;
+ char *end;
+ long i;
+
+ line = load_string(dir, file);
+ if (!line)
+ return -1;
+ i = strtol(line, &end, 16);
+ free(line);
+ if (end == line)
+ return -1;
+ return i;
+}
+
+static int
+dir_filter_tty_colon(const struct dirent *d)
+{
+ return strncmp(d->d_name, "tty:", 4) == 0;
+}
+
+static int
+dir_filter_tty(const struct dirent *d)
+{
+ return strncmp(d->d_name, "tty", 3) == 0;
+}
+
+static char *
+usb_tty(char *sys)
+{
+ char *base;
+ int num_configs;
+ int config;
+ struct dirent **namelist;
+ int interface;
+ int num_interfaces;
+ char endpoint_base[20];
+ char *endpoint_full;
+ char *tty_dir;
+ int ntty;
+ char *tty;
+
+ base = aoview_basename(sys);
+ num_configs = load_hex(sys, "bNumConfigurations");
+ num_interfaces = load_hex(sys, "bNumInterfaces");
+ for (config = 1; config <= num_configs; config++) {
+ for (interface = 0; interface < num_interfaces; interface++) {
+ sprintf(endpoint_base, "%s:%d.%d",
+ base, config, interface);
+ endpoint_full = aoview_fullname(sys, endpoint_base);
+
+ /* Check for tty:ttyACMx style names
+ */
+ ntty = scandir(endpoint_full, &namelist,
+ dir_filter_tty_colon,
+ alphasort);
+ if (ntty > 0) {
+ free(endpoint_full);
+ tty = aoview_fullname("/dev", namelist[0]->d_name + 4);
+ free(namelist);
+ return tty;
+ }
+
+ /* Check for tty/ttyACMx style names
+ */
+ tty_dir = aoview_fullname(endpoint_full, "tty");
+ free(endpoint_full);
+ ntty = scandir(tty_dir, &namelist,
+ dir_filter_tty,
+ alphasort);
+ free (tty_dir);
+ if (ntty > 0) {
+ tty = aoview_fullname("/dev", namelist[0]->d_name);
+ free(namelist);
+ return tty;
+ }
+ }
+ }
+ return NULL;
+}
+
+static struct usbdev *
+usb_scan_device(char *sys)
+{
+ struct usbdev *usbdev;
+
+ usbdev = calloc(1, sizeof (struct usbdev));
+ if (!usbdev)
+ return NULL;
+ usbdev->sys = strdup(sys);
+ usbdev->manufacturer = load_string(sys, "manufacturer");
+ usbdev->product = load_string(sys, "product");
+ usbdev->serial = load_string(sys, "serial");
+ usbdev->idProduct = load_hex(sys, "idProduct");
+ usbdev->idVendor = load_hex(sys, "idVendor");
+ usbdev->tty = usb_tty(sys);
+ return usbdev;
+}
+
+void
+aoview_usbdev_free(struct usbdev *usbdev)
+{
+ free(usbdev->sys);
+ free(usbdev->manufacturer);
+ free(usbdev->product);
+ free(usbdev->serial);
+ free(usbdev->tty);
+ free(usbdev);
+}
+
+#define USB_DEVICES "/sys/bus/usb/devices"
+
+static int
+dir_filter_dev(const struct dirent *d)
+{
+ const char *n = d->d_name;
+ char c;
+
+ while ((c = *n++)) {
+ if (isdigit(c))
+ continue;
+ if (c == '-')
+ continue;
+ if (c == '.' && n != d->d_name + 1)
+ continue;
+ return 0;
+ }
+ return 1;
+}
+
+int
+aoview_usb_scan(struct usbdev ***devs_ret)
+{
+ int n;
+ int ndev = 0;
+ int e;
+ struct dirent **ents;
+ char *dir;
+ struct usbdev **devs = NULL;
+ struct usbdev *dev;
+
+ n = scandir (USB_DEVICES, &ents,
+ dir_filter_dev,
+ alphasort);
+ if (!n)
+ return 0;
+ for (e = 0; e < n; e++) {
+ dir = aoview_fullname(USB_DEVICES, ents[e]->d_name);
+ dev = usb_scan_device(dir);
+ free(dir);
+ if (dev->idVendor == 0xfffe && dev->tty) {
+ if (devs)
+ devs = realloc(devs, ndev + 1 * sizeof (struct usbdev *));
+ else
+ devs = malloc (sizeof (struct usbdev *));
+ devs[ndev++] = dev;
+ }
+ }
+ free(ents);
+ *devs_ret = devs;
+ return ndev;
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+static void
+aoview_dev_dialog_map(GtkWidget *widget, gpointer data)
+{
+ GtkTreeView *dev_list = data;
+ GtkListStore *list_store;
+ GtkTreeIter iter;
+ int ndev, n;
+ struct usbdev **devs;
+
+ list_store = gtk_list_store_new(3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ ndev = aoview_usb_scan(&devs);
+ for (n = 0; n < ndev; n++) {
+ gtk_list_store_append(list_store, &iter);
+ gtk_list_store_set(list_store, &iter,
+ 0, devs[n]->product,
+ 1, devs[n]->serial,
+ 2, devs[n]->tty,
+ -1);
+ }
+ gtk_tree_view_set_model (dev_list, GTK_TREE_MODEL(list_store));
+ g_object_unref(G_OBJECT(list_store));
+ gtk_tree_view_columns_autosize(dev_list);
+}
+
+static GtkMessageDialog *dev_open_fail_dialog;
+
+static void
+aoview_dev_open_failed(char *name)
+{
+ char *utf8_file;
+ utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
+ if (!utf8_file)
+ utf8_file = name;
+ gtk_message_dialog_format_secondary_text(dev_open_fail_dialog,
+ "\"%s\"", utf8_file);
+ if (utf8_file != name)
+ g_free(utf8_file);
+ gtk_dialog_run(GTK_DIALOG(dev_open_fail_dialog));
+ gtk_widget_hide(GTK_WIDGET(dev_open_fail_dialog));
+}
+
+gboolean dialog_save_log;
+
+static void
+aoview_dev_selected(GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gchar *string;
+ gtk_tree_model_get(model, iter,
+ 2, &string,
+ -1);
+ if (dialog_save_log) {
+ dialog_save_log = FALSE;
+ if (!aoview_eeprom_save(string))
+ aoview_dev_open_failed(string);
+ } else {
+ if (!aoview_monitor_connect(string))
+ aoview_dev_open_failed(string);
+ }
+}
+
+static GtkWidget *dialog;
+
+static void
+aoview_dev_dialog_connect(GtkWidget *widget, gpointer data)
+{
+ GtkTreeView *dev_list = data;
+ GtkListStore *list_store;
+ GtkTreeSelection *tree_selection;
+
+ list_store = GTK_LIST_STORE(gtk_tree_view_get_model(dev_list));
+ tree_selection = gtk_tree_view_get_selection(dev_list);
+ gtk_tree_selection_selected_foreach(tree_selection,
+ aoview_dev_selected,
+ data);
+ gtk_widget_hide(dialog);
+}
+
+static void
+aoview_dev_disconnect(GtkWidget *widget)
+{
+ aoview_monitor_disconnect();
+}
+
+static void
+aoview_dev_savelog(GtkWidget *widget, gpointer data)
+{
+ dialog_save_log = TRUE;
+ gtk_widget_show(dialog);
+}
+
+#define _(a) a
+
+void
+aoview_dev_dialog_init(GladeXML *xml)
+{
+ GtkTreeView *dev_list;
+ GtkWidget *connect_button;
+ GtkTreeSelection *dev_selection;
+ GtkWidget *ao_disconnect;
+ GtkWidget *ao_savelog;
+
+ dialog = glade_xml_get_widget(xml, "device_connect_dialog");
+ assert(dialog);
+
+ dev_list = GTK_TREE_VIEW(glade_xml_get_widget(xml, "dev_list"));
+ assert(dev_list);
+
+ aoview_add_plain_text_column(dev_list, _("Product"), 0, 16);
+ aoview_add_plain_text_column(dev_list, _("Serial"), 1, 8);
+ aoview_add_plain_text_column(dev_list, _("Device"), 2, 13);
+
+ dev_selection = gtk_tree_view_get_selection(dev_list);
+ gtk_tree_selection_set_mode(dev_selection, GTK_SELECTION_SINGLE);
+
+ g_signal_connect(G_OBJECT(dialog), "map",
+ G_CALLBACK(aoview_dev_dialog_map),
+ dev_list);
+
+ connect_button = glade_xml_get_widget(xml, "connect_button");
+ assert(connect_button);
+
+ g_signal_connect(G_OBJECT(connect_button), "clicked",
+ G_CALLBACK(aoview_dev_dialog_connect),
+ dev_list);
+
+
+ ao_disconnect = glade_xml_get_widget(xml, "ao_disconnect");
+ assert(ao_disconnect);
+
+ g_signal_connect(G_OBJECT(ao_disconnect), "activate",
+ G_CALLBACK(aoview_dev_disconnect),
+ ao_disconnect);
+
+ ao_savelog = glade_xml_get_widget(xml, "ao_savelog");
+ assert(ao_savelog);
+
+ g_signal_connect(G_OBJECT(ao_savelog), "activate",
+ G_CALLBACK(aoview_dev_savelog),
+ dialog);
+ dev_open_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "dev_open_fail_dialog"));
+ assert(dev_open_fail_dialog);
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+#define EEPROM_LEN 1024
+
+static struct aoview_file *eeprom_file;
+static char eeprom_line[EEPROM_LEN + 1];
+static int eeprom_pos;
+static GtkMessageDialog *eeprom_save_done;
+static GtkWidget *eeprom_save_close;
+static gboolean eeprom_save_shown;
+
+static void
+aoview_eeprom_disconnect(struct aoview_serial *serial)
+{
+ aoview_file_finish(eeprom_file);
+}
+
+static void
+aoview_eeprom_done(struct aoview_serial *serial)
+{
+ gtk_window_set_title(GTK_WINDOW(eeprom_save_done),
+ "EEPROM data saved");
+ gtk_message_dialog_set_markup(eeprom_save_done,
+ "<b>EEPROM data saved as</b>");
+ if (!eeprom_save_shown)
+ gtk_widget_show(GTK_WIDGET(eeprom_save_done));
+ eeprom_save_close = gtk_window_get_default_widget(GTK_WINDOW(eeprom_save_done));
+ if (eeprom_save_close)
+ gtk_widget_set_sensitive(eeprom_save_close, TRUE);
+ aoview_eeprom_disconnect(serial);
+}
+
+static gboolean
+aoview_eeprom_parse(struct aoview_serial *serial,
+ char *line)
+{
+ char cmd;
+ int tick;
+ int a;
+ int b;
+ int serial_number;
+ const char *name;
+ char *utf8_name;
+
+ if (!strcmp(line, "end")) {
+ aoview_eeprom_done(serial);
+ return FALSE;
+ }
+ if (sscanf(line, "serial-number %u", &serial_number) == 1) {
+ aoview_file_set_serial(eeprom_file, serial_number);
+ } else if (sscanf(line, "%c %x %x %x", &cmd, &tick, &a, &b) == 4) {
+ aoview_file_printf(eeprom_file, "%s\n", line);
+ if (cmd == 'S' && a == 8) {
+ aoview_eeprom_done(serial);
+ return FALSE;
+ }
+
+ if (!eeprom_save_shown)
+ {
+ name = aoview_file_name(eeprom_file);
+ if (name) {
+ utf8_name = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
+ if (!utf8_name)
+ utf8_name = (char *) name;
+ gtk_widget_set_sensitive(eeprom_save_close, FALSE);
+ gtk_window_set_title(GTK_WINDOW(eeprom_save_done),
+ "Saving EEPROM data");
+ gtk_message_dialog_set_markup(eeprom_save_done,
+ "<b>Saving EEPROM data as</b>");
+ gtk_message_dialog_format_secondary_text(eeprom_save_done, "%s",
+ utf8_name);
+ if (utf8_name != name)
+ g_free(utf8_name);
+ gtk_container_check_resize(GTK_CONTAINER(eeprom_save_done));
+ gtk_widget_show(GTK_WIDGET(eeprom_save_done));
+ eeprom_save_shown = TRUE;
+ eeprom_save_close = gtk_window_get_default_widget(GTK_WINDOW(eeprom_save_done));
+ if (eeprom_save_close)
+ gtk_widget_set_sensitive(eeprom_save_close, FALSE);
+ }
+ }
+ }
+ return TRUE;
+}
+
+static void
+aoview_eeprom_callback(gpointer user_data,
+ struct aoview_serial *serial,
+ gint revents)
+{
+ int c;
+
+ if (revents & (G_IO_HUP|G_IO_ERR)) {
+ aoview_eeprom_disconnect(serial);
+ return;
+ }
+ if (revents & G_IO_IN) {
+ for (;;) {
+ c = aoview_serial_getc(serial);
+ if (c == -1)
+ break;
+ if (c == '\r')
+ continue;
+ if (c == '\n') {
+ eeprom_line[eeprom_pos] = '\0';
+ if (eeprom_pos)
+ if (!aoview_eeprom_parse(serial, eeprom_line))
+ break;
+ eeprom_pos = 0;
+ } else if (eeprom_pos < EEPROM_LEN)
+ eeprom_line[eeprom_pos++] = c;
+ }
+ }
+}
+
+gboolean
+aoview_eeprom_save(const char *device)
+{
+ struct aoview_serial *serial;
+
+ gtk_widget_hide(GTK_WIDGET(eeprom_save_done));
+ eeprom_save_shown = FALSE;
+ serial = aoview_serial_open(device);
+ if (!serial)
+ return FALSE;
+ aoview_serial_set_callback(serial, aoview_eeprom_callback);
+ aoview_serial_printf(serial, "v\nl\n");
+ return TRUE;
+}
+
+void
+aoview_eeprom_init(GladeXML *xml)
+{
+ eeprom_file = aoview_file_new("eeprom");
+ assert(eeprom_file);
+
+ eeprom_save_done = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "ao_save_done"));
+ assert(eeprom_save_done);
+
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+char *aoview_file_dir;
+
+#define ALTOS_DIR_PATH "/apps/aoview/log_dir"
+#define DEFAULT_DIR "AltOS"
+
+struct aoview_file {
+ char *ext;
+ FILE *file;
+ char *name;
+ int failed;
+ int serial;
+ int sequence;
+};
+
+static void
+aoview_file_save_conf(void)
+{
+ GConfClient *gconf_client;
+
+ gconf_client = gconf_client_get_default();
+ if (gconf_client)
+ {
+ gconf_client_set_string(gconf_client,
+ ALTOS_DIR_PATH,
+ aoview_file_dir,
+ NULL);
+ g_object_unref(G_OBJECT(gconf_client));
+ }
+}
+
+static void
+aoview_file_configure(GtkWidget *widget, gpointer data)
+{
+ GtkFileChooser *chooser = data;
+ aoview_file_dir = gtk_file_chooser_get_filename(chooser);
+ aoview_file_save_conf();
+ gtk_widget_hide(GTK_WIDGET(chooser));
+}
+
+void
+aoview_file_finish(struct aoview_file *file)
+{
+ if (file->file) {
+ fclose(file->file);
+ file->file = NULL;
+ free(file->name);
+ file->name = NULL;
+ }
+ file->failed = 0;
+}
+
+const char *
+aoview_file_name(struct aoview_file *file)
+{
+ return file->name;
+}
+
+static GtkMessageDialog *file_fail_dialog;
+
+static void
+aoview_file_open_failed(char *name)
+{
+ char *utf8_file;
+ utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
+ if (!utf8_file)
+ utf8_file = name;
+ gtk_message_dialog_format_secondary_text(file_fail_dialog,
+ "\"%s\"", utf8_file);
+ if (utf8_file != name)
+ g_free(utf8_file);
+ gtk_widget_show(GTK_WIDGET(file_fail_dialog));
+}
+
+gboolean
+aoview_file_start(struct aoview_file *file)
+{
+ char base[50];
+ struct tm tm;
+ time_t now;
+ char *full;
+ int r;
+
+ if (file->file)
+ return TRUE;
+
+ if (file->failed)
+ return FALSE;
+
+ now = time(NULL);
+ (void) localtime_r(&now, &tm);
+ aoview_mkdir(aoview_file_dir);
+ for (;;) {
+ snprintf(base, sizeof (base), "%04d-%02d-%02d-serial-%03d-flight-%03d.%s",
+ tm.tm_year + 1900,
+ tm.tm_mon + 1,
+ tm.tm_mday,
+ file->serial,
+ file->sequence,
+ file->ext);
+ full = aoview_fullname(aoview_file_dir, base);
+ r = access(full, F_OK);
+ if (r < 0) {
+ file->file = fopen(full, "w");
+ if (!file->file) {
+ aoview_file_open_failed(full);
+ free(full);
+ file->failed = 1;
+ return FALSE;
+ } else {
+ setlinebuf(file->file);
+ file->name = full;
+ return TRUE;
+ }
+ }
+ free(full);
+ file->sequence++;
+ }
+}
+
+void
+aoview_file_vprintf(struct aoview_file *file, char *format, va_list ap)
+{
+ if (!aoview_file_start(file))
+ return;
+ vfprintf(file->file, format, ap);
+}
+
+void
+aoview_file_printf(struct aoview_file *file, char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ aoview_file_vprintf(file, format, ap);
+ va_end(ap);
+}
+
+struct aoview_file *
+aoview_file_new(char *ext)
+{
+ struct aoview_file *file;
+
+ file = calloc (1, sizeof (struct aoview_file));
+ if (!file)
+ return NULL;
+ file->ext = strdup(ext);
+ if (!file->ext) {
+ free(file);
+ return NULL;
+ }
+ return file;
+}
+
+void
+aoview_file_destroy(struct aoview_file *file)
+{
+ if (file->file)
+ fclose(file->file);
+ if (file->name)
+ free(file->name);
+ free(file->ext);
+ free(file);
+}
+
+void
+aoview_file_set_serial(struct aoview_file *file, int serial)
+{
+ if (serial != file->serial)
+ aoview_file_finish(file);
+ file->serial = serial;
+}
+
+int
+aoview_file_get_serial(struct aoview_file *file)
+{
+ return file->serial;
+}
+
+void
+aoview_file_init(GladeXML *xml)
+{
+ GConfClient *gconf_client;
+ char *file_dir = NULL;
+ GtkFileChooser *file_chooser_dialog;
+ GtkWidget *file_configure_ok;
+
+ g_type_init();
+ gconf_client = gconf_client_get_default();
+ if (gconf_client)
+ {
+ file_dir = gconf_client_get_string(gconf_client,
+ ALTOS_DIR_PATH,
+ NULL);
+ g_object_unref(G_OBJECT(gconf_client));
+ }
+ if (!file_dir) {
+ aoview_file_dir = aoview_fullname(getenv("HOME"), DEFAULT_DIR);
+ aoview_file_save_conf();
+ } else {
+ aoview_file_dir = strdup(file_dir);
+ }
+
+ file_chooser_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "file_chooser_dialog"));
+ assert(file_chooser_dialog);
+ gtk_file_chooser_set_filename(file_chooser_dialog, aoview_file_dir);
+
+ file_configure_ok = glade_xml_get_widget(xml, "file_configure_ok");
+ assert(file_configure_ok);
+
+ g_signal_connect(G_OBJECT(file_configure_ok), "clicked",
+ G_CALLBACK(aoview_file_configure),
+ file_chooser_dialog);
+
+
+ file_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "file_fail_dialog"));
+ assert(file_fail_dialog);
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdio.h>
+#include <flite/flite.h>
+#include "aoview.h"
+#include <alsa/asoundlib.h>
+
+cst_voice *register_cmu_us_kal();
+static cst_voice *voice;
+
+static FILE *pipe_write;
+static GThread *aoview_flite_thread;
+
+static snd_pcm_t *alsa_handle;
+
+gpointer
+aoview_flite_task(gpointer data)
+{
+ FILE *input = data;
+ char line[1024];
+ cst_wave *wave;
+ int rate;
+ int channels;
+ int err;
+ char *samples;
+ int num_samples;
+
+ err = snd_pcm_open(&alsa_handle, "default",
+ SND_PCM_STREAM_PLAYBACK, 0);
+ if (err >= 0)
+ {
+ if (err < 0) {
+ snd_pcm_close(alsa_handle);
+ alsa_handle = 0;
+ }
+ }
+ rate = 0;
+ channels = 0;
+ while (fgets(line, sizeof (line) - 1, input) != NULL) {
+ if (!alsa_handle)
+ continue;
+ wave = flite_text_to_wave(line, voice);
+ if (wave->sample_rate != rate ||
+ wave->num_channels != channels)
+ {
+ rate = wave->sample_rate;
+ channels = wave->num_channels;
+ err = snd_pcm_set_params(alsa_handle,
+ SND_PCM_FORMAT_S16,
+ SND_PCM_ACCESS_RW_INTERLEAVED,
+ channels,
+ rate,
+ 1,
+ 100000);
+ if (err < 0)
+ fprintf(stderr, "alsa set_params error %s\n",
+ strerror(-err));
+ }
+ err = snd_pcm_prepare(alsa_handle);
+ if (err < 0)
+ fprintf(stderr, "alsa pcm_prepare error %s\n",
+ strerror(-err));
+ samples = (char *) wave->samples;
+ num_samples = wave->num_samples;
+ while (num_samples > 0) {
+ err = snd_pcm_writei(alsa_handle,
+ samples, num_samples);
+ if (err <= 0) {
+ fprintf(stderr, "alsa write error %s\n",
+ strerror(-err));
+ break;
+ }
+ num_samples -= err;
+ samples += err * 2 * channels;
+ }
+ snd_pcm_drain(alsa_handle);
+ delete_wave(wave);
+ }
+ snd_pcm_close(alsa_handle);
+ alsa_handle = 0;
+ return NULL;
+}
+
+void
+aoview_flite_stop(void)
+{
+ int status;
+ if (pipe_write) {
+ fclose(pipe_write);
+ pipe_write = NULL;
+ }
+ if (aoview_flite_thread) {
+ g_thread_join(aoview_flite_thread);
+ aoview_flite_thread = NULL;
+ }
+}
+
+FILE *
+aoview_flite_start(void)
+{
+ static once;
+ int p[2];
+ GError *error;
+ FILE *pipe_read;
+
+ if (!once) {
+ flite_init();
+ voice = register_cmu_us_kal();
+ if (!voice) {
+ perror("register voice");
+ exit(1);
+ }
+ }
+ aoview_flite_stop();
+ pipe(p);
+ pipe_read = fdopen(p[0], "r");
+ pipe_write = fdopen(p[1], "w");
+ g_thread_create(aoview_flite_task, pipe_read, TRUE, &error);
+ return pipe_write;
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+static struct {
+ char *name;
+ char *initial_value;
+ GtkLabel *widget;
+} label_widgets[] = {
+ { "height_label", "Height (m)", NULL },
+ { "state_label", "State", NULL },
+ { "rssi_label", "RSSI (dBm)", NULL },
+ { "speed_label", "Speed (m/s)", NULL },
+ { "height_value", "0", NULL },
+ { "state_value", "pad", NULL },
+ { "rssi_value", "-50", NULL },
+ { "speed_value", "0", NULL },
+};
+
+static void
+aoview_label_assign(GtkLabel *widget, char *value)
+{
+ char *markup;
+
+ markup = g_markup_printf_escaped("<span font_weight=\"bold\" size=\"xx-large\">%s</span>", value);
+ gtk_label_set_markup(widget, markup);
+ g_free(markup);
+}
+
+void
+aoview_label_show(struct aostate *state)
+{
+ char line[1024];
+ sprintf(line, "%d", state->height);
+ aoview_label_assign(label_widgets[4].widget, line);
+
+ aoview_label_assign(label_widgets[5].widget, state->data.state);
+
+ sprintf(line, "%d", state->data.rssi);
+ aoview_label_assign(label_widgets[6].widget, line);
+
+ if (state->ascent)
+ sprintf(line, "%6.0f", fabs(state->speed));
+ else
+ sprintf(line, "%6.0f", fabs(state->baro_speed));
+ aoview_label_assign(label_widgets[7].widget, line);
+}
+
+void
+aoview_label_init(GladeXML *xml)
+{
+ int i;
+ for (i = 0; i < sizeof(label_widgets)/sizeof(label_widgets[0]); i++) {
+ label_widgets[i].widget = GTK_LABEL(glade_xml_get_widget(xml, label_widgets[i].name));
+ aoview_label_assign(label_widgets[i].widget, label_widgets[i].initial_value);
+ assert(label_widgets[i].widget);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+static struct aoview_file *aoview_log;
+
+void
+aoview_log_new(void)
+{
+ aoview_file_finish(aoview_log);
+ aoview_state_new();
+}
+
+void
+aoview_log_set_serial(int serial)
+{
+ aoview_file_set_serial(aoview_log, serial);
+}
+
+int
+aoview_log_get_serial(void)
+{
+ return aoview_file_get_serial(aoview_log);
+}
+
+void
+aoview_log_printf(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ aoview_file_vprintf(aoview_log, format, ap);
+ va_end(ap);
+}
+
+static void
+aoview_log_new_item(GtkWidget *widget, gpointer data)
+{
+ aoview_file_finish(aoview_log);
+}
+
+void
+aoview_log_init(GladeXML *xml)
+{
+ GtkWidget *log_new;
+
+ aoview_log = aoview_file_new("telem");
+ assert(aoview_log);
+
+ log_new = glade_xml_get_widget(xml, "log_new");
+ assert(log_new);
+ g_signal_connect(G_OBJECT(log_new), "activate",
+ G_CALLBACK(aoview_log_new_item),
+ NULL);
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+static const char aoview_glade[] = {
+#include "aoview_glade.h"
+};
+
+static void usage(void) {
+ printf("aoview [--device|-d device_file]");
+ exit(1);
+}
+
+static void destroy_event(GtkWidget *widget, gpointer data)
+{
+ gtk_main_quit();
+}
+
+extern int _Xdebug;
+
+int main(int argc, char **argv)
+{
+ GladeXML *xml = NULL;
+ GtkWidget *mainwindow;
+ char *device = NULL;
+ GtkAboutDialog *about_dialog;
+
+ static struct option long_options[] = {
+ { "device", 1, 0, 'd'},
+ { "sync", 0, 0, 's'},
+ { 0, 0, 0, 0 }
+ };
+ for (;;) {
+ int c, temp;
+
+ c = getopt_long_only(argc, argv, "sd:", long_options, &temp);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'd':
+ device = optarg;
+ break;
+ case 's':
+ _Xdebug = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ g_thread_init(NULL);
+ gtk_init(&argc, &argv);
+ glade_init();
+
+ xml = glade_xml_new_from_buffer(aoview_glade, sizeof (aoview_glade), NULL, NULL);
+
+ /* connect the signals in the interface */
+ glade_xml_signal_autoconnect(xml);
+
+ /* Hook up the close button. */
+ mainwindow = glade_xml_get_widget(xml, "aoview");
+ assert(mainwindow);
+
+ g_signal_connect (G_OBJECT(mainwindow), "destroy",
+ G_CALLBACK(destroy_event), NULL);
+
+ about_dialog = GTK_ABOUT_DIALOG(glade_xml_get_widget(xml, "about_dialog"));
+ assert(about_dialog);
+ gtk_about_dialog_set_version(about_dialog, AOVIEW_VERSION);
+
+ aoview_voice_init(xml);
+
+ aoview_dev_dialog_init(xml);
+
+ aoview_state_init(xml);
+
+ aoview_file_init(xml);
+
+ aoview_log_init(xml);
+
+ aoview_table_init(xml);
+
+ aoview_eeprom_init(xml);
+
+ aoview_replay_init(xml);
+
+ aoview_label_init(xml);
+
+ aoview_voice_speak("rocket flight monitor ready\n");
+
+ gtk_main();
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+static struct aoview_serial *monitor_serial;
+
+#define MONITOR_LEN 1024
+
+static char monitor_line[MONITOR_LEN + 1];
+static int monitor_pos;
+
+void
+aoview_monitor_disconnect(void)
+{
+ if (monitor_serial) {
+ aoview_serial_close(monitor_serial);
+ monitor_serial = NULL;
+ }
+ aoview_log_new();
+}
+
+static void
+aoview_parse_string(char *target, int len, char *source)
+{
+ strncpy(target, source, len-1);
+ target[len-1] = '\0';
+}
+
+static void
+aoview_parse_int(int *target, char *source)
+{
+ *target = strtol(source, NULL, 0);
+}
+
+static void
+aoview_parse_pos(double *target, char *source)
+{
+ int deg;
+ double min;
+ char dir;
+ double r;
+
+ if (sscanf(source, "%d°%lf'%c", °, &min, &dir) != 3) {
+ *target = 0;
+ return;
+ }
+ r = deg + min / 60.0;
+ if (dir == 'S' || dir == 'W')
+ r = -r;
+ *target = r;
+}
+
+gboolean
+aoview_monitor_parse(const char *input_line)
+{
+ char *saveptr;
+ char *words[64];
+ int nword;
+ char line_buf[8192], *line;
+ struct aodata data;
+
+ /* avoid smashing our input parameter */
+ strncpy (line_buf, input_line, sizeof (line_buf)-1);
+ line_buf[sizeof(line_buf) - 1] = '\0';
+ line = line_buf;
+ for (nword = 0; nword < 64; nword++) {
+ words[nword] = strtok_r(line, " \t\n", &saveptr);
+ line = NULL;
+ if (words[nword] == NULL)
+ break;
+ }
+ if (nword < 36)
+ return FALSE;
+ if (strcmp(words[0], "CALL") != 0)
+ return FALSE;
+ aoview_parse_string(data.callsign, sizeof (data.callsign), words[1]);
+ aoview_parse_int(&data.serial, words[3]);
+
+ aoview_parse_int(&data.rssi, words[5]);
+ aoview_parse_string(data.state, sizeof (data.state), words[9]);
+ aoview_parse_int(&data.tick, words[10]);
+ aoview_parse_int(&data.accel, words[12]);
+ aoview_parse_int(&data.pres, words[14]);
+ aoview_parse_int(&data.temp, words[16]);
+ aoview_parse_int(&data.batt, words[18]);
+ aoview_parse_int(&data.drogue, words[20]);
+ aoview_parse_int(&data.main, words[22]);
+ aoview_parse_int(&data.flight_accel, words[24]);
+ aoview_parse_int(&data.ground_accel, words[26]);
+ aoview_parse_int(&data.flight_vel, words[28]);
+ aoview_parse_int(&data.flight_pres, words[30]);
+ aoview_parse_int(&data.ground_pres, words[32]);
+ aoview_parse_int(&data.gps.nsat, words[34]);
+ if (strcmp (words[36], "unlocked") == 0) {
+ data.gps.gps_connected = 1;
+ data.gps.gps_locked = 0;
+ data.gps.gps_time.hour = data.gps.gps_time.minute = data.gps.gps_time.second = 0;
+ data.gps.lat = data.gps.lon = 0;
+ data.gps.alt = 0;
+ } else if (nword >= 40) {
+ data.gps.gps_locked = 1;
+ data.gps.gps_connected = 1;
+ sscanf(words[36], "%d:%d:%d", &data.gps.gps_time.hour, &data.gps.gps_time.minute, &data.gps.gps_time.second);
+ aoview_parse_pos(&data.gps.lat, words[37]);
+ aoview_parse_pos(&data.gps.lon, words[38]);
+ sscanf(words[39], "%dm", &data.gps.alt);
+ } else {
+ data.gps.gps_connected = 0;
+ data.gps.gps_locked = 0;
+ data.gps.gps_time.hour = data.gps.gps_time.minute = data.gps.gps_time.second = 0;
+ data.gps.lat = data.gps.lon = 0;
+ data.gps.alt = 0;
+ }
+ if (nword >= 46) {
+ data.gps.gps_extended = 1;
+ sscanf(words[40], "%lfm/s", &data.gps.ground_speed);
+ sscanf(words[41], "%d", &data.gps.course);
+ sscanf(words[42], "%lfm/s", &data.gps.climb_rate);
+ sscanf(words[43], "%lf", &data.gps.hdop);
+ sscanf(words[44], "%d", &data.gps.h_error);
+ sscanf(words[45], "%d", &data.gps.v_error);
+ } else {
+ data.gps.gps_extended = 0;
+ data.gps.ground_speed = 0;
+ data.gps.course = 0;
+ data.gps.climb_rate = 0;
+ data.gps.hdop = 0;
+ data.gps.h_error = 0;
+ data.gps.v_error = 0;
+ }
+ aoview_state_notify(&data);
+ return TRUE;
+}
+
+static void
+aoview_monitor_callback(gpointer user_data,
+ struct aoview_serial *serial,
+ gint revents)
+{
+ int c;
+
+ if (revents & (G_IO_HUP|G_IO_ERR)) {
+ aoview_monitor_disconnect();
+ return;
+ }
+ if (revents & G_IO_IN) {
+ for (;;) {
+ c = aoview_serial_getc(serial);
+ if (c == -1)
+ break;
+ if (c == '\r')
+ continue;
+ if (c == '\n') {
+ monitor_line[monitor_pos] = '\0';
+ if (monitor_pos) {
+ if (aoview_monitor_parse(monitor_line)) {
+ aoview_log_set_serial(aostate.data.serial);
+ if (aoview_log_get_serial())
+ aoview_log_printf ("%s\n", monitor_line);
+ }
+ }
+ monitor_pos = 0;
+ } else if (monitor_pos < MONITOR_LEN)
+ monitor_line[monitor_pos++] = c;
+ }
+ }
+}
+
+gboolean
+aoview_monitor_connect(char *tty)
+{
+ aoview_monitor_disconnect();
+ monitor_serial = aoview_serial_open(tty);
+ if (!monitor_serial)
+ return FALSE;
+ aoview_table_clear();
+ aoview_state_reset();
+ aoview_serial_set_callback(monitor_serial,
+ aoview_monitor_callback);
+ return TRUE;
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+static GtkFileChooser *replay_dialog;
+static GtkWidget *replay_ok;
+static FILE *replay_file;
+static int replay_tick;
+
+static int
+find_tick(char *line, gboolean *is_pad)
+{
+ char *state = strstr(line, "STATE");
+ if (!state)
+ return -1;
+ state = strchr(state, ' ');
+ if (!state)
+ return -1;
+ while (*state == ' ')
+ state++;
+ *is_pad = strncmp(state, "pad", 3) == 0;
+ while (*state && !isdigit(*state))
+ state++;
+ return atoi(state);
+}
+
+static void
+aoview_replay_close(void)
+{
+ if (replay_file) {
+ fclose(replay_file);
+ replay_file = NULL;
+ }
+}
+
+static char replay_line[1024];
+
+static gboolean
+aoview_replay_read(gpointer data);
+
+static gboolean
+aoview_replay_execute(gpointer data)
+{
+ aoview_monitor_parse(replay_line);
+ g_idle_add(aoview_replay_read, NULL);
+ return FALSE;
+}
+
+static gboolean
+aoview_replay_read(gpointer data)
+{
+ int tick;
+ gboolean is_pad;
+
+ if (!replay_file)
+ return FALSE;
+ if (fgets(replay_line, sizeof (replay_line), replay_file)) {
+ tick = find_tick(replay_line, &is_pad);
+ if (tick >= 0 && replay_tick >= 0 && !is_pad) {
+ while (tick < replay_tick)
+ tick += 65536;
+ g_timeout_add((tick - replay_tick) * 10,
+ aoview_replay_execute,
+ NULL);
+ } else {
+ aoview_replay_execute(NULL);
+ }
+ replay_tick = tick;
+ } else {
+ aoview_replay_close();
+ }
+ return FALSE;
+}
+
+static void
+aoview_replay_open(GtkWidget *widget, gpointer data)
+{
+ char *replay_file_name;
+ GtkWidget *dialog;
+
+ aoview_replay_close();
+ replay_file_name = gtk_file_chooser_get_filename(replay_dialog);
+ replay_file = fopen(replay_file_name, "r");
+ if (!replay_file) {
+ dialog = gtk_message_dialog_new(GTK_WINDOW(replay_dialog),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error loading file '%s': %s",
+ replay_file_name, g_strerror(errno));
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+ } else {
+ replay_tick = -1;
+ aoview_state_reset();
+ aoview_replay_read(NULL);
+ }
+ gtk_widget_hide(GTK_WIDGET(replay_dialog));
+}
+
+void
+aoview_replay_init(GladeXML *xml)
+{
+ GtkFileFilter *telem_filter;
+ GtkFileFilter *all_filter;
+ GtkFileFilter *log_filter;
+
+ telem_filter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(telem_filter, "*.telem");
+ gtk_file_filter_set_name(telem_filter, "Telemetry Files");
+
+ log_filter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(log_filter, "*.log");
+ gtk_file_filter_set_name(log_filter, "Log Files");
+
+ all_filter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(all_filter, "*");
+ gtk_file_filter_set_name(all_filter, "All Files");
+
+ replay_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "ao_replay_dialog"));
+ assert(replay_dialog);
+ gtk_file_chooser_set_current_folder(replay_dialog, aoview_file_dir);
+ gtk_file_chooser_add_filter(replay_dialog, telem_filter);
+ gtk_file_chooser_add_filter(replay_dialog, log_filter);
+ gtk_file_chooser_add_filter(replay_dialog, all_filter);
+
+ replay_ok = glade_xml_get_widget(xml, "ao_replay_ok");
+ assert(replay_ok);
+ g_signal_connect(G_OBJECT(replay_ok), "clicked",
+ G_CALLBACK(aoview_replay_open),
+ replay_dialog);
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+#include <termios.h>
+
+#define AOVIEW_SERIAL_IN_BUF 64
+#define AOVIEW_SERIAL_OUT_BUF 64
+
+struct aoview_buf {
+ char *buf;
+ int off;
+ int count;
+ int size;
+};
+
+static int
+aoview_buf_write(struct aoview_buf *buf, char *data, int len)
+{
+ if (buf->count + len > buf->size) {
+ int new_size = buf->size * 2;
+ if (new_size == 0)
+ new_size = 1024;
+ if (buf->buf)
+ buf->buf = realloc (buf->buf, new_size);
+ else
+ buf->buf = malloc (new_size);
+ buf->size = new_size;
+ }
+ memcpy(buf->buf + buf->count, data, len);
+ buf->count += len;
+ return len;
+}
+
+static int
+aoview_buf_read(struct aoview_buf *buf, char *data, int len)
+{
+ if (len > buf->count - buf->off)
+ len = buf->count - buf->off;
+ memcpy (data, buf->buf + buf->off, len);
+ buf->off += len;
+ if (buf->off == buf->count)
+ buf->off = buf->count = 0;
+ return len;
+}
+
+static int
+aoview_buf_getc(struct aoview_buf *buf)
+{
+ char b;
+ int r;
+
+ r = aoview_buf_read(buf, &b, 1);
+ if (r == 1)
+ return (int) b;
+ return -1;
+}
+
+static void
+aoview_buf_flush(struct aoview_buf *buf, int fd)
+{
+ int ret;
+
+ if (buf->count > buf->off) {
+ ret = write(fd, buf->buf + buf->off, buf->count - buf->off);
+ if (ret > 0) {
+ buf->off += ret;
+ if (buf->off == buf->count)
+ buf->off = buf->count = 0;
+ }
+ }
+}
+
+static void
+aoview_buf_fill(struct aoview_buf *buf, int fd)
+{
+ int ret;
+
+ while (buf->count >= buf->size) {
+ int new_size = buf->size * 2;
+ buf->buf = realloc (buf->buf, new_size);
+ buf->size = new_size;
+ }
+
+ ret = read(fd, buf->buf + buf->count, buf->size - buf->count);
+ if (ret > 0)
+ buf->count += ret;
+}
+
+static void
+aoview_buf_init(struct aoview_buf *buf)
+{
+ buf->buf = malloc (buf->size = 1024);
+ buf->count = 0;
+}
+
+static void
+aoview_buf_fini(struct aoview_buf *buf)
+{
+ free(buf->buf);
+}
+
+struct aoview_serial {
+ GSource source;
+ int fd;
+ struct termios save_termios;
+ struct aoview_buf in_buf;
+ struct aoview_buf out_buf;
+ GPollFD poll_fd;
+};
+
+
+void
+aoview_serial_printf(struct aoview_serial *serial, char *format, ...)
+{
+ char buf[1024];
+ va_list ap;
+ int ret;
+
+ /* sprintf to a local buffer */
+ va_start(ap, format);
+ ret = vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+ if (ret > sizeof(buf)) {
+ fprintf(stderr, "printf overflow for format %s\n",
+ format);
+ }
+
+ /* flush local buffer to the wire */
+ aoview_buf_write(&serial->out_buf, buf, ret);
+ aoview_buf_flush(&serial->out_buf, serial->fd);
+}
+
+int
+aoview_serial_read(struct aoview_serial *serial, char *buf, int len)
+{
+ return aoview_buf_read(&serial->in_buf, buf, len);
+}
+
+int
+aoview_serial_getc(struct aoview_serial *serial)
+{
+ return aoview_buf_getc(&serial->in_buf);
+}
+
+static gboolean
+serial_prepare(GSource *source, gint *timeout)
+{
+ struct aoview_serial *serial = (struct aoview_serial *) source;
+ *timeout = -1;
+
+ if (serial->out_buf.count)
+ serial->poll_fd.events |= G_IO_OUT;
+ else
+ serial->poll_fd.events &= ~G_IO_OUT;
+ return FALSE;
+}
+
+static gboolean
+serial_check(GSource *source)
+{
+ struct aoview_serial *serial = (struct aoview_serial *) source;
+ gint revents = serial->poll_fd.revents;
+
+ if (revents & G_IO_NVAL)
+ return FALSE;
+ if (revents & G_IO_IN)
+ return TRUE;
+ if (revents & G_IO_OUT)
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean
+serial_dispatch(GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ struct aoview_serial *serial = (struct aoview_serial *) source;
+ aoview_serial_callback func = (aoview_serial_callback) callback;
+ gint revents = serial->poll_fd.revents;
+
+ if (revents & G_IO_IN)
+ aoview_buf_fill(&serial->in_buf, serial->fd);
+
+ if (revents & G_IO_OUT)
+ aoview_buf_flush(&serial->out_buf, serial->fd);
+
+ if (func)
+ (*func)(user_data, serial, revents);
+ return TRUE;
+}
+
+static void
+serial_finalize(GSource *source)
+{
+ struct aoview_serial *serial = (struct aoview_serial *) source;
+
+ aoview_buf_fini(&serial->in_buf);
+ aoview_buf_fini(&serial->out_buf);
+ tcsetattr(serial->fd, TCSAFLUSH, &serial->save_termios);
+ close (serial->fd);
+}
+
+static GSourceFuncs serial_funcs = {
+ serial_prepare,
+ serial_check,
+ serial_dispatch,
+ serial_finalize
+};
+
+struct aoview_serial *
+aoview_serial_open(const char *tty)
+{
+ struct aoview_serial *serial;
+ struct termios termios;
+
+ serial = (struct aoview_serial *) g_source_new(&serial_funcs, sizeof (struct aoview_serial));
+ aoview_buf_init(&serial->in_buf);
+ aoview_buf_init(&serial->out_buf);
+ serial->fd = open (tty, O_RDWR | O_NONBLOCK);
+ if (serial->fd < 0) {
+ g_source_destroy(&serial->source);
+ return NULL;
+ }
+ tcgetattr(serial->fd, &termios);
+ serial->save_termios = termios;
+ cfmakeraw(&termios);
+ tcsetattr(serial->fd, TCSAFLUSH, &termios);
+
+ aoview_serial_printf(serial, "E 0\n");
+ tcdrain(serial->fd);
+ usleep(15*1000);
+ tcflush(serial->fd, TCIFLUSH);
+ serial->poll_fd.fd = serial->fd;
+ serial->poll_fd.events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR;
+ g_source_attach(&serial->source, NULL);
+ g_source_add_poll(&serial->source,&serial->poll_fd);
+ aoview_serial_set_callback(serial, NULL);
+ return serial;
+}
+
+void
+aoview_serial_close(struct aoview_serial *serial)
+{
+ g_source_remove_poll(&serial->source, &serial->poll_fd);
+ close(serial->fd);
+ g_source_destroy(&serial->source);
+}
+
+void
+aoview_serial_set_callback(struct aoview_serial *serial,
+ aoview_serial_callback func)
+{
+ g_source_set_callback(&serial->source, (GSourceFunc) func, serial, NULL);
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+#include <math.h>
+
+static inline double sqr(double a) { return a * a; };
+
+static void
+aoview_great_circle (double start_lat, double start_lon,
+ double end_lat, double end_lon,
+ double *dist, double *bearing)
+{
+ const double rad = M_PI / 180;
+ const double earth_radius = 6371.2 * 1000; /* in meters */
+ double lat1 = rad * start_lat;
+ double lon1 = rad * -start_lon;
+ double lat2 = rad * end_lat;
+ double lon2 = rad * -end_lon;
+
+ double d_lat = lat2 - lat1;
+ double d_lon = lon2 - lon1;
+
+ /* From http://en.wikipedia.org/wiki/Great-circle_distance */
+ double vdn = sqrt(sqr(cos(lat2) * sin(d_lon)) +
+ sqr(cos(lat1) * sin(lat2) -
+ sin(lat1) * cos(lat2) * cos(d_lon)));
+ double vdd = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(d_lon);
+ double d = atan2(vdn,vdd);
+ double course;
+
+ if (cos(lat1) < 1e-20) {
+ if (lat1 > 0)
+ course = M_PI;
+ else
+ course = -M_PI;
+ } else {
+ if (d < 1e-10)
+ course = 0;
+ else
+ course = acos((sin(lat2)-sin(lat1)*cos(d)) /
+ (sin(d)*cos(lat1)));
+ if (sin(lon2-lon1) > 0)
+ course = 2 * M_PI-course;
+ }
+ *dist = d * earth_radius;
+ *bearing = course * 180/M_PI;
+}
+
+static void
+aoview_state_add_deg(int column, char *label, double deg, char pos, char neg)
+{
+ double int_part;
+ double min;
+ char sign = pos;
+
+ if (deg < 0) {
+ deg = -deg;
+ sign = neg;
+ }
+ int_part = floor (deg);
+ min = (deg - int_part) * 60.0;
+ aoview_table_add_row(column, label, "%d°%lf'%c",
+ (int) int_part, min, sign);
+
+}
+
+static char *ascent_states[] = {
+ "boost",
+ "fast",
+ "coast",
+ 0,
+};
+
+static double
+aoview_time(void)
+{
+ struct timespec now;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return (double) now.tv_sec + (double) now.tv_nsec / 1.0e9;
+}
+
+/*
+ * Fill out the derived data fields
+ */
+static void
+aoview_state_derive(struct aodata *data, struct aostate *state)
+{
+ int i;
+ double new_height;
+ double height_change;
+ double time_change;
+ int tick_count;
+
+ state->report_time = aoview_time();
+
+ state->prev_data = state->data;
+ state->prev_npad = state->npad;
+ state->data = *data;
+ tick_count = data->tick;
+ if (tick_count < state->prev_data.tick)
+ tick_count += 65536;
+ time_change = (tick_count - state->prev_data.tick) / 100.0;
+
+ state->ground_altitude = aoview_pres_to_altitude(data->ground_pres);
+ new_height = aoview_pres_to_altitude(data->flight_pres) - state->ground_altitude;
+ height_change = new_height - state->height;
+ state->height = new_height;
+ if (time_change)
+ state->baro_speed = (state->baro_speed * 3 + (height_change / time_change)) / 4.0;
+ state->acceleration = (data->ground_accel - data->flight_accel) / 27.0;
+ state->speed = data->flight_vel / 2700.0;
+ state->temperature = ((data->temp / 32767.0 * 3.3) - 0.5) / 0.01;
+ state->drogue_sense = data->drogue / 32767.0 * 15.0;
+ state->main_sense = data->main / 32767.0 * 15.0;
+ state->battery = data->batt / 32767.0 * 5.0;
+ if (!strcmp(data->state, "pad")) {
+ if (data->gps.gps_locked && data->gps.nsat >= 4) {
+ state->npad++;
+ state->pad_lat_total += data->gps.lat;
+ state->pad_lon_total += data->gps.lon;
+ state->pad_alt_total += data->gps.alt;
+ if (state->npad > 1) {
+ state->pad_lat = (state->pad_lat * 31 + data->gps.lat) / 32.0;
+ state->pad_lon = (state->pad_lon * 31 + data->gps.lon) / 32.0;
+ state->pad_alt = (state->pad_alt * 31 + data->gps.alt) / 32.0;
+ } else {
+ state->pad_lat = data->gps.lat;
+ state->pad_lon = data->gps.lon;
+ state->pad_alt = data->gps.alt;
+ }
+ }
+ }
+ state->ascent = FALSE;
+ for (i = 0; ascent_states[i]; i++)
+ if (!strcmp(data->state, ascent_states[i]))
+ state->ascent = TRUE;
+
+ /* Only look at accelerometer data on the way up */
+ if (state->ascent && state->acceleration > state->max_acceleration)
+ state->max_acceleration = state->acceleration;
+ if (state->ascent && state->speed > state->max_speed)
+ state->max_speed = state->speed;
+
+ if (state->height > state->max_height)
+ state->max_height = state->height;
+ state->gps.gps_locked = data->gps.gps_locked;
+ state->gps.gps_connected = data->gps.gps_connected;
+ if (data->gps.gps_locked) {
+ state->gps = data->gps;
+ state->gps_valid = 1;
+ if (state->npad)
+ aoview_great_circle(state->pad_lat, state->pad_lon, state->gps.lat, state->gps.lon,
+ &state->distance, &state->bearing);
+ }
+ if (state->npad) {
+ state->gps_height = state->gps.alt - state->pad_alt;
+ } else {
+ state->gps_height = 0;
+ }
+}
+
+void
+aoview_speak_state(struct aostate *state)
+{
+ if (strcmp(state->data.state, state->prev_data.state)) {
+ aoview_voice_speak("%s\n", state->data.state);
+ if (!strcmp(state->data.state, "drogue"))
+ aoview_voice_speak("apogee %d meters\n",
+ (int) state->max_height);
+ if (!strcmp(state->prev_data.state, "boost"))
+ aoview_voice_speak("max speed %d meters per second\n",
+ (int) state->max_speed);
+ }
+ if (state->prev_npad < MIN_PAD_SAMPLES && state->npad >= MIN_PAD_SAMPLES)
+ aoview_voice_speak("g p s ready\n");
+}
+
+void
+aoview_speak_height(struct aostate *state)
+{
+ aoview_voice_speak("%d meters\n", state->height);
+}
+
+struct aostate aostate;
+
+static guint aostate_timeout;
+
+#define COMPASS_LIMIT(n) ((n * 22.5) + 22.5/2)
+
+static char *compass_points[] = {
+ "north",
+ "north north east",
+ "north east",
+ "east north east",
+ "east",
+ "east south east",
+ "south east",
+ "south south east",
+ "south",
+ "south south west",
+ "south west",
+ "west south west",
+ "west",
+ "west north west",
+ "north west",
+ "north north west",
+};
+
+static char *
+aoview_compass_point(double bearing)
+{
+ int i;
+ while (bearing < 0)
+ bearing += 360.0;
+ while (bearing >= 360.0)
+ bearing -= 360.0;
+
+ i = floor ((bearing - 22.5/2) / 22.5 + 0.5);
+ if (i < 0) i = 0;
+ if (i >= sizeof (compass_points) / sizeof (compass_points[0]))
+ i = 0;
+ return compass_points[i];
+}
+
+static gboolean
+aoview_state_timeout(gpointer data)
+{
+ double now = aoview_time();
+
+ if (strlen(aostate.data.state) > 0 && strcmp(aostate.data.state, "pad") != 0)
+ aoview_speak_height(&aostate);
+ if (now - aostate.report_time >= 20 || !strcmp(aostate.data.state, "landed")) {
+ if (!aostate.ascent) {
+ if (fabs(aostate.baro_speed) < 20 && aostate.height < 100)
+ aoview_voice_speak("rocket landed safely\n");
+ else
+ aoview_voice_speak("rocket may have crashed\n");
+ if (aostate.gps_valid) {
+ aoview_voice_speak("rocket reported %s of pad distance %d meters\n",
+ aoview_compass_point(aostate.bearing),
+ (int) aostate.distance);
+ }
+ }
+ aostate_timeout = 0;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+aoview_state_reset(void)
+{
+ memset(&aostate, '\0', sizeof (aostate));
+}
+
+void
+aoview_state_notify(struct aodata *data)
+{
+ struct aostate *state = &aostate;
+ aoview_state_derive(data, state);
+ aoview_table_start();
+
+ if (state->npad >= MIN_PAD_SAMPLES)
+ aoview_table_add_row(0, "Ground state", "ready");
+ else
+ aoview_table_add_row(0, "Ground state", "waiting for gps (%d)",
+ MIN_PAD_SAMPLES - state->npad);
+ aoview_table_add_row(0, "Rocket state", "%s", state->data.state);
+ aoview_table_add_row(0, "Callsign", "%s", state->data.callsign);
+ aoview_table_add_row(0, "Rocket serial", "%d", state->data.serial);
+
+ aoview_table_add_row(0, "RSSI", "%6ddBm", state->data.rssi);
+ aoview_table_add_row(0, "Height", "%6dm", state->height);
+ aoview_table_add_row(0, "Max height", "%6dm", state->max_height);
+ aoview_table_add_row(0, "Acceleration", "%7.1fm/s²", state->acceleration);
+ aoview_table_add_row(0, "Max acceleration", "%7.1fm/s²", state->max_acceleration);
+ aoview_table_add_row(0, "Speed", "%7.1fm/s", state->ascent ? state->speed : state->baro_speed);
+ aoview_table_add_row(0, "Max Speed", "%7.1fm/s", state->max_speed);
+ aoview_table_add_row(0, "Temperature", "%6.2f°C", state->temperature);
+ aoview_table_add_row(0, "Battery", "%5.2fV", state->battery);
+ aoview_table_add_row(0, "Drogue", "%5.2fV", state->drogue_sense);
+ aoview_table_add_row(0, "Main", "%5.2fV", state->main_sense);
+ aoview_table_add_row(0, "Pad altitude", "%dm", state->ground_altitude);
+ aoview_table_add_row(1, "Satellites", "%d", state->gps.nsat);
+ if (state->gps.gps_locked) {
+ aoview_table_add_row(1, "GPS", "locked");
+ } else if (state->gps.gps_connected) {
+ aoview_table_add_row(1, "GPS", "unlocked");
+ } else {
+ aoview_table_add_row(1, "GPS", "not available");
+ }
+ if (state->gps_valid) {
+ aoview_state_add_deg(1, "Latitude", state->gps.lat, 'N', 'S');
+ aoview_state_add_deg(1, "Longitude", state->gps.lon, 'E', 'W');
+ aoview_table_add_row(1, "GPS height", "%d", state->gps_height);
+ aoview_table_add_row(1, "GPS time", "%02d:%02d:%02d",
+ state->gps.gps_time.hour,
+ state->gps.gps_time.minute,
+ state->gps.gps_time.second);
+ }
+ if (state->gps.gps_extended) {
+ aoview_table_add_row(1, "GPS ground speed", "%7.1fm/s %d°",
+ state->gps.ground_speed,
+ state->gps.course);
+ aoview_table_add_row(1, "GPS climb rate", "%7.1fm/s",
+ state->gps.climb_rate);
+ aoview_table_add_row(1, "GPS precision", "%4.1f(hdop) %3dm(h) %3dm(v)",
+ state->gps.hdop, state->gps.h_error, state->gps.v_error);
+ }
+ if (state->npad) {
+ aoview_table_add_row(1, "Distance from pad", "%5.0fm", state->distance);
+ aoview_table_add_row(1, "Direction from pad", "%4.0f°", state->bearing);
+ aoview_state_add_deg(1, "Pad latitude", state->pad_lat, 'N', 'S');
+ aoview_state_add_deg(1, "Pad longitude", state->pad_lon, 'E', 'W');
+ aoview_table_add_row(1, "Pad GPS alt", "%gm", state->pad_alt);
+ }
+ aoview_table_finish();
+ aoview_label_show(state);
+ aoview_speak_state(state);
+ if (!aostate_timeout && strcmp(state->data.state, "pad") != 0)
+ aostate_timeout = g_timeout_add_seconds(10, aoview_state_timeout, NULL);
+}
+
+void
+aoview_state_new(void)
+{
+}
+
+void
+aoview_state_init(GladeXML *xml)
+{
+ aoview_state_new();
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+#define NCOL 2
+
+static GtkTreeView *dataview[NCOL];
+static GtkListStore *datalist[NCOL];
+
+void
+aoview_table_start(void)
+{
+ int col;
+ for (col = 0; col < NCOL; col++)
+ datalist[col] = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+}
+
+void
+aoview_table_add_row(int col, char *label, char *format, ...)
+{
+ char buf[1024];
+ va_list ap;
+ GtkTreeIter iter;
+
+ va_start(ap, format);
+ vsnprintf(buf, sizeof (buf), format, ap);
+ va_end(ap);
+ gtk_list_store_append(datalist[col], &iter);
+ gtk_list_store_set(datalist[col], &iter,
+ 0, label,
+ 1, buf,
+ -1);
+}
+
+void
+aoview_table_finish(void)
+{
+ int col;
+ for (col = 0; col < NCOL; col++) {
+ gtk_tree_view_set_model(dataview[col], GTK_TREE_MODEL(datalist[col]));
+ g_object_unref(G_OBJECT(datalist[col]));
+ gtk_tree_view_columns_autosize(dataview[col]);
+ }
+}
+
+void
+aoview_table_clear(void)
+{
+ int col;
+ for (col = 0; col < NCOL; col++)
+ gtk_tree_view_set_model(dataview[col], NULL);
+}
+
+void
+aoview_table_init(GladeXML *xml)
+{
+ int col;
+
+ for (col = 0; col < NCOL; col++) {
+ char name[32];
+ sprintf(name, "dataview_%d", col);
+ dataview[col] = GTK_TREE_VIEW(glade_xml_get_widget(xml, name));
+ assert(dataview[col]);
+
+ aoview_add_plain_text_column(dataview[col], "Field", 0, 20);
+ aoview_add_plain_text_column(dataview[col], "Value", 1, 32);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+char *
+aoview_fullname (char *dir, char *file)
+{
+ char *new;
+ int dlen = strlen (dir);
+ int flen = strlen (file);
+ int slen = 0;
+
+ if (dir[dlen-1] != '/')
+ slen = 1;
+ new = malloc (dlen + slen + flen + 1);
+ if (!new)
+ return 0;
+ strcpy(new, dir);
+ if (slen)
+ strcat (new, "/");
+ strcat(new, file);
+ return new;
+}
+
+char *
+aoview_basename(char *file)
+{
+ char *b;
+
+ b = strrchr(file, '/');
+ if (!b)
+ return file;
+ return b + 1;
+}
+
+int
+aoview_mkdir(char *dir)
+{
+ char *slash;
+ char *d;
+ char *part;
+
+ d = dir;
+ for (;;) {
+ slash = strchr (d, '/');
+ if (!slash)
+ slash = d + strlen(d);
+ if (!*slash)
+ break;
+ part = strndup(dir, slash - dir);
+ if (!access(part, F_OK))
+ if (mkdir(part, 0777) < 0)
+ return -errno;
+ free(part);
+ d = slash + 1;
+ }
+ return 0;
+}
+
+GtkTreeViewColumn *
+aoview_add_plain_text_column (GtkTreeView *view, const gchar *title, gint model_column, gint width)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_NONE, NULL);
+ g_object_set(renderer, "width-chars", width, NULL);
+ column = gtk_tree_view_column_new_with_attributes (title, renderer,
+ "text", model_column,
+ NULL);
+ gtk_tree_view_column_set_resizable (column, FALSE);
+ gtk_tree_view_append_column (view, column);
+
+ return column;
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+#if HAVE_FLITE
+#include <stdarg.h>
+
+FILE *aoview_flite;
+
+void aoview_voice_open(void)
+{
+ int err;
+
+ if (!aoview_flite)
+ aoview_flite = aoview_flite_start();
+}
+
+void aoview_voice_close(void)
+{
+ if (aoview_flite) {
+ aoview_flite_stop();
+ aoview_flite = NULL;
+ }
+}
+
+void aoview_voice_speak(char *format, ...)
+{
+ va_list ap;
+
+ if (aoview_flite) {
+ va_start(ap, format);
+ vfprintf(aoview_flite, format, ap);
+ fflush(aoview_flite);
+ va_end(ap);
+ }
+}
+
+#else
+void aoview_voice_open(void)
+{
+}
+
+void aoview_voice_close(void)
+{
+}
+
+void aoview_voice_speak(char *format, ...)
+{
+}
+#endif
+
+
+static GtkCheckMenuItem *voice_enable;
+
+#define ALTOS_VOICE_PATH "/apps/aoview/voice"
+
+static void
+aoview_voice_enable(GtkWidget *widget, gpointer data)
+{
+ gboolean enabled = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+ GError *error;
+ GConfClient *gconf_client;
+
+ if (enabled) {
+ aoview_voice_open();
+ aoview_voice_speak("enable voice\n");
+ } else {
+ aoview_voice_speak("disable voice\n");
+ aoview_voice_close();
+ }
+ gconf_client = gconf_client_get_default();
+ gconf_client_set_bool(gconf_client,
+ ALTOS_VOICE_PATH,
+ enabled,
+ &error);
+}
+
+void
+aoview_voice_init(GladeXML *xml)
+{
+ gboolean enabled;
+ GConfClient *gconf_client;
+
+ voice_enable = GTK_CHECK_MENU_ITEM(glade_xml_get_widget(xml, "voice_enable"));
+ assert(voice_enable);
+
+ gconf_client = gconf_client_get_default();
+ enabled = TRUE;
+ if (gconf_client)
+ {
+ GError *error;
+
+ error = NULL;
+ enabled = gconf_client_get_bool(gconf_client,
+ ALTOS_VOICE_PATH,
+ &error);
+ if (error)
+ enabled = TRUE;
+ }
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(voice_enable), enabled);
+ if (enabled)
+ aoview_voice_open();
+
+ g_signal_connect(G_OBJECT(voice_enable), "toggled",
+ G_CALLBACK(aoview_voice_enable),
+ voice_enable);
+}
--- /dev/null
+Requirements:
+ real-time display of telemetry
+ off-line display of logged data
+ Logging of telemetry
+ Capture of logged data to disk
+
+Input data:
+ accelerometer
+ barometer
+ thermometer
+ gps
+ drogue and main continuity
+ battery voltage
+ time
+ reported flight state
+ reported events
+
+Computed data:
+ velocity (from accelerometer)
+ altitude
+ range
+ direction
+
+Displays:
+ numeric display of current rocket status
+ (graphics come later)
+ text message log
+++ /dev/null
-*.o
-aoview
-aoview_glade.h
-aoview_flite
+++ /dev/null
-VERSION=$(shell git describe)
-AM_CFLAGS=$(GNOME_CFLAGS) $(ALSA_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\" @FLITE_INCS@
-
-bin_PROGRAMS=aoview
-
-aoview_LDADD=$(GNOME_LIBS) $(FLITE_LIBS) $(ALSA_LIBS)
-
-aoview_SOURCES = \
- aoview_main.c \
- aoview_dev.c \
- aoview_dev_dialog.c \
- aoview_serial.c \
- aoview_monitor.c \
- aoview_state.c \
- aoview_convert.c \
- aoview_log.c \
- aoview_table.c \
- aoview_util.c \
- aoview_file.c \
- aoview_eeprom.c \
- aoview_voice.c \
- aoview_replay.c \
- aoview_label.c \
- aoview_flite.c \
- aoview.h
-
-BUILT_SOURCES = aoview_glade.h
-
-CLEANFILES = aoview_glade.h
-
-aoview_glade.h: aoview.glade
- sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/"/' $< > $@
+++ /dev/null
-<?xml version="1.0"?>
-<glade-interface>
- <!-- interface-requires gtk+ 2.16 -->
- <!-- interface-naming-policy project-wide -->
- <widget class="GtkWindow" id="aoview">
- <property name="width_request">550</property>
- <property name="height_request">700</property>
- <property name="visible">True</property>
- <property name="title" translatable="yes">AltOS View</property>
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <widget class="GtkMenuBar" id="menubar1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkMenuItem" id="menuitem1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_File</property>
- <property name="use_underline">True</property>
- <child>
- <widget class="GtkMenu" id="menu1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem1">
- <property name="label">gtk-new</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem2">
- <property name="label">gtk-open</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem3">
- <property name="label">gtk-save</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem4">
- <property name="label">gtk-save-as</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
- <property name="visible">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem5">
- <property name="label">gtk-quit</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="gtk_main_quit"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkMenuItem" id="menuitem2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Edit</property>
- <property name="use_underline">True</property>
- <child>
- <widget class="GtkMenu" id="menu2">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem6">
- <property name="label">gtk-cut</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem7">
- <property name="label">gtk-copy</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem8">
- <property name="label">gtk-paste</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem9">
- <property name="label">gtk-delete</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkMenuItem" id="menuitem3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Device</property>
- <property name="use_underline">True</property>
- <child>
- <widget class="GtkMenu" id="menu4">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImageMenuItem" id="ao_connect">
- <property name="label" translatable="yes">_Connect to device</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">False</property>
- <signal name="activate_item" handler="gtk_widget_show" object="device_connect_dialog" after="yes"/>
- <signal name="activate" handler="gtk_widget_show" object="device_connect_dialog" after="yes"/>
- <child internal-child="image">
- <widget class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-connect</property>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="ao_disconnect">
- <property name="label" translatable="yes">_Disconnect</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">False</property>
- <child internal-child="image">
- <widget class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="stock">gtk-disconnect</property>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkSeparatorMenuItem" id="seperator">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="ao_savelog">
- <property name="label" translatable="yes">_Save EEPROM data</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">False</property>
- <signal name="activate_item" handler="gtk_widget_show" object="device_connect_dialog" after="yes"/>
- <signal name="activate" handler="gtk_widget_show" object="device_connect_dialog"/>
- <child internal-child="image">
- <widget class="GtkImage" id="image5">
- <property name="visible">True</property>
- <property name="stock">gtk-save</property>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="ao_replay">
- <property name="label" translatable="yes">_Replay</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">False</property>
- <signal name="activate_item" handler="gtk_widget_show" object="ao_replay_dialog" after="yes"/>
- <signal name="activate" handler="gtk_widget_show" object="ao_replay_dialog"/>
- <child internal-child="image">
- <widget class="GtkImage" id="image6">
- <property name="visible">True</property>
- <property name="stock">gtk-media-play</property>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkMenuItem" id="menuitem5">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Log</property>
- <property name="use_underline">True</property>
- <child>
- <widget class="GtkMenu" id="menu5">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImageMenuItem" id="log_new">
- <property name="label" translatable="yes">_New log</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">False</property>
- <child internal-child="image">
- <widget class="GtkImage" id="image3">
- <property name="visible">True</property>
- <property name="stock">gtk-new</property>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkImageMenuItem" id="file_configure">
- <property name="label" translatable="yes">_Configure Log</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">False</property>
- <signal name="activate" handler="gtk_widget_show" object="file_chooser_dialog" after="yes"/>
- <child internal-child="image">
- <widget class="GtkImage" id="image4">
- <property name="visible">True</property>
- <property name="stock">gtk-preferences</property>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkMenuItem" id="menuitem6">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Voice</property>
- <property name="use_underline">True</property>
- <child>
- <widget class="GtkMenu" id="menu6">
- <property name="visible">True</property>
- <child>
- <widget class="GtkCheckMenuItem" id="voice_enable">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Enable _Voice</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkMenuItem" id="menuitem4">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Help</property>
- <property name="use_underline">True</property>
- <child>
- <widget class="GtkMenu" id="menu3">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImageMenuItem" id="imagemenuitem10">
- <property name="label">gtk-about</property>
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="gtk_widget_show" object="about_dialog" after="yes"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">4</property>
- <property name="row_spacing">3</property>
- <property name="homogeneous">True</property>
- <child>
- <widget class="GtkLabel" id="height_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Height (m)</property>
- <property name="justify">center</property>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="state_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">State</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="rssi_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">RSSI (dBm)</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="height_value">
- <property name="visible">True</property>
- <property name="ypad">2</property>
- <property name="label" translatable="yes">0</property>
- <property name="selectable">True</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="state_value">
- <property name="visible">True</property>
- <property name="ypad">2</property>
- <property name="label" translatable="yes">pad</property>
- <property name="selectable">True</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="rssi_value">
- <property name="visible">True</property>
- <property name="ypad">2</property>
- <property name="label" translatable="yes">-50</property>
- <property name="selectable">True</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="speed_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Speed (m/s)</property>
- </widget>
- <packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="speed_value">
- <property name="visible">True</property>
- <property name="label" translatable="yes">0</property>
- <property name="selectable">True</property>
- </widget>
- <packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkTreeView" id="dataview_0">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_expanders">False</property>
- <property name="enable_grid_lines">both</property>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkTreeView" id="dataview_1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_expanders">False</property>
- <property name="enable_grid_lines">both</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkDialog" id="device_connect_dialog">
- <property name="border_width">5</property>
- <property name="type_hint">normal</property>
- <property name="has_separator">False</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child>
- <widget class="GtkTreeView" id="dev_list">
- <property name="width_request">300</property>
- <property name="height_request">100</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_clickable">False</property>
- <property name="rules_hint">True</property>
- <property name="search_column">0</property>
- <property name="show_expanders">False</property>
- <property name="level_indentation">1</property>
- <property name="enable_grid_lines">both</property>
- <property name="enable_tree_lines">True</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="cancel_button">
- <property name="label" translatable="yes">gtk-cancel</property>
- <property name="response_id">1</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="gtk_widget_hide" object="device_connect_dialog" after="yes"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="connect_button">
- <property name="label" translatable="yes">gtk-connect</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkFileChooserDialog" id="file_chooser_dialog">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">Configure Log Directory</property>
- <property name="type_hint">dialog</property>
- <property name="has_separator">False</property>
- <property name="action">select-folder</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox2">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area2">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="file_configure_cancel">
- <property name="label" translatable="yes">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="gtk_widget_hide" object="file_chooser_dialog"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="file_configure_ok">
- <property name="label" translatable="yes">gtk-ok</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkMessageDialog" id="file_fail_dialog">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">Failed to create log</property>
- <property name="type_hint">normal</property>
- <property name="skip_taskbar_hint">True</property>
- <property name="transient_for">aoview</property>
- <property name="message_type">error</property>
- <property name="buttons">close</property>
- <property name="text">Cannot create log file</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox4">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area4">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkMessageDialog" id="dev_open_fail_dialog">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">Failed to open device</property>
- <property name="type_hint">normal</property>
- <property name="skip_taskbar_hint">True</property>
- <property name="transient_for">aoview</property>
- <property name="message_type">error</property>
- <property name="buttons">close</property>
- <property name="text">Cannot open device</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox6">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area6">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkAboutDialog" id="about_dialog">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">About AoView</property>
- <property name="resizable">False</property>
- <property name="type_hint">normal</property>
- <property name="transient_for">aoview</property>
- <property name="has_separator">False</property>
- <property name="program_name">AoView</property>
- <property name="copyright" translatable="yes">Copyright © 2009 Keith Packard</property>
- <property name="comments" translatable="yes">AltOS data capture and display.</property>
- <property name="website">http://altusmetrum.org</property>
- <property name="license" translatable="yes">AoView is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
-
-AoView 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 AoView; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</property>
- <property name="authors">Keith Packard <keithp@keithp.com></property>
- <property name="wrap_license">True</property>
- <signal name="close" handler="gtk_widget_hide" object="about_dialog" after="yes"/>
- <signal name="response" handler="gtk_widget_hide" object="about_dialog" after="yes"/>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox7">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area7">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkMessageDialog" id="ao_save_done">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">EEPROM save complete</property>
- <property name="type_hint">normal</property>
- <property name="skip_taskbar_hint">True</property>
- <property name="transient_for">aoview</property>
- <property name="has_separator">False</property>
- <property name="buttons">close</property>
- <property name="text">Saving EEPROM data as</property>
- <property name="secondary_text"><filename></property>
- <signal name="close" handler="gtk_widget_hide" object="ao_save_done"/>
- <signal name="response" handler="gtk_widget_hide" object="ao_save_done"/>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox11">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area11">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkFileChooserDialog" id="ao_replay_dialog">
- <property name="border_width">5</property>
- <property name="destroy_with_parent">True</property>
- <property name="type_hint">dialog</property>
- <property name="skip_taskbar_hint">True</property>
- <property name="transient_for">aoview</property>
- <property name="has_separator">False</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox10">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area10">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="ao_replay_cancel">
- <property name="label" translatable="yes">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="gtk_widget_hide" object="ao_replay_dialog"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="ao_replay_ok">
- <property name="label" translatable="yes">gtk-ok</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
-</glade-interface>
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef _AOVIEW_H_
-#define _AOVIEW_H_
-
-#define _GNU_SOURCE
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <err.h>
-#include <errno.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <math.h>
-
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-#include <gconf/gconf-client.h>
-
-struct usbdev {
- char *sys;
- char *tty;
- char *manufacturer;
- char *product;
- char *serial;
- int idProduct;
- int idVendor;
-};
-
-struct aogps_time {
- int hour;
- int minute;
- int second;
-};
-
-struct aogps {
- int nsat;
- int gps_locked;
- int gps_connected;
- struct aogps_time gps_time;
- double lat; /* degrees (+N -S) */
- double lon; /* degrees (+E -W) */
- int alt; /* m */
-
- int gps_extended; /* has extra data */
- double ground_speed; /* m/s */
- int course; /* degrees */
- double climb_rate; /* m/s */
- double hdop; /* unitless? */
- int h_error; /* m */
- int v_error; /* m */
-};
-
-struct aodata {
- char callsign[16];
- int serial;
- int rssi;
- char state[16];
- int tick;
- int accel;
- int pres;
- int temp;
- int batt;
- int drogue;
- int main;
- int flight_accel;
- int ground_accel;
- int flight_vel;
- int flight_pres;
- int ground_pres;
- struct aogps gps;
-};
-
-struct aostate {
- struct aodata data;
-
- /* derived data */
-
- struct aodata prev_data;
-
- double report_time;
-
- gboolean ascent; /* going up? */
-
- int ground_altitude;
- int height;
- double speed;
- double acceleration;
- double battery;
- double temperature;
- double main_sense;
- double drogue_sense;
- double baro_speed;
-
- int max_height;
- double max_acceleration;
- double max_speed;
-
- struct aogps gps;
-
- int gps_valid;
- double pad_lat;
- double pad_lon;
- double pad_alt;
- double pad_lat_total;
- double pad_lon_total;
- double pad_alt_total;
- int npad;
- int prev_npad;
-
- double distance;
- double bearing;
- int gps_height;
-
- int speak_tick;
- int speak_altitude;
-};
-
-extern struct aostate aostate;
-
-/* GPS is 'stable' when we've seen at least this many samples */
-#define MIN_PAD_SAMPLES 10
-
-void
-aoview_monitor_disconnect(void);
-
-gboolean
-aoview_monitor_connect(char *tty);
-
-gboolean
-aoview_monitor_parse(const char *line);
-
-void
-aoview_monitor_reset(void);
-
-struct aoview_serial *
-aoview_serial_open(const char *tty);
-
-void
-aoview_serial_close(struct aoview_serial *serial);
-
-typedef void (*aoview_serial_callback)(gpointer user_data, struct aoview_serial *serial, gint revents);
-
-void
-aoview_serial_set_callback(struct aoview_serial *serial,
- aoview_serial_callback func);
-
-void
-aoview_serial_printf(struct aoview_serial *serial, char *format, ...);
-
-int
-aoview_serial_read(struct aoview_serial *serial, char *buf, int len);
-
-int
-aoview_serial_getc(struct aoview_serial *serial);
-
-void
-aoview_dev_dialog_init(GladeXML *xml);
-
-int
-aoview_usb_scan(struct usbdev ***devs_ret);
-
-void
-aoview_usbdev_free(struct usbdev *usbdev);
-
-void
-aoview_state_notify(struct aodata *data);
-
-void
-aoview_state_new(void);
-
-void
-aoview_state_init(GladeXML *xml);
-
-int16_t
-aoview_pres_to_altitude(int16_t pres);
-
-int16_t
-aoview_altitude_to_pres(int16_t alt);
-
-char *
-aoview_fullname (char *dir, char *file);
-
-char *
-aoview_basename(char *file);
-
-GtkTreeViewColumn *
-aoview_add_plain_text_column (GtkTreeView *view, const gchar *title, gint model_column, gint width);
-
-int
-aoview_mkdir(char *dir);
-
-void
-aoview_log_init(GladeXML *xml);
-
-void
-aoview_log_set_serial(int serial);
-
-int
-aoview_log_get_serial(void);
-
-void
-aoview_log_printf(char *format, ...);
-
-void
-aoview_log_new(void);
-
-void
-aoview_table_start(void);
-
-void
-aoview_table_add_row(int column, char *label, char *format, ...);
-
-void
-aoview_table_finish(void);
-
-void
-aoview_table_init(GladeXML *xml);
-
-void
-aoview_table_clear(void);
-
-struct aoview_file;
-
-extern char *aoview_file_dir;
-
-void
-aoview_file_finish(struct aoview_file *file);
-
-gboolean
-aoview_file_start(struct aoview_file *file);
-
-const char *
-aoview_file_name(struct aoview_file *file);
-
-void
-aoview_file_set_serial(struct aoview_file *file, int serial);
-
-int
-aoview_file_get_serial(struct aoview_file *file);
-
-void
-aoview_file_printf(struct aoview_file *file, char *format, ...);
-
-void
-aoview_file_vprintf(struct aoview_file *file, char *format, va_list ap);
-
-struct aoview_file *
-aoview_file_new(char *ext);
-
-void
-aoview_file_destroy(struct aoview_file *file);
-
-void
-aoview_file_init(GladeXML *xml);
-
-/* aoview_eeprom.c */
-
-gboolean
-aoview_eeprom_save(const char *device);
-
-void
-aoview_eeprom_init(GladeXML *xml);
-
-/* aoview_voice.c */
-void aoview_voice_open(void);
-
-void aoview_voice_close(void);
-
-void aoview_voice_speak(char *format, ...);
-
-/* aoview_label.c */
-
-void aoview_label_init(GladeXML *xml);
-
-void
-aoview_label_show(struct aostate *state);
-
-/* aoview_flite.c */
-
-FILE *
-aoview_flite_start(void);
-
-void
-aoview_flite_stop(void);
-
-#endif /* _AOVIEW_H_ */
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-static int16_t altitude_table[2048] = {
-#include "altitude.h"
-};
-
-int16_t
-aoview_pres_to_altitude(int16_t pres)
-{
- pres = pres >> 4;
- if (pres < 0) pres = 0;
- if (pres > 2047) pres = 2047;
- return altitude_table[pres];
-}
-
-int16_t
-aoview_altitude_to_pres(int16_t alt)
-{
- int16_t pres;
-
- for (pres = 0; pres < 2047; pres++)
- if (altitude_table[pres] <= alt)
- break;
- return pres << 4;
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-#include <ctype.h>
-#include <dirent.h>
-
-static char *
-load_string(char *dir, char *file)
-{
- char *full = aoview_fullname(dir, file);
- char line[4096];
- char *r;
- FILE *f;
- int rlen;
-
- f = fopen(full, "r");
- free(full);
- if (!f)
- return NULL;
- r = fgets(line, sizeof (line), f);
- fclose(f);
- if (!r)
- return NULL;
- rlen = strlen(r);
- if (r[rlen-1] == '\n')
- r[rlen-1] = '\0';
- return strdup(r);
-}
-
-static int
-load_hex(char *dir, char *file)
-{
- char *line;
- char *end;
- long i;
-
- line = load_string(dir, file);
- if (!line)
- return -1;
- i = strtol(line, &end, 16);
- free(line);
- if (end == line)
- return -1;
- return i;
-}
-
-static int
-dir_filter_tty_colon(const struct dirent *d)
-{
- return strncmp(d->d_name, "tty:", 4) == 0;
-}
-
-static int
-dir_filter_tty(const struct dirent *d)
-{
- return strncmp(d->d_name, "tty", 3) == 0;
-}
-
-static char *
-usb_tty(char *sys)
-{
- char *base;
- int num_configs;
- int config;
- struct dirent **namelist;
- int interface;
- int num_interfaces;
- char endpoint_base[20];
- char *endpoint_full;
- char *tty_dir;
- int ntty;
- char *tty;
-
- base = aoview_basename(sys);
- num_configs = load_hex(sys, "bNumConfigurations");
- num_interfaces = load_hex(sys, "bNumInterfaces");
- for (config = 1; config <= num_configs; config++) {
- for (interface = 0; interface < num_interfaces; interface++) {
- sprintf(endpoint_base, "%s:%d.%d",
- base, config, interface);
- endpoint_full = aoview_fullname(sys, endpoint_base);
-
- /* Check for tty:ttyACMx style names
- */
- ntty = scandir(endpoint_full, &namelist,
- dir_filter_tty_colon,
- alphasort);
- if (ntty > 0) {
- free(endpoint_full);
- tty = aoview_fullname("/dev", namelist[0]->d_name + 4);
- free(namelist);
- return tty;
- }
-
- /* Check for tty/ttyACMx style names
- */
- tty_dir = aoview_fullname(endpoint_full, "tty");
- free(endpoint_full);
- ntty = scandir(tty_dir, &namelist,
- dir_filter_tty,
- alphasort);
- free (tty_dir);
- if (ntty > 0) {
- tty = aoview_fullname("/dev", namelist[0]->d_name);
- free(namelist);
- return tty;
- }
- }
- }
- return NULL;
-}
-
-static struct usbdev *
-usb_scan_device(char *sys)
-{
- struct usbdev *usbdev;
-
- usbdev = calloc(1, sizeof (struct usbdev));
- if (!usbdev)
- return NULL;
- usbdev->sys = strdup(sys);
- usbdev->manufacturer = load_string(sys, "manufacturer");
- usbdev->product = load_string(sys, "product");
- usbdev->serial = load_string(sys, "serial");
- usbdev->idProduct = load_hex(sys, "idProduct");
- usbdev->idVendor = load_hex(sys, "idVendor");
- usbdev->tty = usb_tty(sys);
- return usbdev;
-}
-
-void
-aoview_usbdev_free(struct usbdev *usbdev)
-{
- free(usbdev->sys);
- free(usbdev->manufacturer);
- free(usbdev->product);
- free(usbdev->serial);
- free(usbdev->tty);
- free(usbdev);
-}
-
-#define USB_DEVICES "/sys/bus/usb/devices"
-
-static int
-dir_filter_dev(const struct dirent *d)
-{
- const char *n = d->d_name;
- char c;
-
- while ((c = *n++)) {
- if (isdigit(c))
- continue;
- if (c == '-')
- continue;
- if (c == '.' && n != d->d_name + 1)
- continue;
- return 0;
- }
- return 1;
-}
-
-int
-aoview_usb_scan(struct usbdev ***devs_ret)
-{
- int n;
- int ndev = 0;
- int e;
- struct dirent **ents;
- char *dir;
- struct usbdev **devs = NULL;
- struct usbdev *dev;
-
- n = scandir (USB_DEVICES, &ents,
- dir_filter_dev,
- alphasort);
- if (!n)
- return 0;
- for (e = 0; e < n; e++) {
- dir = aoview_fullname(USB_DEVICES, ents[e]->d_name);
- dev = usb_scan_device(dir);
- free(dir);
- if (dev->idVendor == 0xfffe && dev->tty) {
- if (devs)
- devs = realloc(devs, ndev + 1 * sizeof (struct usbdev *));
- else
- devs = malloc (sizeof (struct usbdev *));
- devs[ndev++] = dev;
- }
- }
- free(ents);
- *devs_ret = devs;
- return ndev;
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-static void
-aoview_dev_dialog_map(GtkWidget *widget, gpointer data)
-{
- GtkTreeView *dev_list = data;
- GtkListStore *list_store;
- GtkTreeIter iter;
- int ndev, n;
- struct usbdev **devs;
-
- list_store = gtk_list_store_new(3,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- ndev = aoview_usb_scan(&devs);
- for (n = 0; n < ndev; n++) {
- gtk_list_store_append(list_store, &iter);
- gtk_list_store_set(list_store, &iter,
- 0, devs[n]->product,
- 1, devs[n]->serial,
- 2, devs[n]->tty,
- -1);
- }
- gtk_tree_view_set_model (dev_list, GTK_TREE_MODEL(list_store));
- g_object_unref(G_OBJECT(list_store));
- gtk_tree_view_columns_autosize(dev_list);
-}
-
-static GtkMessageDialog *dev_open_fail_dialog;
-
-static void
-aoview_dev_open_failed(char *name)
-{
- char *utf8_file;
- utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
- if (!utf8_file)
- utf8_file = name;
- gtk_message_dialog_format_secondary_text(dev_open_fail_dialog,
- "\"%s\"", utf8_file);
- if (utf8_file != name)
- g_free(utf8_file);
- gtk_dialog_run(GTK_DIALOG(dev_open_fail_dialog));
- gtk_widget_hide(GTK_WIDGET(dev_open_fail_dialog));
-}
-
-gboolean dialog_save_log;
-
-static void
-aoview_dev_selected(GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- gchar *string;
- gtk_tree_model_get(model, iter,
- 2, &string,
- -1);
- if (dialog_save_log) {
- dialog_save_log = FALSE;
- if (!aoview_eeprom_save(string))
- aoview_dev_open_failed(string);
- } else {
- if (!aoview_monitor_connect(string))
- aoview_dev_open_failed(string);
- }
-}
-
-static GtkWidget *dialog;
-
-static void
-aoview_dev_dialog_connect(GtkWidget *widget, gpointer data)
-{
- GtkTreeView *dev_list = data;
- GtkListStore *list_store;
- GtkTreeSelection *tree_selection;
-
- list_store = GTK_LIST_STORE(gtk_tree_view_get_model(dev_list));
- tree_selection = gtk_tree_view_get_selection(dev_list);
- gtk_tree_selection_selected_foreach(tree_selection,
- aoview_dev_selected,
- data);
- gtk_widget_hide(dialog);
-}
-
-static void
-aoview_dev_disconnect(GtkWidget *widget)
-{
- aoview_monitor_disconnect();
-}
-
-static void
-aoview_dev_savelog(GtkWidget *widget, gpointer data)
-{
- dialog_save_log = TRUE;
- gtk_widget_show(dialog);
-}
-
-#define _(a) a
-
-void
-aoview_dev_dialog_init(GladeXML *xml)
-{
- GtkTreeView *dev_list;
- GtkWidget *connect_button;
- GtkTreeSelection *dev_selection;
- GtkWidget *ao_disconnect;
- GtkWidget *ao_savelog;
-
- dialog = glade_xml_get_widget(xml, "device_connect_dialog");
- assert(dialog);
-
- dev_list = GTK_TREE_VIEW(glade_xml_get_widget(xml, "dev_list"));
- assert(dev_list);
-
- aoview_add_plain_text_column(dev_list, _("Product"), 0, 16);
- aoview_add_plain_text_column(dev_list, _("Serial"), 1, 8);
- aoview_add_plain_text_column(dev_list, _("Device"), 2, 13);
-
- dev_selection = gtk_tree_view_get_selection(dev_list);
- gtk_tree_selection_set_mode(dev_selection, GTK_SELECTION_SINGLE);
-
- g_signal_connect(G_OBJECT(dialog), "map",
- G_CALLBACK(aoview_dev_dialog_map),
- dev_list);
-
- connect_button = glade_xml_get_widget(xml, "connect_button");
- assert(connect_button);
-
- g_signal_connect(G_OBJECT(connect_button), "clicked",
- G_CALLBACK(aoview_dev_dialog_connect),
- dev_list);
-
-
- ao_disconnect = glade_xml_get_widget(xml, "ao_disconnect");
- assert(ao_disconnect);
-
- g_signal_connect(G_OBJECT(ao_disconnect), "activate",
- G_CALLBACK(aoview_dev_disconnect),
- ao_disconnect);
-
- ao_savelog = glade_xml_get_widget(xml, "ao_savelog");
- assert(ao_savelog);
-
- g_signal_connect(G_OBJECT(ao_savelog), "activate",
- G_CALLBACK(aoview_dev_savelog),
- dialog);
- dev_open_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "dev_open_fail_dialog"));
- assert(dev_open_fail_dialog);
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-#define EEPROM_LEN 1024
-
-static struct aoview_file *eeprom_file;
-static char eeprom_line[EEPROM_LEN + 1];
-static int eeprom_pos;
-static GtkMessageDialog *eeprom_save_done;
-static GtkWidget *eeprom_save_close;
-static gboolean eeprom_save_shown;
-
-static void
-aoview_eeprom_disconnect(struct aoview_serial *serial)
-{
- aoview_file_finish(eeprom_file);
-}
-
-static void
-aoview_eeprom_done(struct aoview_serial *serial)
-{
- gtk_window_set_title(GTK_WINDOW(eeprom_save_done),
- "EEPROM data saved");
- gtk_message_dialog_set_markup(eeprom_save_done,
- "<b>EEPROM data saved as</b>");
- if (!eeprom_save_shown)
- gtk_widget_show(GTK_WIDGET(eeprom_save_done));
- eeprom_save_close = gtk_window_get_default_widget(GTK_WINDOW(eeprom_save_done));
- if (eeprom_save_close)
- gtk_widget_set_sensitive(eeprom_save_close, TRUE);
- aoview_eeprom_disconnect(serial);
-}
-
-static gboolean
-aoview_eeprom_parse(struct aoview_serial *serial,
- char *line)
-{
- char cmd;
- int tick;
- int a;
- int b;
- int serial_number;
- const char *name;
- char *utf8_name;
-
- if (!strcmp(line, "end")) {
- aoview_eeprom_done(serial);
- return FALSE;
- }
- if (sscanf(line, "serial-number %u", &serial_number) == 1) {
- aoview_file_set_serial(eeprom_file, serial_number);
- } else if (sscanf(line, "%c %x %x %x", &cmd, &tick, &a, &b) == 4) {
- aoview_file_printf(eeprom_file, "%s\n", line);
- if (cmd == 'S' && a == 8) {
- aoview_eeprom_done(serial);
- return FALSE;
- }
-
- if (!eeprom_save_shown)
- {
- name = aoview_file_name(eeprom_file);
- if (name) {
- utf8_name = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
- if (!utf8_name)
- utf8_name = (char *) name;
- gtk_widget_set_sensitive(eeprom_save_close, FALSE);
- gtk_window_set_title(GTK_WINDOW(eeprom_save_done),
- "Saving EEPROM data");
- gtk_message_dialog_set_markup(eeprom_save_done,
- "<b>Saving EEPROM data as</b>");
- gtk_message_dialog_format_secondary_text(eeprom_save_done, "%s",
- utf8_name);
- if (utf8_name != name)
- g_free(utf8_name);
- gtk_container_check_resize(GTK_CONTAINER(eeprom_save_done));
- gtk_widget_show(GTK_WIDGET(eeprom_save_done));
- eeprom_save_shown = TRUE;
- eeprom_save_close = gtk_window_get_default_widget(GTK_WINDOW(eeprom_save_done));
- if (eeprom_save_close)
- gtk_widget_set_sensitive(eeprom_save_close, FALSE);
- }
- }
- }
- return TRUE;
-}
-
-static void
-aoview_eeprom_callback(gpointer user_data,
- struct aoview_serial *serial,
- gint revents)
-{
- int c;
-
- if (revents & (G_IO_HUP|G_IO_ERR)) {
- aoview_eeprom_disconnect(serial);
- return;
- }
- if (revents & G_IO_IN) {
- for (;;) {
- c = aoview_serial_getc(serial);
- if (c == -1)
- break;
- if (c == '\r')
- continue;
- if (c == '\n') {
- eeprom_line[eeprom_pos] = '\0';
- if (eeprom_pos)
- if (!aoview_eeprom_parse(serial, eeprom_line))
- break;
- eeprom_pos = 0;
- } else if (eeprom_pos < EEPROM_LEN)
- eeprom_line[eeprom_pos++] = c;
- }
- }
-}
-
-gboolean
-aoview_eeprom_save(const char *device)
-{
- struct aoview_serial *serial;
-
- gtk_widget_hide(GTK_WIDGET(eeprom_save_done));
- eeprom_save_shown = FALSE;
- serial = aoview_serial_open(device);
- if (!serial)
- return FALSE;
- aoview_serial_set_callback(serial, aoview_eeprom_callback);
- aoview_serial_printf(serial, "v\nl\n");
- return TRUE;
-}
-
-void
-aoview_eeprom_init(GladeXML *xml)
-{
- eeprom_file = aoview_file_new("eeprom");
- assert(eeprom_file);
-
- eeprom_save_done = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "ao_save_done"));
- assert(eeprom_save_done);
-
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-char *aoview_file_dir;
-
-#define ALTOS_DIR_PATH "/apps/aoview/log_dir"
-#define DEFAULT_DIR "AltOS"
-
-struct aoview_file {
- char *ext;
- FILE *file;
- char *name;
- int failed;
- int serial;
- int sequence;
-};
-
-static void
-aoview_file_save_conf(void)
-{
- GConfClient *gconf_client;
-
- gconf_client = gconf_client_get_default();
- if (gconf_client)
- {
- gconf_client_set_string(gconf_client,
- ALTOS_DIR_PATH,
- aoview_file_dir,
- NULL);
- g_object_unref(G_OBJECT(gconf_client));
- }
-}
-
-static void
-aoview_file_configure(GtkWidget *widget, gpointer data)
-{
- GtkFileChooser *chooser = data;
- aoview_file_dir = gtk_file_chooser_get_filename(chooser);
- aoview_file_save_conf();
- gtk_widget_hide(GTK_WIDGET(chooser));
-}
-
-void
-aoview_file_finish(struct aoview_file *file)
-{
- if (file->file) {
- fclose(file->file);
- file->file = NULL;
- free(file->name);
- file->name = NULL;
- }
- file->failed = 0;
-}
-
-const char *
-aoview_file_name(struct aoview_file *file)
-{
- return file->name;
-}
-
-static GtkMessageDialog *file_fail_dialog;
-
-static void
-aoview_file_open_failed(char *name)
-{
- char *utf8_file;
- utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
- if (!utf8_file)
- utf8_file = name;
- gtk_message_dialog_format_secondary_text(file_fail_dialog,
- "\"%s\"", utf8_file);
- if (utf8_file != name)
- g_free(utf8_file);
- gtk_widget_show(GTK_WIDGET(file_fail_dialog));
-}
-
-gboolean
-aoview_file_start(struct aoview_file *file)
-{
- char base[50];
- struct tm tm;
- time_t now;
- char *full;
- int r;
-
- if (file->file)
- return TRUE;
-
- if (file->failed)
- return FALSE;
-
- now = time(NULL);
- (void) localtime_r(&now, &tm);
- aoview_mkdir(aoview_file_dir);
- for (;;) {
- snprintf(base, sizeof (base), "%04d-%02d-%02d-serial-%03d-flight-%03d.%s",
- tm.tm_year + 1900,
- tm.tm_mon + 1,
- tm.tm_mday,
- file->serial,
- file->sequence,
- file->ext);
- full = aoview_fullname(aoview_file_dir, base);
- r = access(full, F_OK);
- if (r < 0) {
- file->file = fopen(full, "w");
- if (!file->file) {
- aoview_file_open_failed(full);
- free(full);
- file->failed = 1;
- return FALSE;
- } else {
- setlinebuf(file->file);
- file->name = full;
- return TRUE;
- }
- }
- free(full);
- file->sequence++;
- }
-}
-
-void
-aoview_file_vprintf(struct aoview_file *file, char *format, va_list ap)
-{
- if (!aoview_file_start(file))
- return;
- vfprintf(file->file, format, ap);
-}
-
-void
-aoview_file_printf(struct aoview_file *file, char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- aoview_file_vprintf(file, format, ap);
- va_end(ap);
-}
-
-struct aoview_file *
-aoview_file_new(char *ext)
-{
- struct aoview_file *file;
-
- file = calloc (1, sizeof (struct aoview_file));
- if (!file)
- return NULL;
- file->ext = strdup(ext);
- if (!file->ext) {
- free(file);
- return NULL;
- }
- return file;
-}
-
-void
-aoview_file_destroy(struct aoview_file *file)
-{
- if (file->file)
- fclose(file->file);
- if (file->name)
- free(file->name);
- free(file->ext);
- free(file);
-}
-
-void
-aoview_file_set_serial(struct aoview_file *file, int serial)
-{
- if (serial != file->serial)
- aoview_file_finish(file);
- file->serial = serial;
-}
-
-int
-aoview_file_get_serial(struct aoview_file *file)
-{
- return file->serial;
-}
-
-void
-aoview_file_init(GladeXML *xml)
-{
- GConfClient *gconf_client;
- char *file_dir = NULL;
- GtkFileChooser *file_chooser_dialog;
- GtkWidget *file_configure_ok;
-
- g_type_init();
- gconf_client = gconf_client_get_default();
- if (gconf_client)
- {
- file_dir = gconf_client_get_string(gconf_client,
- ALTOS_DIR_PATH,
- NULL);
- g_object_unref(G_OBJECT(gconf_client));
- }
- if (!file_dir) {
- aoview_file_dir = aoview_fullname(getenv("HOME"), DEFAULT_DIR);
- aoview_file_save_conf();
- } else {
- aoview_file_dir = strdup(file_dir);
- }
-
- file_chooser_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "file_chooser_dialog"));
- assert(file_chooser_dialog);
- gtk_file_chooser_set_filename(file_chooser_dialog, aoview_file_dir);
-
- file_configure_ok = glade_xml_get_widget(xml, "file_configure_ok");
- assert(file_configure_ok);
-
- g_signal_connect(G_OBJECT(file_configure_ok), "clicked",
- G_CALLBACK(aoview_file_configure),
- file_chooser_dialog);
-
-
- file_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "file_fail_dialog"));
- assert(file_fail_dialog);
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdio.h>
-#include <flite/flite.h>
-#include "aoview.h"
-#include <alsa/asoundlib.h>
-
-cst_voice *register_cmu_us_kal();
-static cst_voice *voice;
-
-static FILE *pipe_write;
-static GThread *aoview_flite_thread;
-
-static snd_pcm_t *alsa_handle;
-
-gpointer
-aoview_flite_task(gpointer data)
-{
- FILE *input = data;
- char line[1024];
- cst_wave *wave;
- int rate;
- int channels;
- int err;
- char *samples;
- int num_samples;
-
- err = snd_pcm_open(&alsa_handle, "default",
- SND_PCM_STREAM_PLAYBACK, 0);
- if (err >= 0)
- {
- if (err < 0) {
- snd_pcm_close(alsa_handle);
- alsa_handle = 0;
- }
- }
- rate = 0;
- channels = 0;
- while (fgets(line, sizeof (line) - 1, input) != NULL) {
- if (!alsa_handle)
- continue;
- wave = flite_text_to_wave(line, voice);
- if (wave->sample_rate != rate ||
- wave->num_channels != channels)
- {
- rate = wave->sample_rate;
- channels = wave->num_channels;
- err = snd_pcm_set_params(alsa_handle,
- SND_PCM_FORMAT_S16,
- SND_PCM_ACCESS_RW_INTERLEAVED,
- channels,
- rate,
- 1,
- 100000);
- if (err < 0)
- fprintf(stderr, "alsa set_params error %s\n",
- strerror(-err));
- }
- err = snd_pcm_prepare(alsa_handle);
- if (err < 0)
- fprintf(stderr, "alsa pcm_prepare error %s\n",
- strerror(-err));
- samples = (char *) wave->samples;
- num_samples = wave->num_samples;
- while (num_samples > 0) {
- err = snd_pcm_writei(alsa_handle,
- samples, num_samples);
- if (err <= 0) {
- fprintf(stderr, "alsa write error %s\n",
- strerror(-err));
- break;
- }
- num_samples -= err;
- samples += err * 2 * channels;
- }
- snd_pcm_drain(alsa_handle);
- delete_wave(wave);
- }
- snd_pcm_close(alsa_handle);
- alsa_handle = 0;
- return NULL;
-}
-
-void
-aoview_flite_stop(void)
-{
- int status;
- if (pipe_write) {
- fclose(pipe_write);
- pipe_write = NULL;
- }
- if (aoview_flite_thread) {
- g_thread_join(aoview_flite_thread);
- aoview_flite_thread = NULL;
- }
-}
-
-FILE *
-aoview_flite_start(void)
-{
- static once;
- int p[2];
- GError *error;
- FILE *pipe_read;
-
- if (!once) {
- flite_init();
- voice = register_cmu_us_kal();
- if (!voice) {
- perror("register voice");
- exit(1);
- }
- }
- aoview_flite_stop();
- pipe(p);
- pipe_read = fdopen(p[0], "r");
- pipe_write = fdopen(p[1], "w");
- g_thread_create(aoview_flite_task, pipe_read, TRUE, &error);
- return pipe_write;
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-static struct {
- char *name;
- char *initial_value;
- GtkLabel *widget;
-} label_widgets[] = {
- { "height_label", "Height (m)", NULL },
- { "state_label", "State", NULL },
- { "rssi_label", "RSSI (dBm)", NULL },
- { "speed_label", "Speed (m/s)", NULL },
- { "height_value", "0", NULL },
- { "state_value", "pad", NULL },
- { "rssi_value", "-50", NULL },
- { "speed_value", "0", NULL },
-};
-
-static void
-aoview_label_assign(GtkLabel *widget, char *value)
-{
- char *markup;
-
- markup = g_markup_printf_escaped("<span font_weight=\"bold\" size=\"xx-large\">%s</span>", value);
- gtk_label_set_markup(widget, markup);
- g_free(markup);
-}
-
-void
-aoview_label_show(struct aostate *state)
-{
- char line[1024];
- sprintf(line, "%d", state->height);
- aoview_label_assign(label_widgets[4].widget, line);
-
- aoview_label_assign(label_widgets[5].widget, state->data.state);
-
- sprintf(line, "%d", state->data.rssi);
- aoview_label_assign(label_widgets[6].widget, line);
-
- if (state->ascent)
- sprintf(line, "%6.0f", fabs(state->speed));
- else
- sprintf(line, "%6.0f", fabs(state->baro_speed));
- aoview_label_assign(label_widgets[7].widget, line);
-}
-
-void
-aoview_label_init(GladeXML *xml)
-{
- int i;
- for (i = 0; i < sizeof(label_widgets)/sizeof(label_widgets[0]); i++) {
- label_widgets[i].widget = GTK_LABEL(glade_xml_get_widget(xml, label_widgets[i].name));
- aoview_label_assign(label_widgets[i].widget, label_widgets[i].initial_value);
- assert(label_widgets[i].widget);
- }
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-static struct aoview_file *aoview_log;
-
-void
-aoview_log_new(void)
-{
- aoview_file_finish(aoview_log);
- aoview_state_new();
-}
-
-void
-aoview_log_set_serial(int serial)
-{
- aoview_file_set_serial(aoview_log, serial);
-}
-
-int
-aoview_log_get_serial(void)
-{
- return aoview_file_get_serial(aoview_log);
-}
-
-void
-aoview_log_printf(char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- aoview_file_vprintf(aoview_log, format, ap);
- va_end(ap);
-}
-
-static void
-aoview_log_new_item(GtkWidget *widget, gpointer data)
-{
- aoview_file_finish(aoview_log);
-}
-
-void
-aoview_log_init(GladeXML *xml)
-{
- GtkWidget *log_new;
-
- aoview_log = aoview_file_new("telem");
- assert(aoview_log);
-
- log_new = glade_xml_get_widget(xml, "log_new");
- assert(log_new);
- g_signal_connect(G_OBJECT(log_new), "activate",
- G_CALLBACK(aoview_log_new_item),
- NULL);
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-static const char aoview_glade[] = {
-#include "aoview_glade.h"
-};
-
-static void usage(void) {
- printf("aoview [--device|-d device_file]");
- exit(1);
-}
-
-static void destroy_event(GtkWidget *widget, gpointer data)
-{
- gtk_main_quit();
-}
-
-extern int _Xdebug;
-
-int main(int argc, char **argv)
-{
- GladeXML *xml = NULL;
- GtkWidget *mainwindow;
- char *device = NULL;
- GtkAboutDialog *about_dialog;
-
- static struct option long_options[] = {
- { "device", 1, 0, 'd'},
- { "sync", 0, 0, 's'},
- { 0, 0, 0, 0 }
- };
- for (;;) {
- int c, temp;
-
- c = getopt_long_only(argc, argv, "sd:", long_options, &temp);
- if (c == -1)
- break;
-
- switch (c) {
- case 'd':
- device = optarg;
- break;
- case 's':
- _Xdebug = 1;
- break;
- default:
- usage();
- }
- }
-
- g_thread_init(NULL);
- gtk_init(&argc, &argv);
- glade_init();
-
- xml = glade_xml_new_from_buffer(aoview_glade, sizeof (aoview_glade), NULL, NULL);
-
- /* connect the signals in the interface */
- glade_xml_signal_autoconnect(xml);
-
- /* Hook up the close button. */
- mainwindow = glade_xml_get_widget(xml, "aoview");
- assert(mainwindow);
-
- g_signal_connect (G_OBJECT(mainwindow), "destroy",
- G_CALLBACK(destroy_event), NULL);
-
- about_dialog = GTK_ABOUT_DIALOG(glade_xml_get_widget(xml, "about_dialog"));
- assert(about_dialog);
- gtk_about_dialog_set_version(about_dialog, AOVIEW_VERSION);
-
- aoview_voice_init(xml);
-
- aoview_dev_dialog_init(xml);
-
- aoview_state_init(xml);
-
- aoview_file_init(xml);
-
- aoview_log_init(xml);
-
- aoview_table_init(xml);
-
- aoview_eeprom_init(xml);
-
- aoview_replay_init(xml);
-
- aoview_label_init(xml);
-
- aoview_voice_speak("rocket flight monitor ready\n");
-
- gtk_main();
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-static struct aoview_serial *monitor_serial;
-
-#define MONITOR_LEN 1024
-
-static char monitor_line[MONITOR_LEN + 1];
-static int monitor_pos;
-
-void
-aoview_monitor_disconnect(void)
-{
- if (monitor_serial) {
- aoview_serial_close(monitor_serial);
- monitor_serial = NULL;
- }
- aoview_log_new();
-}
-
-static void
-aoview_parse_string(char *target, int len, char *source)
-{
- strncpy(target, source, len-1);
- target[len-1] = '\0';
-}
-
-static void
-aoview_parse_int(int *target, char *source)
-{
- *target = strtol(source, NULL, 0);
-}
-
-static void
-aoview_parse_pos(double *target, char *source)
-{
- int deg;
- double min;
- char dir;
- double r;
-
- if (sscanf(source, "%d°%lf'%c", °, &min, &dir) != 3) {
- *target = 0;
- return;
- }
- r = deg + min / 60.0;
- if (dir == 'S' || dir == 'W')
- r = -r;
- *target = r;
-}
-
-gboolean
-aoview_monitor_parse(const char *input_line)
-{
- char *saveptr;
- char *words[64];
- int nword;
- char line_buf[8192], *line;
- struct aodata data;
-
- /* avoid smashing our input parameter */
- strncpy (line_buf, input_line, sizeof (line_buf)-1);
- line_buf[sizeof(line_buf) - 1] = '\0';
- line = line_buf;
- for (nword = 0; nword < 64; nword++) {
- words[nword] = strtok_r(line, " \t\n", &saveptr);
- line = NULL;
- if (words[nword] == NULL)
- break;
- }
- if (nword < 36)
- return FALSE;
- if (strcmp(words[0], "CALL") != 0)
- return FALSE;
- aoview_parse_string(data.callsign, sizeof (data.callsign), words[1]);
- aoview_parse_int(&data.serial, words[3]);
-
- aoview_parse_int(&data.rssi, words[5]);
- aoview_parse_string(data.state, sizeof (data.state), words[9]);
- aoview_parse_int(&data.tick, words[10]);
- aoview_parse_int(&data.accel, words[12]);
- aoview_parse_int(&data.pres, words[14]);
- aoview_parse_int(&data.temp, words[16]);
- aoview_parse_int(&data.batt, words[18]);
- aoview_parse_int(&data.drogue, words[20]);
- aoview_parse_int(&data.main, words[22]);
- aoview_parse_int(&data.flight_accel, words[24]);
- aoview_parse_int(&data.ground_accel, words[26]);
- aoview_parse_int(&data.flight_vel, words[28]);
- aoview_parse_int(&data.flight_pres, words[30]);
- aoview_parse_int(&data.ground_pres, words[32]);
- aoview_parse_int(&data.gps.nsat, words[34]);
- if (strcmp (words[36], "unlocked") == 0) {
- data.gps.gps_connected = 1;
- data.gps.gps_locked = 0;
- data.gps.gps_time.hour = data.gps.gps_time.minute = data.gps.gps_time.second = 0;
- data.gps.lat = data.gps.lon = 0;
- data.gps.alt = 0;
- } else if (nword >= 40) {
- data.gps.gps_locked = 1;
- data.gps.gps_connected = 1;
- sscanf(words[36], "%d:%d:%d", &data.gps.gps_time.hour, &data.gps.gps_time.minute, &data.gps.gps_time.second);
- aoview_parse_pos(&data.gps.lat, words[37]);
- aoview_parse_pos(&data.gps.lon, words[38]);
- sscanf(words[39], "%dm", &data.gps.alt);
- } else {
- data.gps.gps_connected = 0;
- data.gps.gps_locked = 0;
- data.gps.gps_time.hour = data.gps.gps_time.minute = data.gps.gps_time.second = 0;
- data.gps.lat = data.gps.lon = 0;
- data.gps.alt = 0;
- }
- if (nword >= 46) {
- data.gps.gps_extended = 1;
- sscanf(words[40], "%lfm/s", &data.gps.ground_speed);
- sscanf(words[41], "%d", &data.gps.course);
- sscanf(words[42], "%lfm/s", &data.gps.climb_rate);
- sscanf(words[43], "%lf", &data.gps.hdop);
- sscanf(words[44], "%d", &data.gps.h_error);
- sscanf(words[45], "%d", &data.gps.v_error);
- } else {
- data.gps.gps_extended = 0;
- data.gps.ground_speed = 0;
- data.gps.course = 0;
- data.gps.climb_rate = 0;
- data.gps.hdop = 0;
- data.gps.h_error = 0;
- data.gps.v_error = 0;
- }
- aoview_state_notify(&data);
- return TRUE;
-}
-
-static void
-aoview_monitor_callback(gpointer user_data,
- struct aoview_serial *serial,
- gint revents)
-{
- int c;
-
- if (revents & (G_IO_HUP|G_IO_ERR)) {
- aoview_monitor_disconnect();
- return;
- }
- if (revents & G_IO_IN) {
- for (;;) {
- c = aoview_serial_getc(serial);
- if (c == -1)
- break;
- if (c == '\r')
- continue;
- if (c == '\n') {
- monitor_line[monitor_pos] = '\0';
- if (monitor_pos) {
- if (aoview_monitor_parse(monitor_line)) {
- aoview_log_set_serial(aostate.data.serial);
- if (aoview_log_get_serial())
- aoview_log_printf ("%s\n", monitor_line);
- }
- }
- monitor_pos = 0;
- } else if (monitor_pos < MONITOR_LEN)
- monitor_line[monitor_pos++] = c;
- }
- }
-}
-
-gboolean
-aoview_monitor_connect(char *tty)
-{
- aoview_monitor_disconnect();
- monitor_serial = aoview_serial_open(tty);
- if (!monitor_serial)
- return FALSE;
- aoview_table_clear();
- aoview_state_reset();
- aoview_serial_set_callback(monitor_serial,
- aoview_monitor_callback);
- return TRUE;
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-static GtkFileChooser *replay_dialog;
-static GtkWidget *replay_ok;
-static FILE *replay_file;
-static int replay_tick;
-
-static int
-find_tick(char *line, gboolean *is_pad)
-{
- char *state = strstr(line, "STATE");
- if (!state)
- return -1;
- state = strchr(state, ' ');
- if (!state)
- return -1;
- while (*state == ' ')
- state++;
- *is_pad = strncmp(state, "pad", 3) == 0;
- while (*state && !isdigit(*state))
- state++;
- return atoi(state);
-}
-
-static void
-aoview_replay_close(void)
-{
- if (replay_file) {
- fclose(replay_file);
- replay_file = NULL;
- }
-}
-
-static char replay_line[1024];
-
-static gboolean
-aoview_replay_read(gpointer data);
-
-static gboolean
-aoview_replay_execute(gpointer data)
-{
- aoview_monitor_parse(replay_line);
- g_idle_add(aoview_replay_read, NULL);
- return FALSE;
-}
-
-static gboolean
-aoview_replay_read(gpointer data)
-{
- int tick;
- gboolean is_pad;
-
- if (!replay_file)
- return FALSE;
- if (fgets(replay_line, sizeof (replay_line), replay_file)) {
- tick = find_tick(replay_line, &is_pad);
- if (tick >= 0 && replay_tick >= 0 && !is_pad) {
- while (tick < replay_tick)
- tick += 65536;
- g_timeout_add((tick - replay_tick) * 10,
- aoview_replay_execute,
- NULL);
- } else {
- aoview_replay_execute(NULL);
- }
- replay_tick = tick;
- } else {
- aoview_replay_close();
- }
- return FALSE;
-}
-
-static void
-aoview_replay_open(GtkWidget *widget, gpointer data)
-{
- char *replay_file_name;
- GtkWidget *dialog;
-
- aoview_replay_close();
- replay_file_name = gtk_file_chooser_get_filename(replay_dialog);
- replay_file = fopen(replay_file_name, "r");
- if (!replay_file) {
- dialog = gtk_message_dialog_new(GTK_WINDOW(replay_dialog),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Error loading file '%s': %s",
- replay_file_name, g_strerror(errno));
- gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy(dialog);
- } else {
- replay_tick = -1;
- aoview_state_reset();
- aoview_replay_read(NULL);
- }
- gtk_widget_hide(GTK_WIDGET(replay_dialog));
-}
-
-void
-aoview_replay_init(GladeXML *xml)
-{
- GtkFileFilter *telem_filter;
- GtkFileFilter *all_filter;
- GtkFileFilter *log_filter;
-
- telem_filter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(telem_filter, "*.telem");
- gtk_file_filter_set_name(telem_filter, "Telemetry Files");
-
- log_filter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(log_filter, "*.log");
- gtk_file_filter_set_name(log_filter, "Log Files");
-
- all_filter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(all_filter, "*");
- gtk_file_filter_set_name(all_filter, "All Files");
-
- replay_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "ao_replay_dialog"));
- assert(replay_dialog);
- gtk_file_chooser_set_current_folder(replay_dialog, aoview_file_dir);
- gtk_file_chooser_add_filter(replay_dialog, telem_filter);
- gtk_file_chooser_add_filter(replay_dialog, log_filter);
- gtk_file_chooser_add_filter(replay_dialog, all_filter);
-
- replay_ok = glade_xml_get_widget(xml, "ao_replay_ok");
- assert(replay_ok);
- g_signal_connect(G_OBJECT(replay_ok), "clicked",
- G_CALLBACK(aoview_replay_open),
- replay_dialog);
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-#include <termios.h>
-
-#define AOVIEW_SERIAL_IN_BUF 64
-#define AOVIEW_SERIAL_OUT_BUF 64
-
-struct aoview_buf {
- char *buf;
- int off;
- int count;
- int size;
-};
-
-static int
-aoview_buf_write(struct aoview_buf *buf, char *data, int len)
-{
- if (buf->count + len > buf->size) {
- int new_size = buf->size * 2;
- if (new_size == 0)
- new_size = 1024;
- if (buf->buf)
- buf->buf = realloc (buf->buf, new_size);
- else
- buf->buf = malloc (new_size);
- buf->size = new_size;
- }
- memcpy(buf->buf + buf->count, data, len);
- buf->count += len;
- return len;
-}
-
-static int
-aoview_buf_read(struct aoview_buf *buf, char *data, int len)
-{
- if (len > buf->count - buf->off)
- len = buf->count - buf->off;
- memcpy (data, buf->buf + buf->off, len);
- buf->off += len;
- if (buf->off == buf->count)
- buf->off = buf->count = 0;
- return len;
-}
-
-static int
-aoview_buf_getc(struct aoview_buf *buf)
-{
- char b;
- int r;
-
- r = aoview_buf_read(buf, &b, 1);
- if (r == 1)
- return (int) b;
- return -1;
-}
-
-static void
-aoview_buf_flush(struct aoview_buf *buf, int fd)
-{
- int ret;
-
- if (buf->count > buf->off) {
- ret = write(fd, buf->buf + buf->off, buf->count - buf->off);
- if (ret > 0) {
- buf->off += ret;
- if (buf->off == buf->count)
- buf->off = buf->count = 0;
- }
- }
-}
-
-static void
-aoview_buf_fill(struct aoview_buf *buf, int fd)
-{
- int ret;
-
- while (buf->count >= buf->size) {
- int new_size = buf->size * 2;
- buf->buf = realloc (buf->buf, new_size);
- buf->size = new_size;
- }
-
- ret = read(fd, buf->buf + buf->count, buf->size - buf->count);
- if (ret > 0)
- buf->count += ret;
-}
-
-static void
-aoview_buf_init(struct aoview_buf *buf)
-{
- buf->buf = malloc (buf->size = 1024);
- buf->count = 0;
-}
-
-static void
-aoview_buf_fini(struct aoview_buf *buf)
-{
- free(buf->buf);
-}
-
-struct aoview_serial {
- GSource source;
- int fd;
- struct termios save_termios;
- struct aoview_buf in_buf;
- struct aoview_buf out_buf;
- GPollFD poll_fd;
-};
-
-
-void
-aoview_serial_printf(struct aoview_serial *serial, char *format, ...)
-{
- char buf[1024];
- va_list ap;
- int ret;
-
- /* sprintf to a local buffer */
- va_start(ap, format);
- ret = vsnprintf(buf, sizeof(buf), format, ap);
- va_end(ap);
- if (ret > sizeof(buf)) {
- fprintf(stderr, "printf overflow for format %s\n",
- format);
- }
-
- /* flush local buffer to the wire */
- aoview_buf_write(&serial->out_buf, buf, ret);
- aoview_buf_flush(&serial->out_buf, serial->fd);
-}
-
-int
-aoview_serial_read(struct aoview_serial *serial, char *buf, int len)
-{
- return aoview_buf_read(&serial->in_buf, buf, len);
-}
-
-int
-aoview_serial_getc(struct aoview_serial *serial)
-{
- return aoview_buf_getc(&serial->in_buf);
-}
-
-static gboolean
-serial_prepare(GSource *source, gint *timeout)
-{
- struct aoview_serial *serial = (struct aoview_serial *) source;
- *timeout = -1;
-
- if (serial->out_buf.count)
- serial->poll_fd.events |= G_IO_OUT;
- else
- serial->poll_fd.events &= ~G_IO_OUT;
- return FALSE;
-}
-
-static gboolean
-serial_check(GSource *source)
-{
- struct aoview_serial *serial = (struct aoview_serial *) source;
- gint revents = serial->poll_fd.revents;
-
- if (revents & G_IO_NVAL)
- return FALSE;
- if (revents & G_IO_IN)
- return TRUE;
- if (revents & G_IO_OUT)
- return TRUE;
- return FALSE;
-}
-
-static gboolean
-serial_dispatch(GSource *source,
- GSourceFunc callback,
- gpointer user_data)
-{
- struct aoview_serial *serial = (struct aoview_serial *) source;
- aoview_serial_callback func = (aoview_serial_callback) callback;
- gint revents = serial->poll_fd.revents;
-
- if (revents & G_IO_IN)
- aoview_buf_fill(&serial->in_buf, serial->fd);
-
- if (revents & G_IO_OUT)
- aoview_buf_flush(&serial->out_buf, serial->fd);
-
- if (func)
- (*func)(user_data, serial, revents);
- return TRUE;
-}
-
-static void
-serial_finalize(GSource *source)
-{
- struct aoview_serial *serial = (struct aoview_serial *) source;
-
- aoview_buf_fini(&serial->in_buf);
- aoview_buf_fini(&serial->out_buf);
- tcsetattr(serial->fd, TCSAFLUSH, &serial->save_termios);
- close (serial->fd);
-}
-
-static GSourceFuncs serial_funcs = {
- serial_prepare,
- serial_check,
- serial_dispatch,
- serial_finalize
-};
-
-struct aoview_serial *
-aoview_serial_open(const char *tty)
-{
- struct aoview_serial *serial;
- struct termios termios;
-
- serial = (struct aoview_serial *) g_source_new(&serial_funcs, sizeof (struct aoview_serial));
- aoview_buf_init(&serial->in_buf);
- aoview_buf_init(&serial->out_buf);
- serial->fd = open (tty, O_RDWR | O_NONBLOCK);
- if (serial->fd < 0) {
- g_source_destroy(&serial->source);
- return NULL;
- }
- tcgetattr(serial->fd, &termios);
- serial->save_termios = termios;
- cfmakeraw(&termios);
- tcsetattr(serial->fd, TCSAFLUSH, &termios);
-
- aoview_serial_printf(serial, "E 0\n");
- tcdrain(serial->fd);
- usleep(15*1000);
- tcflush(serial->fd, TCIFLUSH);
- serial->poll_fd.fd = serial->fd;
- serial->poll_fd.events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR;
- g_source_attach(&serial->source, NULL);
- g_source_add_poll(&serial->source,&serial->poll_fd);
- aoview_serial_set_callback(serial, NULL);
- return serial;
-}
-
-void
-aoview_serial_close(struct aoview_serial *serial)
-{
- g_source_remove_poll(&serial->source, &serial->poll_fd);
- close(serial->fd);
- g_source_destroy(&serial->source);
-}
-
-void
-aoview_serial_set_callback(struct aoview_serial *serial,
- aoview_serial_callback func)
-{
- g_source_set_callback(&serial->source, (GSourceFunc) func, serial, NULL);
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-#include <math.h>
-
-static inline double sqr(double a) { return a * a; };
-
-static void
-aoview_great_circle (double start_lat, double start_lon,
- double end_lat, double end_lon,
- double *dist, double *bearing)
-{
- const double rad = M_PI / 180;
- const double earth_radius = 6371.2 * 1000; /* in meters */
- double lat1 = rad * start_lat;
- double lon1 = rad * -start_lon;
- double lat2 = rad * end_lat;
- double lon2 = rad * -end_lon;
-
- double d_lat = lat2 - lat1;
- double d_lon = lon2 - lon1;
-
- /* From http://en.wikipedia.org/wiki/Great-circle_distance */
- double vdn = sqrt(sqr(cos(lat2) * sin(d_lon)) +
- sqr(cos(lat1) * sin(lat2) -
- sin(lat1) * cos(lat2) * cos(d_lon)));
- double vdd = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(d_lon);
- double d = atan2(vdn,vdd);
- double course;
-
- if (cos(lat1) < 1e-20) {
- if (lat1 > 0)
- course = M_PI;
- else
- course = -M_PI;
- } else {
- if (d < 1e-10)
- course = 0;
- else
- course = acos((sin(lat2)-sin(lat1)*cos(d)) /
- (sin(d)*cos(lat1)));
- if (sin(lon2-lon1) > 0)
- course = 2 * M_PI-course;
- }
- *dist = d * earth_radius;
- *bearing = course * 180/M_PI;
-}
-
-static void
-aoview_state_add_deg(int column, char *label, double deg, char pos, char neg)
-{
- double int_part;
- double min;
- char sign = pos;
-
- if (deg < 0) {
- deg = -deg;
- sign = neg;
- }
- int_part = floor (deg);
- min = (deg - int_part) * 60.0;
- aoview_table_add_row(column, label, "%d°%lf'%c",
- (int) int_part, min, sign);
-
-}
-
-static char *ascent_states[] = {
- "boost",
- "fast",
- "coast",
- 0,
-};
-
-static double
-aoview_time(void)
-{
- struct timespec now;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- return (double) now.tv_sec + (double) now.tv_nsec / 1.0e9;
-}
-
-/*
- * Fill out the derived data fields
- */
-static void
-aoview_state_derive(struct aodata *data, struct aostate *state)
-{
- int i;
- double new_height;
- double height_change;
- double time_change;
- int tick_count;
-
- state->report_time = aoview_time();
-
- state->prev_data = state->data;
- state->prev_npad = state->npad;
- state->data = *data;
- tick_count = data->tick;
- if (tick_count < state->prev_data.tick)
- tick_count += 65536;
- time_change = (tick_count - state->prev_data.tick) / 100.0;
-
- state->ground_altitude = aoview_pres_to_altitude(data->ground_pres);
- new_height = aoview_pres_to_altitude(data->flight_pres) - state->ground_altitude;
- height_change = new_height - state->height;
- state->height = new_height;
- if (time_change)
- state->baro_speed = (state->baro_speed * 3 + (height_change / time_change)) / 4.0;
- state->acceleration = (data->ground_accel - data->flight_accel) / 27.0;
- state->speed = data->flight_vel / 2700.0;
- state->temperature = ((data->temp / 32767.0 * 3.3) - 0.5) / 0.01;
- state->drogue_sense = data->drogue / 32767.0 * 15.0;
- state->main_sense = data->main / 32767.0 * 15.0;
- state->battery = data->batt / 32767.0 * 5.0;
- if (!strcmp(data->state, "pad")) {
- if (data->gps.gps_locked && data->gps.nsat >= 4) {
- state->npad++;
- state->pad_lat_total += data->gps.lat;
- state->pad_lon_total += data->gps.lon;
- state->pad_alt_total += data->gps.alt;
- if (state->npad > 1) {
- state->pad_lat = (state->pad_lat * 31 + data->gps.lat) / 32.0;
- state->pad_lon = (state->pad_lon * 31 + data->gps.lon) / 32.0;
- state->pad_alt = (state->pad_alt * 31 + data->gps.alt) / 32.0;
- } else {
- state->pad_lat = data->gps.lat;
- state->pad_lon = data->gps.lon;
- state->pad_alt = data->gps.alt;
- }
- }
- }
- state->ascent = FALSE;
- for (i = 0; ascent_states[i]; i++)
- if (!strcmp(data->state, ascent_states[i]))
- state->ascent = TRUE;
-
- /* Only look at accelerometer data on the way up */
- if (state->ascent && state->acceleration > state->max_acceleration)
- state->max_acceleration = state->acceleration;
- if (state->ascent && state->speed > state->max_speed)
- state->max_speed = state->speed;
-
- if (state->height > state->max_height)
- state->max_height = state->height;
- state->gps.gps_locked = data->gps.gps_locked;
- state->gps.gps_connected = data->gps.gps_connected;
- if (data->gps.gps_locked) {
- state->gps = data->gps;
- state->gps_valid = 1;
- if (state->npad)
- aoview_great_circle(state->pad_lat, state->pad_lon, state->gps.lat, state->gps.lon,
- &state->distance, &state->bearing);
- }
- if (state->npad) {
- state->gps_height = state->gps.alt - state->pad_alt;
- } else {
- state->gps_height = 0;
- }
-}
-
-void
-aoview_speak_state(struct aostate *state)
-{
- if (strcmp(state->data.state, state->prev_data.state)) {
- aoview_voice_speak("%s\n", state->data.state);
- if (!strcmp(state->data.state, "drogue"))
- aoview_voice_speak("apogee %d meters\n",
- (int) state->max_height);
- if (!strcmp(state->prev_data.state, "boost"))
- aoview_voice_speak("max speed %d meters per second\n",
- (int) state->max_speed);
- }
- if (state->prev_npad < MIN_PAD_SAMPLES && state->npad >= MIN_PAD_SAMPLES)
- aoview_voice_speak("g p s ready\n");
-}
-
-void
-aoview_speak_height(struct aostate *state)
-{
- aoview_voice_speak("%d meters\n", state->height);
-}
-
-struct aostate aostate;
-
-static guint aostate_timeout;
-
-#define COMPASS_LIMIT(n) ((n * 22.5) + 22.5/2)
-
-static char *compass_points[] = {
- "north",
- "north north east",
- "north east",
- "east north east",
- "east",
- "east south east",
- "south east",
- "south south east",
- "south",
- "south south west",
- "south west",
- "west south west",
- "west",
- "west north west",
- "north west",
- "north north west",
-};
-
-static char *
-aoview_compass_point(double bearing)
-{
- int i;
- while (bearing < 0)
- bearing += 360.0;
- while (bearing >= 360.0)
- bearing -= 360.0;
-
- i = floor ((bearing - 22.5/2) / 22.5 + 0.5);
- if (i < 0) i = 0;
- if (i >= sizeof (compass_points) / sizeof (compass_points[0]))
- i = 0;
- return compass_points[i];
-}
-
-static gboolean
-aoview_state_timeout(gpointer data)
-{
- double now = aoview_time();
-
- if (strlen(aostate.data.state) > 0 && strcmp(aostate.data.state, "pad") != 0)
- aoview_speak_height(&aostate);
- if (now - aostate.report_time >= 20 || !strcmp(aostate.data.state, "landed")) {
- if (!aostate.ascent) {
- if (fabs(aostate.baro_speed) < 20 && aostate.height < 100)
- aoview_voice_speak("rocket landed safely\n");
- else
- aoview_voice_speak("rocket may have crashed\n");
- if (aostate.gps_valid) {
- aoview_voice_speak("rocket reported %s of pad distance %d meters\n",
- aoview_compass_point(aostate.bearing),
- (int) aostate.distance);
- }
- }
- aostate_timeout = 0;
- return FALSE;
- }
- return TRUE;
-}
-
-void
-aoview_state_reset(void)
-{
- memset(&aostate, '\0', sizeof (aostate));
-}
-
-void
-aoview_state_notify(struct aodata *data)
-{
- struct aostate *state = &aostate;
- aoview_state_derive(data, state);
- aoview_table_start();
-
- if (state->npad >= MIN_PAD_SAMPLES)
- aoview_table_add_row(0, "Ground state", "ready");
- else
- aoview_table_add_row(0, "Ground state", "waiting for gps (%d)",
- MIN_PAD_SAMPLES - state->npad);
- aoview_table_add_row(0, "Rocket state", "%s", state->data.state);
- aoview_table_add_row(0, "Callsign", "%s", state->data.callsign);
- aoview_table_add_row(0, "Rocket serial", "%d", state->data.serial);
-
- aoview_table_add_row(0, "RSSI", "%6ddBm", state->data.rssi);
- aoview_table_add_row(0, "Height", "%6dm", state->height);
- aoview_table_add_row(0, "Max height", "%6dm", state->max_height);
- aoview_table_add_row(0, "Acceleration", "%7.1fm/s²", state->acceleration);
- aoview_table_add_row(0, "Max acceleration", "%7.1fm/s²", state->max_acceleration);
- aoview_table_add_row(0, "Speed", "%7.1fm/s", state->ascent ? state->speed : state->baro_speed);
- aoview_table_add_row(0, "Max Speed", "%7.1fm/s", state->max_speed);
- aoview_table_add_row(0, "Temperature", "%6.2f°C", state->temperature);
- aoview_table_add_row(0, "Battery", "%5.2fV", state->battery);
- aoview_table_add_row(0, "Drogue", "%5.2fV", state->drogue_sense);
- aoview_table_add_row(0, "Main", "%5.2fV", state->main_sense);
- aoview_table_add_row(0, "Pad altitude", "%dm", state->ground_altitude);
- aoview_table_add_row(1, "Satellites", "%d", state->gps.nsat);
- if (state->gps.gps_locked) {
- aoview_table_add_row(1, "GPS", "locked");
- } else if (state->gps.gps_connected) {
- aoview_table_add_row(1, "GPS", "unlocked");
- } else {
- aoview_table_add_row(1, "GPS", "not available");
- }
- if (state->gps_valid) {
- aoview_state_add_deg(1, "Latitude", state->gps.lat, 'N', 'S');
- aoview_state_add_deg(1, "Longitude", state->gps.lon, 'E', 'W');
- aoview_table_add_row(1, "GPS height", "%d", state->gps_height);
- aoview_table_add_row(1, "GPS time", "%02d:%02d:%02d",
- state->gps.gps_time.hour,
- state->gps.gps_time.minute,
- state->gps.gps_time.second);
- }
- if (state->gps.gps_extended) {
- aoview_table_add_row(1, "GPS ground speed", "%7.1fm/s %d°",
- state->gps.ground_speed,
- state->gps.course);
- aoview_table_add_row(1, "GPS climb rate", "%7.1fm/s",
- state->gps.climb_rate);
- aoview_table_add_row(1, "GPS precision", "%4.1f(hdop) %3dm(h) %3dm(v)",
- state->gps.hdop, state->gps.h_error, state->gps.v_error);
- }
- if (state->npad) {
- aoview_table_add_row(1, "Distance from pad", "%5.0fm", state->distance);
- aoview_table_add_row(1, "Direction from pad", "%4.0f°", state->bearing);
- aoview_state_add_deg(1, "Pad latitude", state->pad_lat, 'N', 'S');
- aoview_state_add_deg(1, "Pad longitude", state->pad_lon, 'E', 'W');
- aoview_table_add_row(1, "Pad GPS alt", "%gm", state->pad_alt);
- }
- aoview_table_finish();
- aoview_label_show(state);
- aoview_speak_state(state);
- if (!aostate_timeout && strcmp(state->data.state, "pad") != 0)
- aostate_timeout = g_timeout_add_seconds(10, aoview_state_timeout, NULL);
-}
-
-void
-aoview_state_new(void)
-{
-}
-
-void
-aoview_state_init(GladeXML *xml)
-{
- aoview_state_new();
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-#define NCOL 2
-
-static GtkTreeView *dataview[NCOL];
-static GtkListStore *datalist[NCOL];
-
-void
-aoview_table_start(void)
-{
- int col;
- for (col = 0; col < NCOL; col++)
- datalist[col] = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-}
-
-void
-aoview_table_add_row(int col, char *label, char *format, ...)
-{
- char buf[1024];
- va_list ap;
- GtkTreeIter iter;
-
- va_start(ap, format);
- vsnprintf(buf, sizeof (buf), format, ap);
- va_end(ap);
- gtk_list_store_append(datalist[col], &iter);
- gtk_list_store_set(datalist[col], &iter,
- 0, label,
- 1, buf,
- -1);
-}
-
-void
-aoview_table_finish(void)
-{
- int col;
- for (col = 0; col < NCOL; col++) {
- gtk_tree_view_set_model(dataview[col], GTK_TREE_MODEL(datalist[col]));
- g_object_unref(G_OBJECT(datalist[col]));
- gtk_tree_view_columns_autosize(dataview[col]);
- }
-}
-
-void
-aoview_table_clear(void)
-{
- int col;
- for (col = 0; col < NCOL; col++)
- gtk_tree_view_set_model(dataview[col], NULL);
-}
-
-void
-aoview_table_init(GladeXML *xml)
-{
- int col;
-
- for (col = 0; col < NCOL; col++) {
- char name[32];
- sprintf(name, "dataview_%d", col);
- dataview[col] = GTK_TREE_VIEW(glade_xml_get_widget(xml, name));
- assert(dataview[col]);
-
- aoview_add_plain_text_column(dataview[col], "Field", 0, 20);
- aoview_add_plain_text_column(dataview[col], "Value", 1, 32);
- }
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-char *
-aoview_fullname (char *dir, char *file)
-{
- char *new;
- int dlen = strlen (dir);
- int flen = strlen (file);
- int slen = 0;
-
- if (dir[dlen-1] != '/')
- slen = 1;
- new = malloc (dlen + slen + flen + 1);
- if (!new)
- return 0;
- strcpy(new, dir);
- if (slen)
- strcat (new, "/");
- strcat(new, file);
- return new;
-}
-
-char *
-aoview_basename(char *file)
-{
- char *b;
-
- b = strrchr(file, '/');
- if (!b)
- return file;
- return b + 1;
-}
-
-int
-aoview_mkdir(char *dir)
-{
- char *slash;
- char *d;
- char *part;
-
- d = dir;
- for (;;) {
- slash = strchr (d, '/');
- if (!slash)
- slash = d + strlen(d);
- if (!*slash)
- break;
- part = strndup(dir, slash - dir);
- if (!access(part, F_OK))
- if (mkdir(part, 0777) < 0)
- return -errno;
- free(part);
- d = slash + 1;
- }
- return 0;
-}
-
-GtkTreeViewColumn *
-aoview_add_plain_text_column (GtkTreeView *view, const gchar *title, gint model_column, gint width)
-{
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
-
- renderer = gtk_cell_renderer_text_new ();
- g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_NONE, NULL);
- g_object_set(renderer, "width-chars", width, NULL);
- column = gtk_tree_view_column_new_with_attributes (title, renderer,
- "text", model_column,
- NULL);
- gtk_tree_view_column_set_resizable (column, FALSE);
- gtk_tree_view_append_column (view, column);
-
- return column;
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "aoview.h"
-
-#if HAVE_FLITE
-#include <stdarg.h>
-
-FILE *aoview_flite;
-
-void aoview_voice_open(void)
-{
- int err;
-
- if (!aoview_flite)
- aoview_flite = aoview_flite_start();
-}
-
-void aoview_voice_close(void)
-{
- if (aoview_flite) {
- aoview_flite_stop();
- aoview_flite = NULL;
- }
-}
-
-void aoview_voice_speak(char *format, ...)
-{
- va_list ap;
-
- if (aoview_flite) {
- va_start(ap, format);
- vfprintf(aoview_flite, format, ap);
- fflush(aoview_flite);
- va_end(ap);
- }
-}
-
-#else
-void aoview_voice_open(void)
-{
-}
-
-void aoview_voice_close(void)
-{
-}
-
-void aoview_voice_speak(char *format, ...)
-{
-}
-#endif
-
-
-static GtkCheckMenuItem *voice_enable;
-
-#define ALTOS_VOICE_PATH "/apps/aoview/voice"
-
-static void
-aoview_voice_enable(GtkWidget *widget, gpointer data)
-{
- gboolean enabled = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
- GError *error;
- GConfClient *gconf_client;
-
- if (enabled) {
- aoview_voice_open();
- aoview_voice_speak("enable voice\n");
- } else {
- aoview_voice_speak("disable voice\n");
- aoview_voice_close();
- }
- gconf_client = gconf_client_get_default();
- gconf_client_set_bool(gconf_client,
- ALTOS_VOICE_PATH,
- enabled,
- &error);
-}
-
-void
-aoview_voice_init(GladeXML *xml)
-{
- gboolean enabled;
- GConfClient *gconf_client;
-
- voice_enable = GTK_CHECK_MENU_ITEM(glade_xml_get_widget(xml, "voice_enable"));
- assert(voice_enable);
-
- gconf_client = gconf_client_get_default();
- enabled = TRUE;
- if (gconf_client)
- {
- GError *error;
-
- error = NULL;
- enabled = gconf_client_get_bool(gconf_client,
- ALTOS_VOICE_PATH,
- &error);
- if (error)
- enabled = TRUE;
- }
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(voice_enable), enabled);
- if (enabled)
- aoview_voice_open();
-
- g_signal_connect(G_OBJECT(voice_enable), "toggled",
- G_CALLBACK(aoview_voice_enable),
- voice_enable);
-}
+++ /dev/null
-Requirements:
- real-time display of telemetry
- off-line display of logged data
- Logging of telemetry
- Capture of logged data to disk
-
-Input data:
- accelerometer
- barometer
- thermometer
- gps
- drogue and main continuity
- battery voltage
- time
- reported flight state
- reported events
-
-Computed data:
- velocity (from accelerometer)
- altitude
- range
- direction
-
-Displays:
- numeric display of current rocket status
- (graphics come later)
- text message log
+++ /dev/null
-SUBDIRS=lib ccload s51 ccmanual ccdump aoload
+++ /dev/null
-bin_PROGRAMS=aoload
-
-AM_CFLAGS=-I$(top_srcdir)/cctools/lib $(LIBUSB_CFLAGS)
-AOLOAD_LIBS=$(top_builddir)/cctools/lib/libcc.a
-
-aoload_DEPENDENCIES = $(AOLOAD_LIBS)
-
-aoload_LDADD=$(AOLOAD_LIBS) $(LIBUSB_LIBS)
-
-aoload_SOURCES = aoload.c
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdlib.h>
-#include <limits.h>
-#include <stdint.h>
-#include "ccdbg.h"
-
-#define AO_USB_DESC_STRING 3
-
-void
-usage(char *program)
-{
- fprintf(stderr, "usage: %s <filename.ihx> <serial>\n", program);
- exit(1);
-}
-
-struct sym {
- unsigned addr;
- char *name;
-} serial_symbols[] = {
- { 0, "_ao_serial_number" },
-#define AO_SERIAL_NUMBER (serial_symbols[0].addr)
- { 0, "_ao_usb_descriptors" },
-#define AO_USB_DESCRIPTORS (serial_symbols[1].addr)
-};
-
-#define NUM_SERIAL_SYMBOLS (sizeof(serial_symbols)/sizeof(serial_symbols[0]))
-
-static int
-find_symbols(FILE *map)
-{
- char line[2048];
- char *addr, *addr_end;
- char *name;
- char *save;
- char *colon;
- unsigned long a;
- int s;
- int found = 0;
-
- while (fgets(line, sizeof(line), map) != NULL) {
- line[sizeof(line)-1] = '\0';
- addr = strtok_r(line, " \t\n", &save);
- if (!addr)
- continue;
- name = strtok_r(NULL, " \t\n", &save);
- if (!name)
- continue;
- colon = strchr (addr, ':');
- if (!colon)
- continue;
- a = strtoul(colon+1, &addr_end, 16);
- if (a == ULONG_MAX || addr_end == addr)
- continue;
- for (s = 0; s < NUM_SERIAL_SYMBOLS; s++)
- if (!strcmp(serial_symbols[s].name, name)) {
- serial_symbols[s].addr = (unsigned) a;
- ++found;
- break;
- }
- }
- return found == NUM_SERIAL_SYMBOLS;
-}
-
-static int
-rewrite(struct hex_image *image, unsigned addr, char *data, int len)
-{
- int i;
- if (addr < image->address || image->address + image->length < addr + len)
- return 0;
- printf("rewrite %04x:", addr);
- for (i = 0; i < len; i++)
- printf (" %02x", image->data[addr - image->address + i]);
- printf(" ->");
- for (i = 0; i < len; i++)
- printf (" %02x", data[i]);
- printf("\n");
- memcpy(image->data + addr - image->address, data, len);
-}
-
-int
-main (int argc, char **argv)
-{
- struct ccdbg *dbg;
- uint8_t status;
- uint16_t pc;
- struct hex_file *hex;
- struct hex_image *image;
- char *filename;
- FILE *file;
- FILE *map;
- char *serial_string;
- unsigned int serial;
- char *mapname, *dot;
- char *serial_ucs2;
- int serial_ucs2_len;
- char serial_int[2];
- unsigned int s;
- int i;
- unsigned usb_descriptors;
- int string_num;
-
- filename = argv[1];
- if (filename == NULL)
- usage(argv[0]);
- mapname = strdup(filename);
- dot = strrchr(mapname, '.');
- if (!dot || strcmp(dot, ".ihx") != 0)
- usage(argv[0]);
- strcpy(dot, ".map");
-
- serial_string = argv[2];
- if (serial_string == NULL)
- usage(argv[0]);
-
- file = fopen(filename, "r");
- if (!file) {
- perror(filename);
- exit(1);
- }
- map = fopen(mapname, "r");
- if (!map) {
- perror(mapname);
- exit(1);
- }
- if (!find_symbols(map)) {
- fprintf(stderr, "Cannot find symbols in \"%s\"\n", mapname);
- exit(1);
- }
- fclose(map);
-
- hex = ccdbg_hex_file_read(file, filename);
- fclose(file);
- if (!hex) {
- perror(filename);
- exit (1);
- }
- image = ccdbg_hex_image_create(hex);
- if (!image) {
- fprintf(stderr, "image create failed\n");
- exit (1);
- }
- ccdbg_hex_file_free(hex);
-
- serial = strtoul(serial_string, NULL, 0);
- if (!serial)
- usage(argv[0]);
-
- serial_int[0] = serial & 0xff;
- serial_int[1] = (serial >> 8) & 0xff;
-
- if (!rewrite(image, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) {
- fprintf(stderr, "Cannot rewrite serial integer at %04x\n",
- AO_SERIAL_NUMBER);
- exit(1);
- }
-
- usb_descriptors = AO_USB_DESCRIPTORS - image->address;
- string_num = 0;
- while (image->data[usb_descriptors] != 0 && usb_descriptors < image->length) {
- if (image->data[usb_descriptors+1] == AO_USB_DESC_STRING) {
- ++string_num;
- if (string_num == 4)
- break;
- }
- usb_descriptors += image->data[usb_descriptors];
- }
- if (usb_descriptors >= image->length || image->data[usb_descriptors] == 0 ) {
- fprintf(stderr, "Cannot rewrite serial string at %04x\n", AO_USB_DESCRIPTORS);
- exit(1);
- }
-
- serial_ucs2_len = image->data[usb_descriptors] - 2;
- serial_ucs2 = malloc(serial_ucs2_len);
- if (!serial_ucs2) {
- fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len);
- exit(1);
- }
- s = serial;
- for (i = serial_ucs2_len / 2; i; i--) {
- serial_ucs2[i * 2 - 1] = 0;
- serial_ucs2[i * 2 - 2] = (s % 10) + '0';
- s /= 10;
- }
- if (!rewrite(image, usb_descriptors + 2 + image->address, serial_ucs2, serial_ucs2_len))
- usage(argv[0]);
-
- dbg = ccdbg_open();
- if (!dbg)
- exit (1);
-
- ccdbg_add_debug(CC_DEBUG_FLASH);
-
- ccdbg_debug_mode(dbg);
- ccdbg_halt(dbg);
- if (image->address == 0xf000) {
- printf("Loading %d bytes to execute from RAM\n",
- image->length);
- ccdbg_write_hex_image(dbg, image, 0);
- } else if (image->address == 0x0000) {
- printf("Loading %d bytes to execute from FLASH\n",
- image->length);
- ccdbg_flash_hex_image(dbg, image);
- } else {
- printf("Cannot load code to 0x%04x\n",
- image->address);
- ccdbg_hex_image_free(image);
- ccdbg_close(dbg);
- exit(1);
- }
- ccdbg_set_pc(dbg, image->address);
- ccdbg_resume(dbg);
- ccdbg_close(dbg);
- exit (0);
-}
+++ /dev/null
-bin_PROGRAMS=ccdump
-
-AM_CFLAGS=-I$(top_srcdir)/cctools/lib $(LIBUSB_CFLAGS)
-CCDUMP_LIBS=$(top_builddir)/cctools/lib/libcc.a
-
-ccdump_DEPENDENCIES = $(CCDUMP_LIBS)
-
-ccdump_LDADD=$(CCDUMP_LIBS) $(LIBUSB_LIBS)
-
-ccdump_SOURCES = ccdump.c
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "cc-usb.h"
-
-#define NUM_BLOCK 512
-
-int
-main (int argc, char **argv)
-{
- struct cc_usb *cc;
- int block;
- uint8_t bytes[32 * (2 + 8)];
- uint8_t *b;
- int i, j;
- uint32_t addr;
- char *tty;
-
- tty = getenv("CCDBG_TTY");
- cc = cc_usb_open(tty);
- for (block = 0; block < NUM_BLOCK; block++) {
- cc_queue_read(cc, bytes, sizeof (bytes));
- cc_usb_printf(cc, "e %x\n", block);
- cc_usb_sync(cc);
- for (i = 0; i < 32; i++) {
- b = bytes + (i * 10);
- addr = block * 256 + i * 8;
- printf ("%06x", addr);
- for (j = 0; j < 8; j++) {
- printf (" %02x", b[j+2]);
- }
- printf ("\n");
- }
- }
- cc_usb_close(cc);
- exit (0);
-}
+++ /dev/null
-bin_PROGRAMS=ccload
-
-AM_CFLAGS=-I$(top_srcdir)/cctools/lib $(LIBUSB_CFLAGS)
-CCLOAD_LIBS=$(top_builddir)/cctools/lib/libcc.a
-
-ccload_DEPENDENCIES = $(CCLOAD_LIBS)
-
-ccload_LDADD=$(CCLOAD_LIBS) $(LIBUSB_LIBS)
-
-ccload_SOURCES = ccload.c
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-
-int
-main (int argc, char **argv)
-{
- struct ccdbg *dbg;
- uint8_t status;
- uint16_t pc;
- struct hex_file *hex;
- struct hex_image *image;
- char *filename;
- FILE *file;
-
- filename = argv[1];
- if (filename == NULL) {
- fprintf(stderr, "usage: %s <filename.ihx>\n", argv[0]);
- exit(1);
- }
- file = fopen(filename, "r");
- if (!file) {
- perror(filename);
- exit(1);
- }
- hex = ccdbg_hex_file_read(file, filename);
- fclose(file);
- if (!hex)
- exit (1);
- image = ccdbg_hex_image_create(hex);
- if (!image) {
- fprintf(stderr, "image create failed\n");
- exit (1);
- }
-
- ccdbg_hex_file_free(hex);
- dbg = ccdbg_open();
- if (!dbg)
- exit (1);
-
- ccdbg_add_debug(CC_DEBUG_FLASH);
-
- ccdbg_debug_mode(dbg);
- ccdbg_halt(dbg);
- if (image->address == 0xf000) {
- printf("Loading %d bytes to execute from RAM\n",
- image->length);
- ccdbg_write_hex_image(dbg, image, 0);
- } else if (image->address == 0x0000) {
- printf("Loading %d bytes to execute from FLASH\n",
- image->length);
- ccdbg_flash_hex_image(dbg, image);
- } else {
- printf("Cannot load code to 0x%04x\n",
- image->address);
- ccdbg_hex_image_free(image);
- ccdbg_close(dbg);
- exit(1);
- }
- ccdbg_set_pc(dbg, image->address);
- ccdbg_resume(dbg);
- ccdbg_close(dbg);
- exit (0);
-}
+++ /dev/null
-bin_PROGRAMS=ccmanual
-
-AM_CFLAGS=-I$(top_srcdir)/cctools/lib $(LIBUSB_CFLAGS)
-CCMANUAL_LIBS=$(top_builddir)/cctools/lib/libcc.a
-
-ccmanual_DEPENDENCIES = $(CCMANUAL_LIBS)
-
-ccmanual_LDADD=$(CCMANUAL_LIBS) $(LIBUSB_LIBS)
-
-ccmanual_SOURCES = ccmanual.c
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-
-int
-main (int argc, char **argv)
-{
- struct ccdbg *dbg;
-
- dbg = ccdbg_open();
- if (!dbg)
- exit (1);
-
- ccdbg_add_debug(CC_DEBUG_BITBANG);
-
- ccdbg_manual(dbg, stdin);
-}
+++ /dev/null
-noinst_LIBRARIES = libcc.a
-
-AM_CFLAGS=$(WARN_CFLAGS) $(LIBUSB_CFLAGS)
-
-libcc_a_SOURCES = \
- ccdbg-command.c \
- ccdbg-debug.c \
- ccdbg-debug.h \
- ccdbg-flash.c \
- ccdbg.h \
- ccdbg-hex.c \
- ccdbg-io.c \
- ccdbg-manual.c \
- ccdbg-memory.c \
- ccdbg-rom.c \
- ccdbg-state.c \
- cc-usb.c \
- cc-usb.h \
- cc-bitbang.c \
- cc-bitbang.h \
- cp-usb-async.c \
- cp-usb-async.h
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "ccdbg-debug.h"
-#include "cc-bitbang.h"
-
-#include "cp-usb-async.h"
-
-struct cc_bitbang {
- struct cp_usb_async *cp_async;
-};
-
-static uint32_t cc_clock_us = CC_CLOCK_US;
-static uint32_t cc_reset_us = CC_RESET_US;
-
-void
-cc_bitbang_set_clock(uint32_t us)
-{
- cc_clock_us = us;
-}
-
-void
-cc_bitbang_half_clock(struct cc_bitbang *bb)
-{
- struct timespec req, rem;
- req.tv_sec = (cc_clock_us / 2) / 1000000;
- req.tv_nsec = ((cc_clock_us / 2) % 1000000) * 1000;
- nanosleep(&req, &rem);
-}
-
-void
-cc_bitbang_wait_reset(struct cc_bitbang *bb)
-{
- struct timespec req, rem;
-
- cc_bitbang_sync(bb);
- req.tv_sec = (cc_reset_us) / 1000000;
- req.tv_nsec = ((cc_reset_us) % 1000000) * 1000;
- nanosleep(&req, &rem);
-}
-
-struct cc_bitbang *
-cc_bitbang_open(void)
-{
- struct cc_bitbang *bb;
-
- bb = calloc(sizeof (struct cc_bitbang), 1);
- if (!bb) {
- perror("calloc");
- return NULL;
- }
- bb->cp_async = cp_usb_async_open();
- if (!bb->cp_async) {
- free (bb);
- return NULL;
- }
- return bb;
-}
-
-void
-cc_bitbang_close(struct cc_bitbang *bb)
-{
- cp_usb_async_close(bb->cp_async);
- free (bb);
-}
-
-void
-cc_bitbang_debug_mode(struct cc_bitbang *bb)
-{
- /* force two rising clocks while holding RESET_N low */
- ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
- ccdbg_debug(CC_DEBUG_COMMAND, "# Debug mode\n");
- ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA );
- cc_bitbang_wait_reset(bb);
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA );
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N);
- cc_bitbang_wait_reset(bb);
-}
-
-void
-cc_bitbang_reset(struct cc_bitbang *bb)
-{
- ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
- ccdbg_debug(CC_DEBUG_COMMAND, "# Reset\n");
- ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
- cc_bitbang_wait_reset(bb);
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA );
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
- cc_bitbang_wait_reset(bb);
-}
-
-int
-cc_bitbang_write(struct cc_bitbang *bb, uint8_t mask, uint8_t value)
-{
- cp_usb_async_write(bb->cp_async, mask, value);
- return 0;
-}
-
-void
-cc_bitbang_read(struct cc_bitbang *bb, uint8_t *valuep)
-{
- cp_usb_async_read(bb->cp_async, valuep);
-}
-
-void
-cc_bitbang_sync(struct cc_bitbang *bb)
-{
- cp_usb_async_sync(bb->cp_async);
-}
-
-static char
-is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit)
-{
- if (mask&bit) {
- if (get&bit)
- return on;
- else
- return '.';
- } else
- return '-';
-}
-
-void
-cc_bitbang_print(char *format, uint8_t mask, uint8_t set)
-{
- ccdbg_debug (CC_DEBUG_BITBANG, format,
- is_bit(set, mask, 'C', CC_CLOCK),
- is_bit(set, mask, 'D', CC_DATA),
- is_bit(set, mask, 'R', CC_RESET_N));
-}
-
-void
-cc_bitbang_send(struct cc_bitbang *bb, uint8_t mask, uint8_t set)
-{
- cc_bitbang_write(bb, mask, set);
- cc_bitbang_print("%c %c %c\n", mask, set);
- cc_bitbang_half_clock(bb);
-}
-
-void
-cc_bitbang_send_bit(struct cc_bitbang *bb, uint8_t bit)
-{
- if (bit) bit = CC_DATA;
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|bit|CC_RESET_N);
- cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, bit|CC_RESET_N);
-}
-
-void
-cc_bitbang_send_byte(struct cc_bitbang *bb, uint8_t byte)
-{
- int bit;
- ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Send Byte 0x%02x\n#\n", byte);
- for (bit = 7; bit >= 0; bit--) {
- cc_bitbang_send_bit(bb, (byte >> bit) & 1);
- if (bit == 3)
- ccdbg_debug(CC_DEBUG_BITBANG, "\n");
- }
- cc_bitbang_sync(bb);
-}
-
-void
-cc_bitbang_send_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes)
-{
- while (nbytes--)
- cc_bitbang_send_byte(bb, *bytes++);
-}
-
-void
-cc_bitbang_recv_bit(struct cc_bitbang *bb, int first, uint8_t *bit)
-{
- uint8_t mask = first ? CC_DATA : 0;
-
- cc_bitbang_send(bb, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
- cc_bitbang_read(bb, bit);
- cc_bitbang_send(bb, CC_CLOCK| CC_RESET_N, CC_RESET_N);
-}
-
-void
-cc_bitbang_recv_byte(struct cc_bitbang *bb, int first, uint8_t *bytep)
-{
- uint8_t byte = 0;
- uint8_t bits[8];
- int bit;
-
- ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n");
- for (bit = 0; bit < 8; bit++) {
- cc_bitbang_recv_bit(bb, first, &bits[bit]);
- first = 0;
- }
- cc_bitbang_sync(bb);
- for (bit = 0; bit < 8; bit++) {
- byte = byte << 1;
- byte |= (bits[bit] & CC_DATA) ? 1 : 0;
- cc_bitbang_print("#\t%c %c %c\n", CC_DATA, bits[bit]);
- if (bit == 3)
- ccdbg_debug(CC_DEBUG_BITBANG, "\n");
- }
- ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte);
- *bytep = byte;
-}
-
-void
-cc_bitbang_recv_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes)
-{
- int i;
- int first = 1;
- for (i = 0; i < nbytes; i++) {
- cc_bitbang_recv_byte(bb, first, &bytes[i]);
- first = 0;
- }
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef _CC_BITBANG_H_
-#define _CC_BITBANG_H_
-
-#include <stdint.h>
-
-#define CC_CLOCK 0x1
-#define CC_DATA 0x2
-#define CC_RESET_N 0x4
-#define CC_CLOCK_US (2)
-
-/* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground
- * and a 2.7k resistor to the reset line. This takes about 6us
- * to settle, so we'll wait longer than that after changing the reset line
- */
-#define CC_RESET_US (12)
-
-struct cc_bitbang;
-
-void
-cc_bitbang_set_clock(uint32_t us);
-
-void
-cc_bitbang_half_clock(struct cc_bitbang *bb);
-
-void
-cc_bitbang_wait_reset(struct cc_bitbang *bb);
-
-struct cc_bitbang *
-cc_bitbang_open(void);
-
-void
-cc_bitbang_close(struct cc_bitbang *bb);
-
-void
-cc_bitbang_debug_mode(struct cc_bitbang *bb);
-
-void
-cc_bitbang_reset(struct cc_bitbang *bb);
-
-int
-cc_bitbang_write(struct cc_bitbang *bb, uint8_t mask, uint8_t value);
-
-void
-cc_bitbang_read(struct cc_bitbang *bb, uint8_t *valuep);
-
-void
-cc_bitbang_sync(struct cc_bitbang *bb);
-
-void
-cc_bitbang_print(char *format, uint8_t mask, uint8_t set);
-
-void
-cc_bitbang_print(char *format, uint8_t mask, uint8_t set);
-
-void
-cc_bitbang_send(struct cc_bitbang *bb, uint8_t mask, uint8_t set);
-
-void
-cc_bitbang_send_bit(struct cc_bitbang *bb, uint8_t bit);
-
-void
-cc_bitbang_send_byte(struct cc_bitbang *bb, uint8_t byte);
-
-void
-cc_bitbang_send_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes);
-
-void
-cc_bitbang_recv_bit(struct cc_bitbang *bb, int first, uint8_t *bit);
-
-void
-cc_bitbang_recv_byte(struct cc_bitbang *bb, int first, uint8_t *bytep);
-
-void
-cc_bitbang_recv_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes);
-
-#endif /* _CC_BITBANG_H_ */
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <poll.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <termios.h>
-#include "ccdbg-debug.h"
-#include "cc-usb.h"
-
-
-#define CC_NUM_READ 16
-/*
- * AltOS has different buffer sizes for in/out packets
- */
-#define CC_IN_BUF 256
-#define CC_OUT_BUF 64
-#define DEFAULT_TTY "/dev/ttyACM0"
-
-struct cc_read {
- uint8_t *buf;
- int len;
-};
-
-struct cc_usb {
- int fd;
- uint8_t in_buf[CC_IN_BUF];
- int in_count;
- uint8_t out_buf[CC_OUT_BUF];
- int out_count;
- struct cc_read read_buf[CC_NUM_READ];
- int read_count;
-};
-
-#define NOT_HEX 0xff
-
-static uint8_t
-cc_hex_nibble(uint8_t c)
-{
- if ('0' <= c && c <= '9')
- return c - '0';
- if ('a' <= c && c <= 'f')
- return c - 'a' + 10;
- if ('A' <= c && c <= 'F')
- return c - 'A' + 10;
- return NOT_HEX;
-}
-
-/*
- * Take raw input bytes, parse them as hex
- * and write them to the waiting buffer
- */
-static void
-cc_handle_in(struct cc_usb *cc)
-{
- uint8_t h, l;
- int in_pos;
- int read_pos;
-
- in_pos = 0;
- read_pos = 0;
- while (read_pos < cc->read_count && in_pos < cc->in_count) {
- /*
- * Skip to next hex character
- */
- while (in_pos < cc->in_count &&
- cc_hex_nibble(cc->in_buf[in_pos]) == NOT_HEX)
- in_pos++;
- /*
- * Make sure we have two characters left
- */
- if (cc->in_count - in_pos < 2)
- break;
- /*
- * Parse hex number
- */
- h = cc_hex_nibble(cc->in_buf[in_pos]);
- l = cc_hex_nibble(cc->in_buf[in_pos+1]);
- if (h == NOT_HEX || l == NOT_HEX) {
- fprintf(stderr, "hex read error\n");
- break;
- }
- in_pos += 2;
- /*
- * Store hex number
- */
- *cc->read_buf[read_pos].buf++ = (h << 4) | l;
- if (--cc->read_buf[read_pos].len <= 0)
- read_pos++;
- }
-
- /* Move remaining bytes to the start of the input buffer */
- if (in_pos) {
- memmove(cc->in_buf, cc->in_buf + in_pos,
- cc->in_count - in_pos);
- cc->in_count -= in_pos;
- }
-
- /* Move pending reads to the start of the array */
- if (read_pos) {
- memmove(cc->read_buf, cc->read_buf + read_pos,
- (cc->read_count - read_pos) * sizeof (cc->read_buf[0]));
- cc->read_count -= read_pos;
- }
-
- /* Once we're done reading, flush any pending input */
- if (cc->read_count == 0)
- cc->in_count = 0;
-}
-
-static void
-cc_usb_dbg(int indent, uint8_t *bytes, int len)
-{
- int eol = 1;
- int i;
- uint8_t c;
- while (len--) {
- c = *bytes++;
- if (eol) {
- for (i = 0; i < indent; i++)
- ccdbg_debug(CC_DEBUG_BITBANG, " ");
- eol = 0;
- }
- switch (c) {
- case '\r':
- ccdbg_debug(CC_DEBUG_BITBANG, "^M");
- break;
- case '\n':
- eol = 1;
- default:
- ccdbg_debug(CC_DEBUG_BITBANG, "%c", c);
- }
- }
-}
-
-/*
- * Flush pending writes, fill pending reads
- */
-void
-cc_usb_sync(struct cc_usb *cc)
-{
- int ret;
- struct pollfd fds;
- int timeout;
-
- fds.fd = cc->fd;
- for (;;) {
- if (cc->read_count || cc->out_count)
- timeout = -1;
- else
- timeout = 0;
- fds.events = 0;
- if (cc->in_count < CC_IN_BUF)
- fds.events |= POLLIN;
- if (cc->out_count)
- fds.events |= POLLOUT;
- ret = poll(&fds, 1, timeout);
- if (ret == 0)
- break;
- if (ret < 0) {
- perror("poll");
- break;
- }
- if (fds.revents & POLLIN) {
- ret = read(cc->fd, cc->in_buf + cc->in_count,
- CC_IN_BUF - cc->in_count);
- if (ret > 0) {
- cc_usb_dbg(24, cc->in_buf + cc->in_count, ret);
- cc->in_count += ret;
- cc_handle_in(cc);
- } else if (ret < 0)
- perror("read");
- }
- if (fds.revents & POLLOUT) {
- ret = write(cc->fd, cc->out_buf,
- cc->out_count);
- if (ret > 0) {
- cc_usb_dbg(0, cc->out_buf, ret);
- memmove(cc->out_buf,
- cc->out_buf + ret,
- cc->out_count - ret);
- cc->out_count -= ret;
- } else if (ret < 0)
- perror("write");
- }
- }
-}
-
-void
-cc_usb_printf(struct cc_usb *cc, char *format, ...)
-{
- char buf[1024], *b;
- va_list ap;
- int ret, this_time;
-
- /* sprintf to a local buffer */
- va_start(ap, format);
- ret = vsnprintf(buf, sizeof(buf), format, ap);
- va_end(ap);
- if (ret > sizeof(buf)) {
- fprintf(stderr, "printf overflow for format %s\n",
- format);
- }
-
- /* flush local buffer to the wire */
- b = buf;
- while (ret > 0) {
- this_time = ret;
- if (this_time > CC_OUT_BUF - cc->out_count)
- this_time = CC_OUT_BUF - cc->out_count;
- memcpy(cc->out_buf + cc->out_count, b, this_time);
- cc->out_count += this_time;
- ret -= this_time;
- b += this_time;
- while (cc->out_count >= CC_OUT_BUF)
- cc_usb_sync(cc);
- }
-}
-
-int
-cc_usb_send_bytes(struct cc_usb *cc, uint8_t *bytes, int len)
-{
- int this_len;
- int ret = len;
-
- while (len) {
- this_len = len;
- if (this_len > 8)
- this_len = 8;
- len -= this_len;
- cc_usb_printf(cc, "P");
- while (this_len--)
- cc_usb_printf (cc, " %02x", (*bytes++) & 0xff);
- cc_usb_printf(cc, "\n");
- }
- return ret;
-}
-
-void
-cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len)
-{
- struct cc_read *read_buf;
- while (cc->read_count >= CC_NUM_READ)
- cc_usb_sync(cc);
- read_buf = &cc->read_buf[cc->read_count++];
- read_buf->buf = buf;
- read_buf->len = len;
-}
-
-int
-cc_usb_recv_bytes(struct cc_usb *cc, uint8_t *buf, int len)
-{
- cc_queue_read(cc, buf, len);
- cc_usb_printf(cc, "G %x\n", len);
- return len;
-}
-
-int
-cc_usb_write_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len)
-{
- cc_usb_printf(cc, "O %x %x\n", len, addr);
- while (len--)
- cc_usb_printf(cc, "%02x", *bytes++);
- cc_usb_sync(cc);
- return 0;
-}
-
-int
-cc_usb_read_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len)
-{
- int i;
- cc_queue_read(cc, bytes, len);
- cc_usb_printf(cc, "I %x %x\n", len, addr);
- cc_usb_sync(cc);
- for (i = 0; i < len; i++) {
- if ((i & 15) == 0) {
- if (i)
- ccdbg_debug(CC_DEBUG_MEMORY, "\n");
- ccdbg_debug(CC_DEBUG_MEMORY, "\t%04x", addr + i);
- }
- ccdbg_debug(CC_DEBUG_MEMORY, " %02x", bytes[i]);
- }
- ccdbg_debug(CC_DEBUG_MEMORY, "\n");
- return 0;
-}
-
-int
-cc_usb_debug_mode(struct cc_usb *cc)
-{
- cc_usb_sync(cc);
- cc_usb_printf(cc, "D\n");
- return 1;
-}
-
-int
-cc_usb_reset(struct cc_usb *cc)
-{
- cc_usb_sync(cc);
- cc_usb_printf(cc, "R\n");
- return 1;
-}
-
-static struct termios save_termios;
-
-struct cc_usb *
-cc_usb_open(char *tty)
-{
- struct cc_usb *cc;
- struct termios termios;
-
- if (!tty)
- tty = DEFAULT_TTY;
- cc = calloc (sizeof (struct cc_usb), 1);
- if (!cc)
- return NULL;
- cc->fd = open(tty, O_RDWR | O_NONBLOCK);
- if (cc->fd < 0) {
- perror(tty);
- free (cc);
- return NULL;
- }
- tcgetattr(cc->fd, &termios);
- save_termios = termios;
- cfmakeraw(&termios);
- tcsetattr(cc->fd, TCSAFLUSH, &termios);
- cc_usb_printf(cc, "E 0\nm 0\n");
- cc_usb_sync(cc);
- sleep(1);
- cc_usb_sync(cc);
- return cc;
-}
-
-void
-cc_usb_close(struct cc_usb *cc)
-{
- tcsetattr(cc->fd, TCSAFLUSH, &save_termios);
- close (cc->fd);
- free (cc);
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef _CC_USB_H_
-#define _CC_USB_H_
-
-#include <stdint.h>
-
-struct cc_usb;
-
-struct cc_usb *
-cc_usb_open(char *tty);
-
-void
-cc_usb_close(struct cc_usb *cc);
-
-int
-cc_usb_send_bytes(struct cc_usb *cc, uint8_t *bytes, int len);
-
-int
-cc_usb_recv_bytes(struct cc_usb *cc, uint8_t *bytes, int len);
-
-int
-cc_usb_write_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len);
-
-int
-cc_usb_read_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len);
-
-int
-cc_usb_debug_mode(struct cc_usb *cc);
-
-int
-cc_usb_reset(struct cc_usb *cc);
-
-void
-cc_usb_sync(struct cc_usb *cc);
-
-void
-cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len);
-
-void
-cc_usb_printf(struct cc_usb *cc, char *format, ...);
-
-#endif /* _CC_USB_H_ */
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-
-uint8_t
-ccdbg_chip_erase(struct ccdbg *dbg)
-{
- return ccdbg_cmd_write_read8(dbg, CC_CHIP_ERASE, NULL, 0);
-}
-
-uint8_t
-ccdbg_wr_config(struct ccdbg *dbg, uint8_t config)
-{
- return ccdbg_cmd_write_read8(dbg, CC_WR_CONFIG, &config, 1);
-}
-
-uint8_t
-ccdbg_rd_config(struct ccdbg *dbg)
-{
- return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0);
-}
-
-uint16_t
-ccdbg_get_pc(struct ccdbg *dbg)
-{
- uint16_t pc1, pc2;
-
- pc1 = ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0);
- pc2 = ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0);
- if (pc1 != pc2)
- fprintf (stderr, "Invalid pc %04x != %04x\n",
- pc1, pc2);
- return pc2;
-}
-
-uint8_t
-ccdbg_read_status(struct ccdbg *dbg)
-{
- return ccdbg_cmd_write_read8(dbg, CC_READ_STATUS, NULL, 0);
-}
-
-uint8_t
-ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr)
-{
- uint8_t data[3];
-
- data[0] = (number << 3) | (enable << 2);
- data[1] = (addr >> 8);
- data[2] = addr;
- return ccdbg_cmd_write_read8(dbg, CC_SET_HW_BRKPNT, data, 3);
-}
-
-uint8_t
-ccdbg_halt(struct ccdbg *dbg)
-{
- return ccdbg_cmd_write_read8(dbg, CC_HALT, NULL, 0);
-}
-
-uint8_t
-ccdbg_resume(struct ccdbg *dbg)
-{
- return ccdbg_cmd_write_read8(dbg, CC_RESUME, NULL, 0);
-}
-
-uint8_t
-ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes)
-{
- return ccdbg_cmd_write_read8(dbg, CC_DEBUG_INSTR(nbytes), instr, nbytes);
-}
-
-void
-ccdbg_debug_instr_discard(struct ccdbg *dbg, uint8_t *instr, int nbytes)
-{
- static uint8_t discard;
- ccdbg_cmd_write_queue8(dbg, CC_DEBUG_INSTR(nbytes),
- instr, nbytes, &discard);
-}
-
-void
-ccdbg_debug_instr_queue(struct ccdbg *dbg, uint8_t *instr, int nbytes,
- uint8_t *reply)
-{
- return ccdbg_cmd_write_queue8(dbg, CC_DEBUG_INSTR(nbytes),
- instr, nbytes, reply);
-}
-
-uint8_t
-ccdbg_step_instr(struct ccdbg *dbg)
-{
- return ccdbg_cmd_write_read8(dbg, CC_STEP_INSTR, NULL, 0);
-}
-
-uint8_t
-ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes)
-{
- return ccdbg_cmd_write_read8(dbg, CC_STEP_REPLACE(nbytes), instr, nbytes);
-}
-
-uint16_t
-ccdbg_get_chip_id(struct ccdbg *dbg)
-{
- return ccdbg_cmd_write_read16(dbg, CC_GET_CHIP_ID, NULL, 0);
-}
-
-/*
- * Execute a sequence of instructions
- */
-uint8_t
-ccdbg_execute(struct ccdbg *dbg, uint8_t *inst)
-{
- uint8_t status = 0;
- while(inst[0] != 0) {
- uint8_t len = inst[0];
- int i;
- ccdbg_debug(CC_DEBUG_INSTRUCTIONS, "\t%02x", inst[1]);
- for (i = 0; i < len - 1; i++)
- ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " %02x", inst[i+2]);
- ccdbg_debug_instr_queue(dbg, inst+1, len, &status);
- for (; i < 3; i++)
- ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " ");
- ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " -> %02x\n", status);
- inst += len + 1;
- }
- ccdbg_sync(dbg);
- return status;
-}
-
-static uint8_t jump_mem[] = {
- 3, LJMP, 0xf0, 0x00,
-#define PC_HIGH 2
-#define PC_LOW 3
- 0
-};
-
-uint8_t
-ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc)
-{
- jump_mem[PC_HIGH] = pc >> 8;
- jump_mem[PC_LOW] = pc & 0xff;
- return ccdbg_execute(dbg, jump_mem);
-}
-
-uint8_t
-ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image)
-{
- uint16_t pc;
- uint8_t status;
-
- if (image->address < 0xf000) {
- fprintf(stderr, "Cannot execute program starting at 0x%04x\n", image->address);
- return -1;
- }
- ccdbg_write_hex_image(dbg, image, 0);
- ccdbg_set_pc(dbg, image->address);
- pc = ccdbg_get_pc(dbg);
- ccdbg_debug(CC_DEBUG_EXECUTE, "pc starts at 0x%04x\n", pc);
- status = ccdbg_resume(dbg);
- ccdbg_debug(CC_DEBUG_EXECUTE, "resume status: 0x%02x\n", status);
- return 0;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-#include <stdarg.h>
-
-int
-ccdbg_level = 0;
-
-void
-ccdbg_add_debug(int level)
-{
- ccdbg_level |= level;
-}
-
-void
-ccdbg_clear_debug(int level)
-{
- ccdbg_level &= ~level;
-}
-
-static int initialized;
-
-void
-ccdbg_debug(int level, char *format, ...)
-{
- va_list ap;
-
- if (!initialized) {
- char *level;
- initialized = 1;
- level = getenv("CCDEBUG");
- if (level)
- ccdbg_level |= strtoul(level, NULL, 0);
- }
- if (ccdbg_level & level) {
- va_start(ap, format);
- vprintf(format, ap);
- va_end(ap);
- }
-}
-
-void
-ccdbg_flush(int level)
-{
- if (ccdbg_level & level)
- fflush(stdout);
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef _CCDBG_DEBUG_H_
-#define _CCDBG_DEBUG_H_
-/* Debug levels
- */
-#define CC_DEBUG_BITBANG 0x00000001
-#define CC_DEBUG_COMMAND 0x00000002
-#define CC_DEBUG_INSTRUCTIONS 0x00000004
-#define CC_DEBUG_EXECUTE 0x00000008
-#define CC_DEBUG_FLASH 0x00000010
-#define CC_DEBUG_MEMORY 0x00000020
-#define CC_DEBUG_USB_ASYNC 0x00000040
-
-/* ccdbg-debug.c */
-void
-ccdbg_debug(int level, char *format, ...);
-
-void
-ccdbg_add_debug(int level);
-
-void
-ccdbg_clear_debug(int level);
-
-void
-ccdbg_flush(int level);
-
-#endif /* _CCDBG_DEBUG_H_ */
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-
-/* From SWRA124 section 3.1.6 */
-
-static uint8_t flash_page[] = {
-
- MOV_direct_data, P1DIR, 0x02,
- MOV_direct_data, P1, 0xFF,
-
- MOV_direct_data, FADDRH, 0,
-#define FLASH_ADDR_HIGH 8
-
- MOV_direct_data, FADDRL, 0,
-#define FLASH_ADDR_LOW 11
-
- MOV_DPTR_data16, 0, 0,
-#define RAM_ADDR_HIGH 13
-#define RAM_ADDR_LOW 14
-
- MOV_Rn_data(7), 0,
-#define FLASH_WORDS_HIGH 16
-
- MOV_Rn_data(6), 0,
-#define FLASH_WORDS_LOW 18
-
- MOV_direct_data, FWT, 0x20,
-#define FLASH_TIMING 21
-
- MOV_direct_data, FCTL, FCTL_ERASE,
-/* eraseWaitLoop: */
- MOV_A_direct, FCTL,
- JB, ACC(FCTL_BUSY_BIT), 0xfb,
-
- MOV_direct_data, P1, 0xfd,
-
- MOV_direct_data, FCTL, FCTL_WRITE,
-/* writeLoop: */
- MOV_Rn_data(5), 2,
-/* writeWordLoop: */
- MOVX_A_atDPTR,
- INC_DPTR,
- MOV_direct_A, FWDATA,
- DJNZ_Rn_rel(5), 0xfa, /* writeWordLoop */
-/* writeWaitLoop: */
- MOV_A_direct, FCTL,
- JB, ACC(FCTL_SWBSY_BIT), 0xfb, /* writeWaitLoop */
- DJNZ_Rn_rel(6), 0xf1, /* writeLoop */
- DJNZ_Rn_rel(7), 0xef, /* writeLoop */
-
- MOV_direct_data, P1DIR, 0x00,
- MOV_direct_data, P1, 0xFF,
- TRAP,
-};
-
-#define FLASH_RAM 0xf000
-
-#if 0
-static uint8_t flash_erase_page[] = {
- 3, MOV_direct_data, FADDRH, 0,
-#define ERASE_PAGE_HIGH 3
-
- 3, MOV_direct_data, FADDRL, 0,
-#define ERASE_PAGE_LOW 7
-
- 3, MOV_direct_data, FWT, 0x2A,
- 3, MOV_direct_data, FCTL, FCTL_ERASE,
- 0
-};
-
-static uint8_t flash_read_control[] = {
- 2, MOV_A_direct, FCTL,
- 0
-};
-#endif
-
-#if 0
-static uint8_t flash_control_clear[] = {
- 3, MOV_direct_data, FCTL, 0,
- 2, MOV_A_direct, FCTL,
- 0
-};
-#endif
-
-#if 0
-static uint8_t
-ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr)
-{
- uint16_t page_addr = addr >> 1;
- uint8_t status;
- uint8_t old[0x10], new[0x10];
- int i;
-
- ccdbg_read_memory(dbg, addr, old, 0x10);
- flash_erase_page[ERASE_PAGE_HIGH] = page_addr >> 8;
- flash_erase_page[ERASE_PAGE_LOW] = page_addr & 0xff;
- status = ccdbg_execute(dbg, flash_erase_page);
- ccdbg_debug(CC_DEBUG_FLASH, "erase status 0x%02x\n", status);
- do {
- status = ccdbg_execute(dbg, flash_read_control);
- ccdbg_debug(CC_DEBUG_FLASH, "fctl 0x%02x\n", status);
- } while (status & FCTL_BUSY);
- ccdbg_read_memory(dbg, addr, new, 0x10);
- for (i = 0; i < 0x10; i++)
- ccdbg_debug(CC_DEBUG_FLASH, "0x%02x -> 0x%02x\n", old[i], new[i]);
- status = ccdbg_execute(dbg, flash_control_clear);
- ccdbg_debug(CC_DEBUG_FLASH, "clear fctl 0x%02x\n", status);
- return 0;
-}
-#endif
-
-#if 0
-static uint8_t flash_write[] = {
- MOV_direct_data, P1DIR, 0x02,
- MOV_direct_data, P1, 0xFD,
-
- MOV_A_direct, FCTL,
- JB, ACC(FCTL_BUSY_BIT), 0xf1,
-
- MOV_direct_data, FCTL, 0x20,
-
- MOV_direct_data, FADDRH, 0,
-#define WRITE_PAGE_HIGH 16
-
- MOV_direct_data, FADDRL, 0,
-#define WRITE_PAGE_LOW 19
-
- MOV_direct_data, FCTL, FCTL_WRITE,
- MOV_direct_data, FWDATA, 0,
-#define WRITE_BYTE_0 25
- MOV_direct_data, FWDATA, 0,
-#define WRITE_BYTE_1 28
- MOV_A_direct, FCTL,
- JB, ACC(FCTL_SWBSY_BIT), 0xf1,
-
- MOV_direct_data, P1, 0xFF,
- TRAP,
-};
-#endif
-
-static uint8_t
-ccdbg_clock_init(struct ccdbg *dbg)
-{
- static uint8_t set_clkcon_fast[] = {
- 3, MOV_direct_data, CLKCON, 0x00,
- 0
- };
-
- static uint8_t get_sleep[] = {
- 2, MOV_A_direct, SLEEP,
- 0
- };
-
- uint8_t status;
-
- ccdbg_execute(dbg, set_clkcon_fast);
- do {
- status = ccdbg_execute(dbg, get_sleep);
- } while (!(status & 0x40));
- return 0;
-}
-
-#if 0
-static uint8_t
-ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2])
-{
- uint16_t page_addr = addr >> 1;
- uint8_t check[2];
- uint8_t status;
- int i;
-
- flash_write[WRITE_PAGE_HIGH] = page_addr >> 8;
- flash_write[WRITE_PAGE_LOW] = page_addr & 0xff;
- flash_write[WRITE_BYTE_0] = data[0];
- flash_write[WRITE_BYTE_1] = data[1];
- ccdbg_debug(CC_DEBUG_FLASH, "upload flash write\n");
- ccdbg_write_memory(dbg, 0xf000, flash_write, sizeof(flash_write));
- ccdbg_set_pc(dbg, 0xf000);
- ccdbg_resume(dbg);
- for (;;) {
- status = ccdbg_read_status(dbg);
- ccdbg_debug(CC_DEBUG_FLASH, "waiting for write 0x%02x\n", status);
- if ((status & CC_STATUS_CPU_HALTED) != 0)
- break;
- sleep (1);
- }
- status = ccdbg_execute(dbg, flash_control_clear);
- ccdbg_debug(CC_DEBUG_FLASH, "clear fctl 0x%02x\n", status);
- ccdbg_read_memory(dbg, addr, check, 2);
- for (i = 0; i < 2; i++)
- ccdbg_debug(CC_DEBUG_FLASH, "0x%02x : 0x%02x\n", data[i], check[i]);
- return 0;
-}
-#endif
-
-#define TIMERS_OFF 0x08
-#define DMA_PAUSE 0x04
-#define TIMER_SUSPEND 0x02
-#define SEL_FLASH_INFO_PAGE 0x01
-
-#if 0
-static uint8_t
-ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock)
-{
- uint8_t config;
- uint8_t bytes[2];
- uint8_t old[1], new[1];
-
- config = ccdbg_rd_config(dbg);
- ccdbg_wr_config(dbg, config|SEL_FLASH_INFO_PAGE);
- bytes[0] = lock;
- bytes[1] = 0;
- ccdbg_flash_erase_page(dbg, 0);
- ccdbg_read_memory(dbg, 0, old, 1);
- ccdbg_flash_write_word(dbg, 0, bytes);
- ccdbg_read_memory(dbg, 0, new, 1);
- ccdbg_debug(CC_DEBUG_FLASH, "flash lock 0x%02x -> 0x%02x\n", old[0], new[0]);
- ccdbg_wr_config(dbg, config & ~SEL_FLASH_INFO_PAGE);
- return 0;
-}
-#endif
-
-uint8_t
-ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)
-{
- uint16_t offset;
- uint16_t flash_prog;
- uint16_t flash_len;
- uint8_t fwt;
- uint16_t flash_addr;
- uint16_t flash_word_addr;
- uint16_t flash_words;
- uint8_t flash_words_high, flash_words_low;
- uint16_t ram_addr;
- uint16_t pc;
- uint8_t status;
- uint16_t remain, this_time, start;
- uint8_t verify[0x400];
- int times;
-
- ccdbg_clock_init(dbg);
- if (image->address + image->length > 0x8000) {
- fprintf(stderr, "cannot flash image from 0x%04x to 0x%04x\n",
- image->address, image->address + image->length);
- return 1;
- }
- if (image->address & 0x3ff) {
- fprintf(stderr, "flash image must start on page boundary\n");
- return 1;
- }
- ram_addr = 0xf000;
-
-
- flash_prog = 0xf400;
-
- fwt = 0x20;
-
- flash_page[FLASH_TIMING] = fwt;
- ccdbg_debug(CC_DEBUG_FLASH, "Upload %d flash program bytes to 0x%04x\n",
- sizeof (flash_page), flash_prog);
- ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page));
-
- remain = image->length;
- start = 0;
- while (remain) {
- this_time = remain;
- if (this_time > 0x400)
- this_time = 0x400;
-
- offset = ram_addr - (image->address + start);
-
- ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr);
- ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time);
-#if 0
- ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in ram\n", this_time);
- ccdbg_read_memory(dbg, ram_addr, verify, this_time);
- if (memcmp (image->data + start, verify, this_time) != 0) {
- fprintf(stderr, "ram verify failed\n");
- return 1;
- }
-#endif
-
- flash_addr = image->address + start;
- flash_word_addr = flash_addr >> 1;
- flash_len = this_time + (this_time & 1);
- flash_words = flash_len >> 1;
-
- flash_words_low = flash_words & 0xff;
- flash_words_high = flash_words >> 8;
-
- /* The flash code above is lame */
- if (flash_words_low)
- flash_words_high++;
-
- ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_HIGH, flash_word_addr >> 8);
- ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_LOW, flash_word_addr & 0xff);
-
- ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_HIGH, ram_addr >> 8);
- ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_LOW, ram_addr & 0xff);
-
- ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words_high);
- ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words_low);
-
- ccdbg_set_pc(dbg, flash_prog);
- pc = ccdbg_get_pc(dbg);
- ccdbg_debug(CC_DEBUG_FLASH, "Flashing %d bytes at 0x%04x\n",
- this_time, flash_addr);
- status = ccdbg_resume(dbg);
- for (times = 0; times < 10; times++) {
- status = ccdbg_read_status(dbg);
- ccdbg_debug(CC_DEBUG_FLASH, ".");
- ccdbg_flush(CC_DEBUG_FLASH);
- if ((status & CC_STATUS_CPU_HALTED) != 0)
- break;
- usleep(10000);
- }
- ccdbg_debug(CC_DEBUG_FLASH, "\n");
- if (times == 10) {
- fprintf(stderr, "flash page timed out\n");
- return 1;
- }
-
- ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in flash\n", this_time);
- ccdbg_read_memory(dbg, flash_addr, verify, this_time);
- if (memcmp (image->data + start, verify, this_time) != 0) {
- int i;
- fprintf(stderr, "flash verify failed\n");
- for (i = 0; i < this_time; i++) {
- if (image->data[start + i] != verify[i])
- fprintf(stderr, "0x%04x: 0x%02x != 0x%02x\n",
- start + i, image->data[start+i], verify[i]);
- }
- return 1;
- }
- remain -= this_time;
- start += this_time;
- }
- return 0;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-#include <stdarg.h>
-#include <ctype.h>
-
-struct hex_input {
- FILE *file;
- int line;
- char *name;
-};
-
-enum hex_read_state {
- read_marker,
- read_length,
- read_address,
- read_type,
- read_data,
- read_checksum,
- read_newline,
- read_white,
- read_done,
-};
-
-
-static void
-ccdbg_hex_error(struct hex_input *input, char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- fprintf(stderr, "Hex error %s:%d: ", input->name, input->line);
- vfprintf(stderr, format, ap);
- fprintf(stderr, "\n");
- va_end(ap);
-}
-
-static void
-ccdbg_hex_free(struct hex_record *record)
-{
- if (!record) return;
- free(record);
-}
-
-static struct hex_record *
-ccdbg_hex_alloc(uint8_t length)
-{
- struct hex_record *record;
-
- record = calloc(1, sizeof(struct hex_record) + length);
- record->length = length;
- return record;
-}
-
-static int
-ishex(char c)
-{
- return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
-}
-
-static int
-fromhex(char c)
-{
- if (isdigit(c))
- return c - '0';
- if ('a' <= c && c <= 'f')
- return c - 'a' + 10;
- if ('A' <= c && c <= 'F')
- return c - 'A' + 10;
- abort();
- return 0;
-}
-
-static uint8_t
-ccdbg_hex_checksum(struct hex_record *record)
-{
- uint8_t checksum = 0;
- int i;
-
- checksum += record->length;
- checksum += record->address >> 8;
- checksum += record->address & 0xff;
- checksum += record->type;
- for (i = 0; i < record->length; i++)
- checksum += record->data[i];
- return -checksum;
-}
-
-static struct hex_record *
-ccdbg_hex_read_record(struct hex_input *input)
-{
- struct hex_record *record = NULL;
- enum hex_read_state state = read_marker;
- char c;
- int nhexbytes;
- uint32_t hex;
- uint32_t ndata;
- uint8_t checksum;
-
- while (state != read_done) {
- c = getc(input->file);
- if (c == EOF && state != read_white) {
- ccdbg_hex_error(input, "Unexpected EOF");
- goto bail;
- }
- if (c == ' ')
- continue;
- if (c == '\n')
- input->line++;
- switch (state) {
- case read_marker:
- if (c != ':') {
- ccdbg_hex_error(input, "Missing ':'");
- goto bail;
- }
- state = read_length;
- nhexbytes = 2;
- hex = 0;
- break;
- case read_length:
- case read_address:
- case read_type:
- case read_data:
- case read_checksum:
- if (!ishex(c)) {
- ccdbg_hex_error(input, "Non-hex char '%c'",
- c);
- goto bail;
- }
- hex = hex << 4 | fromhex(c);
- --nhexbytes;
- if (nhexbytes != 0)
- break;
-
- switch (state) {
- case read_length:
- record = ccdbg_hex_alloc(hex);
- if (!record) {
- ccdbg_hex_error(input, "Out of memory");
- goto bail;
- }
- state = read_address;
- nhexbytes = 4;
- break;
- case read_address:
- record->address = hex;
- state = read_type;
- nhexbytes = 2;
- break;
- case read_type:
- record->type = hex;
- state = read_data;
- nhexbytes = 2;
- ndata = 0;
- break;
- case read_data:
- record->data[ndata] = hex;
- ndata++;
- nhexbytes = 2;
- break;
- case read_checksum:
- record->checksum = hex;
- state = read_newline;
- break;
- default:
- break;
- }
- if (state == read_data)
- if (ndata == record->length) {
- nhexbytes = 2;
- state = read_checksum;
- }
- hex = 0;
- break;
- case read_newline:
- if (c != '\n' && c != '\r') {
- ccdbg_hex_error(input, "Missing newline");
- goto bail;
- }
- state = read_white;
- break;
- case read_white:
- if (!isspace(c)) {
- if (c == '\n')
- input->line--;
- if (c != EOF)
- ungetc(c, input->file);
- state = read_done;
- }
- break;
- case read_done:
- break;
- }
- }
- checksum = ccdbg_hex_checksum(record);
- if (checksum != record->checksum) {
- ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n",
- record->checksum, checksum);
- goto bail;
- }
- return record;
-
-bail:
- ccdbg_hex_free(record);
- return NULL;
-}
-
-void
-ccdbg_hex_file_free(struct hex_file *hex)
-{
- int i;
-
- if (!hex)
- return;
- for (i = 0; i < hex->nrecord; i++)
- ccdbg_hex_free(hex->records[i]);
- free(hex);
-}
-
-static int
-ccdbg_hex_record_compar(const void *av, const void *bv)
-{
- const struct hex_record *a = *(struct hex_record **) av;
- const struct hex_record *b = *(struct hex_record **) bv;
-
- return (int) a->address - (int) b->address;
-}
-
-struct hex_file *
-ccdbg_hex_file_read(FILE *file, char *name)
-{
- struct hex_input input;
- struct hex_file *hex = NULL, *newhex;
- struct hex_record *record;
- int srecord = 1;
- int done = 0;
-
- hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1);
- input.name = name;
- input.line = 1;
- input.file = file;
- while (!done) {
- record = ccdbg_hex_read_record(&input);
- if (!record)
- goto bail;
- if (hex->nrecord == srecord) {
- srecord *= 2;
- newhex = realloc(hex,
- sizeof (struct hex_file) +
- srecord * sizeof (struct hex_record *));
- if (!newhex)
- goto bail;
- hex = newhex;
- }
- hex->records[hex->nrecord++] = record;
- if (record->type == HEX_RECORD_EOF)
- done = 1;
- }
- /*
- * Sort them into increasing addresses, except for EOF
- */
- qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *),
- ccdbg_hex_record_compar);
- return hex;
-
-bail:
- ccdbg_hex_file_free(hex);
- return NULL;
-}
-
-struct hex_image *
-ccdbg_hex_image_create(struct hex_file *hex)
-{
- struct hex_image *image;
- struct hex_record *first, *last, *record;
- int i;
- uint32_t base, bound;
- uint32_t offset;
- int length;
-
- first = hex->records[0];
- last = hex->records[hex->nrecord - 2]; /* skip EOF */
- base = (uint32_t) first->address;
- bound = (uint32_t) last->address + (uint32_t) last->length;
- length = bound - base;
- image = calloc(sizeof(struct hex_image) + length, 1);
- if (!image)
- return NULL;
- image->address = base;
- image->length = length;
- memset(image->data, 0xff, length);
- for (i = 0; i < hex->nrecord - 1; i++) {
- record = hex->records[i];
- offset = record->address - base;
- memcpy(image->data + offset, record->data, record->length);
- }
- return image;
-}
-
-void
-ccdbg_hex_image_free(struct hex_image *image)
-{
- free(image);
-}
-
-int
-ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b)
-{
- if (a->length != b->length)
- return 0;
- if (memcmp(a->data, b->data, a->length) != 0)
- return 0;
- return 1;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-#include <time.h>
-#include "cc-usb.h"
-#include "cc-bitbang.h"
-
-struct ccdbg *
-ccdbg_open(void)
-{
- struct ccdbg *dbg;
- char *tty;
-
- dbg = calloc(sizeof (struct ccdbg), 1);
- if (!dbg) {
- perror("calloc");
- return NULL;
- }
- tty = getenv("CCDBG_TTY");
- if (!tty || tty[0] == '/')
- dbg->usb = cc_usb_open(tty);
- if (!dbg->usb) {
- dbg->bb = cc_bitbang_open();
- if (!dbg->bb) {
- free(dbg);
- return NULL;
- }
- }
- return dbg;
-}
-
-void
-ccdbg_close(struct ccdbg *dbg)
-{
- if (dbg->usb)
- cc_usb_close(dbg->usb);
- if (dbg->bb)
- cc_bitbang_close(dbg->bb);
- free (dbg);
-}
-
-void
-ccdbg_debug_mode(struct ccdbg *dbg)
-{
- if (dbg->usb)
- cc_usb_debug_mode(dbg->usb);
- else if (dbg->bb)
- cc_bitbang_debug_mode(dbg->bb);
-}
-
-void
-ccdbg_reset(struct ccdbg *dbg)
-{
- if (dbg->usb)
- cc_usb_reset(dbg->usb);
- else if (dbg->bb)
- cc_bitbang_reset(dbg->bb);
-}
-
-void
-ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes)
-{
- if (dbg->usb)
- cc_usb_send_bytes(dbg->usb, bytes, nbytes);
- else if (dbg->bb)
- cc_bitbang_send_bytes(dbg->bb, bytes, nbytes);
-}
-
-void
-ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes)
-{
- if (dbg->usb)
- cc_usb_recv_bytes(dbg->usb, bytes, nbytes);
- else if (dbg->bb)
- cc_bitbang_recv_bytes(dbg->bb, bytes, nbytes);
-}
-
-void
-ccdbg_sync(struct ccdbg *dbg)
-{
- if (dbg->usb)
- cc_usb_sync(dbg->usb);
- else if (dbg->bb)
- cc_bitbang_sync(dbg->bb);
-}
-
-void
-ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
-{
- ccdbg_send_bytes(dbg, &cmd, 1);
- ccdbg_send_bytes(dbg, data, len);
-}
-
-uint8_t
-ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
-{
- uint8_t byte[1];
- ccdbg_cmd_write(dbg, cmd, data, len);
- ccdbg_recv_bytes(dbg, byte, 1);
- ccdbg_sync(dbg);
- return byte[0];
-}
-
-uint16_t
-ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
-{
- uint8_t byte[2];
- ccdbg_cmd_write(dbg, cmd, data, len);
- ccdbg_recv_bytes(dbg, byte, 2);
- ccdbg_sync(dbg);
- return (byte[0] << 8) | byte[1];
-}
-
-void
-ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd,
- uint8_t *data, int len,
- uint8_t *reply)
-{
- ccdbg_cmd_write(dbg, cmd, data, len);
- ccdbg_recv_bytes(dbg, reply, 1);
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-#include "cc-bitbang.h"
-
-/*
- * Manual bit-banging to debug the low level protocol
- */
-
-static void
-get_bit(char *line, int i, char on, uint8_t bit, uint8_t *bits, uint8_t *masks)
-{
- if (line[i] == on) {
- *bits |= bit;
- *masks |= bit;
- return;
- }
- if (line[i] == '.') {
- *masks |= bit;
- return;
- }
- if (line[i] == '-') {
- return;
- }
- fprintf(stderr, "bad line %s\n", line);
- exit (1);
-}
-
-void
-ccdbg_manual(struct ccdbg *dbg, FILE *input)
-{
- char line[80];
- uint8_t set, mask;
-
- if (dbg->bb == NULL) {
- fprintf(stderr, "Must use bitbang API for manual mode\n");
- return;
- }
- while (fgets(line, sizeof line, input)) {
- if (line[0] == '#' || line[0] == '\n') {
- printf ("%s", line);
- continue;
- }
- set = 0;
- mask = 0;
- get_bit(line, 0, 'C', CC_CLOCK, &set, &mask);
- get_bit(line, 2, 'D', CC_DATA, &set, &mask);
- get_bit(line, 4, 'R', CC_RESET_N, &set, &mask);
- if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) {
- uint8_t read;
- cc_bitbang_read(dbg->bb, &read);
- cc_bitbang_sync(dbg->bb);
- cc_bitbang_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read);
- if ((set & CC_CLOCK) == 0)
- printf ("\t%d", (read&CC_DATA) ? 1 : 0);
- printf ("\n");
- }
- cc_bitbang_send(dbg->bb, mask, set);
- cc_bitbang_sync(dbg->bb);
- }
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-
-/*
- * Read and write arbitrary memory through the debug port
- */
-
-static uint8_t memory_init[] = {
- 3, MOV_DPTR_data16, 0, 0,
-#define HIGH_START 2
-#define LOW_START 3
- 0,
-};
-
-
-static uint8_t write8[] = {
- 2, MOV_A_data, 0,
-#define DATA_BYTE 2
- 1, MOVX_atDPTR_A,
- 1, INC_DPTR,
- 0
-};
-
-static uint8_t read8[] = {
- 1, MOVX_A_atDPTR,
- 1, INC_DPTR,
- 0,
-};
-
-uint8_t
-ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
-{
- int i, nl = 0;
- struct ccstate state;
-
- if (dbg->usb)
- return cc_usb_write_memory(dbg->usb, addr, bytes, nbytes);
- ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP);
- memory_init[HIGH_START] = addr >> 8;
- memory_init[LOW_START] = addr;
- (void) ccdbg_execute(dbg, memory_init);
- for (i = 0; i < nbytes; i++) {
- write8[DATA_BYTE] = *bytes++;
- ccdbg_execute(dbg, write8);
- if ((i & 0xf) == 0xf) {
- ccdbg_debug(CC_DEBUG_MEMORY, ".");
- ccdbg_flush(CC_DEBUG_MEMORY);
- nl = 1;
- }
- if ((i & 0xff) == 0xff) {
- ccdbg_debug(CC_DEBUG_MEMORY, "\n");
- nl = 0;
- }
- }
- ccdbg_state_restore(dbg, &state);
- if (nl)
- ccdbg_debug(CC_DEBUG_MEMORY, "\n");
- return 0;
-}
-
-uint8_t
-ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
-{
- int i, nl = 0;
- struct ccstate state;
-
- if (ccdbg_rom_contains(dbg, addr, nbytes)) {
- ccdbg_rom_replace_xmem(dbg, addr, bytes, nbytes);
- return 0;
- }
- if (dbg->usb)
- return cc_usb_read_memory(dbg->usb, addr, bytes, nbytes);
- ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP);
- memory_init[HIGH_START] = addr >> 8;
- memory_init[LOW_START] = addr;
- (void) ccdbg_execute(dbg, memory_init);
- for (i = 0; i < nbytes; i++) {
- *bytes++ = ccdbg_execute(dbg, read8);
- if ((i & 0xf) == 0xf) {
- ccdbg_debug(CC_DEBUG_MEMORY, ".");
- ccdbg_flush(CC_DEBUG_MEMORY);
- nl = 1;
- }
- if ((i & 0xff) == 0xff) {
- ccdbg_debug(CC_DEBUG_MEMORY, "\n");
- nl = 0;
- }
- }
- ccdbg_state_replace_xmem(dbg, &state, addr, bytes, nbytes);
- ccdbg_state_restore(dbg, &state);
- if (nl)
- ccdbg_debug(CC_DEBUG_MEMORY, "\n");
- return 0;
-}
-
-uint8_t
-ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte)
-{
- return ccdbg_write_memory(dbg, addr, &byte, 1);
-}
-
-uint8_t
-ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset)
-{
- ccdbg_write_memory(dbg, image->address + offset, image->data, image->length);
- return 0;
-}
-
-struct hex_image *
-ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length)
-{
- struct hex_image *image;
-
- image = calloc(sizeof(struct hex_image) + length, 1);
- image->address = address;
- image->length = length;
- memset(image->data, 0xff, length);
- ccdbg_read_memory(dbg, address, image->data, length);
- return image;
-}
-
-static uint8_t sfr_read[] = {
- 2, MOV_A_direct, 0,
-#define SFR_READ_ADDR 2
- 0,
-};
-
-static uint8_t sfr_write[] = {
- 3, MOV_direct_data, 0, 0,
-#define SFR_WRITE_ADDR 2
-#define SFR_WRITE_DATA 3
- 0,
-};
-
-uint8_t
-ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes)
-{
- int i;
- struct ccstate state;
-
- ccdbg_state_save(dbg, &state, CC_STATE_ACC);
- for (i = 0; i < nbytes; i++) {
- sfr_read[SFR_READ_ADDR] = addr + i;
- *bytes++ = ccdbg_execute(dbg, sfr_read);
- }
- ccdbg_state_replace_sfr(dbg, &state, addr, bytes, nbytes);
- ccdbg_state_restore(dbg, &state);
- return 0;
-}
-
-uint8_t
-ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes)
-{
- int i;
-
- for (i = 0; i < nbytes; i++) {
- sfr_write[SFR_WRITE_ADDR] = addr + i;
- sfr_write[SFR_WRITE_DATA] = *bytes++;
- ccdbg_execute(dbg, sfr_write);
- }
- return 0;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-
-uint8_t
-ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom)
-{
- if (dbg->rom)
- ccdbg_hex_image_free(dbg->rom);
- dbg->rom = rom;
- return 0;
-}
-
-uint8_t
-ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes)
-{
- struct hex_image *rom = dbg->rom;
- if (!rom)
- return 0;
- if (addr < rom->address || rom->address + rom->length < addr + nbytes)
- return 0;
- return 1;
-}
-
-uint8_t
-ccdbg_rom_replace_xmem(struct ccdbg *dbg,
- uint16_t addr, uint8_t *bytes, int nbytes)
-{
- struct hex_image *rom = dbg->rom;
- if (!rom)
- return 0;
-
- if (rom->address < addr + nbytes && addr < rom->address + rom->length) {
- int start, stop;
-
- start = addr;
- if (addr < rom->address)
- start = rom->address;
- stop = addr + nbytes;
- if (rom->address + rom->length < stop)
- stop = rom->address + rom->length;
- memcpy(bytes + start - addr, rom->data + start - rom->address,
- stop - start);
- return 1;
- }
- return 0;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ccdbg.h"
-
-static uint8_t save_acc[] = {
- 1, NOP,
- 0
-};
-
-static uint8_t save_sfr[] = {
- 2, MOV_A_direct, 0,
-#define SAVE_SFR_ADDR 2
- 0,
-};
-
-struct sfr_state {
- uint8_t address;
- uint16_t mask;
- char *name;
-};
-
-static struct sfr_state sfrs[CC_STATE_NSFR] = {
- { SFR_DPL0, CC_STATE_DP, "dpl0" },
- { SFR_DPH0, CC_STATE_DP, "dph0" },
- { SFR_DPL1, CC_STATE_DP, "dpl1" },
- { SFR_DPH1, CC_STATE_DP, "dph1" },
- { PSW(0), CC_STATE_PSW, "psw" },
-};
-
-uint8_t
-ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask)
-{
- int i;
-
- mask |= CC_STATE_ACC;
- if (mask & CC_STATE_ACC)
- state->acc = ccdbg_execute(dbg, save_acc);
- for (i = 0; i < CC_STATE_NSFR; i++) {
- if (sfrs[i].mask & mask) {
- save_sfr[SAVE_SFR_ADDR] = sfrs[i].address;
- state->sfr[i] = ccdbg_execute(dbg, save_sfr);
- }
- }
- state->mask = mask;
- return 0;
-}
-
-static uint8_t restore_sfr[] = {
- 3, MOV_direct_data, 0, 0,
-#define RESTORE_SFR_ADDR 2
-#define RESTORE_SFR_DATA 3
- 0
-};
-
-static uint8_t restore_acc[] = {
- 2, MOV_A_data, 0,
-#define RESTORE_ACC_DATA 2
- 0
-};
-
-uint8_t
-ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state)
-{
- int i;
- for (i = CC_STATE_NSFR - 1; i >= 0; i--) {
- if (sfrs[i].mask & state->mask) {
- restore_sfr[RESTORE_SFR_ADDR] = sfrs[i].address;
- restore_sfr[RESTORE_SFR_DATA] = state->sfr[i];
- ccdbg_execute(dbg, restore_sfr);
- }
- }
- if (state->mask & CC_STATE_ACC) {
- restore_acc[RESTORE_ACC_DATA] = state->acc;
- ccdbg_execute(dbg, restore_acc);
- }
- state->mask = 0;
- return 0;
-}
-
-static void
-ccdbg_state_replace(uint16_t sfr_addr, uint8_t sfr, char *name,
- uint16_t addr, uint8_t *bytes, int nbytes)
-{
- sfr_addr += 0xdf00;
-
- if (addr <= sfr_addr && sfr_addr < addr + nbytes) {
- fprintf(stderr, "replacing %s at 0x%04x - read 0x%02x saved 0x%02x\n",
- name, sfr_addr, bytes[sfr_addr - addr], sfr);
- bytes[sfr_addr - addr] = sfr;
- }
-}
-
-void
-ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state,
- uint16_t addr, uint8_t *bytes, int nbytes)
-{
- int i;
- if (state->mask & CC_STATE_ACC)
- ccdbg_state_replace(ACC(0), state->acc, "acc",
- addr, bytes, nbytes);
- for (i = 0; i < CC_STATE_NSFR; i++)
- if (state->mask & sfrs[i].mask)
- ccdbg_state_replace(sfrs[i].address, state->sfr[i],
- sfrs[i].name, addr, bytes, nbytes);
-}
-
-void
-ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state,
- uint8_t addr, uint8_t *bytes, int nbytes)
-{
- ccdbg_state_replace_xmem(dbg, state, (uint16_t) addr + 0xdf00, bytes, nbytes);
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef _CCDBG_H_
-#define _CCDBG_H_
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include "ccdbg-debug.h"
-#include "cc-bitbang.h"
-#include "cc-usb.h"
-
-/* 8051 instructions
- */
-#define NOP 0x00
-#define MOV_direct_data 0x75
-#define LJMP 0x02
-#define MOV_Rn_data(n) (0x78 | (n))
-#define DJNZ_Rn_rel(n) (0xd8 | (n))
-#define MOV_A_direct 0xe5
-#define MOV_direct1_direct2 0x85
-#define MOV_direct_A 0xf5
-#define MOV_DPTR_data16 0x90
-#define MOV_A_data 0x74
-#define MOVX_atDPTR_A 0xf0
-#define MOVX_A_atDPTR 0xe0
-#define INC_DPTR 0xa3
-#define TRAP 0xa5
-#define SJMP 0x80
-#define JB 0x20
-
-/* 8051 special function registers
- */
-
-#define SFR_P0 0x80
-#define SFR_SP 0x81
-#define SFR_DPL0 0x82
-#define SFR_DPH0 0x83
-#define SFR_DPL1 0x84
-#define SFR_DPH1 0x85
-
-/* flash controller */
-#define FWT 0xAB
-#define FADDRL 0xAC
-#define FADDRH 0xAD
-#define FCTL 0xAE
-# define FCTL_BUSY 0x80
-# define FCTL_BUSY_BIT 7
-# define FCTL_SWBSY 0x40
-# define FCTL_SWBSY_BIT 6
-# define FCTL_CONTRD 0x10
-# define FCTL_WRITE 0x02
-# define FCTL_ERASE 0x01
-#define FWDATA 0xAF
-
-#define SLEEP 0xBE
-
-/* clock controller */
-#define CLKCON 0xC6
-#define CLKCON_OSC32K 0x80
-#define CLKCON_OSC 0x40
-#define CLKCON_TICKSPD 0x38
-#define CLKCON_CLKSPD 0x07
-
-/* I/O pins */
-#define P0 0x80
-#define P1 0x90
-#define P2 0xA0
-#define P0DIR 0xFD
-#define P1DIR 0xFE
-#define P2DIR 0xFF
-
-/* Bit-addressable accumulator */
-#define ACC(bit) (0xE0 | (bit))
-
-/* Bit-addressable status word */
-#define PSW(bit) (0xD0 | (bit))
-
-struct ccdbg {
- struct cc_bitbang *bb;
- struct cc_usb *usb;
- struct hex_image *rom;
-};
-
-/* Intel hex file format data
- */
-struct hex_record {
- uint8_t length;
- uint16_t address;
- uint8_t type;
- uint8_t checksum;
- uint8_t data[0];
-};
-
-struct hex_file {
- int nrecord;
- struct hex_record *records[0];
-};
-
-struct hex_image {
- uint16_t address;
- uint16_t length;
- uint8_t data[0];
-};
-
-#define CC_STATE_ACC 0x1
-#define CC_STATE_PSW 0x2
-#define CC_STATE_DP 0x4
-
-#define CC_STATE_NSFR 5
-
-struct ccstate {
- uint16_t mask;
- uint8_t acc;
- uint8_t sfr[CC_STATE_NSFR];
-};
-
-#define HEX_RECORD_NORMAL 0x00
-#define HEX_RECORD_EOF 0x01
-#define HEX_RECORD_EXTENDED_ADDRESS 0x02
-
-/* CC1111 debug port commands
- */
-#define CC_CHIP_ERASE 0x14
-
-#define CC_WR_CONFIG 0x1d
-#define CC_RD_CONFIG 0x24
-# define CC_CONFIG_TIMERS_OFF (1 << 3)
-# define CC_CONFIG_DMA_PAUSE (1 << 2)
-# define CC_CONFIG_TIMER_SUSPEND (1 << 1)
-# define CC_SET_FLASH_INFO_PAGE (1 << 0)
-
-#define CC_GET_PC 0x28
-#define CC_READ_STATUS 0x34
-# define CC_STATUS_CHIP_ERASE_DONE (1 << 7)
-# define CC_STATUS_PCON_IDLE (1 << 6)
-# define CC_STATUS_CPU_HALTED (1 << 5)
-# define CC_STATUS_POWER_MODE_0 (1 << 4)
-# define CC_STATUS_HALT_STATUS (1 << 3)
-# define CC_STATUS_DEBUG_LOCKED (1 << 2)
-# define CC_STATUS_OSCILLATOR_STABLE (1 << 1)
-# define CC_STATUS_STACK_OVERFLOW (1 << 0)
-
-#define CC_SET_HW_BRKPNT 0x3b
-# define CC_HW_BRKPNT_N(n) ((n) << 3)
-# define CC_HW_BRKPNT_N_MASK (0x3 << 3)
-# define CC_HW_BRKPNT_ENABLE (1 << 2)
-
-#define CC_HALT 0x44
-#define CC_RESUME 0x4c
-#define CC_DEBUG_INSTR(n) (0x54|(n))
-#define CC_STEP_INSTR 0x5c
-#define CC_STEP_REPLACE(n) (0x64|(n))
-#define CC_GET_CHIP_ID 0x68
-
-/* ccdbg-command.c */
-void
-ccdbg_debug_mode(struct ccdbg *dbg);
-
-void
-ccdbg_reset(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_chip_erase(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_wr_config(struct ccdbg *dbg, uint8_t config);
-
-uint8_t
-ccdbg_rd_config(struct ccdbg *dbg);
-
-uint16_t
-ccdbg_get_pc(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_read_status(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr);
-
-uint8_t
-ccdbg_halt(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_resume(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes);
-
-void
-ccdbg_debug_instr_discard(struct ccdbg *dbg, uint8_t *instr, int nbytes);
-
-void
-ccdbg_debug_instr_queue(struct ccdbg *dbg, uint8_t *instr, int nbytes,
- uint8_t *reply);
-
-uint8_t
-ccdbg_step_instr(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes);
-
-uint16_t
-ccdbg_get_chip_id(struct ccdbg *dbg);
-
-uint8_t
-ccdbg_execute(struct ccdbg *dbg, uint8_t *inst);
-
-uint8_t
-ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc);
-
-uint8_t
-ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image);
-
-/* ccdbg-flash.c */
-uint8_t
-ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image);
-
-/* ccdbg-hex.c */
-struct hex_file *
-ccdbg_hex_file_read(FILE *file, char *name);
-
-void
-ccdbg_hex_file_free(struct hex_file *hex);
-
-struct hex_image *
-ccdbg_hex_image_create(struct hex_file *hex);
-
-void
-ccdbg_hex_image_free(struct hex_image *image);
-
-int
-ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b);
-
-/* ccdbg-io.c */
-struct ccdbg *
-ccdbg_open(void);
-
-void
-ccdbg_close(struct ccdbg *dbg);
-
-void
-ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len);
-
-uint8_t
-ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len);
-
-void
-ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd,
- uint8_t *data, int len, uint8_t *reply);
-
-uint16_t
-ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len);
-
-void
-ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes);
-
-void
-ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes);
-
-void
-ccdbg_sync(struct ccdbg *dbg);
-
-/* ccdbg-manual.c */
-
-void
-ccdbg_manual(struct ccdbg *dbg, FILE *input);
-
-/* ccdbg-memory.c */
-uint8_t
-ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
-
-uint8_t
-ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
-
-uint8_t
-ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte);
-
-uint8_t
-ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset);
-
-struct hex_image *
-ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length);
-
-uint8_t
-ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);
-
-uint8_t
-ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);
-
-/* ccdbg-rom.c */
-uint8_t
-ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom);
-
-uint8_t
-ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes);
-
-uint8_t
-ccdbg_rom_replace_xmem(struct ccdbg *dbg,
- uint16_t addrp, uint8_t *bytesp, int nbytes);
-
-/* ccdbg-state.c */
-uint8_t
-ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask);
-
-uint8_t
-ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state);
-
-void
-ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state,
- uint16_t addr, uint8_t *bytes, int nbytes);
-
-void
-ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state,
- uint8_t addr, uint8_t *bytes, int nbytes);
-
-#endif /* _CCDBG_H_ */
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "cp-usb-async.h"
-#include "ccdbg-debug.h"
-
-#define MAX_OUTSTANDING 256
-#define CP_TIMEOUT 1000 /* ms */
-
-struct cp_usb_packet {
- struct libusb_transfer *transfer;
- enum { packet_read, packet_write } direction;
- unsigned char data[9];
- uint8_t *valuep;
-};
-
-struct cp_usb_async {
- libusb_context *ctx;
- libusb_device_handle *handle;
- struct cp_usb_packet packet[MAX_OUTSTANDING];
- int p, ack;
- uint8_t value;
- uint8_t set;
-};
-
-struct cp_usb_async *
-cp_usb_async_open(void)
-{
- struct cp_usb_async *cp;
- int ret;
-
- cp = calloc(sizeof (struct cp_usb_async), 1);
- if (!cp)
- return NULL;
- ret = libusb_init(&cp->ctx);
- if (ret) {
- free(cp);
- return NULL;
- }
- cp->handle = libusb_open_device_with_vid_pid(cp->ctx,
- 0x10c4, 0xea60);
- cp->ack = -1;
- if (!cp->handle) {
- libusb_exit(cp->ctx);
- free(cp);
- return NULL;
- }
- cp->value = 0;
- cp->set = 0;
- return cp;
-}
-
-void
-cp_usb_async_close(struct cp_usb_async *cp)
-{
- libusb_close(cp->handle);
- libusb_exit(cp->ctx);
- free(cp);
-}
-
-static void
-cp_usb_async_transfer_callback(struct libusb_transfer *transfer)
-{
- struct cp_usb_async *cp = transfer->user_data;
- int p;
-
- for (p = 0; p < cp->p; p++)
- if (cp->packet[p].transfer == transfer)
- break;
- if (p == cp->p) {
- fprintf(stderr, "unknown transfer\n");
- return;
- }
- switch (cp->packet[p].direction) {
- case packet_read:
- ccdbg_debug(CC_DEBUG_USB_ASYNC, "ack read %d 0x%02x\n",
- p, cp->packet[p].data[8]);
- *cp->packet[p].valuep = cp->packet[p].data[8];
- break;
- case packet_write:
- ccdbg_debug(CC_DEBUG_USB_ASYNC, "ack write %d\n", p);
- break;
- }
- if (p > cp->ack)
- cp->ack = p;
-}
-
-void
-cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value)
-{
- int p;
- uint16_t gpio_set;
- int ret;
-
- if (cp->set) {
- value = (cp->value & ~mask) | (value & mask);
- mask = value ^ cp->value;
- }
- cp->set = 1;
- cp->value = value;
- gpio_set = ((uint16_t) value << 8) | mask;
- if (cp->p == MAX_OUTSTANDING)
- cp_usb_async_sync(cp);
- p = cp->p;
- if (!cp->packet[p].transfer)
- cp->packet[p].transfer = libusb_alloc_transfer(0);
- cp->packet[p].direction = packet_write;
- libusb_fill_control_setup(cp->packet[p].data,
- 0x40, /* request */
- 0xff, /* request type */
- 0x37e1, /* value */
- gpio_set, /* index */
- 0); /* length */
-
- libusb_fill_control_transfer(cp->packet[p].transfer,
- cp->handle,
- cp->packet[p].data,
- cp_usb_async_transfer_callback,
- cp,
- CP_TIMEOUT);
- ccdbg_debug(CC_DEBUG_USB_ASYNC, "Write packet %d 0x%x 0x%x\n", p, mask, value);
- ret = libusb_submit_transfer(cp->packet[p].transfer);
- if (ret)
- fprintf(stderr, "libusb_submit_transfer failed %d\n", ret);
- cp->p++;
-}
-
-void
-cp_usb_async_read(struct cp_usb_async *cp, uint8_t *valuep)
-{
- int p;
- int ret;
-
- if (cp->p == MAX_OUTSTANDING)
- cp_usb_async_sync(cp);
- p = cp->p;
- if (!cp->packet[p].transfer)
- cp->packet[p].transfer = libusb_alloc_transfer(0);
- cp->packet[p].valuep = valuep;
- cp->packet[p].direction = packet_read;
- libusb_fill_control_setup(cp->packet[p].data,
- 0xc0, /* request */
- 0xff, /* request type */
- 0x00c2, /* value */
- 0, /* index */
- 1); /* length */
-
- libusb_fill_control_transfer(cp->packet[p].transfer,
- cp->handle,
- cp->packet[p].data,
- cp_usb_async_transfer_callback,
- cp,
- CP_TIMEOUT);
- ccdbg_debug(CC_DEBUG_USB_ASYNC, "Read packet %d\n", p);
- ret = libusb_submit_transfer(cp->packet[p].transfer);
- if (ret)
- fprintf(stderr, "libusb_submit_transfer failed %d\n", ret);
- cp->p++;
-}
-
-void
-cp_usb_async_sync(struct cp_usb_async *cp)
-{
- while (cp->ack < cp->p - 1) {
- libusb_handle_events(cp->ctx);
- }
- cp->p = 0;
- cp->ack = -1;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef _CP_USB_ASYNC_H_
-#define _CP_USB_ASYNC_H_
-#include <libusb.h>
-
-struct cp_usb_async *
-cp_usb_async_open(void);
-
-void
-cp_usb_async_close(struct cp_usb_async *cp);
-
-void
-cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value);
-
-void
-cp_usb_async_read(struct cp_usb_async *cp, uint8_t *valuep);
-
-void
-cp_usb_async_sync(struct cp_usb_async *cp);
-
-#endif
+++ /dev/null
-bin_PROGRAMS=s51
-
-AM_CFLAGS=-I$(top_srcdir)/cctools/lib $(LIBUSB_CFLAGS)
-S51_LIBS=$(top_builddir)/cctools/lib/libcc.a -lreadline
-
-man_MANS = s51.1
-
-s51_DEPENDENCIES = $(S51_LIBS)
-
-s51_LDADD=$(S51_LIBS) $(LIBUSB_LIBS)
-
-s51_SOURCES = s51-parse.c s51-command.c s51-main.c
+++ /dev/null
-Listens on port 9756 for a command stream.
-
-Dump commands:
- di <start> <end> - dump imem
- ds <start> <end> - dump sprs
- dx <start> <end> - dump xaddr
-
- Returns a string of hex pairs, each preceded by a space,
- with 8 pairs per line
-
-Memory access commands:
- set mem <prefix> <start> <end>
- dump <prefix> <start> <end>
-
- <prefix> is one of:
-
- xram - external ram or external stack
- rom - code space
- iram - internal ram or stack
- sfr - special function register
-
-
- dump <addr>
- set bit <addr>
-
- bit addressable space
-
-Set PC:
-
- pc <addr>
-
- Sets PC to specified address
-
- pc
-
- Returns current PC
-
-Breakpoints
-
- break <addr>
- clear <addr>
-
-Load a file
-
- file "<filename>"
-
-Execution control:
-
- run <start> - run starting at <start>
- run <start> <stop> - set temporary bp at <stop>
- run - continue
- next - step over calls(?)
- step - step one instruction
-
- reset - reset the simulator
- res - synonym?
-
-Error messages:
-
- start with "Error:"
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "s51.h"
-
-static uint16_t start_address;
-
-static enum command_result
-parse_int(char *value, int *result)
-{
- char *endptr;
-
- *result = strtol(value, &endptr, 0);
- if (endptr == value)
- return command_syntax;
- return command_success;
-}
-
-static enum command_result
-parse_uint16(char *value, uint16_t *uint16)
-{
- int v;
- enum command_result result;
-
- result = parse_int(value, &v);
- if (result != command_success)
- return command_error;
- if (v < 0 || v > 0xffff)
- return command_error;
- *uint16 = v;
- return command_success;
-}
-
-static enum command_result
-parse_uint8(char *value, uint8_t *uint8)
-{
- int v;
- enum command_result result;
-
- result = parse_int(value, &v);
- if (result != command_success)
- return command_error;
- if (v < 0 || v > 0xff)
- return command_error;
- *uint8 = v;
- return command_success;
-}
-
-enum command_result
-command_quit (int argc, char **argv)
-{
- ccdbg_reset(s51_dbg);
- exit(0);
- return command_error;
-}
-
-static void
-dump_bytes(uint8_t *memory, int length, uint16_t start, char *format)
-{
- int group, i;
-
- for (group = 0; group < length; group += 8) {
- s51_printf(format, start + group);
- for (i = group; i < length && i < group + 8; i++)
- s51_printf("%02x ", memory[i]);
- for (; i < group + 8; i++)
- s51_printf(" ");
- for (i = group; i < length && i < group + 8; i++) {
- if (isascii(memory[i]) && isprint(memory[i]))
- s51_printf("%c", memory[i]);
- else
- s51_printf(".");
- }
- s51_printf("\n");
- }
-}
-
-enum command_result
-command_di (int argc, char **argv)
-{
- uint16_t start, end;
- uint8_t memory[65536];
- uint8_t status;
- int length;
-
- if (argc != 3)
- return command_error;
- if (parse_uint16(argv[1], &start) != command_success)
- return command_error;
- if (parse_uint16(argv[2], &end) != command_success)
- return command_error;
- length = (int) end - (int) start + 1;
- status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
- dump_bytes(memory, length, start, "0x%02x ");
- return command_success;
-}
-
-enum command_result
-command_ds (int argc, char **argv)
-{
- uint8_t start, end;
- uint8_t memory[0x100];
- uint8_t status;
- int length;
-
- if (argc != 3)
- return command_error;
- if (parse_uint8(argv[1], &start) != command_success)
- return command_error;
- if (parse_uint8(argv[2], &end) != command_success)
- return command_error;
- length = (int) end - (int) start + 1;
- status = ccdbg_read_sfr(s51_dbg, start, memory, length);
- dump_bytes(memory, length, start, "0x%02x ");
- return command_success;
-}
-
-enum command_result
-command_dx (int argc, char **argv)
-{
- uint16_t start, end;
- uint8_t memory[65536];
- uint8_t status;
- int length;
-
- if (argc != 3)
- return command_error;
- if (parse_uint16(argv[1], &start) != command_success)
- return command_error;
- if (parse_uint16(argv[2], &end) != command_success)
- return command_error;
- length = (int) end - (int) start + 1;
- status = ccdbg_read_memory(s51_dbg, start, memory, length);
- dump_bytes(memory, length, start, "0x%04x ");
- return command_success;
-}
-
-enum command_result
-command_set (int argc, char **argv)
-{
- uint16_t address;
- uint8_t *data;
- int len = argc - 3;
- int i;
- enum command_result ret = command_success;
-
- if (len < 0)
- return command_error;
- if (parse_uint16(argv[2], &address) != command_success)
- return command_error;
- if (len == 0)
- return command_success;
- data = malloc(len);
- if (!data)
- return command_error;
- for (i = 0; i < len; i++)
- if (parse_uint8(argv[i+3], &data[i]) != command_success)
- return command_error;
-
- if (strcmp(argv[1], "xram") == 0) {
- ccdbg_write_memory(s51_dbg, address, data, len);
- } else if (strcmp(argv[1], "iram") == 0) {
- ccdbg_write_memory(s51_dbg, address + 0xff00, data, len);
- } else if (strcmp(argv[1], "sfr") == 0) {
- ccdbg_write_sfr(s51_dbg, (uint8_t) address, data, len);
- } else
- ret = command_error;
- free(data);
- return ret;
-}
-
-enum command_result
-command_dump (int argc, char **argv)
-{
- if (argv[1]) {
- if (strcmp(argv[1], "rom") == 0 ||
- strcmp(argv[1], "xram") == 0)
- return command_dx(argc-1, argv+1);
- if (strcmp(argv[1], "iram") == 0)
- return command_di(argc-1, argv+1);
- if (strcmp(argv[1], "sfr") == 0)
- return command_ds(argc-1, argv+1);
- }
- return command_error;
-}
-
-enum command_result
-command_file (int argc, char **argv)
-{
- struct hex_file *hex;
- struct hex_image *image;
- FILE *file;
-
- if (argc != 2)
- return command_error;
- file = fopen (argv[1], "r");
- if (!file)
- return command_error;
- hex = ccdbg_hex_file_read(file, argv[1]);
- fclose(file);
- if (!hex)
- return command_error;
- if (hex->nrecord == 0) {
- ccdbg_hex_file_free(hex);
- return command_error;
- }
- image = ccdbg_hex_image_create(hex);
- ccdbg_hex_file_free(hex);
- start_address = image->address;
- ccdbg_set_rom(s51_dbg, image);
- return command_success;
-}
-
-enum command_result
-command_pc (int argc, char **argv)
-{
- uint16_t pc;
- if (argv[1]) {
- enum command_result result;
- result = parse_uint16(argv[1], &pc);
- if (result != command_success)
- return result;
- ccdbg_set_pc(s51_dbg, pc);
- } else {
- pc = ccdbg_get_pc(s51_dbg);
- s51_printf(" 0x%04x 00\n", pc);
- }
- return command_success;
-}
-
-struct cc_break {
- int enabled;
- int temporary;
- uint16_t address;
-};
-
-#define CC_NUM_BREAKPOINTS 4
-
-static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
-
-static void
-disable_breakpoint(int b)
-{
- uint8_t status;
-
- status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
- if (status != 0x00 && status != 0xff)
- s51_printf("disable_breakpoint status 0x%02x\n", status);
-}
-
-static void
-enable_breakpoint(int b)
-{
- uint8_t status;
-
- status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
- if (status != 0xff)
- s51_printf("enable_breakpoint status 0x%02x\n", status);
-}
-
-static void
-enable_breakpoints(void)
-{
- int b;
- for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
- if (breakpoints[b].enabled)
- enable_breakpoint(b);
-}
-
-enum command_result
-set_breakpoint(uint16_t address, int temporary)
-{
- int b;
- uint8_t status;
- for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
- if (breakpoints[b].enabled == 0)
- break;
- if (breakpoints[b].address == address)
- break;
- }
- if (b == CC_NUM_BREAKPOINTS) {
- s51_printf("Error: too many breakpoints requested\n");
- return command_success;
- }
- if (breakpoints[b].enabled == 0) {
- breakpoints[b].address = address;
- enable_breakpoint(b);
- }
- ++breakpoints[b].enabled;
- s51_printf("Breakpoint %d at 0x%04x\n", b, address);
- breakpoints[b].temporary += temporary;
- return command_success;
-}
-
-enum command_result
-clear_breakpoint(uint16_t address, int temporary)
-{
- int b;
- uint8_t status;
-
- for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
- if (breakpoints[b].enabled != 0 &&
- ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
- breakpoints[b].address == address)
- break;
- }
- if (b == CC_NUM_BREAKPOINTS) {
- s51_printf("Error: no matching breakpoint found\n");
- return command_success;
- }
- --breakpoints[b].enabled;
- breakpoints[b].temporary -= temporary;
- if (breakpoints[b].enabled == 0) {
- disable_breakpoint(b);
- breakpoints[b].address = -1;
- }
- return command_success;
-}
-
-
-int
-find_breakpoint(uint16_t address)
-{
- int b;
-
- for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
- if (breakpoints[b].enabled && breakpoints[b].address == address)
- break;
- if (b == CC_NUM_BREAKPOINTS)
- return -1;
- return b;
-}
-
-enum command_result
-command_break (int argc, char **argv)
-{
- int b;
- uint16_t address;
- enum command_result result;
-
- if (argc == 1) {
- for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
- if (breakpoints[b].enabled)
- s51_printf("Breakpoint %d 0x%04x\n",
- b, breakpoints[b].address);
- return command_success;
- }
- if (argc != 2)
- return command_error;
- result = parse_uint16(argv[1], &address);
- if (result != command_success)
- return result;
-
- return set_breakpoint(address, 0);
-}
-
-enum command_result
-command_clear (int argc, char **argv)
-{
- int b;
- uint16_t address;
- enum command_result result;
-
- if (argc != 2)
- return command_error;
- result = parse_uint16(argv[1], &address);
- if (result != command_success)
- return result;
- return clear_breakpoint(address, 0);
-}
-
-void
-cc_stopped(uint8_t status)
-{
- uint16_t pc;
- int b;
- int code;
- char *reason;
-
- pc = ccdbg_get_pc(s51_dbg);
- if (status & CC_STATUS_CPU_HALTED) {
- if ((status & CC_STATUS_HALT_STATUS) != 0) {
- pc = pc - 1;
- code = 104;
- reason = "Breakpoint";
- b = find_breakpoint(pc);
- if (b != -1 && breakpoints[b].temporary)
- clear_breakpoint(pc, 1);
- ccdbg_set_pc(s51_dbg, pc);
- } else {
- code = 105;
- reason = "Interrupt";
- }
- s51_printf("Stop at 0x%04x: (%d) %s\n",
- pc, code, reason);
- }
-}
-
-uint8_t
-cc_step(uint16_t pc)
-{
- int b;
- uint8_t status;
-
- b = find_breakpoint(pc);
- if (b != -1)
- disable_breakpoint(b);
- status = ccdbg_step_instr(s51_dbg);
- if (b != -1)
- enable_breakpoint(b);
- return status;
-}
-
-enum command_result
-command_run (int argc, char **argv)
-{
- uint16_t start, end;
- enum command_result result;
- uint16_t pc;
- uint8_t status;
- int b;
-
- if (argv[1]) {
- result = parse_uint16(argv[1], &start);
- if (result != command_success)
- return result;
- if (argv[2]) {
- result = parse_uint16(argv[2], &end);
- if (result != command_success)
- return result;
- }
- if (start_address && start == 0) {
- start = start_address;
- s51_printf("Starting at 0x%04x\n", start);
- }
- ccdbg_set_pc(s51_dbg, start);
- }
- else
- start = ccdbg_get_pc(s51_dbg);
- s51_printf("Resume at 0x%04x\n", start);
- pc = start;
- b = find_breakpoint(pc);
- if (b != -1) {
- cc_step(pc);
- pc = ccdbg_get_pc(s51_dbg);
- if (find_breakpoint(pc) != -1) {
- status = ccdbg_read_status(s51_dbg);
- cc_stopped(status);
- return command_success;
- }
- }
- ccdbg_resume(s51_dbg);
- result = cc_wait();
- return result;
-}
-
-enum command_result
-command_next (int argc, char **argv)
-{
- return command_step(argc, argv);
-}
-
-enum command_result
-command_step (int argc, char **argv)
-{
- uint16_t pc;
- uint8_t opcode;
- uint8_t a;
-
- a = cc_step(ccdbg_get_pc(s51_dbg));
- s51_printf(" ACC= 0x%02x\n", a);
- pc = ccdbg_get_pc(s51_dbg);
- ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
- s51_printf(" ? 0x%04x %02x\n", pc, opcode);
- return command_success;
-}
-
-enum command_result
-command_load (int argc, char **argv)
-{
- char *filename = argv[1];
- FILE *file;
- struct hex_file *hex;
- struct hex_image *image;
-
- if (!filename)
- return command_error;
- file = fopen(filename, "r");
- if (!file) {
- perror(filename);
- return command_error;
- }
- hex = ccdbg_hex_file_read(file, filename);
- fclose(file);
- if (!hex) {
- return command_error;
- }
- image = ccdbg_hex_image_create(hex);
- ccdbg_hex_file_free(hex);
- if (!image) {
- fprintf(stderr, "image create failed\n");
- return command_error;
- }
- if (image->address >= 0xf000) {
- printf("Loading %d bytes to RAM at 0x%04x\n",
- image->length, image->address);
- ccdbg_write_hex_image(s51_dbg, image, 0);
- } else {
- fprintf(stderr, "Can only load to RAM\n");
- }
- ccdbg_hex_image_free(image);
- return command_success;
-}
-
-enum command_result
-command_halt (int argc, char **argv)
-{
- uint16_t pc;
- ccdbg_halt(s51_dbg);
- pc = ccdbg_get_pc(s51_dbg);
- s51_printf("Halted at 0x%04x\n", pc);
- return command_success;
-}
-
-enum command_result
-command_stop (int argc, char **argv)
-{
- return command_success;
-}
-
-enum command_result
-command_reset (int argc, char **argv)
-{
- ccdbg_debug_mode(s51_dbg);
- ccdbg_halt(s51_dbg);
- enable_breakpoints();
- return command_success;
-}
-
-enum command_result
-command_status(int argc, char **argv)
-{
- uint8_t status;
-
- status = ccdbg_read_status(s51_dbg);
- if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
- s51_printf("\tChip erase in progress\n");
- if (status & CC_STATUS_PCON_IDLE)
- s51_printf("\tCPU is idle (clock gated)\n");
- if (status & CC_STATUS_CPU_HALTED)
- s51_printf("\tCPU halted\n");
- else
- s51_printf("\tCPU running\n");
- if ((status & CC_STATUS_POWER_MODE_0) == 0)
- s51_printf("\tPower Mode 1-3 selected\n");
- if (status & CC_STATUS_HALT_STATUS)
- s51_printf("\tHalted by software or hw breakpoint\n");
- else
- s51_printf("\tHalted by debug command\n");
- if (status & CC_STATUS_DEBUG_LOCKED)
- s51_printf("\tDebug interface is locked\n");
- if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
- s51_printf("\tOscillators are not stable\n");
- if (status & CC_STATUS_STACK_OVERFLOW)
- s51_printf("\tStack overflow\n");
- return command_success;
-}
-
-static enum command_result
-info_breakpoints(int argc, char **argv)
-{
- int b;
- uint16_t address;
- enum command_result result;
-
- if (argc == 1) {
- s51_printf("Num Type Disp Hit Cnt Address What\n");
- for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
- if (breakpoints[b].enabled) {
- s51_printf("%-3d fetch %s 1 1 0x%04x uc::disass() unimplemented\n",
- b,
- breakpoints[b].temporary ? "del " : "keep",
- breakpoints[b].address);
- }
- return command_success;
- }
-
-}
-
-static enum command_result
-info_help(int argc, char **argv);
-
-static struct command_function infos[] = {
- { "breakpoints", "b", info_breakpoints, "[b]reakpoints",
- "List current breakpoints\n" },
- { "help", "?", info_help, "help",
- "Print this list\n" },
-
- { NULL, NULL, NULL, NULL, NULL },
-};
-
-static enum command_result
-info_help(int argc, char **argv)
-{
- return command_function_help(infos, argc, argv);
-}
-
-enum command_result
-command_info(int argc, char **argv)
-{
- struct command_function *func;
-
- if (argc < 2)
- return command_error;
- func = command_string_to_function(infos, argv[1]);
- if (!func)
- return command_syntax;
- return (*func->func)(argc-1, argv+1);
-}
-
-enum command_result
-cc_wait(void)
-{
- for(;;) {
- uint8_t status;
- status = ccdbg_read_status(s51_dbg);
- if (status & CC_STATUS_CPU_HALTED) {
- cc_stopped(status);
- return command_success;
- }
- if (s51_interrupted || s51_check_input()) {
-
- ccdbg_halt(s51_dbg);
- status = ccdbg_read_status(s51_dbg);
- cc_stopped(status);
- return command_interrupt;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "s51.h"
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <poll.h>
-
-static int s51_port = 0;
-static char *cpu = "8051";
-static double freq = 11059200;
-char *s51_prompt = "> ";
-struct ccdbg *s51_dbg;
-int s51_interrupted = 0;
-int s51_monitor = 0;
-
-static FILE *s51_input;
-static FILE *s51_output;
-
-static void
-usage(void)
-{
- fprintf(stderr, "You're doing it wrong.\n");
- exit(1);
-}
-
-void s51_sigint()
-{
- s51_interrupted = 1;
-}
-
-int
-main(int argc, char **argv)
-{
- int flags, opt;
- char *endptr;
- struct sigvec vec, ovec;
-
- while ((opt = getopt(argc, argv, "PVvHhmt:X:c:r:Z:s:S:p:")) != -1) {
- switch (opt) {
- case 't':
- cpu = optarg;
- break;
- case 'X':
- freq = strtod(optarg, &endptr);
- if (endptr == optarg)
- usage();
- if (endptr[0] != '\0') {
- if (!strcmp(endptr, "k"))
- freq *= 1000;
- else if (!strcmp(endptr, "M") )
- freq *= 1000000;
- else
- usage ();
- }
- break;
- case 'c':
- break;
- case 'r':
- case 'Z':
- s51_port = strtol(optarg, &endptr, 0);
- if (endptr == optarg || strlen(endptr) != 0)
- usage();
- break;
- case 's':
- break;
- case 'S':
- break;
- case 'p':
- s51_prompt = optarg;
- break;
- case 'P':
- s51_prompt = NULL;
- break;
- case 'V':
- break;
- case 'v':
- break;
- case 'H':
- exit (0);
- break;
- case 'h':
- usage ();
- break;
- case 'm':
- s51_monitor = 1;
- break;
- }
- }
- if (s51_port) {
- int l, r, one = 1;
- int s;
- struct sockaddr_in in;
-
- l = socket(AF_INET, SOCK_STREAM, 0);
- if (l < 0) {
- perror ("socket");
- exit(1);
- }
- r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
- if (r) {
- perror("setsockopt");
- exit(1);
- }
- in.sin_family = AF_INET;
- in.sin_port = htons(s51_port);
- in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- r = bind(l, (struct sockaddr *) &in, sizeof (in));
- if (r) {
- perror("bind");
- exit(1);
- }
- r = listen(l, 5);
- if (r) {
- perror("listen");
- exit(1);
- }
- for (;;) {
- struct sockaddr_in client_addr;
- socklen_t client_len = sizeof (struct sockaddr_in);
-
- s = accept(l, (struct sockaddr *)
- &client_addr, &client_len);
- if (s < 0) {
- perror("accept");
- exit(1);
- }
- s51_input = fdopen(s, "r");
- s51_output = fdopen(s, "w");
- if (!s51_input || !s51_output) {
- perror("fdopen");
- exit(1);
- }
- vec.sv_handler = SIG_IGN;
- vec.sv_mask = 0;
- vec.sv_flags = 0;
- sigvec(SIGINT, &vec, &ovec);
- command_read();
- sigvec(SIGINT, &ovec, NULL);
- fclose(s51_input);
- fclose(s51_output);
- }
- } else {
- s51_input = stdin;
- s51_output = stdout;
- vec.sv_handler = s51_sigint;
- vec.sv_mask = 0;
- vec.sv_flags = 0;
- sigvec(SIGINT, &vec, &ovec);
- command_read();
- }
- exit(0);
-}
-
-void
-s51_printf(char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- vfprintf(s51_output, format, ap);
- if (s51_monitor)
- vfprintf(stdout, format, ap);
- va_end(ap);
-}
-
-void
-s51_putc(int c)
-{
- putc(c, s51_output);
-}
-
-#include <readline/readline.h>
-#include <readline/history.h>
-
-int
-s51_read_line(char *line, int len)
-{
- int ret;
- if (s51_output == stdout && s51_input == stdin && s51_prompt) {
- char *r;
-
- r = readline(s51_prompt);
- if (r == NULL)
- return 0;
- strncpy (line, r, len);
- line[len-1] = '\0';
- add_history(r);
- return 1;
- } else {
- if (s51_prompt)
- s51_printf("%s", s51_prompt);
- else
- s51_putc('\0');
- fflush(s51_output);
- ret = fgets(line, len, s51_input) != NULL;
- if (s51_monitor)
- printf("> %s", line);
- fflush(stdout);
- }
- return ret;
-}
-
-int
-s51_check_input(void)
-{
- struct pollfd input;
- int r;
- int c;
-
- input.fd = fileno(s51_input);
- input.events = POLLIN;
- r = poll(&input, 1, 0);
- if (r > 0) {
- char line[256];
- (void) s51_read_line(line, sizeof (line));
- return 1;
- }
- return 0;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "s51.h"
-
-static struct command_function functions[] = {
- { "help", "?", command_help, "help", "Print this list\n" },
- { "quit", "q", command_quit, "[q]uit", "Quit\n" },
- { "di", "di", command_di, "di <start> <end>",
- "Dump imem\n" },
- { "ds", "ds", command_ds, "ds <start> <end>",
- "Dump sprs\n" },
- { "dx", "dx", command_dx, "dx <start> <end>",
- "Dump xaddr\n" },
- { "set", "t", command_set, "se[t] mem <prefix> <address> <data> ...",
- "Set mem {xram|rom|iram|sfr}\n"
- "set bit <addr>\n" },
- { "dump", "d", command_dump, "[d]ump <prefix> <start> <end>",
- "Dump {xram|rom|iram|sfr} <start> <end>\n" },
- { "file", "file", command_file, "file <filename>",
- "Pretend to load executable from <filename>\n" },
- { "pc", "p", command_pc, "[p]c [addr]",
- "Get or set pc value\n" },
- { "break", "b", command_break,"[b]reak <addr>",
- "Set break point\n" },
- { "clear", "c", command_clear,"[c]lear <addr>",
- "Clear break point\n" },
- { "run", "r", command_run, "[r]un [start] [stop]",
- "Run with optional start and temp breakpoint addresses\n" },
- { "go", "g", command_run, "[g]o [start] [stop]",
- "Run with optional start and temp breakpoint addresses\n" },
- { "next", "n", command_next, "[n]ext",
- "Step over one instruction, past any call\n" },
- { "step", "s", command_step, "[s]tep",
- "Single step\n" },
- { "load", "l", command_load, "[l]oad <file>",
- "Load a hex file into memory or flash" },
- { "halt", "h", command_halt, "[h]alt",
- "Halt the processor\n" },
- { "reset","res",command_reset, "[res]et",
- "Reset the CPU\n" },
- { "status","status",command_status, "status",
- "Display CC1111 debug status\n" },
- { "info", "i", command_info, "[i]info",
- "Get information\n" },
- { "stop", "stop", command_stop, "stop",
- "Ignored\n" },
- { NULL, NULL, NULL, NULL, NULL },
-};
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE 1
-#endif
-
-static int
-string_to_int(char *s, int *v)
-{
- char *endptr;
-
- if (isdigit(s[0]) || s[0] == '-' || s[0] == '+') {
- *v = strtol(s, &endptr, 0);
- if (endptr == s)
- return FALSE;
- } else if (*s == '\'') {
- s++;
- if (*s == '\\') {
- s++;
- switch (*s) {
- case 'n':
- *v = '\n';
- break;
- case 't':
- *v = '\t';
- break;
- default:
- *v = (int) *s;
- break;
- }
- } else
- *v = (int) *s;
- s++;
- if (*s != '\'')
- return FALSE;
- }
- else
- return FALSE;
- return TRUE;
-}
-
-struct command_function *
-command_string_to_function(struct command_function *functions, char *name)
-{
- int i;
- for (i = 0; functions[i].name; i++)
- if (!strcmp(name, functions[i].name) ||
- !strcmp(name, functions[i].alias))
- return &functions[i];
- return NULL;
-}
-
-enum command_result
-command_function_help(struct command_function *functions, int argc, char **argv)
-{
- int i;
- struct command_function *func;
-
- if (argc == 1) {
- for (i = 0; functions[i].name; i++)
- s51_printf("%-10s%s\n", functions[i].name,
- functions[i].usage);
- } else {
- for (i = 1; i < argc; i++) {
- func = command_string_to_function(functions, argv[i]);
- if (!func) {
- s51_printf("%-10s unknown command\n", argv[i]);
- return command_syntax;
- }
- s51_printf("%-10s %s\n%s", func->name,
- func->usage, func->help);
- }
- }
- return command_debug;
-}
-
-static int
-command_split_into_words(char *line, char **argv)
-{
- char quotechar;
- int argc;
-
- argc = 0;
- while (*line) {
- while (isspace(*line))
- line++;
- if (!*line)
- break;
- if (*line == '"') {
- quotechar = *line++;
- *argv++ = line;
- argc++;
- while (*line && *line != quotechar)
- line++;
- if (*line)
- *line++ = '\0';
- } else {
- *argv++ = line;
- argc++;
- while (*line && !isspace(*line))
- line++;
- if (*line)
- *line++ = '\0';
- }
- }
- *argv = 0;
- return argc;
-}
-
-enum command_result
-command_help(int argc, char **argv)
-{
- return command_function_help(functions, argc, argv);
-}
-
-void
-command_syntax_error(int argc, char **argv)
-{
- s51_printf("Syntax error in:");
- while (*argv)
- s51_printf(" %s", *argv++);
- s51_printf("\n");
-}
-
-void
-command_read (void)
-{
- int argc;
- char line[1024];
- char *argv[20];
- enum command_result result;
- struct command_function *func;
-
- s51_dbg = ccdbg_open ();
- if (!s51_dbg) {
- perror("ccdbg_open");
- exit(1);
- }
- ccdbg_debug_mode(s51_dbg);
- ccdbg_halt(s51_dbg);
- s51_printf("Welcome to the non-simulated processor\n");
- for (;;) {
- if (s51_read_line (line, sizeof line) == 0)
- break;
- s51_interrupted = 0;
- argc = command_split_into_words(line, argv);
- if (argc > 0) {
- func = command_string_to_function(functions, argv[0]);
- if (!func)
- command_syntax_error(argc, argv);
- else
- {
- result = (*func->func)(argc, argv);
- if (s51_interrupted)
- result = command_interrupt;
- switch (result) {
- case command_syntax:
- command_syntax_error(argc, argv);
- break;
- case command_error:
- s51_printf("Error\n");
- break;
- case command_success:
- break;
- case command_interrupt:
- ccdbg_halt(s51_dbg);
- s51_printf("Interrupted\n");
- break;
- default:
- break;
- }
- }
- }
- }
- ccdbg_close(s51_dbg);
- s51_printf("...\n");
-}
+++ /dev/null
-.\"
-.\" Copyright © 2009 Keith Packard <keithp@keithp.com>
-.\"
-.\" 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.,
-.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-.\"
-.\"
-.TH S51 1 "s51" ""
-.SH NAME
-s51 \- hex debugger for cc1111 processors
-.SH SYNOPSIS
-.B "s51"
-[\-t \fIcpu-type\fP]
-[\-X \fIfrequency\fP]
-[\-c]
-[\-r \fIlisten-port\fP]
-[\-Z \fIlisten-port\fP]
-[\-s]
-[\-S]
-[\-p \fIprompt\fP]
-[\-V]
-[\-v]
-[\-H]
-[\-h]
-[\-m]
-.SH DESCRIPTION
-.I s51
-connects to a cc1111 processor through a cp1203-based USB-to-serial
-converter board, using the GPIO pins available on that chip. It provides an
-interface compatible with the 8051 emulator of the same name (s51), but
-communicating with the real chip instead of an emulation. Using a modified
-version of the SDCC debugger (sdcdb), you can control program execution
-on the target machine at source-level.
-
-.SH OPTIONS
-The command line options are designed to be compatible with the 8051
-emulator so that it can be used with sdcdb. As such, they're all one letter
-long.
-.IP "\-t \fIcpu-type\fP"
-The 8051 emulator can operate as one of several different chips. Oddly, the
-real hardware cannot, so this option is ignored.
-.IP "\-X \fIfrequency\fP"
-Similarly, the emulator can pretend to run at an arbitrary frequency
-which the real hardware cannot do. Ignored.
-.IP "\-c"
-.IP "\-s"
-.IP "\-S"
-.IP "\-v"
-.IP "\-V"
-All ignored.
-.IP "\-r \fIlisten-port\fP, -Z \fIlisten-port\fP"
-The emulator and sdcdb communicate through a network socket. This option
-switches the debugger from communicating through stdin/stdout to listening
-on a specific network port instead. Once a connection is made, the debugger
-continues on, using that network port for command input and output. The
-debugger uses port 9756, and attempts to connect before launching s51, so if
-s51 is listening on this port before sdcdb is started, sdcdb will end up
-talking to the existing s51 instance. That's often useful for debugging s51
-itself.
-.IP "\-p \fIprompt\fP"
-This sets the command prompt to the specified string.
-.IP "\-P"
-This sets the command prompt to a single NUL character. This is for use by
-sdcdb.
-.IP "\-h"
-This should print a usage message, but does nothing useful currently.
-.IP "\-m"
-This option is not present in the original 8051 emulator, and causes s51 to
-dump all commands and replies that are received from and sent to sdcdb.
-.SH COMMANDS
-Once started, s51 connects to the cc1111 via the CP2103 using libusb2 and
-then reads and executes commands, either from stdin, or the nework
-connection to sdcdb.
-.PP
-Unlike the command line, s51 contains built-in help for each of these
-commands, via the 'help' command. Most of the commands are available in a
-long form and a single character short form. Below, the short form follows
-the long form after a comma.
-.IP "help, ? {command}"
-Without arguments, prints a list of available commands. With an argument
-prints more detail about the specific command
-.IP "quit, q"
-Terminates the application, without changing the state of the target
-processor.
-.IP "di [start] [end]"
-Dumps imem (256 bytes of "internal" memory) from start to end (inclusive).
-.IP "ds [start] [end]"
-Dumps sprs from start to end (inclusive). Note that while most sprs are
-visible in the global address space, some are not, so use this command
-instead of "dx" to read them.
-.IP "dx [start] [end]"
-Dump external (global) memory from start to end (inclusive).
-.IP "set, t <prefix> [start] {data ...}"
-Store to the memory space specified by prefix where prefix is one of "xram",
-"rom", "iram", or "sfr". Store bytes starting at start.
-.IP "dump, d <prefix> [start] [end]"
-Dump from the memory space specified by prefix, where prefix is one of
-"xram", "rom", "iram" or "sfr". Dumps from start to end (inclusive).
-.IP "file [filename]"
-Specifies an intel-format hex file (ihx) that contains the contents of the
-rom area loaded into the cc1111. This is used to respond to requests to dump
-rom memory contents without getting them from the cc1111 (which is slow).
-.IP "pc, p {address}"
-If the address argument is given, this sets the program counter to the
-specified value. Otherwise, the current program counter value is displayed.
-.IP "break, b [address]"
-Sets a breakpoint at the specified address. This uses the built-in hardware
-breakpoint support in the cc1111. As a result, it supports no more than four
-breakpoints at once. You must therefore use a modified version of sdcdb which
-changes how program execution is controlled to work within this limit.
-.IP "clear, c [address]"
-Clear a breakpoint from the specified address.
-.IP "run, r, go, g {start} {stop}"
-Resumes execution of the program. If the start argument is present, then it
-begins at that address, otherwise it continues running at the current pc. If
-a stop argument is present, then a temporary breakpoint is set at that
-address. This temporary breakpoint will be removed when execution hits it.
-.IP "next, n"
-Step one instruction. In the original s51 program this would ignore
-subroutines, but as sdcdb doesn't require this functionality, it's not
-available here.
-.IP "step, s"
-Step one instruction.
-.IP "load, l [filename]"
-This is not implemented, but it is supposed to load a hex file into flash.
-Use the ccload program instead.
-.IP "halt, h"
-Halt the processor. This is the only command which can be sent while the
-program is running. It is ignored at other times.
-.IP "reset, res"
-Reset the processor. This pulls the reset pin low and re-enables debug mode.
-Check the cc1111 documentation to see precisely what this does.
-.IP "status"
-This dumps the cc1111 debug status register.
-.IP "info, i breakpoints, b"
-List the current breakpoints.
-.IP "info, i help, ?"
-List the things you can get info on.
-.IP "stop"
-This doesn't do anything and is present only to retain compatibility with
-the original 8051 emulator.
-.SH "BOARD BRINGUP DEBUGGING"
-.PP
-While the original purpose for this program was to connect the source
-debugger with the hardware, it can also be used as a low-level hex debugger
-all on its own. In particular, all of the cc1111 peripherals can be
-manipulated directly from the s51 command line.
-.IP "Starting s51"
-If the CP2103 is plugged in, and the CC1111 is connected correctly, the
-\'s51\' command itself should connect to the device without trouble.
-Note that the CP2103 must have the GPIO pins configured correctly as well.
-.IP
-$ s51
-.br
-Welcome to the non-simulated processor
-.br
-> status
-.br
- CPU halted
-.br
- Halted by debug command
-.br
->
-.IP "Turning on LEDs"
-Two of the cc1111 GPIO pins, P1_0 and P1_1 are capable of driving external
-LEDs. To control these, set the Port 1 direction bits to make these output
-pins and then change the Port 1 data to set them high or low:
-.IP
-> set sfr 0xfe 0x02 # set P1DIR to 0x2
-.br
-> set sfr 0x90 0x02 # set P1_1 to high
-.br
-> set sfr 0x90 0x00 # set P1_1 to low
-.IP "Reading the A/D converters"
-The six A/D converter inputs can each be connected to any of the P0 pins,
-ground, the A/D voltage refernece, an internal temperature sensor or VDD/3.
-To read one of these values, select an A/D converter to use then start the
-conversion process. The cc1111 manual has the table for selecting the input
-on page 144.
-.IP
-To configure one of the P0 pins for use by the A/D unit, we program the
-ADCCFG register, setting the bits in that which match the pins desired:
-.IP
-> set sfr 0xf2 0x3f # enable all 6 A/D inputs
-.IP
-To trigger a single conversion, we ask the A/D unit to perform an 'extra'
-conversion, which means to do a single conversion not a whole sequence of
-conversions. This is controlled by the ADCCON3 register at 0xB6:
-.IP
-> set sfr 0xb6 0xb2 # sample P0_2 using 12 bits of precision
-.br
-> ds 0xba 0xbb # dump the ADC data low and high regs
-.br
-> set sfr 0xb6 0xbe # sample internal temperature sensor
-.br
-> ds 0xba 0xbb # dump the ADC data low and high regs
-.SH "SEE ALSO"
-sdcdb(1), ccload(1)
-.SH AUTHOR
-Keith Packard
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <ccdbg.h>
-
-extern char *s51_prompt;
-extern struct ccdbg *s51_dbg;
-extern int s51_interrupted;
-extern int s51_monitor;
-
-enum command_result {
- command_success, command_debug, command_syntax, command_interrupt, command_error,
-};
-
-struct command_function {
- char *name;
- char *alias;
- enum command_result (*func)(int argc, char **argv);
- char *usage;
- char *help;
-};
-
-struct command_function *
-command_string_to_function(struct command_function *functions, char *name);
-
-enum command_result
-command_function_help(struct command_function *functions, int argc, char **argv);
-
-void
-command_syntax_error(int argc, char **argv);
-
-enum command_result
-command_quit (int argc, char **argv);
-
-enum command_result
-command_help (int argc, char **argv);
-
-enum command_result
-command_stop (int argc, char **argv);
-
-enum command_result
-command_di (int argc, char **argv);
-
-enum command_result
-command_ds (int argc, char **argv);
-
-enum command_result
-command_dx (int argc, char **argv);
-
-enum command_result
-command_set (int argc, char **argv);
-
-enum command_result
-command_dump (int argc, char **argv);
-
-enum command_result
-command_file (int argc, char **argv);
-
-enum command_result
-command_pc (int argc, char **argv);
-
-enum command_result
-command_break (int argc, char **argv);
-
-enum command_result
-command_clear (int argc, char **argv);
-
-enum command_result
-command_run (int argc, char **argv);
-
-enum command_result
-command_next (int argc, char **argv);
-
-enum command_result
-command_step (int argc, char **argv);
-
-enum command_result
-command_load (int argc, char **argv);
-
-enum command_result
-command_halt (int argc, char **argv);
-
-enum command_result
-command_reset (int argc, char **argv);
-
-enum command_result
-command_status (int argc, char **argv);
-
-enum command_result
-command_info (int argc, char **argv);
-
-enum command_result
-cc_wait(void);
-
-void
-command_read (void);
-
-void
-s51_printf(char *format, ...);
-
-void
-s51_putc(int c);
-
-int
-s51_check_input(void);
-
-int
-s51_read_line(char *line, int len);
+++ /dev/null
-PROG=adc_serial
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --stack-auto --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=$(PROG).c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=$(PROG)-flash.ihx $(PROG)-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-$(PROG)-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL)
-
-$(PROG)-flash.ihx: $(PROG)-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdint.h>
-
-/*
- * Test ADC in DMA mode
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-sfr at 0xbe SLEEP;
-
-# define SLEEP_USB_EN (1 << 7)
-# define SLEEP_XOSC_STB (1 << 6)
-
-sfr at 0xF1 PERCFG;
-#define PERCFG_T1CFG_ALT_1 (0 << 6)
-#define PERCFG_T1CFG_ALT_2 (1 << 6)
-
-#define PERCFG_T3CFG_ALT_1 (0 << 5)
-#define PERCFG_T3CFG_ALT_2 (1 << 5)
-
-#define PERCFG_T4CFG_ALT_1 (0 << 4)
-#define PERCFG_T4CFG_ALT_2 (1 << 4)
-
-#define PERCFG_U1CFG_ALT_1 (0 << 1)
-#define PERCFG_U1CFG_ALT_2 (1 << 1)
-
-#define PERCFG_U0CFG_ALT_1 (0 << 0)
-#define PERCFG_U0CFG_ALT_2 (1 << 0)
-
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-/*
- * UART registers
- */
-
-sfr at 0x86 U0CSR;
-sfr at 0xF8 U1CSR;
-
-/*
- * IRCON2
- */
-sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
-
-sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
-sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
-sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
-sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
-sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
-sbit at 0xEB P1IF; /* Port1 interrupt flag */
-sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
-
-# define UxCSR_MODE_UART (1 << 7)
-# define UxCSR_MODE_SPI (0 << 7)
-# define UxCSR_RE (1 << 6)
-# define UxCSR_SLAVE (1 << 5)
-# define UxCSR_MASTER (0 << 5)
-# define UxCSR_FE (1 << 4)
-# define UxCSR_ERR (1 << 3)
-# define UxCSR_RX_BYTE (1 << 2)
-# define UxCSR_TX_BYTE (1 << 1)
-# define UxCSR_ACTIVE (1 << 0)
-
-sfr at 0xc4 U0UCR;
-sfr at 0xfb U1UCR;
-
-# define UxUCR_FLUSH (1 << 7)
-# define UxUCR_FLOW_DISABLE (0 << 6)
-# define UxUCR_FLOW_ENABLE (1 << 6)
-# define UxUCR_D9_EVEN_PARITY (0 << 5)
-# define UxUCR_D9_ODD_PARITY (1 << 5)
-# define UxUCR_BIT9_8_BITS (0 << 4)
-# define UxUCR_BIT9_9_BITS (1 << 4)
-# define UxUCR_PARITY_DISABLE (0 << 3)
-# define UxUCR_PARITY_ENABLE (1 << 3)
-# define UxUCR_SPB_1_STOP_BIT (0 << 2)
-# define UxUCR_SPB_2_STOP_BITS (1 << 2)
-# define UxUCR_STOP_LOW (0 << 1)
-# define UxUCR_STOP_HIGH (1 << 1)
-# define UxUCR_START_LOW (0 << 0)
-# define UxUCR_START_HIGH (1 << 0)
-
-sfr at 0xc5 U0GCR;
-sfr at 0xfc U1GCR;
-
-# define UxGCR_CPOL_NEGATIVE (0 << 7)
-# define UxGCR_CPOL_POSITIVE (1 << 7)
-# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
-# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
-# define UxGCR_ORDER_LSB (0 << 5)
-# define UxGCR_ORDER_MSB (1 << 5)
-# define UxGCR_BAUD_E_MASK (0x1f)
-# define UxGCR_BAUD_E_SHIFT 0
-
-sfr at 0xc1 U0DBUF;
-sfr at 0xf9 U1DBUF;
-sfr at 0xc2 U0BAUD;
-sfr at 0xfa U1BAUD;
-
-#define DEBUG P1_1
-
-
-# define DMA_LEN_HIGH_VLEN_MASK (7 << 5)
-# define DMA_LEN_HIGH_VLEN_LEN (0 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5)
-# define DMA_LEN_HIGH_VLEN (2 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5)
-# define DMA_LEN_HIGH_MASK (0x1f)
-
-# define DMA_CFG0_WORDSIZE_8 (0 << 7)
-# define DMA_CFG0_WORDSIZE_16 (1 << 7)
-# define DMA_CFG0_TMODE_MASK (3 << 5)
-# define DMA_CFG0_TMODE_SINGLE (0 << 5)
-# define DMA_CFG0_TMODE_BLOCK (1 << 5)
-# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5)
-# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
-
-/*
- * DMA triggers
- */
-# define DMA_CFG0_TRIGGER_NONE 0
-# define DMA_CFG0_TRIGGER_PREV 1
-# define DMA_CFG0_TRIGGER_T1_CH0 2
-# define DMA_CFG0_TRIGGER_T1_CH1 3
-# define DMA_CFG0_TRIGGER_T1_CH2 4
-# define DMA_CFG0_TRIGGER_T2_OVFL 6
-# define DMA_CFG0_TRIGGER_T3_CH0 7
-# define DMA_CFG0_TRIGGER_T3_CH1 8
-# define DMA_CFG0_TRIGGER_T4_CH0 9
-# define DMA_CFG0_TRIGGER_T4_CH1 10
-# define DMA_CFG0_TRIGGER_IOC_0 12
-# define DMA_CFG0_TRIGGER_IOC_1 13
-# define DMA_CFG0_TRIGGER_URX0 14
-# define DMA_CFG0_TRIGGER_UTX0 15
-# define DMA_CFG0_TRIGGER_URX1 16
-# define DMA_CFG0_TRIGGER_UTX1 17
-# define DMA_CFG0_TRIGGER_FLASH 18
-# define DMA_CFG0_TRIGGER_RADIO 19
-# define DMA_CFG0_TRIGGER_ADC_CHALL 20
-# define DMA_CFG0_TRIGGER_ADC_CH0 21
-# define DMA_CFG0_TRIGGER_ADC_CH1 22
-# define DMA_CFG0_TRIGGER_ADC_CH2 23
-# define DMA_CFG0_TRIGGER_ADC_CH3 24
-# define DMA_CFG0_TRIGGER_ADC_CH4 25
-# define DMA_CFG0_TRIGGER_ADC_CH5 26
-# define DMA_CFG0_TRIGGER_ADC_CH6 27
-# define DMA_CFG0_TRIGGER_I2SRX 27
-# define DMA_CFG0_TRIGGER_ADC_CH7 28
-# define DMA_CFG0_TRIGGER_I2STX 28
-# define DMA_CFG0_TRIGGER_ENC_DW 29
-# define DMA_CFG0_TRIGGER_DNC_UP 30
-
-# define DMA_CFG1_SRCINC_MASK (3 << 6)
-# define DMA_CFG1_SRCINC_0 (0 << 6)
-# define DMA_CFG1_SRCINC_1 (1 << 6)
-# define DMA_CFG1_SRCINC_2 (2 << 6)
-# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6)
-
-# define DMA_CFG1_DESTINC_MASK (3 << 4)
-# define DMA_CFG1_DESTINC_0 (0 << 4)
-# define DMA_CFG1_DESTINC_1 (1 << 4)
-# define DMA_CFG1_DESTINC_2 (2 << 4)
-# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4)
-
-# define DMA_CFG1_IRQMASK (1 << 3)
-# define DMA_CFG1_M8 (1 << 2)
-
-# define DMA_CFG1_PRIORITY_MASK (3 << 0)
-# define DMA_CFG1_PRIORITY_LOW (0 << 0)
-# define DMA_CFG1_PRIORITY_NORMAL (1 << 0)
-# define DMA_CFG1_PRIORITY_HIGH (2 << 0)
-
-/*
- * DMAARM - DMA Channel Arm
- */
-
-sfr at 0xD6 DMAARM;
-
-# define DMAARM_ABORT (1 << 7)
-# define DMAARM_DMAARM4 (1 << 4)
-# define DMAARM_DMAARM3 (1 << 3)
-# define DMAARM_DMAARM2 (1 << 2)
-# define DMAARM_DMAARM1 (1 << 1)
-# define DMAARM_DMAARM0 (1 << 0)
-
-/*
- * DMAREQ - DMA Channel Start Request and Status
- */
-
-sfr at 0xD7 DMAREQ;
-
-# define DMAREQ_DMAREQ4 (1 << 4)
-# define DMAREQ_DMAREQ3 (1 << 3)
-# define DMAREQ_DMAREQ2 (1 << 2)
-# define DMAREQ_DMAREQ1 (1 << 1)
-# define DMAREQ_DMAREQ0 (1 << 0)
-
-/*
- * DMA configuration 0 address
- */
-
-sfr at 0xD5 DMA0CFGH;
-sfr at 0xD4 DMA0CFGL;
-
-/*
- * DMA configuration 1-4 address
- */
-
-sfr at 0xD3 DMA1CFGH;
-sfr at 0xD2 DMA1CFGL;
-
-/*
- * DMAIRQ - DMA Interrupt Flag
- */
-
-sfr at 0xD1 DMAIRQ;
-
-# define DMAIRQ_DMAIF4 (1 << 4)
-# define DMAIRQ_DMAIF3 (1 << 3)
-# define DMAIRQ_DMAIF2 (1 << 2)
-# define DMAIRQ_DMAIF1 (1 << 1)
-# define DMAIRQ_DMAIF0 (1 << 0)
-
-struct cc_dma_channel {
- uint8_t src_high;
- uint8_t src_low;
- uint8_t dst_high;
- uint8_t dst_low;
- uint8_t len_high;
- uint8_t len_low;
- uint8_t cfg0;
- uint8_t cfg1;
-};
-
-/*
- * ADC Data register, low and high
- */
-sfr at 0xBA ADCL;
-sfr at 0xBB ADCH;
-__xdata __at (0xDFBA) volatile uint16_t ADCXDATA;
-
-/*
- * ADC Control Register 1
- */
-sfr at 0xB4 ADCCON1;
-
-# define ADCCON1_EOC (1 << 7) /* conversion complete */
-# define ADCCON1_ST (1 << 6) /* start conversion */
-
-# define ADCCON1_STSEL_MASK (3 << 4) /* start select */
-# define ADCCON1_STSEL_EXTERNAL (0 << 4) /* P2_0 pin triggers */
-# define ADCCON1_STSEL_FULLSPEED (1 << 4) /* full speed, no waiting */
-# define ADCCON1_STSEL_TIMER1 (2 << 4) /* timer 1 channel 0 */
-# define ADCCON1_STSEL_START (3 << 4) /* set start bit */
-
-# define ADCCON1_RCTRL_MASK (3 << 2) /* random number control */
-# define ADCCON1_RCTRL_COMPLETE (0 << 2) /* operation completed */
-# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2) /* Clock the LFSR once */
-
-/*
- * ADC Control Register 2
- */
-sfr at 0xB5 ADCCON2;
-
-# define ADCCON2_SREF_MASK (3 << 6) /* reference voltage */
-# define ADCCON2_SREF_1_25V (0 << 6) /* internal 1.25V */
-# define ADCCON2_SREF_EXTERNAL (1 << 6) /* external on AIN7 cc1110 */
-# define ADCCON2_SREF_VDD (2 << 6) /* VDD on the AVDD pin */
-# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6) /* external on AIN6-7 cc1110 */
-
-# define ADCCON2_SDIV_MASK (3 << 4) /* decimation rate */
-# define ADCCON2_SDIV_64 (0 << 4) /* 7 bits */
-# define ADCCON2_SDIV_128 (1 << 4) /* 9 bits */
-# define ADCCON2_SDIV_256 (2 << 4) /* 10 bits */
-# define ADCCON2_SDIV_512 (3 << 4) /* 12 bits */
-
-# define ADCCON2_SCH_MASK (0xf << 0) /* Sequence channel select */
-# define ADCCON2_SCH_SHIFT 0
-# define ADCCON2_SCH_AIN0 (0 << 0)
-# define ADCCON2_SCH_AIN1 (1 << 0)
-# define ADCCON2_SCH_AIN2 (2 << 0)
-# define ADCCON2_SCH_AIN3 (3 << 0)
-# define ADCCON2_SCH_AIN4 (4 << 0)
-# define ADCCON2_SCH_AIN5 (5 << 0)
-# define ADCCON2_SCH_AIN6 (6 << 0)
-# define ADCCON2_SCH_AIN7 (7 << 0)
-# define ADCCON2_SCH_AIN0_AIN1 (8 << 0)
-# define ADCCON2_SCH_AIN2_AIN3 (9 << 0)
-# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0)
-# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0)
-# define ADCCON2_SCH_GND (0xc << 0)
-# define ADCCON2_SCH_VREF (0xd << 0)
-# define ADCCON2_SCH_TEMP (0xe << 0)
-# define ADCCON2_SCH_VDD_3 (0xf << 0)
-
-
-/*
- * ADC Control Register 3
- */
-
-sfr at 0xB6 ADCCON3;
-
-# define ADCCON3_EREF_MASK (3 << 6) /* extra conversion reference */
-# define ADCCON3_EREF_1_25 (0 << 6) /* internal 1.25V */
-# define ADCCON3_EREF_EXTERNAL (1 << 6) /* external AIN7 cc1110 */
-# define ADCCON3_EREF_VDD (2 << 6) /* VDD on the AVDD pin */
-# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6) /* external AIN6-7 cc1110 */
-# define ADCCON2_EDIV_MASK (3 << 4) /* extral decimation */
-# define ADCCON2_EDIV_64 (0 << 4) /* 7 bits */
-# define ADCCON2_EDIV_128 (1 << 4) /* 9 bits */
-# define ADCCON2_EDIV_256 (2 << 4) /* 10 bits */
-# define ADCCON2_EDIV_512 (3 << 4) /* 12 bits */
-# define ADCCON3_ECH_MASK (0xf << 0) /* Sequence channel select */
-# define ADCCON3_ECH_SHIFT 0
-# define ADCCON3_ECH_AIN0 (0 << 0)
-# define ADCCON3_ECH_AIN1 (1 << 0)
-# define ADCCON3_ECH_AIN2 (2 << 0)
-# define ADCCON3_ECH_AIN3 (3 << 0)
-# define ADCCON3_ECH_AIN4 (4 << 0)
-# define ADCCON3_ECH_AIN5 (5 << 0)
-# define ADCCON3_ECH_AIN6 (6 << 0)
-# define ADCCON3_ECH_AIN7 (7 << 0)
-# define ADCCON3_ECH_AIN0_AIN1 (8 << 0)
-# define ADCCON3_ECH_AIN2_AIN3 (9 << 0)
-# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0)
-# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0)
-# define ADCCON3_ECH_GND (0xc << 0)
-# define ADCCON3_ECH_VREF (0xd << 0)
-# define ADCCON3_ECH_TEMP (0xe << 0)
-# define ADCCON3_ECH_VDD_3 (0xf << 0)
-
-sfr at 0xF2 ADCCFG;
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0;
- unsigned char j = 0;
-
- n++;
- while (--n != 0)
- while (--i != 0)
- while (--j != 0)
- nop();
-}
-
-void
-debug_byte(uint8_t byte)
-{
- uint8_t s;
-
- for (s = 0; s < 8; s++) {
- DEBUG = byte & 1;
- delay(5);
- byte >>= 1;
- }
-}
-
-struct cc_dma_channel __xdata dma_config;
-
-#define ADC_LEN 6
-
-/* The DMA engine writes to XDATA in MSB order */
-struct dma_xdata16 {
- uint8_t high;
- uint8_t low;
-};
-
-struct dma_xdata16 adc_output[ADC_LEN];
-
-#define DMA_XDATA16(a,n) ((uint16_t) ((a)[n].high << 8) | (uint16_t) (a[n].low))
-
-#define ADDRH(a) (((uint16_t) (a)) >> 8)
-#define ADDRL(a) (((uint16_t) (a)))
-
-void
-adc_init(void)
-{
- dma_config.cfg0 = (DMA_CFG0_WORDSIZE_16 |
- DMA_CFG0_TMODE_REPEATED_SINGLE |
- DMA_CFG0_TRIGGER_ADC_CHALL);
- dma_config.cfg1 = (DMA_CFG1_SRCINC_0 |
- DMA_CFG1_DESTINC_1 |
- DMA_CFG1_PRIORITY_NORMAL);
-
- dma_config.src_high = ADDRH(&ADCXDATA);
- dma_config.src_low = ADDRL(&ADCXDATA);
- dma_config.dst_high = ADDRH(adc_output);
- dma_config.dst_low = ADDRL(adc_output);
- dma_config.len_high = 0;
- dma_config.len_low = ADC_LEN;
- DMA0CFGH = ADDRH(&dma_config);
- DMA0CFGL = ADDRL(&dma_config);
- ADCCFG = ((1 << 0) | /* acceleration */
- (1 << 1) | /* pressure */
- (1 << 2) | /* temperature */
- (1 << 3) | /* battery voltage */
- (1 << 4) | /* drogue sense */
- (1 << 5)); /* main sense */
-
- ADCCON1 = (ADCCON1_STSEL_START); /* ST bit triggers */
- ADCCON2 = (ADCCON2_SREF_VDD | /* reference voltage is VDD */
- ADCCON2_SDIV_512 | /* 12 bit ADC results */
- ADCCON2_SCH_AIN5); /* sample all 6 inputs */
-}
-
-void
-adc_run(void)
-{
- DMAIRQ &= ~1;
- DMAARM |= 1;
- ADCCON1 |= ADCCON1_ST;
- while ((DMAIRQ & 1) == 0)
- ;
-}
-
-/*
- * This version uses the USART in UART mode
- */
-void
-usart_init(void)
-{
- P1DIR |= (1 << 2);
- /*
- * Configure the peripheral pin choices
- * for both of the serial ports
- *
- * Note that telemetrum will use U1CFG_ALT_2
- * but that overlaps with SPI ALT_2, so until
- * we can test that this works, we'll set this
- * to ALT_1
- */
- PERCFG = (PERCFG_U1CFG_ALT_2 |
- PERCFG_U0CFG_ALT_1);
-
- /*
- * Make the UART pins controlled by the UART
- * hardware
- */
- P1SEL |= ((1 << 6) | (1 << 7));
-
- /*
- * UART mode with the receiver enabled
- */
- U1CSR = (UxCSR_MODE_UART |
- UxCSR_RE);
- /*
- * Pick a 38.4kbaud rate
- */
- U1BAUD = 163;
- U1GCR = 10 << UxGCR_BAUD_E_SHIFT; /* 38400 */
-// U1GCR = 3 << UxGCR_BAUD_E_SHIFT; /* 300 */
- /*
- * Reasonable serial parameters
- */
- U1UCR = (UxUCR_FLUSH |
- UxUCR_FLOW_DISABLE |
- UxUCR_D9_ODD_PARITY |
- UxUCR_BIT9_8_BITS |
- UxUCR_PARITY_DISABLE |
- UxUCR_SPB_2_STOP_BITS |
- UxUCR_STOP_HIGH |
- UxUCR_START_LOW);
-}
-
-void
-usart_out_byte(uint8_t byte)
-{
- U1DBUF = byte;
- while (!UTX1IF)
- ;
- UTX1IF = 0;
-}
-
-void
-usart_out_string(uint8_t *string)
-{
- uint8_t b;
-
- while (b = *string++)
- usart_out_byte(b);
-}
-
-#define NUM_LEN 6
-
-uint8_t __xdata num_buffer[NUM_LEN];
-uint8_t __xdata * __xdata num_ptr;
-
-void
-usart_out_number(uint16_t v)
-{
-
- num_ptr = num_buffer + NUM_LEN;
- *--num_ptr = '\0';
- do {
- *--num_ptr = '0' + v % 10;
- v /= 10;
- } while (v);
- while (num_ptr != num_buffer)
- *--num_ptr = ' ';
- usart_out_string(num_buffer);
-}
-
-#define ADC(n) DMA_XDATA16(adc_output,n)
-
-main ()
-{
- P1DIR = 3;
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
-
- adc_init();
- P1_0 = 1;
- usart_init();
- for (;;) {
- adc_run();
- usart_out_string("accel: ");
- usart_out_number(ADC(0));
- usart_out_string(" pres: ");
- usart_out_number(ADC(1));
- usart_out_string(" temp: ");
- usart_out_number(ADC(2));
- usart_out_string(" batt: ");
- usart_out_number(ADC(3));
- usart_out_string(" drogue: ");
- usart_out_number(ADC(4));
- usart_out_string(" main: ");
- usart_out_number(ADC(5));
- usart_out_string("\r\n");
- delay(10);
- }
-}
+++ /dev/null
-PROG=adc
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=$(PROG).c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=$(PROG)-flash.ihx $(PROG)-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-$(PROG)-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL)
-
-$(PROG)-flash.ihx: $(PROG)-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdint.h>
-
-/*
- * Test ADC in DMA mode
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-sfr at 0xbe SLEEP;
-
-# define SLEEP_USB_EN (1 << 7)
-# define SLEEP_XOSC_STB (1 << 6)
-
-sfr at 0xF1 PERCFG;
-#define PERCFG_T1CFG_ALT_1 (0 << 6)
-#define PERCFG_T1CFG_ALT_2 (1 << 6)
-
-#define PERCFG_T3CFG_ALT_1 (0 << 5)
-#define PERCFG_T3CFG_ALT_2 (1 << 5)
-
-#define PERCFG_T4CFG_ALT_1 (0 << 4)
-#define PERCFG_T4CFG_ALT_2 (1 << 4)
-
-#define PERCFG_U1CFG_ALT_1 (0 << 1)
-#define PERCFG_U1CFG_ALT_2 (1 << 1)
-
-#define PERCFG_U0CFG_ALT_1 (0 << 0)
-#define PERCFG_U0CFG_ALT_2 (1 << 0)
-
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-/*
- * UART registers
- */
-
-sfr at 0x86 U0CSR;
-sfr at 0xF8 U1CSR;
-
-/*
- * IRCON2
- */
-sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
-
-sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
-sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
-sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
-sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
-sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
-sbit at 0xEB P1IF; /* Port1 interrupt flag */
-sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
-
-# define UxCSR_MODE_UART (1 << 7)
-# define UxCSR_MODE_SPI (0 << 7)
-# define UxCSR_RE (1 << 6)
-# define UxCSR_SLAVE (1 << 5)
-# define UxCSR_MASTER (0 << 5)
-# define UxCSR_FE (1 << 4)
-# define UxCSR_ERR (1 << 3)
-# define UxCSR_RX_BYTE (1 << 2)
-# define UxCSR_TX_BYTE (1 << 1)
-# define UxCSR_ACTIVE (1 << 0)
-
-sfr at 0xc4 U0UCR;
-sfr at 0xfb U1UCR;
-
-# define UxUCR_FLUSH (1 << 7)
-# define UxUCR_FLOW_DISABLE (0 << 6)
-# define UxUCR_FLOW_ENABLE (1 << 6)
-# define UxUCR_D9_EVEN_PARITY (0 << 5)
-# define UxUCR_D9_ODD_PARITY (1 << 5)
-# define UxUCR_BIT9_8_BITS (0 << 4)
-# define UxUCR_BIT9_9_BITS (1 << 4)
-# define UxUCR_PARITY_DISABLE (0 << 3)
-# define UxUCR_PARITY_ENABLE (1 << 3)
-# define UxUCR_SPB_1_STOP_BIT (0 << 2)
-# define UxUCR_SPB_2_STOP_BITS (1 << 2)
-# define UxUCR_STOP_LOW (0 << 1)
-# define UxUCR_STOP_HIGH (1 << 1)
-# define UxUCR_START_LOW (0 << 0)
-# define UxUCR_START_HIGH (1 << 0)
-
-sfr at 0xc5 U0GCR;
-sfr at 0xfc U1GCR;
-
-# define UxGCR_CPOL_NEGATIVE (0 << 7)
-# define UxGCR_CPOL_POSITIVE (1 << 7)
-# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
-# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
-# define UxGCR_ORDER_LSB (0 << 5)
-# define UxGCR_ORDER_MSB (1 << 5)
-# define UxGCR_BAUD_E_MASK (0x1f)
-# define UxGCR_BAUD_E_SHIFT 0
-
-sfr at 0xc1 U0DBUF;
-sfr at 0xf9 U1DBUF;
-sfr at 0xc2 U0BAUD;
-sfr at 0xfa U1BAUD;
-
-#define DEBUG P1_1
-
-
-# define DMA_LEN_HIGH_VLEN_MASK (7 << 5)
-# define DMA_LEN_HIGH_VLEN_LEN (0 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5)
-# define DMA_LEN_HIGH_VLEN (2 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5)
-# define DMA_LEN_HIGH_MASK (0x1f)
-
-# define DMA_CFG0_WORDSIZE_8 (0 << 7)
-# define DMA_CFG0_WORDSIZE_16 (1 << 7)
-# define DMA_CFG0_TMODE_MASK (3 << 5)
-# define DMA_CFG0_TMODE_SINGLE (0 << 5)
-# define DMA_CFG0_TMODE_BLOCK (1 << 5)
-# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5)
-# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
-
-/*
- * DMA triggers
- */
-# define DMA_CFG0_TRIGGER_NONE 0
-# define DMA_CFG0_TRIGGER_PREV 1
-# define DMA_CFG0_TRIGGER_T1_CH0 2
-# define DMA_CFG0_TRIGGER_T1_CH1 3
-# define DMA_CFG0_TRIGGER_T1_CH2 4
-# define DMA_CFG0_TRIGGER_T2_OVFL 6
-# define DMA_CFG0_TRIGGER_T3_CH0 7
-# define DMA_CFG0_TRIGGER_T3_CH1 8
-# define DMA_CFG0_TRIGGER_T4_CH0 9
-# define DMA_CFG0_TRIGGER_T4_CH1 10
-# define DMA_CFG0_TRIGGER_IOC_0 12
-# define DMA_CFG0_TRIGGER_IOC_1 13
-# define DMA_CFG0_TRIGGER_URX0 14
-# define DMA_CFG0_TRIGGER_UTX0 15
-# define DMA_CFG0_TRIGGER_URX1 16
-# define DMA_CFG0_TRIGGER_UTX1 17
-# define DMA_CFG0_TRIGGER_FLASH 18
-# define DMA_CFG0_TRIGGER_RADIO 19
-# define DMA_CFG0_TRIGGER_ADC_CHALL 20
-# define DMA_CFG0_TRIGGER_ADC_CH0 21
-# define DMA_CFG0_TRIGGER_ADC_CH1 22
-# define DMA_CFG0_TRIGGER_ADC_CH2 23
-# define DMA_CFG0_TRIGGER_ADC_CH3 24
-# define DMA_CFG0_TRIGGER_ADC_CH4 25
-# define DMA_CFG0_TRIGGER_ADC_CH5 26
-# define DMA_CFG0_TRIGGER_ADC_CH6 27
-# define DMA_CFG0_TRIGGER_I2SRX 27
-# define DMA_CFG0_TRIGGER_ADC_CH7 28
-# define DMA_CFG0_TRIGGER_I2STX 28
-# define DMA_CFG0_TRIGGER_ENC_DW 29
-# define DMA_CFG0_TRIGGER_DNC_UP 30
-
-# define DMA_CFG1_SRCINC_MASK (3 << 6)
-# define DMA_CFG1_SRCINC_0 (0 << 6)
-# define DMA_CFG1_SRCINC_1 (1 << 6)
-# define DMA_CFG1_SRCINC_2 (2 << 6)
-# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6)
-
-# define DMA_CFG1_DESTINC_MASK (3 << 4)
-# define DMA_CFG1_DESTINC_0 (0 << 4)
-# define DMA_CFG1_DESTINC_1 (1 << 4)
-# define DMA_CFG1_DESTINC_2 (2 << 4)
-# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4)
-
-# define DMA_CFG1_IRQMASK (1 << 3)
-# define DMA_CFG1_M8 (1 << 2)
-
-# define DMA_CFG1_PRIORITY_MASK (3 << 0)
-# define DMA_CFG1_PRIORITY_LOW (0 << 0)
-# define DMA_CFG1_PRIORITY_NORMAL (1 << 0)
-# define DMA_CFG1_PRIORITY_HIGH (2 << 0)
-
-/*
- * DMAARM - DMA Channel Arm
- */
-
-sfr at 0xD6 DMAARM;
-
-# define DMAARM_ABORT (1 << 7)
-# define DMAARM_DMAARM4 (1 << 4)
-# define DMAARM_DMAARM3 (1 << 3)
-# define DMAARM_DMAARM2 (1 << 2)
-# define DMAARM_DMAARM1 (1 << 1)
-# define DMAARM_DMAARM0 (1 << 0)
-
-/*
- * DMAREQ - DMA Channel Start Request and Status
- */
-
-sfr at 0xD7 DMAREQ;
-
-# define DMAREQ_DMAREQ4 (1 << 4)
-# define DMAREQ_DMAREQ3 (1 << 3)
-# define DMAREQ_DMAREQ2 (1 << 2)
-# define DMAREQ_DMAREQ1 (1 << 1)
-# define DMAREQ_DMAREQ0 (1 << 0)
-
-/*
- * DMA configuration 0 address
- */
-
-sfr at 0xD5 DMA0CFGH;
-sfr at 0xD4 DMA0CFGL;
-
-/*
- * DMA configuration 1-4 address
- */
-
-sfr at 0xD3 DMA1CFGH;
-sfr at 0xD2 DMA1CFGL;
-
-/*
- * DMAIRQ - DMA Interrupt Flag
- */
-
-sfr at 0xD1 DMAIRQ;
-
-# define DMAIRQ_DMAIF4 (1 << 4)
-# define DMAIRQ_DMAIF3 (1 << 3)
-# define DMAIRQ_DMAIF2 (1 << 2)
-# define DMAIRQ_DMAIF1 (1 << 1)
-# define DMAIRQ_DMAIF0 (1 << 0)
-
-struct cc_dma_channel {
- uint8_t src_high;
- uint8_t src_low;
- uint8_t dst_high;
- uint8_t dst_low;
- uint8_t len_high;
- uint8_t len_low;
- uint8_t cfg0;
- uint8_t cfg1;
-};
-
-/*
- * ADC Data register, low and high
- */
-sfr at 0xBA ADCL;
-sfr at 0xBB ADCH;
-__xdata __at (0xDFBA) volatile uint16_t ADCXDATA;
-
-/*
- * ADC Control Register 1
- */
-sfr at 0xB4 ADCCON1;
-
-# define ADCCON1_EOC (1 << 7) /* conversion complete */
-# define ADCCON1_ST (1 << 6) /* start conversion */
-
-# define ADCCON1_STSEL_MASK (3 << 4) /* start select */
-# define ADCCON1_STSEL_EXTERNAL (0 << 4) /* P2_0 pin triggers */
-# define ADCCON1_STSEL_FULLSPEED (1 << 4) /* full speed, no waiting */
-# define ADCCON1_STSEL_TIMER1 (2 << 4) /* timer 1 channel 0 */
-# define ADCCON1_STSEL_START (3 << 4) /* set start bit */
-
-# define ADCCON1_RCTRL_MASK (3 << 2) /* random number control */
-# define ADCCON1_RCTRL_COMPLETE (0 << 2) /* operation completed */
-# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2) /* Clock the LFSR once */
-
-/*
- * ADC Control Register 2
- */
-sfr at 0xB5 ADCCON2;
-
-# define ADCCON2_SREF_MASK (3 << 6) /* reference voltage */
-# define ADCCON2_SREF_1_25V (0 << 6) /* internal 1.25V */
-# define ADCCON2_SREF_EXTERNAL (1 << 6) /* external on AIN7 cc1110 */
-# define ADCCON2_SREF_VDD (2 << 6) /* VDD on the AVDD pin */
-# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6) /* external on AIN6-7 cc1110 */
-
-# define ADCCON2_SDIV_MASK (3 << 4) /* decimation rate */
-# define ADCCON2_SDIV_64 (0 << 4) /* 7 bits */
-# define ADCCON2_SDIV_128 (1 << 4) /* 9 bits */
-# define ADCCON2_SDIV_256 (2 << 4) /* 10 bits */
-# define ADCCON2_SDIV_512 (3 << 4) /* 12 bits */
-
-# define ADCCON2_SCH_MASK (0xf << 0) /* Sequence channel select */
-# define ADCCON2_SCH_SHIFT 0
-# define ADCCON2_SCH_AIN0 (0 << 0)
-# define ADCCON2_SCH_AIN1 (1 << 0)
-# define ADCCON2_SCH_AIN2 (2 << 0)
-# define ADCCON2_SCH_AIN3 (3 << 0)
-# define ADCCON2_SCH_AIN4 (4 << 0)
-# define ADCCON2_SCH_AIN5 (5 << 0)
-# define ADCCON2_SCH_AIN6 (6 << 0)
-# define ADCCON2_SCH_AIN7 (7 << 0)
-# define ADCCON2_SCH_AIN0_AIN1 (8 << 0)
-# define ADCCON2_SCH_AIN2_AIN3 (9 << 0)
-# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0)
-# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0)
-# define ADCCON2_SCH_GND (0xc << 0)
-# define ADCCON2_SCH_VREF (0xd << 0)
-# define ADCCON2_SCH_TEMP (0xe << 0)
-# define ADCCON2_SCH_VDD_3 (0xf << 0)
-
-
-/*
- * ADC Control Register 3
- */
-
-sfr at 0xB6 ADCCON3;
-
-# define ADCCON3_EREF_MASK (3 << 6) /* extra conversion reference */
-# define ADCCON3_EREF_1_25 (0 << 6) /* internal 1.25V */
-# define ADCCON3_EREF_EXTERNAL (1 << 6) /* external AIN7 cc1110 */
-# define ADCCON3_EREF_VDD (2 << 6) /* VDD on the AVDD pin */
-# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6) /* external AIN6-7 cc1110 */
-# define ADCCON2_EDIV_MASK (3 << 4) /* extral decimation */
-# define ADCCON2_EDIV_64 (0 << 4) /* 7 bits */
-# define ADCCON2_EDIV_128 (1 << 4) /* 9 bits */
-# define ADCCON2_EDIV_256 (2 << 4) /* 10 bits */
-# define ADCCON2_EDIV_512 (3 << 4) /* 12 bits */
-# define ADCCON3_ECH_MASK (0xf << 0) /* Sequence channel select */
-# define ADCCON3_ECH_SHIFT 0
-# define ADCCON3_ECH_AIN0 (0 << 0)
-# define ADCCON3_ECH_AIN1 (1 << 0)
-# define ADCCON3_ECH_AIN2 (2 << 0)
-# define ADCCON3_ECH_AIN3 (3 << 0)
-# define ADCCON3_ECH_AIN4 (4 << 0)
-# define ADCCON3_ECH_AIN5 (5 << 0)
-# define ADCCON3_ECH_AIN6 (6 << 0)
-# define ADCCON3_ECH_AIN7 (7 << 0)
-# define ADCCON3_ECH_AIN0_AIN1 (8 << 0)
-# define ADCCON3_ECH_AIN2_AIN3 (9 << 0)
-# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0)
-# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0)
-# define ADCCON3_ECH_GND (0xc << 0)
-# define ADCCON3_ECH_VREF (0xd << 0)
-# define ADCCON3_ECH_TEMP (0xe << 0)
-# define ADCCON3_ECH_VDD_3 (0xf << 0)
-
-sfr at 0xF2 ADCCFG;
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0;
- unsigned char j = 0;
-
- n++;
- while (--n != 0)
- while (--i != 0)
- while (--j != 0)
- nop();
-}
-
-void
-debug_byte(uint8_t byte)
-{
- uint8_t s;
-
- for (s = 0; s < 8; s++) {
- DEBUG = byte & 1;
- delay(5);
- byte >>= 1;
- }
-}
-
-struct cc_dma_channel __xdata dma_config;
-
-#define ADC_LEN 6
-
-uint16_t __xdata adc_output[ADC_LEN];
-
-#define ADDRH(a) (((uint16_t) (a)) >> 8)
-#define ADDRL(a) (((uint16_t) (a)))
-
-void
-adc_init(void)
-{
- dma_config.cfg0 = (DMA_CFG0_WORDSIZE_16 |
- DMA_CFG0_TMODE_REPEATED_SINGLE |
- DMA_CFG0_TRIGGER_ADC_CHALL);
- dma_config.cfg1 = (DMA_CFG1_SRCINC_0 |
- DMA_CFG1_DESTINC_1 |
- DMA_CFG1_PRIORITY_NORMAL);
-
- dma_config.src_high = ADDRH(&ADCXDATA);
- dma_config.src_low = ADDRL(&ADCXDATA);
- dma_config.dst_high = ADDRH(adc_output);
- dma_config.dst_low = ADDRL(adc_output);
- dma_config.len_high = 0;
- dma_config.len_low = ADC_LEN;
- DMA0CFGH = ADDRH(&dma_config);
- DMA0CFGL = ADDRL(&dma_config);
- ADCCFG = ((1 << 0) | /* acceleration */
- (1 << 1) | /* pressure */
- (1 << 2) | /* temperature */
- (1 << 3) | /* battery voltage */
- (1 << 4) | /* drogue sense */
- (1 << 5)); /* main sense */
-
- ADCCON1 = (ADCCON1_STSEL_START); /* ST bit triggers */
- ADCCON2 = (ADCCON2_SREF_VDD | /* reference voltage is VDD */
- ADCCON2_SDIV_512 | /* 12 bit ADC results */
- ADCCON2_SCH_AIN5); /* sample all 6 inputs */
-}
-
-void
-adc_run(void)
-{
- DMAIRQ &= ~1;
- DMAARM |= 1;
- ADCCON1 |= ADCCON1_ST;
- while ((DMAIRQ & 1) == 0)
- ;
-}
-
-main ()
-{
- int i;
- P1DIR |= 2;
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
- while (P1 & 0x4)
- ;
-
- adc_init();
- for (;;) {
- adc_run();
- for (i = 0; i < ADC_LEN; i++)
- debug_byte(adc_output[i]);
- }
-}
+++ /dev/null
-PROG=beep_timer
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=$(PROG).c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=$(PROG)-flash.ihx $(PROG)-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-$(PROG)-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL)
-
-$(PROG)-flash.ihx: $(PROG)-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-sfr at 0xbe SLEEP;
-
-# define SLEEP_USB_EN (1 << 7)
-# define SLEEP_XOSC_STB (1 << 6)
-
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-sfr at 0xF1 PERCFG;
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-#define P2SEL_PRI3P1_USART0 (0 << 6)
-#define P2SEL_PRI3P1_USART1 (1 << 6)
-#define P2SEL_PRI2P1_USART1 (0 << 5)
-#define P2SEL_PRI2P1_TIMER3 (1 << 5)
-#define P2SEL_PRI1P1_TIMER1 (0 << 4)
-#define P2SEL_PRI1P1_TIMER4 (1 << 4)
-#define P2SEL_PRI0P1_USART0 (0 << 3)
-#define P2SEL_PRI0P1_TIMER1 (1 << 3)
-#define P2SEL_SELP2_4_GPIO (0 << 2)
-#define P2SEL_SELP2_4_PERIPHERAL (1 << 2)
-#define P2SEL_SELP2_3_GPIO (0 << 1)
-#define P2SEL_SELP2_3_PERIPHERAL (1 << 1)
-#define P2SEL_SELP2_0_GPIO (0 << 0)
-#define P2SEL_SELP2_0_PERIPHERAL (1 << 0)
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-sfr at 0xF1 PERCFG;
-#define PERCFG_T1CFG_ALT_1 (0 << 6)
-#define PERCFG_T1CFG_ALT_2 (1 << 6)
-
-#define PERCFG_T3CFG_ALT_1 (0 << 5)
-#define PERCFG_T3CFG_ALT_2 (1 << 5)
-
-#define PERCFG_T4CFG_ALT_1 (0 << 4)
-#define PERCFG_T4CFG_ALT_2 (1 << 4)
-
-#define PERCFG_U1CFG_ALT_1 (0 << 1)
-#define PERCFG_U1CFG_ALT_2 (1 << 1)
-
-#define PERCFG_U0CFG_ALT_1 (0 << 0)
-#define PERCFG_U0CFG_ALT_2 (1 << 0)
-
-/* Timer count */
-sfr at 0xCA T3CNT;
-sfr at 0xEA T4CNT;
-
-/* Timer control */
-
-sfr at 0xCB T3CTL;
-sfr at 0xEB T4CTL;
-
-#define TxCTL_DIV_1 (0 << 5)
-#define TxCTL_DIV_2 (1 << 5)
-#define TxCTL_DIV_4 (2 << 5)
-#define TxCTL_DIV_8 (3 << 5)
-#define TxCTL_DIV_16 (4 << 5)
-#define TxCTL_DIV_32 (5 << 5)
-#define TxCTL_DIV_64 (6 << 5)
-#define TxCTL_DIV_128 (7 << 5)
-#define TxCTL_START (1 << 4)
-#define TxCTL_OVFIM (1 << 3)
-#define TxCTL_CLR (1 << 2)
-#define TxCTL_MODE_FREE (0 << 0)
-#define TxCTL_MODE_DOWN (1 << 0)
-#define TxCTL_MODE_MODULO (2 << 0)
-#define TxCTL_MODE_UP_DOWN (3 << 0)
-
-/* Timer 4 channel 0 compare control */
-
-sfr at 0xCC T3CCTL0;
-sfr at 0xCE T3CCTL1;
-sfr at 0xEC T4CCTL0;
-sfr at 0xEE T4CCTL1;
-
-#define TxCCTLy_IM (1 << 6)
-#define TxCCTLy_CMP_SET (0 << 3)
-#define TxCCTLy_CMP_CLEAR (1 << 3)
-#define TxCCTLy_CMP_TOGGLE (2 << 3)
-#define TxCCTLy_CMP_SET_UP_CLEAR_DOWN (3 << 3)
-#define TxCCTLy_CMP_CLEAR_UP_SET_DOWN (4 << 3)
-#define TxCCTLy_CMP_SET_CLEAR_FF (5 << 3)
-#define TxCCTLy_CMP_CLEAR_SET_00 (6 << 3)
-#define TxCCTLy_CMP_MODE_ENABLE (1 << 2)
-
-/* Timer compare value */
-sfr at 0xCD T3CC0;
-sfr at 0xCF T3CC1;
-sfr at 0xED T4CC0;
-sfr at 0xEF T4CC1;
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0, j = 0;
-
- n <<= 1;
- while (--n != 0)
- while (--j != 0)
- while (--i != 0)
- nop();
-}
-
-void
-dit() {
- T4CTL |= TxCTL_START;
- delay(1);
- T4CTL &= ~TxCTL_START;
- delay(1);
-}
-
-void
-dah () {
- T4CTL |= TxCTL_START;
- delay(3);
- T4CTL &= ~TxCTL_START;
- delay(1);
-}
-
-void
-charspace () {
- delay(2);
-}
-
-void
-wordspace () {
- delay(8);
-}
-
-#define _ dit();
-#define ___ dah();
-#define C charspace();
-#define W wordspace();
-
-main ()
-{
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
-
- /* Use timer 4 alternate config 2 */
- PERCFG = PERCFG_T4CFG_ALT_2;
- /* Use P2_4 for timer 4 output */
- P2SEL = P2SEL_SELP2_0_PERIPHERAL;
-
- T4CCTL0 = TxCCTLy_CMP_TOGGLE|TxCCTLy_CMP_MODE_ENABLE;
- T4CC0 = 125;
- T4CTL = TxCTL_DIV_32 | TxCTL_MODE_MODULO;
-
- for (;;) {
- ___ _ ___ _ C ___ ___ _ ___ W /* cq */
- ___ _ _ C _ W /* de */
- ___ _ ___ C ___ _ _ C /* kd */
- ___ ___ _ _ _ C _ _ _ C /* 7s */
- ___ ___ _ ___ C ___ ___ _ W /* qg */
- if (T4CC0 == 94)
- T4CC0 = 125;
- else
- T4CC0 = 94;
- }
-}
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=beep.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=beep-flash.ihx beep-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-beep-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o beep-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o beep-flash.ihx $(REL)
-
-beep-flash.ihx: beep-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-
-sfr at 0xF1 PERCFG;
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0;
-
- n <<= 1;
- while (--n != 0) {
- i = 211;
- while (--i != 0)
- nop();
- }
-}
-
-void
-tone (unsigned char n, unsigned char m)
-{
- unsigned char i = 0;
- while (--m != 0) {
- while (--i != 0) {
- P2 = 0xff;
- delay(n);
- P2 = 0xfe;
- delay(n);
- }
- }
-}
-
-void
-high() {
- tone(1, 2);
-}
-
-void
-low() {
- tone(2, 1);
-}
-
-main ()
-{
- CLKCON = 0;
- /* Set P2_0 to output */
- P2DIR = 0x01;
- P1INP = 0x00;
- P2INP = 0x00;
- for (;;) {
- high();
-/* low(); */
- }
-}
+++ /dev/null
-*.ihx
-*.adb
-*.asm
-*.cdb
-*.lnk
-*.lst
-*.map
-*.mem
-*.rel
-*.rst
-*.sym
-blink-flash
-blink-ram
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=blink.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=blink-flash.ihx blink-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-blink-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink-flash.ihx $(REL)
-
-blink-flash.ihx: blink-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-
-sfr at 0xF1 PERCFG;
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0, j = 0;
-
- n <<= 1;
- while (--n != 0)
- while (--j != 0)
- while (--i != 0)
- nop();
-}
-
-void
-dit() {
- P1 = 0xff;
- delay(1);
- P1 = 0xfd;
- delay(1);
-}
-
-void
-dah () {
- P1 = 0xff;
- delay(3);
- P1 = 0xfd;
- delay(1);
-}
-
-void
-charspace () {
- delay(2);
-}
-
-void
-wordspace () {
- delay(8);
-}
-
-#define _ dit();
-#define ___ dah();
-#define C charspace();
-#define W wordspace();
-
-main ()
-{
- CLKCON = 0;
- /* Set p1_1 to output */
- P1DIR = 0x02;
- P1INP = 0x00;
- P2INP = 0x00;
- for (;;) {
- ___ _ ___ _ C ___ ___ _ ___ W /* cq */
- ___ _ _ C _ W /* de */
- ___ _ ___ C ___ _ _ C /* kd */
- ___ ___ _ _ _ C _ _ _ C /* 7s */
- ___ ___ _ ___ C ___ ___ _ W /* qg */
- }
-}
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=dma.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=dma-flash.ihx dma-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-dma-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o dma-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o dma-flash.ihx $(REL)
-
-dma-flash.ihx: dma-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdint.h>
-
-/*
- * Test DMA
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-sfr at 0xbe SLEEP;
-
-# define SLEEP_USB_EN (1 << 7)
-# define SLEEP_XOSC_STB (1 << 6)
-
-sfr at 0xF1 PERCFG;
-#define PERCFG_T1CFG_ALT_1 (0 << 6)
-#define PERCFG_T1CFG_ALT_2 (1 << 6)
-
-#define PERCFG_T3CFG_ALT_1 (0 << 5)
-#define PERCFG_T3CFG_ALT_2 (1 << 5)
-
-#define PERCFG_T4CFG_ALT_1 (0 << 4)
-#define PERCFG_T4CFG_ALT_2 (1 << 4)
-
-#define PERCFG_U1CFG_ALT_1 (0 << 1)
-#define PERCFG_U1CFG_ALT_2 (1 << 1)
-
-#define PERCFG_U0CFG_ALT_1 (0 << 0)
-#define PERCFG_U0CFG_ALT_2 (1 << 0)
-
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-/*
- * UART registers
- */
-
-sfr at 0x86 U0CSR;
-sfr at 0xF8 U1CSR;
-
-/*
- * IRCON2
- */
-sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
-
-sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
-sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
-sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
-sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
-sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
-sbit at 0xEB P1IF; /* Port1 interrupt flag */
-sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
-
-# define UxCSR_MODE_UART (1 << 7)
-# define UxCSR_MODE_SPI (0 << 7)
-# define UxCSR_RE (1 << 6)
-# define UxCSR_SLAVE (1 << 5)
-# define UxCSR_MASTER (0 << 5)
-# define UxCSR_FE (1 << 4)
-# define UxCSR_ERR (1 << 3)
-# define UxCSR_RX_BYTE (1 << 2)
-# define UxCSR_TX_BYTE (1 << 1)
-# define UxCSR_ACTIVE (1 << 0)
-
-sfr at 0xc4 U0UCR;
-sfr at 0xfb U1UCR;
-
-# define UxUCR_FLUSH (1 << 7)
-# define UxUCR_FLOW_DISABLE (0 << 6)
-# define UxUCR_FLOW_ENABLE (1 << 6)
-# define UxUCR_D9_EVEN_PARITY (0 << 5)
-# define UxUCR_D9_ODD_PARITY (1 << 5)
-# define UxUCR_BIT9_8_BITS (0 << 4)
-# define UxUCR_BIT9_9_BITS (1 << 4)
-# define UxUCR_PARITY_DISABLE (0 << 3)
-# define UxUCR_PARITY_ENABLE (1 << 3)
-# define UxUCR_SPB_1_STOP_BIT (0 << 2)
-# define UxUCR_SPB_2_STOP_BITS (1 << 2)
-# define UxUCR_STOP_LOW (0 << 1)
-# define UxUCR_STOP_HIGH (1 << 1)
-# define UxUCR_START_LOW (0 << 0)
-# define UxUCR_START_HIGH (1 << 0)
-
-sfr at 0xc5 U0GCR;
-sfr at 0xfc U1GCR;
-
-# define UxGCR_CPOL_NEGATIVE (0 << 7)
-# define UxGCR_CPOL_POSITIVE (1 << 7)
-# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
-# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
-# define UxGCR_ORDER_LSB (0 << 5)
-# define UxGCR_ORDER_MSB (1 << 5)
-# define UxGCR_BAUD_E_MASK (0x1f)
-# define UxGCR_BAUD_E_SHIFT 0
-
-sfr at 0xc1 U0DBUF;
-sfr at 0xf9 U1DBUF;
-sfr at 0xc2 U0BAUD;
-sfr at 0xfa U1BAUD;
-
-#define DEBUG P1_1
-
-
-# define DMA_LEN_HIGH_VLEN_MASK (7 << 5)
-# define DMA_LEN_HIGH_VLEN_LEN (0 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5)
-# define DMA_LEN_HIGH_VLEN (2 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5)
-# define DMA_LEN_HIGH_MASK (0x1f)
-
-# define DMA_CFG0_WORDSIZE_8 (0 << 7)
-# define DMA_CFG0_WORDSIZE_16 (1 << 7)
-# define DMA_CFG0_TMODE_MASK (3 << 5)
-# define DMA_CFG0_TMODE_SINGLE (0 << 5)
-# define DMA_CFG0_TMODE_BLOCK (1 << 5)
-# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5)
-# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
-
-/*
- * DMA triggers
- */
-# define DMA_CFG0_TRIGGER_NONE 0
-# define DMA_CFG0_TRIGGER_PREV 1
-# define DMA_CFG0_TRIGGER_T1_CH0 2
-# define DMA_CFG0_TRIGGER_T1_CH1 3
-# define DMA_CFG0_TRIGGER_T1_CH2 4
-# define DMA_CFG0_TRIGGER_T2_OVFL 6
-# define DMA_CFG0_TRIGGER_T3_CH0 7
-# define DMA_CFG0_TRIGGER_T3_CH1 8
-# define DMA_CFG0_TRIGGER_T4_CH0 9
-# define DMA_CFG0_TRIGGER_T4_CH1 10
-# define DMA_CFG0_TRIGGER_IOC_0 12
-# define DMA_CFG0_TRIGGER_IOC_1 13
-# define DMA_CFG0_TRIGGER_URX0 14
-# define DMA_CFG0_TRIGGER_UTX0 15
-# define DMA_CFG0_TRIGGER_URX1 16
-# define DMA_CFG0_TRIGGER_UTX1 17
-# define DMA_CFG0_TRIGGER_FLASH 18
-# define DMA_CFG0_TRIGGER_RADIO 19
-# define DMA_CFG0_TRIGGER_ADC_CHALL 20
-# define DMA_CFG0_TRIGGER_ADC_CH0 21
-# define DMA_CFG0_TRIGGER_ADC_CH1 22
-# define DMA_CFG0_TRIGGER_ADC_CH2 23
-# define DMA_CFG0_TRIGGER_ADC_CH3 24
-# define DMA_CFG0_TRIGGER_ADC_CH4 25
-# define DMA_CFG0_TRIGGER_ADC_CH5 26
-# define DMA_CFG0_TRIGGER_ADC_CH6 27
-# define DMA_CFG0_TRIGGER_I2SRX 27
-# define DMA_CFG0_TRIGGER_ADC_CH7 28
-# define DMA_CFG0_TRIGGER_I2STX 28
-# define DMA_CFG0_TRIGGER_ENC_DW 29
-# define DMA_CFG0_TRIGGER_DNC_UP 30
-
-# define DMA_CFG1_SRCINC_MASK (3 << 6)
-# define DMA_CFG1_SRCINC_0 (0 << 6)
-# define DMA_CFG1_SRCINC_1 (1 << 6)
-# define DMA_CFG1_SRCINC_2 (2 << 6)
-# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6)
-
-# define DMA_CFG1_DESTINC_MASK (3 << 4)
-# define DMA_CFG1_DESTINC_0 (0 << 4)
-# define DMA_CFG1_DESTINC_1 (1 << 4)
-# define DMA_CFG1_DESTINC_2 (2 << 4)
-# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4)
-
-# define DMA_CFG1_IRQMASK (1 << 3)
-# define DMA_CFG1_M8 (1 << 2)
-
-# define DMA_CFG1_PRIORITY_MASK (3 << 0)
-# define DMA_CFG1_PRIORITY_LOW (0 << 0)
-# define DMA_CFG1_PRIORITY_NORMAL (1 << 0)
-# define DMA_CFG1_PRIORITY_HIGH (2 << 0)
-
-/*
- * DMAARM - DMA Channel Arm
- */
-
-sfr at 0xD6 DMAARM;
-
-# define DMAARM_ABORT (1 << 7)
-# define DMAARM_DMAARM4 (1 << 4)
-# define DMAARM_DMAARM3 (1 << 3)
-# define DMAARM_DMAARM2 (1 << 2)
-# define DMAARM_DMAARM1 (1 << 1)
-# define DMAARM_DMAARM0 (1 << 0)
-
-/*
- * DMAREQ - DMA Channel Start Request and Status
- */
-
-sfr at 0xD7 DMAREQ;
-
-# define DMAREQ_DMAREQ4 (1 << 4)
-# define DMAREQ_DMAREQ3 (1 << 3)
-# define DMAREQ_DMAREQ2 (1 << 2)
-# define DMAREQ_DMAREQ1 (1 << 1)
-# define DMAREQ_DMAREQ0 (1 << 0)
-
-/*
- * DMA configuration 0 address
- */
-
-sfr at 0xD5 DMA0CFGH;
-sfr at 0xD4 DMA0CFGL;
-
-/*
- * DMA configuration 1-4 address
- */
-
-sfr at 0xD3 DMA1CFGH;
-sfr at 0xD2 DMA1CFGL;
-
-/*
- * DMAIRQ - DMA Interrupt Flag
- */
-
-sfr at 0xD1 DMAIRQ;
-
-# define DMAIRQ_DMAIF4 (1 << 4)
-# define DMAIRQ_DMAIF3 (1 << 3)
-# define DMAIRQ_DMAIF2 (1 << 2)
-# define DMAIRQ_DMAIF1 (1 << 1)
-# define DMAIRQ_DMAIF0 (1 << 0)
-
-struct cc_dma_channel {
- uint8_t src_high;
- uint8_t src_low;
- uint8_t dst_high;
- uint8_t dst_low;
- uint8_t len_high;
- uint8_t len_low;
- uint8_t cfg0;
- uint8_t cfg1;
-};
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0;
- unsigned char j = 0;
-
- n++;
- while (--n != 0)
- while (--i != 0)
- while (--j != 0)
- nop();
-}
-
-void
-debug_byte(uint8_t byte)
-{
- uint8_t s;
-
- for (s = 0; s < 8; s++) {
- DEBUG = byte & 1;
- delay(5);
- byte >>= 1;
- }
-}
-
-struct cc_dma_channel __xdata config;
-
-#define DMA_LEN 8
-
-uint8_t __xdata dma_input[DMA_LEN];
-uint8_t __xdata dma_output[DMA_LEN];
-
-#define ADDRH(a) (((uint16_t) (a)) >> 8)
-#define ADDRL(a) (((uint16_t) (a)))
-
-void
-dma_init(void)
-{
- int i;
- config.cfg0 = (DMA_CFG0_WORDSIZE_8 |
- DMA_CFG0_TMODE_BLOCK |
- DMA_CFG0_TRIGGER_NONE);
- config.cfg1 = (DMA_CFG1_SRCINC_1 |
- DMA_CFG1_DESTINC_1 |
- DMA_CFG1_PRIORITY_NORMAL);
-
- config.src_high = ADDRH(dma_input);
- config.src_low = ADDRL(dma_input);
- config.dst_high = ADDRH(dma_output);
- config.dst_low = ADDRL(dma_output);
- config.len_high = 0;
- config.len_low = DMA_LEN;
- DMA0CFGH = ADDRH(&config);
- DMA0CFGL = ADDRL(&config);
- for (i = 0; i < DMA_LEN; i++)
- dma_input[i] = i + 1;
-}
-
-void
-dma_run(void)
-{
- DMAREQ |= 1;
- DMAARM |= 1;
- while (DMAARM & 1)
- ;
-}
-
-main ()
-{
- int i;
- P1DIR |= 2;
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
-
- dma_init();
- dma_run();
- for (;;) {
- for (i = 0; i < DMA_LEN; i++)
- debug_byte(dma_output[i]);
- }
-}
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=ee.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=ee-flash.ihx ee-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-ee-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o ee-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o ee-flash.ihx $(REL)
-
-ee-flash.ihx: ee-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdint.h>
-
-/*
- * Validate the SPI-connected EEPROM
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-sfr at 0xbe SLEEP;
-
-# define SLEEP_USB_EN (1 << 7)
-# define SLEEP_XOSC_STB (1 << 6)
-
-sfr at 0xF1 PERCFG;
-#define PERCFG_T1CFG_ALT_1 (0 << 6)
-#define PERCFG_T1CFG_ALT_2 (1 << 6)
-
-#define PERCFG_T3CFG_ALT_1 (0 << 5)
-#define PERCFG_T3CFG_ALT_2 (1 << 5)
-
-#define PERCFG_T4CFG_ALT_1 (0 << 4)
-#define PERCFG_T4CFG_ALT_2 (1 << 4)
-
-#define PERCFG_U1CFG_ALT_1 (0 << 1)
-#define PERCFG_U1CFG_ALT_2 (1 << 1)
-
-#define PERCFG_U0CFG_ALT_1 (0 << 0)
-#define PERCFG_U0CFG_ALT_2 (1 << 0)
-
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-/*
- * UART registers
- */
-
-sfr at 0x86 U0CSR;
-sfr at 0xF8 U1CSR;
-
-# define UxCSR_MODE_UART (1 << 7)
-# define UxCSR_MODE_SPI (0 << 7)
-# define UxCSR_RE (1 << 6)
-# define UxCSR_SLAVE (1 << 5)
-# define UxCSR_MASTER (0 << 5)
-# define UxCSR_FE (1 << 4)
-# define UxCSR_ERR (1 << 3)
-# define UxCSR_RX_BYTE (1 << 2)
-# define UxCSR_TX_BYTE (1 << 1)
-# define UxCSR_ACTIVE (1 << 0)
-
-sfr at 0xc4 U0UCR;
-sfr at 0xfb U1UCR;
-
-sfr at 0xc5 U0GCR;
-sfr at 0xfc U1GCR;
-
-# define UxGCR_CPOL_NEGATIVE (0 << 7)
-# define UxGCR_CPOL_POSITIVE (1 << 7)
-# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
-# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
-# define UxGCR_ORDER_LSB (0 << 5)
-# define UxGCR_ORDER_MSB (1 << 5)
-# define UxGCR_BAUD_E_MASK (0x1f)
-# define UxGCR_BAUD_E_SHIFT 0
-
-sfr at 0xc1 U0DBUF;
-sfr at 0xf9 U1DBUF;
-sfr at 0xc2 U0BAUD;
-sfr at 0xfa U1BAUD;
-
-#define MOSI P1_5
-#define MISO P1_4
-#define SCK P1_3
-#define CS P1_2
-
-#define DEBUG P1_1
-
-#define BITBANG 0
-#define USART 1
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0;
- unsigned char j = 0;
-
- while (--n != 0)
- while (--i != 0)
- while (--j != 0)
- nop();
-}
-
-#if BITBANG
-
-/*
- * This version directly manipulates the GPIOs to synthesize SPI
- */
-
-void
-bitbang_cs(uint8_t b)
-{
- SCK = 0;
- CS = b;
- delay(1);
-}
-
-void
-bitbang_out_bit(uint8_t b)
-{
- MOSI = b;
- delay(1);
- SCK = 1;
- delay(1);
- SCK = 0;
-}
-
-void
-bitbang_out_byte(uint8_t byte)
-{
- uint8_t s;
-
- for (s = 0; s < 8; s++) {
- uint8_t b = (byte & 0x80) ? 1 : 0;
- bitbang_out_bit(b);
- byte <<= 1;
- }
-}
-
-uint8_t
-bitbang_in_bit(void)
-{
- uint8_t b;
-
- delay(1);
- SCK = 1;
- delay(1);
- b = MISO;
- SCK = 0;
- return b;
-}
-
-uint8_t
-bitbang_in_byte(void)
-{
- uint8_t byte = 0;
- uint8_t s;
- uint8_t b;
-
- for (s = 0; s < 8; s++) {
- b = bitbang_in_bit();
- byte = byte << 1;
- byte |= b;
- }
- return byte;
-}
-
-void
-bit_bang_init(void)
-{
- CS = 1;
- SCK = 0;
- P1DIR = ((1 << 5) |
- (0 << 4) |
- (1 << 3) |
- (1 << 2) |
- (1 << 1));
-}
-
-#define spi_init() bitbang_init()
-#define spi_out_byte(b) bitbang_out_byte(b)
-#define spi_in_byte() bitbang_in_byte()
-#define spi_cs(b) bitbang_cs(b)
-#endif
-
-#if USART
-
-/*
- * This version uses the USART in SPI mode
- */
-void
-usart_init(void)
-{
- /*
- * Configure our chip select line
- */
- CS = 1;
- P1DIR |= (1 << 2);
- /*
- * Configure the peripheral pin choices
- * for both of the serial ports
- *
- * Note that telemetrum will use U1CFG_ALT_2
- * but that overlaps with SPI ALT_2, so until
- * we can test that this works, we'll set this
- * to ALT_1
- */
- PERCFG = (PERCFG_U1CFG_ALT_1 |
- PERCFG_U0CFG_ALT_2);
-
- /*
- * Make the SPI pins controlled by the SPI
- * hardware
- */
- P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3));
-
- /*
- * SPI in master mode
- */
- U0CSR = (UxCSR_MODE_SPI |
- UxCSR_MASTER);
-
- /*
- * The cc1111 is limited to a 24/8 MHz SPI clock,
- * while the 25LC1024 is limited to 20MHz. So,
- * use the 3MHz clock (BAUD_E 17, BAUD_M 0)
- */
- U0BAUD = 0;
- U0GCR = (UxGCR_CPOL_NEGATIVE |
- UxGCR_CPHA_FIRST_EDGE |
- UxGCR_ORDER_MSB |
- (17 << UxGCR_BAUD_E_SHIFT));
-}
-
-void
-usart_cs(uint8_t b)
-{
- CS = b;
-}
-
-uint8_t
-usart_in_out(uint8_t byte)
-{
- U0DBUF = byte;
- while ((U0CSR & UxCSR_TX_BYTE) == 0)
- ;
- U0CSR &= ~UxCSR_TX_BYTE;
- return U0DBUF;
-}
-
-void
-usart_out_byte(uint8_t byte)
-{
- (void) usart_in_out(byte);
-}
-
-uint8_t
-usart_in_byte(void)
-{
- return usart_in_out(0xff);
-}
-
-#define spi_init() usart_init()
-#define spi_out_byte(b) usart_out_byte(b)
-#define spi_in_byte() usart_in_byte()
-#define spi_cs(b) usart_cs(b)
-
-#endif
-
-uint8_t
-rdsr(void)
-{
- uint8_t status;
- spi_cs(0);
- spi_out_byte(0x05);
- status = spi_in_byte();
- spi_cs(1);
- return status;
-}
-
-void
-wrsr(uint8_t status)
-{
- spi_cs(0);
- spi_out_byte(0x01);
- spi_out_byte(status);
- spi_cs(1);
-}
-
-void
-wren(void)
-{
- spi_cs(0);
- spi_out_byte(0x06);
- spi_cs(1);
-}
-
-void
-write(uint32_t addr, uint8_t *bytes, uint16_t len)
-{
- wren();
- spi_cs(0);
- spi_out_byte(0x02);
- spi_out_byte(addr >> 16);
- spi_out_byte(addr >> 8);
- spi_out_byte(addr);
- while (len-- > 0)
- spi_out_byte(*bytes++);
- spi_cs(1);
- for (;;) {
- uint8_t status = rdsr();
- if ((status & (1 << 0)) == 0)
- break;
- }
-}
-
-void
-read(uint32_t addr, uint8_t *bytes, uint16_t len)
-{
- spi_cs(0);
- spi_out_byte(0x03);
- spi_out_byte(addr >> 16);
- spi_out_byte(addr >> 8);
- spi_out_byte(addr);
- while (len-- > 0)
- *bytes++ = spi_in_byte();
- spi_cs(1);
-}
-
-void
-debug_byte(uint8_t byte)
-{
- uint8_t s;
-
- for (s = 0; s < 8; s++) {
- DEBUG = byte & 1;
- delay(5);
- byte >>= 1;
- }
-}
-
-#define STRING "\360\252"
-#define LENGTH 2
-
-main ()
-{
- uint8_t status;
- uint8_t buf[LENGTH];
- int i;
-
- P1DIR |= 2;
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
-
- spi_init();
-
- status = rdsr();
- /*
- * Turn off both block-protect bits
- */
- status &= ~((1 << 3) | (1 << 2));
- /*
- * Turn off write protect enable
- */
- status &= ~(1 << 7);
- wrsr(status);
- write(0x0, STRING, LENGTH);
- for (;;) {
- read(0x0, buf, LENGTH);
- for (i = 0; i < LENGTH; i++)
- debug_byte(buf[i]);
- }
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-void rftxrx_isr (void) __interrupt(0) __using(1)
-{
-}
-
-void adc_isr (void) __interrupt(1) __using(1)
-{
-}
-
-void urx0_isr (void) __interrupt(2) __using(1)
-{
-}
-
-void urx1_isr (void) __interrupt(3) __using(1)
-{
-}
-
-void enc_isr (void) __interrupt(4) __using(1)
-{
-}
-
-void st_isr (void) __interrupt(5) __using(1)
-{
-}
-
-void usb_isr (void) __interrupt(6) __using(1)
-{
-}
-
-void utx0_isr (void) __interrupt(7) __using(1)
-{
-}
-
-void dma_isr (void) __interrupt(8) __using(1)
-{
-}
-
-void t1_isr (void) __interrupt(9) __using(1)
-{
-}
-
-void t2_isr (void) __interrupt(10) __using(1)
-{
-}
-
-void t3_isr (void) __interrupt(11) __using(1)
-{
-}
-
-void t4_isr (void) __interrupt(12) __using(1)
-{
-}
-
-void p0int_isr (void) __interrupt(13) __using(1)
-{
-}
-
-void utx1_isr (void) __interrupt(14) __using(1)
-{
-}
-
-void p1int_isr (void) __interrupt(15) __using(1)
-{
-}
-
-void rf_isr (void) __interrupt(16) __using(1)
-{
-}
-
-void wdt_isr (void) __interrupt(17) __using(1)
-{
-}
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=xmit.c recv.c init.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=xmit-flash.ihx xmit-ram.ihx recv-flash.ihx recv-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-xmit-ram.ihx: xmit.rel init.rel Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o xmit-ram.ihx xmit.rel init.rel
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o xmit-flash.ihx xmit.rel init.rel
-
-xmit-flash.ihx: xmit-ram.ihx
-
-recv-ram.ihx: recv.rel init.rel Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o recv-ram.ihx recv.rel init.rel
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o recv-flash.ihx recv.rel init.rel
-
-recv-flash.ihx: recv-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "radio.h"
-
-/* Values from SmartRF® Studio for:
- *
- * Deviation: 20.507812 kHz
- * Datarate: 38.360596 kBaud
- * Modulation: GFSK
- * RF Freq: 434.549927 MHz
- * Channel: 99.975586 kHz
- * Channel: 0
- * RX filter: 93.75 kHz
- */
-
-/*
- * For 434.550MHz, the frequency value is:
- *
- * 434.550e6 / (24e6 / 2**16) = 1186611.2
- */
-
-#define FREQ_CONTROL 1186611
-
-/*
- * For IF freq of 140.62kHz, the IF value is:
- *
- * 140.62e3 / (24e6 / 2**10) = 6
- */
-
-#define IF_FREQ_CONTROL 6
-
-/*
- * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are
- *
- * BW = 24e6 / (8 * (4 + M) * 2 ** E)
- *
- * So, M = 0 and E = 3
- */
-
-#define CHANBW_M 0
-#define CHANBW_E 3
-
-/*
- * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are:
- *
- * R = (256 + M) * 2** E * 24e6 / 2**28
- *
- * So M is 163 and E is 10
- */
-
-#define DRATE_E 10
-#define DRATE_M 163
-
-/*
- * For a channel deviation of 20.5kHz, the DEVIATION_E and DEVIATION_M values are:
- *
- * F = 24e6/2**17 * (8 + DEVIATION_M) * 2**DEVIATION_E
- *
- * So M is 6 and E is 3
- */
-
-#define DEVIATION_M 6
-#define DEVIATION_E 3
-
-#define PACKET_LEN 128
-
-/* This are from the table for 433MHz */
-
-#define RF_POWER_M30_DBM 0x12
-#define RF_POWER_M20_DBM 0x0e
-#define RF_POWER_M15_DBM 0x1d
-#define RF_POWER_M10_DBM 0x34
-#define RF_POWER_M5_DBM 0x2c
-#define RF_POWER_0_DBM 0x60
-#define RF_POWER_5_DBM 0x84
-#define RF_POWER_7_DBM 0xc8
-#define RF_POWER_10_DBM 0xc0
-
-#define RF_POWER RF_POWER_0_DBM
-
-static __code uint8_t radio_setup[] = {
- RF_PA_TABLE7_OFF, RF_POWER,
- RF_PA_TABLE6_OFF, RF_POWER,
- RF_PA_TABLE5_OFF, RF_POWER,
- RF_PA_TABLE4_OFF, RF_POWER,
- RF_PA_TABLE3_OFF, RF_POWER,
- RF_PA_TABLE2_OFF, RF_POWER,
- RF_PA_TABLE1_OFF, RF_POWER,
- RF_PA_TABLE0_OFF, RF_POWER,
-
- RF_FREQ2_OFF, FREQ_CONTROL >> 16,
- RF_FREQ1_OFF, FREQ_CONTROL >> 8,
- RF_FREQ0_OFF, FREQ_CONTROL >> 0,
-
- RF_FSCTRL1_OFF, (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT),
- RF_FSCTRL0_OFF, (0 << RF_FSCTRL0_FREQOFF_SHIFT),
-
- RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
- (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
- (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
- RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
- RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF |
- RF_MDMCFG2_MOD_FORMAT_GFSK |
- RF_MDMCFG2_SYNC_MODE_15_16_THRES),
- RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_EN |
- RF_MDMCFG1_NUM_PREAMBLE_4 |
- (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
- RF_MDMCFG0_OFF, (17 << RF_MDMCFG0_CHANSPC_M_SHIFT),
-
- RF_CHANNR_OFF, 0,
-
- RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) |
- (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
-
- /* SmartRF says set LODIV_BUF_CURRENT_TX to 0
- * And, we're not using power ramping, so use PA_POWER 0
- */
- RF_FREND0_OFF, ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) |
- (0 << RF_FREND0_PA_POWER_SHIFT)),
-
- RF_FREND1_OFF, ((1 << RF_FREND1_LNA_CURRENT_SHIFT) |
- (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) |
- (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) |
- (2 << RF_FREND1_MIX_CURRENT_SHIFT)),
-
- RF_FSCAL3_OFF, 0xE9,
- RF_FSCAL2_OFF, 0x0A,
- RF_FSCAL1_OFF, 0x00,
- RF_FSCAL0_OFF, 0x1F,
-
- RF_TEST2_OFF, 0x88,
- RF_TEST1_OFF, 0x31,
- RF_TEST0_OFF, 0x09,
-
- /* default sync values */
- RF_SYNC1_OFF, 0xD3,
- RF_SYNC0_OFF, 0x91,
-
- /* max packet length */
- RF_PKTLEN_OFF, PACKET_LEN,
-
- RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)|
- PKTCTRL1_APPEND_STATUS|
- PKTCTRL1_ADR_CHK_NONE),
- RF_PKTCTRL0_OFF, (RF_PKTCTRL0_WHITE_DATA|
- RF_PKTCTRL0_PKT_FORMAT_NORMAL|
- RF_PKTCTRL0_CRC_EN|
- RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
- RF_ADDR_OFF, 0x00,
- RF_MCSM2_OFF, (RF_MCSM2_RX_TIME_END_OF_PACKET),
- RF_MCSM1_OFF, (RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING|
- RF_MCSM1_RXOFF_MODE_IDLE|
- RF_MCSM1_TXOFF_MODE_IDLE),
- RF_MCSM0_OFF, (RF_MCSM0_FS_AUTOCAL_FROM_IDLE|
- RF_MCSM0_MAGIC_3|
- RF_MCSM0_CLOSE_IN_RX_18DB),
- RF_FOCCFG_OFF, (RF_FOCCFG_FOC_PRE_K_3K,
- RF_FOCCFG_FOC_POST_K_PRE_K,
- RF_FOCCFG_FOC_LIMIT_BW_OVER_4),
- RF_BSCFG_OFF, (RF_BSCFG_BS_PRE_K_2K|
- RF_BSCFG_BS_PRE_KP_3KP|
- RF_BSCFG_BS_POST_KI_PRE_KI|
- RF_BSCFG_BS_POST_KP_PRE_KP|
- RF_BSCFG_BS_LIMIT_0),
- RF_AGCCTRL2_OFF, 0x43,
- RF_AGCCTRL1_OFF, 0x40,
- RF_AGCCTRL0_OFF, 0x91,
-
- RF_IOCFG2_OFF, 0x00,
- RF_IOCFG1_OFF, 0x00,
- RF_IOCFG0_OFF, 0x00,
-};
-
-void
-radio_init(void) {
- uint8_t i;
- for (i = 0; i < sizeof (radio_setup); i += 2)
- RF[radio_setup[i]] = radio_setup[i+1];
-}
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0;
-
- n <<= 1;
- while (--n != 0)
- while (--i != 0)
- nop();
-}
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdint.h>
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-
-sfr at 0xF1 PERCFG;
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-sfr at 0xD9 RFD;
-sfr at 0xE9 RFIF;
-#define RFIF_IM_TXUNF (1 << 7)
-#define RFIF_IM_RXOVF (1 << 6)
-#define RFIF_IM_TIMEOUT (1 << 5)
-#define RFIF_IM_DONE (1 << 4)
-#define RFIF_IM_CS (1 << 3)
-#define RFIF_IM_PQT (1 << 2)
-#define RFIF_IM_CCA (1 << 1)
-#define RFIF_IM_SFD (1 << 0)
-
-sfr at 0xE1 RFST;
-
-sfr at 0x88 TCON;
-
-sfr at 0xbe SLEEP;
-
-# define SLEEP_USB_EN (1 << 7)
-# define SLEEP_XOSC_STB (1 << 6)
-
-sbit at 0x89 RFTXRXIF;
-
-#define TCON_RFTXRXIF (1 << 1)
-
-#define RFST_SFSTXON 0x00
-#define RFST_SCAL 0x01
-#define RFST_SRX 0x02
-#define RFST_STX 0x03
-#define RFST_SIDLE 0x04
-
-__xdata __at (0xdf00) uint8_t RF[0x3c];
-
-__xdata __at (0xdf2f) uint8_t RF_IOCFG2;
-#define RF_IOCFG2_OFF 0x2f
-
-__xdata __at (0xdf30) uint8_t RF_IOCFG1;
-#define RF_IOCFG1_OFF 0x30
-
-__xdata __at (0xdf31) uint8_t RF_IOCFG0;
-#define RF_IOCFG0_OFF 0x31
-
-__xdata __at (0xdf00) uint8_t RF_SYNC1;
-#define RF_SYNC1_OFF 0x00
-
-__xdata __at (0xdf01) uint8_t RF_SYNC0;
-#define RF_SYNC0_OFF 0x01
-
-__xdata __at (0xdf02) uint8_t RF_PKTLEN;
-#define RF_PKTLEN_OFF 0x02
-
-__xdata __at (0xdf03) uint8_t RF_PKTCTRL1;
-#define RF_PKTCTRL1_OFF 0x03
-#define PKTCTRL1_PQT_MASK (0x7 << 5)
-#define PKTCTRL1_PQT_SHIFT 5
-#define PKTCTRL1_APPEND_STATUS (1 << 2)
-#define PKTCTRL1_ADR_CHK_NONE (0 << 0)
-#define PKTCTRL1_ADR_CHK_NO_BROADCAST (1 << 0)
-#define PKTCTRL1_ADR_CHK_00_BROADCAST (2 << 0)
-#define PKTCTRL1_ADR_CHK_00_FF_BROADCAST (3 << 0)
-
-/* If APPEND_STATUS is used, two bytes will be added to the packet data */
-#define PKT_APPEND_STATUS_0_RSSI_MASK (0xff)
-#define PKT_APPEND_STATUS_0_RSSI_SHIFT 0
-#define PKT_APPEND_STATUS_1_CRC_OK (1 << 7)
-#define PKT_APPEND_STATUS_1_LQI_MASK (0x7f)
-#define PKT_APPEND_STATUS_1_LQI_SHIFT 0
-
-__xdata __at (0xdf04) uint8_t RF_PKTCTRL0;
-#define RF_PKTCTRL0_OFF 0x04
-#define RF_PKTCTRL0_WHITE_DATA (1 << 6)
-#define RF_PKTCTRL0_PKT_FORMAT_NORMAL (0 << 4)
-#define RF_PKTCTRL0_PKT_FORMAT_RANDOM (2 << 4)
-#define RF_PKTCTRL0_CRC_EN (1 << 2)
-#define RF_PKTCTRL0_LENGTH_CONFIG_FIXED (0 << 0)
-#define RF_PKTCTRL0_LENGTH_CONFIG_VARIABLE (1 << 0)
-
-__xdata __at (0xdf05) uint8_t RF_ADDR;
-#define RF_ADDR_OFF 0x05
-
-__xdata __at (0xdf06) uint8_t RF_CHANNR;
-#define RF_CHANNR_OFF 0x06
-
-__xdata __at (0xdf07) uint8_t RF_FSCTRL1;
-#define RF_FSCTRL1_OFF 0x07
-
-#define RF_FSCTRL1_FREQ_IF_SHIFT (0)
-
-__xdata __at (0xdf08) uint8_t RF_FSCTRL0;
-#define RF_FSCTRL0_OFF 0x08
-
-#define RF_FSCTRL0_FREQOFF_SHIFT (0)
-
-__xdata __at (0xdf09) uint8_t RF_FREQ2;
-#define RF_FREQ2_OFF 0x09
-
-__xdata __at (0xdf0a) uint8_t RF_FREQ1;
-#define RF_FREQ1_OFF 0x0a
-
-__xdata __at (0xdf0b) uint8_t RF_FREQ0;
-#define RF_FREQ0_OFF 0x0b
-
-__xdata __at (0xdf0c) uint8_t RF_MDMCFG4;
-#define RF_MDMCFG4_OFF 0x0c
-
-#define RF_MDMCFG4_CHANBW_E_SHIFT 6
-#define RF_MDMCFG4_CHANBW_M_SHIFT 4
-#define RF_MDMCFG4_DRATE_E_SHIFT 0
-
-__xdata __at (0xdf0d) uint8_t RF_MDMCFG3;
-#define RF_MDMCFG3_OFF 0x0d
-
-#define RF_MDMCFG3_DRATE_M_SHIFT 0
-
-__xdata __at (0xdf0e) uint8_t RF_MDMCFG2;
-#define RF_MDMCFG2_OFF 0x0e
-
-#define RF_MDMCFG2_DEM_DCFILT_OFF (1 << 7)
-#define RF_MDMCFG2_DEM_DCFILT_ON (0 << 7)
-
-#define RF_MDMCFG2_MOD_FORMAT_MASK (7 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_2_FSK (0 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_GFSK (1 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_ASK_OOK (3 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_MSK (7 << 4)
-
-#define RF_MDMCFG2_MANCHESTER_EN (1 << 3)
-
-#define RF_MDMCFG2_SYNC_MODE_MASK (0x7 << 0)
-#define RF_MDMCFG2_SYNC_MODE_NONE (0x0 << 0)
-#define RF_MDMCFG2_SYNC_MODE_15_16 (0x1 << 0)
-#define RF_MDMCFG2_SYNC_MODE_16_16 (0x2 << 0)
-#define RF_MDMCFG2_SYNC_MODE_30_32 (0x3 << 0)
-#define RF_MDMCFG2_SYNC_MODE_NONE_THRES (0x4 << 0)
-#define RF_MDMCFG2_SYNC_MODE_15_16_THRES (0x5 << 0)
-#define RF_MDMCFG2_SYNC_MODE_16_16_THRES (0x6 << 0)
-#define RF_MDMCFG2_SYNC_MODE_30_32_THRES (0x7 << 0)
-
-__xdata __at (0xdf0f) uint8_t RF_MDMCFG1;
-#define RF_MDMCFG1_OFF 0x0f
-
-#define RF_MDMCFG1_FEC_EN (1 << 7)
-#define RF_MDMCFG1_FEC_DIS (0 << 7)
-
-#define RF_MDMCFG1_NUM_PREAMBLE_MASK (7 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_2 (0 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_3 (1 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_4 (2 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_6 (3 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_8 (4 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_12 (5 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_16 (6 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_24 (7 << 4)
-
-#define RF_MDMCFG1_CHANSPC_E_MASK (3 << 0)
-#define RF_MDMCFG1_CHANSPC_E_SHIFT (0)
-
-__xdata __at (0xdf10) uint8_t RF_MDMCFG0;
-#define RF_MDMCFG0_OFF 0x10
-
-#define RF_MDMCFG0_CHANSPC_M_SHIFT (0)
-
-__xdata __at (0xdf11) uint8_t RF_DEVIATN;
-#define RF_DEVIATN_OFF 0x11
-
-#define RF_DEVIATN_DEVIATION_E_SHIFT 4
-#define RF_DEVIATN_DEVIATION_M_SHIFT 0
-
-__xdata __at (0xdf12) uint8_t RF_MCSM2;
-#define RF_MCSM2_OFF 0x12
-#define RF_MCSM2_RX_TIME_RSSI (1 << 4)
-#define RF_MCSM2_RX_TIME_QUAL (1 << 3)
-#define RF_MCSM2_RX_TIME_MASK (0x7)
-#define RF_MCSM2_RX_TIME_SHIFT 0
-#define RF_MCSM2_RX_TIME_END_OF_PACKET (7)
-
-__xdata __at (0xdf13) uint8_t RF_MCSM1;
-#define RF_MCSM1_OFF 0x13
-#define RF_MCSM1_CCA_MODE_ALWAYS (0 << 4)
-#define RF_MCSM1_CCA_MODE_RSSI_BELOW (1 << 4)
-#define RF_MCSM1_CCA_MODE_UNLESS_RECEIVING (2 << 4)
-#define RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING (3 << 4)
-#define RF_MCSM1_RXOFF_MODE_IDLE (0 << 2)
-#define RF_MCSM1_RXOFF_MODE_FSTXON (1 << 2)
-#define RF_MCSM1_RXOFF_MODE_TX (2 << 2)
-#define RF_MCSM1_RXOFF_MODE_RX (3 << 2)
-#define RF_MCSM1_TXOFF_MODE_IDLE (0 << 0)
-#define RF_MCSM1_TXOFF_MODE_FSTXON (1 << 0)
-#define RF_MCSM1_TXOFF_MODE_TX (2 << 0)
-#define RF_MCSM1_TXOFF_MODE_RX (3 << 0)
-
-__xdata __at (0xdf14) uint8_t RF_MCSM0;
-#define RF_MCSM0_OFF 0x14
-#define RF_MCSM0_FS_AUTOCAL_NEVER (0 << 4)
-#define RF_MCSM0_FS_AUTOCAL_FROM_IDLE (1 << 4)
-#define RF_MCSM0_FS_AUTOCAL_TO_IDLE (2 << 4)
-#define RF_MCSM0_FS_AUTOCAL_TO_IDLE_EVERY_4 (3 << 4)
-#define RF_MCSM0_MAGIC_3 (1 << 3)
-#define RF_MCSM0_MAGIC_2 (1 << 2)
-#define RF_MCSM0_CLOSE_IN_RX_0DB (0 << 0)
-#define RF_MCSM0_CLOSE_IN_RX_6DB (1 << 0)
-#define RF_MCSM0_CLOSE_IN_RX_12DB (2 << 0)
-#define RF_MCSM0_CLOSE_IN_RX_18DB (3 << 0)
-
-__xdata __at (0xdf15) uint8_t RF_FOCCFG;
-#define RF_FOCCFG_OFF 0x15
-#define RF_FOCCFG_FOC_BS_CS_GATE (1 << 5)
-#define RF_FOCCFG_FOC_PRE_K_1K (0 << 3)
-#define RF_FOCCFG_FOC_PRE_K_2K (1 << 3)
-#define RF_FOCCFG_FOC_PRE_K_3K (2 << 3)
-#define RF_FOCCFG_FOC_PRE_K_4K (3 << 3)
-#define RF_FOCCFG_FOC_POST_K_PRE_K (0 << 2)
-#define RF_FOCCFG_FOC_POST_K_PRE_K_OVER_2 (1 << 2)
-#define RF_FOCCFG_FOC_LIMIT_0 (0 << 0)
-#define RF_FOCCFG_FOC_LIMIT_BW_OVER_8 (1 << 0)
-#define RF_FOCCFG_FOC_LIMIT_BW_OVER_4 (2 << 0)
-#define RF_FOCCFG_FOC_LIMIT_BW_OVER_2 (3 << 0)
-
-__xdata __at (0xdf16) uint8_t RF_BSCFG;
-#define RF_BSCFG_OFF 0x16
-#define RF_BSCFG_BS_PRE_K_1K (0 << 6)
-#define RF_BSCFG_BS_PRE_K_2K (1 << 6)
-#define RF_BSCFG_BS_PRE_K_3K (2 << 6)
-#define RF_BSCFG_BS_PRE_K_4K (3 << 6)
-#define RF_BSCFG_BS_PRE_KP_1KP (0 << 4)
-#define RF_BSCFG_BS_PRE_KP_2KP (1 << 4)
-#define RF_BSCFG_BS_PRE_KP_3KP (2 << 4)
-#define RF_BSCFG_BS_PRE_KP_4KP (3 << 4)
-#define RF_BSCFG_BS_POST_KI_PRE_KI (0 << 3)
-#define RF_BSCFG_BS_POST_KI_PRE_KI_OVER_2 (1 << 3)
-#define RF_BSCFG_BS_POST_KP_PRE_KP (0 << 2)
-#define RF_BSCFG_BS_POST_KP_PRE_KP_OVER_2 (1 << 2)
-#define RF_BSCFG_BS_LIMIT_0 (0 << 0)
-#define RF_BSCFG_BS_LIMIT_3_125 (1 << 0)
-#define RF_BSCFG_BS_LIMIT_6_25 (2 << 0)
-#define RF_BSCFG_BS_LIMIT_12_5 (3 << 0)
-
-__xdata __at (0xdf17) uint8_t RF_AGCCTRL2;
-#define RF_AGCCTRL2_OFF 0x17
-
-__xdata __at (0xdf18) uint8_t RF_AGCCTRL1;
-#define RF_AGCCTRL1_OFF 0x18
-
-__xdata __at (0xdf19) uint8_t RF_AGCCTRL0;
-#define RF_AGCCTRL0_OFF 0x19
-
-__xdata __at (0xdf1a) uint8_t RF_FREND1;
-#define RF_FREND1_OFF 0x1a
-
-#define RF_FREND1_LNA_CURRENT_SHIFT 6
-#define RF_FREND1_LNA2MIX_CURRENT_SHIFT 4
-#define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT 2
-#define RF_FREND1_MIX_CURRENT_SHIFT 0
-
-__xdata __at (0xdf1b) uint8_t RF_FREND0;
-#define RF_FREND0_OFF 0x1b
-
-#define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK (0x3 << 4)
-#define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT 4
-#define RF_FREND0_PA_POWER_MASK (0x7)
-#define RF_FREND0_PA_POWER_SHIFT 0
-
-__xdata __at (0xdf1c) uint8_t RF_FSCAL3;
-#define RF_FSCAL3_OFF 0x1c
-
-__xdata __at (0xdf1d) uint8_t RF_FSCAL2;
-#define RF_FSCAL2_OFF 0x1d
-
-__xdata __at (0xdf1e) uint8_t RF_FSCAL1;
-#define RF_FSCAL1_OFF 0x1e
-
-__xdata __at (0xdf1f) uint8_t RF_FSCAL0;
-#define RF_FSCAL0_OFF 0x1f
-
-__xdata __at (0xdf23) uint8_t RF_TEST2;
-#define RF_TEST2_OFF 0x23
-
-#define RF_TEST2_NORMAL_MAGIC 0x88
-#define RF_TEST2_RX_LOW_DATA_RATE_MAGIC 0x81
-
-__xdata __at (0xdf24) uint8_t RF_TEST1;
-#define RF_TEST1_OFF 0x24
-
-#define RF_TEST1_TX_MAGIC 0x31
-#define RF_TEST1_RX_LOW_DATA_RATE_MAGIC 0x35
-
-__xdata __at (0xdf25) uint8_t RF_TEST0;
-#define RF_TEST0_OFF 0x25
-
-#define RF_TEST0_7_2_MASK (0xfc)
-#define RF_TEST0_VCO_SEL_CAL_EN (1 << 1)
-#define RF_TEST0_0_MASK (1)
-
-/* These are undocumented, and must be computed
- * using the provided tool.
- */
-__xdata __at (0xdf27) uint8_t RF_PA_TABLE7;
-#define RF_PA_TABLE7_OFF 0x27
-
-__xdata __at (0xdf28) uint8_t RF_PA_TABLE6;
-#define RF_PA_TABLE6_OFF 0x28
-
-__xdata __at (0xdf29) uint8_t RF_PA_TABLE5;
-#define RF_PA_TABLE5_OFF 0x29
-
-__xdata __at (0xdf2a) uint8_t RF_PA_TABLE4;
-#define RF_PA_TABLE4_OFF 0x2a
-
-__xdata __at (0xdf2b) uint8_t RF_PA_TABLE3;
-#define RF_PA_TABLE3_OFF 0x2b
-
-__xdata __at (0xdf2c) uint8_t RF_PA_TABLE2;
-#define RF_PA_TABLE2_OFF 0x2c
-
-__xdata __at (0xdf2d) uint8_t RF_PA_TABLE1;
-#define RF_PA_TABLE1_OFF 0x2d
-
-__xdata __at (0xdf2e) uint8_t RF_PA_TABLE0;
-#define RF_PA_TABLE0_OFF 0x2e
-
-__xdata __at (0xdf36) uint8_t RF_PARTNUM;
-#define RF_PARTNUM_OFF 0x36
-
-__xdata __at (0xdf37) uint8_t RF_VERSION;
-#define RF_VERSION_OFF 0x37
-
-__xdata __at (0xdf38) uint8_t RF_FREQEST;
-#define RF_FREQEST_OFF 0x38
-
-__xdata __at (0xdf39) uint8_t RF_LQI;
-#define RF_LQI_OFF 0x39
-
-#define RF_LQI_CRC_OK (1 << 7)
-#define RF_LQI_LQI_EST_MASK (0x7f)
-
-__xdata __at (0xdf3a) uint8_t RF_RSSI;
-#define RF_RSSI_OFF 0x3a
-
-__xdata __at (0xdf3b) uint8_t RF_MARCSTATE;
-#define RF_MARCSTATE_OFF 0x3b
-
-#define RF_MARCSTATE_MASK 0x0f
-#define RF_MARCSTATE_SLEEP 0x00
-#define RF_MARCSTATE_IDLE 0x01
-#define RF_MARCSTATE_VCOON_MC 0x03
-#define RF_MARCSTATE_REGON_MC 0x04
-#define RF_MARCSTATE_MANCAL 0x05
-#define RF_MARCSTATE_VCOON 0x06
-#define RF_MARCSTATE_REGON 0x07
-#define RF_MARCSTATE_STARTCAL 0x08
-#define RF_MARCSTATE_BWBOOST 0x09
-#define RF_MARCSTATE_FS_LOCK 0x0a
-#define RF_MARCSTATE_IFADCON 0x0b
-#define RF_MARCSTATE_ENDCAL 0x0c
-#define RF_MARCSTATE_RX 0x0d
-#define RF_MARCSTATE_RX_END 0x0e
-#define RF_MARCSTATE_RX_RST 0x0f
-#define RF_MARCSTATE_TXRX_SWITCH 0x10
-#define RF_MARCSTATE_RX_OVERFLOW 0x11
-#define RF_MARCSTATE_FSTXON 0x12
-#define RF_MARCSTATE_TX 0x13
-#define RF_MARCSTATE_TX_END 0x14
-#define RF_MARCSTATE_RXTX_SWITCH 0x15
-#define RF_MARCSTATE_TX_UNDERFLOW 0x16
-
-
-__xdata __at (0xdf3c) uint8_t RF_PKTSTATUS;
-#define RF_PKTSTATUS_OFF 0x3c
-
-#define RF_PKTSTATUS_CRC_OK (1 << 7)
-#define RF_PKTSTATUS_CS (1 << 6)
-#define RF_PKTSTATUS_PQT_REACHED (1 << 5)
-#define RF_PKTSTATUS_CCA (1 << 4)
-#define RF_PKTSTATUS_SFD (1 << 3)
-
-__xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC;
-#define RF_VCO_VC_DAC_OFF 0x3d
-
-#define PACKET_LEN 128
-
-void
-radio_init(void);
-
-void
-delay (unsigned char n);
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "radio.h"
-
-main ()
-{
- static uint8_t packet[PACKET_LEN + 2];
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
- /* Set P2_0 to output */
- P1 = 0;
- P1DIR = 0x02;
- radio_init ();
- delay(100);
-
- for (;;) {
- uint8_t i;
- RFST = RFST_SIDLE;
- RFIF = 0;
- delay(100);
- RFST = RFST_SRX;
-// while (!(RFIF & RFIF_IM_CS));
-// P1 = 2;
- for (i = 0; i < PACKET_LEN + 2; i++) {
- while (!RFTXRXIF)
- ;
- P1=2;
- RFTXRXIF = 0;
- packet[i] = RFD;
- }
- P1 = 0;
-
- /* check packet contents */
- for (i = 0; i < PACKET_LEN; i++)
- if (packet[i] != i)
- break;
-
- /* get excited if the packet came through correctly */
- if (i == PACKET_LEN &&
- packet[PACKET_LEN+1] & PKT_APPEND_STATUS_1_CRC_OK)
- {
- for (i = 0; i < 5; i++){
- P1 = 2;
- delay(100);
- P1 = 0;
- delay(100);
- }
- }
- delay(100);
- }
-}
+++ /dev/null
-/*
- * Copyright © 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "radio.h"
-
-main ()
-{
- int16_t j;
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
- P1 = 0;
- P1DIR = 3;
- radio_init ();
- delay(100);
-
- for (;;) {
- uint8_t i;
-
- for (j = 0; j < 100; j++)
- delay(100);
- P1 = 2;
- RFST = RFST_SIDLE;
- delay(1);
- RFST = RFST_STX;
- for (i = 0; i < PACKET_LEN; i++) {
- while (!RFTXRXIF);
- RFTXRXIF = 0;
- RFD = i;
- }
- P1 = 0;
- }
-}
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=--out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=serial.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=serial-flash.ihx serial-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-serial-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o serial-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o serial-flash.ihx $(REL)
-
-serial-flash.ihx: serial-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-
-install:
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include <stdint.h>
-
-/*
- * Validate UART1
- */
-
-sfr at 0x80 P0;
-sfr at 0x90 P1;
-sfr at 0xA0 P2;
-sfr at 0xC6 CLKCON;
-sfr at 0xbe SLEEP;
-
-# define SLEEP_USB_EN (1 << 7)
-# define SLEEP_XOSC_STB (1 << 6)
-
-sfr at 0xF1 PERCFG;
-#define PERCFG_T1CFG_ALT_1 (0 << 6)
-#define PERCFG_T1CFG_ALT_2 (1 << 6)
-
-#define PERCFG_T3CFG_ALT_1 (0 << 5)
-#define PERCFG_T3CFG_ALT_2 (1 << 5)
-
-#define PERCFG_T4CFG_ALT_1 (0 << 4)
-#define PERCFG_T4CFG_ALT_2 (1 << 4)
-
-#define PERCFG_U1CFG_ALT_1 (0 << 1)
-#define PERCFG_U1CFG_ALT_2 (1 << 1)
-
-#define PERCFG_U0CFG_ALT_1 (0 << 0)
-#define PERCFG_U0CFG_ALT_2 (1 << 0)
-
-sfr at 0xF2 ADCCFG;
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-sfr at 0x8F P0INP;
-sfr at 0xF6 P1INP;
-sfr at 0xF7 P2INP;
-
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-/*
- * UART registers
- */
-
-sfr at 0x86 U0CSR;
-sfr at 0xF8 U1CSR;
-
-/*
- * IRCON2
- */
-sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */
-
-sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */
-sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */
-sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */
-sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */
-sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */
-sbit at 0xEB P1IF; /* Port1 interrupt flag */
-sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */
-
-# define UxCSR_MODE_UART (1 << 7)
-# define UxCSR_MODE_SPI (0 << 7)
-# define UxCSR_RE (1 << 6)
-# define UxCSR_SLAVE (1 << 5)
-# define UxCSR_MASTER (0 << 5)
-# define UxCSR_FE (1 << 4)
-# define UxCSR_ERR (1 << 3)
-# define UxCSR_RX_BYTE (1 << 2)
-# define UxCSR_TX_BYTE (1 << 1)
-# define UxCSR_ACTIVE (1 << 0)
-
-sfr at 0xc4 U0UCR;
-sfr at 0xfb U1UCR;
-
-# define UxUCR_FLUSH (1 << 7)
-# define UxUCR_FLOW_DISABLE (0 << 6)
-# define UxUCR_FLOW_ENABLE (1 << 6)
-# define UxUCR_D9_EVEN_PARITY (0 << 5)
-# define UxUCR_D9_ODD_PARITY (1 << 5)
-# define UxUCR_BIT9_8_BITS (0 << 4)
-# define UxUCR_BIT9_9_BITS (1 << 4)
-# define UxUCR_PARITY_DISABLE (0 << 3)
-# define UxUCR_PARITY_ENABLE (1 << 3)
-# define UxUCR_SPB_1_STOP_BIT (0 << 2)
-# define UxUCR_SPB_2_STOP_BITS (1 << 2)
-# define UxUCR_STOP_LOW (0 << 1)
-# define UxUCR_STOP_HIGH (1 << 1)
-# define UxUCR_START_LOW (0 << 0)
-# define UxUCR_START_HIGH (1 << 0)
-
-sfr at 0xc5 U0GCR;
-sfr at 0xfc U1GCR;
-
-# define UxGCR_CPOL_NEGATIVE (0 << 7)
-# define UxGCR_CPOL_POSITIVE (1 << 7)
-# define UxGCR_CPHA_FIRST_EDGE (0 << 6)
-# define UxGCR_CPHA_SECOND_EDGE (1 << 6)
-# define UxGCR_ORDER_LSB (0 << 5)
-# define UxGCR_ORDER_MSB (1 << 5)
-# define UxGCR_BAUD_E_MASK (0x1f)
-# define UxGCR_BAUD_E_SHIFT 0
-
-sfr at 0xc1 U0DBUF;
-sfr at 0xf9 U1DBUF;
-sfr at 0xc2 U0BAUD;
-sfr at 0xfa U1BAUD;
-
-#define MOSI P1_5
-#define MISO P1_4
-#define SCK P1_3
-#define CS P1_2
-
-#define DEBUG P1_1
-
-#define USART 1
-
-#define nop() _asm nop _endasm;
-
-void
-delay (unsigned char n)
-{
- unsigned char i = 0;
- unsigned char j = 0;
-
- n++;
- while (--n != 0)
- while (--i != 0)
- while (--j != 0)
- nop();
-}
-
-/*
- * This version uses the USART in SPI mode
- */
-void
-usart_init(void)
-{
- P1DIR |= (1 << 2);
- /*
- * Configure the peripheral pin choices
- * for both of the serial ports
- *
- * Note that telemetrum will use U1CFG_ALT_2
- * but that overlaps with SPI ALT_2, so until
- * we can test that this works, we'll set this
- * to ALT_1
- */
- PERCFG = (PERCFG_U1CFG_ALT_2 |
- PERCFG_U0CFG_ALT_1);
-
- /*
- * Make the UART pins controlled by the UART
- * hardware
- */
- P1SEL |= ((1 << 6) | (1 << 7));
-
- /*
- * UART mode with the receiver enabled
- */
- U1CSR = (UxCSR_MODE_UART |
- UxCSR_RE);
- /*
- * Pick a 38.4kbaud rate
- */
- U1BAUD = 163;
- U1GCR = 10 << UxGCR_BAUD_E_SHIFT; /* 38400 */
-// U1GCR = 3 << UxGCR_BAUD_E_SHIFT; /* 300 */
- /*
- * Reasonable serial parameters
- */
- U1UCR = (UxUCR_FLUSH |
- UxUCR_FLOW_DISABLE |
- UxUCR_D9_ODD_PARITY |
- UxUCR_BIT9_8_BITS |
- UxUCR_PARITY_DISABLE |
- UxUCR_SPB_2_STOP_BITS |
- UxUCR_STOP_HIGH |
- UxUCR_START_LOW);
-}
-
-void
-usart_out_byte(uint8_t byte)
-{
- U1DBUF = byte;
- while (!UTX1IF)
- ;
- UTX1IF = 0;
-}
-
-void
-usart_out_string(uint8_t *string)
-{
- uint8_t b;
-
- while (b = *string++)
- usart_out_byte(b);
-}
-
-uint8_t
-usart_in_byte(void)
-{
- uint8_t b;
- while ((U1CSR & UxCSR_RX_BYTE) == 0)
- ;
- b = U1DBUF;
- U1CSR &= ~UxCSR_RX_BYTE;
- return b;
-}
-
-void
-debug_byte(uint8_t byte)
-{
- uint8_t s;
-
- for (s = 0; s < 8; s++) {
- DEBUG = byte & 1;
- delay(5);
- byte >>= 1;
- }
-}
-
-main ()
-{
- P1DIR |= 2;
- CLKCON = 0;
- while (!(SLEEP & SLEEP_XOSC_STB))
- ;
-
- usart_init();
-
- for (;;) {
- usart_out_string("hello world\r\n");
- debug_byte(usart_in_byte());
- }
-
-}
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=-L/local/share/sdcc/lib/large --out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=simple.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=simple-flash.ihx simple-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-simple-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o simple-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o simple-flash.ihx $(REL)
-
-simple-flash.ihx: simple-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-sfr at 0x90 P1;
-sfr at 0xC6 CLKCON;
-
-sfr at 0xFE P1DIR;
-sfr at 0xF6 P1INP;
-
-void delay(int n) __reentrant
-{
- while (n--)
- _asm nop _endasm;
-}
-int
-main (void) __reentrant
-{
- long i;
- CLKCON = 0;
- /* Set p1_1 to output */
- P1DIR = 0x02;
- for (;;) {
- P1 ^= 0x2;
- for (i = 0; i < 1000; i++)
- delay(1000);
- }
-}
+++ /dev/null
-CC=sdcc
-NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
- --nolabelopt --nooverlay --peep-asm
-DEBUG=--debug
-
-CFLAGS=--model-large $(DEBUG) --less-pedantic \
- --no-peep --int-long-reent --float-reent \
- --data-loc 0x30
-
-LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx
-LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024
-
-LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024
-
-SRC=timer.c
-ADB=$(SRC:.c=.adb)
-ASM=$(SRC:.c=.asm)
-LNK=$(SRC:.c=.lnk)
-LST=$(SRC:.c=.lst)
-REL=$(SRC:.c=.rel)
-RST=$(SRC:.c=.rst)
-SYM=$(SRC:.c=.sym)
-
-PROGS=timer-flash.ihx timer-ram.ihx
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c
- $(CC) -c $(CFLAGS) -o$*.rel $<
-
-all: $(PROGS)
-
-timer-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o timer-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o timer-flash.ihx $(REL)
-
-timer-flash.ihx: timer-ram.ihx
-
-clean:
- rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
- rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+++ /dev/null
-/*-------------------------------------------------------------------------
- Register Declarations for the ChipCon CC1111 Processor Range
-
- Copyright © 2008 Keith Packard <keithp@keithp.com>
-
- 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.,
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
- Adapted from the Cygnal C8051F12x config file which is:
-
- Copyright (C) 2003 - Maarten Brock, sourceforge.brock@dse.nl
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
-
-#ifndef _CC1111_H_
-#define _CC1111_H_
-
-
-/* BYTE Registers */
-
-sfr at 0x80 P0 ; /* PORT 0 */
-sfr at 0x81 SP ; /* STACK POINTER */
-sfr at 0x82 DPL ; /* DATA POINTER - LOW BYTE */
-sfr at 0x83 DPH ; /* DATA POINTER - HIGH BYTE */
-sfr at 0x84 DPL1 ; /* DATA POINTER 1 - LOW BYTE */
-sfr at 0x85 DPH1 ; /* DATA POINTER 1 - HIGH BYTE */
-sfr at 0x86 U0CSR ; /* USART 0 Control and status */
-sfr at 0x87 PCON ; /* POWER CONTROL */
-sfr at 0x88 TCON ; /* TIMER CONTROL */
-sfr at 0x89 P0IFG ; /* TIMER MODE */
-sfr at 0x8A P1IFG ; /* TIMER 0 - LOW BYTE */
-sfr at 0x8B P2IFG ; /* TIMER 1 - LOW BYTE */
-sfr at 0x8C PICTL ; /* TIMER 0 - HIGH BYTE */
-sfr at 0x8D P1IEN ; /* TIMER 1 - HIGH BYTE */
-
-sfr at 0x8F P0INP ; /* FLASH WRITE/ERASE CONTROL */
-sfr at 0x90 P1 ; /* PORT 1 */
-sfr at 0x91 RFIM ; /* UART 0 STATUS */
-sfr at 0x92 DPS ; /* */
-sfr at 0x93 MPAGE ; /* */
-sfr at 0x94 _SFR94_ ; /* */
-sfr at 0x95 ENDIAN ; /* */
-sfr at 0x96 _SFR96_ ; /* */
-sfr at 0x97 _SFR97_ ; /* */
-sfr at 0x98 S0CON ; /* UART 0 CONTROL */
-sfr at 0x99 _SFR99_ ; /* UART 0 BUFFER */
-sfr at 0x9A IEN2 ; /* SPI 0 CONFIGURATION */
-sfr at 0x9B S1CON ; /* SPI 0 DATA */
-sfr at 0x9C T2CT ; /* SPI 0 DATA */
-sfr at 0x9D T2PR ; /* SPI 0 CLOCK RATE CONTROL */
-sfr at 0x9E T2CTL ; /* SPI 0 CLOCK RATE CONTROL */
-sfr at 0x9F _SFR9F_ ; /* SPI 0 CLOCK RATE CONTROL */
-sfr at 0xA0 P2 ; /* PORT 2 */
-sfr at 0xA1 WORIRQ ; /* EMIF TIMING CONTROL */
-sfr at 0xA2 WORCTRL ; /* EMIF CONTROL */
-sfr at 0xA3 WOREVT0 ; /* EMIF CONFIGURATION */
-sfr at 0xA4 WOREVT1 ; /* EMIF CONFIGURATION */
-sfr at 0xA5 WORTIME0 ; /* EMIF CONFIGURATION */
-sfr at 0xA6 WORTIME1 ; /* EMIF CONFIGURATION */
-sfr at 0xA7 _SFRA7_ ; /* EMIF CONFIGURATION */
-sfr at 0xA8 IEN0 ; /* INTERRUPT ENABLE */
-sfr at 0xA9 IP0 ; /* UART 0 SLAVE ADDRESS */
-sfr at 0xAA _SFRAA_ ; /* */
-sfr at 0xAB FWT ; /* */
-sfr at 0xAC FADDRL ; /* */
-sfr at 0xAD FADDRH ; /* */
-sfr at 0xAE FCTL ; /* */
-sfr at 0xAF FWDATA ; /* */
-sfr at 0xB0 _SFRB0_ ; /* */
-sfr at 0xB1 ENCDI ; /* FLASH BANK SELECT */
-sfr at 0xB2 ENCDO ; /* */
-sfr at 0xB3 ENCCS ; /* */
-sfr at 0xB4 ADCCON1 ; /* */
-sfr at 0xB5 ADCCON2 ; /* */
-sfr at 0xB6 ADCCON3 ; /* */
-sfr at 0xB8 IEN1 ; /* INTERRUPT PRIORITY */
-sfr at 0xB9 IP1 ; /* */
-sfr at 0xBA ADCL ; /* */
-sfr at 0xBB ADCH ; /* */
-sfr at 0xBC RNDL ; /* */
-sfr at 0xBD RNDH ; /* */
-sfr at 0xBE SLEEP ; /* */
-sfr at 0xC0 IRCON ; /* */
-sfr at 0xC1 U0DBUF ; /* */
-sfr at 0xC2 U0BAUD ; /* */
-sfr at 0xC4 U0UCR ; /* */
-sfr at 0xC5 U0GCR ; /* */
-sfr at 0xC6 CLKCON ; /* */
-sfr at 0xC7 MEMCTR ; /* */
-sfr at 0xC9 WDCTL ; /* */
-sfr at 0xCA T3CNT ; /* */
-sfr at 0xCB T3CTL ; /* */
-sfr at 0xCC T3CCTL0 ; /* */
-sfr at 0xCD T3CC0 ; /* */
-sfr at 0xCE T3CCTL1 ; /* */
-sfr at 0xCF T3CC1 ; /* */
-sfr at 0xD0 PSW ; /* */
-sfr at 0xD1 DMAIRQ ; /* */
-sfr at 0xD2 DMA1CFGL ; /* */
-sfr at 0xD3 DMA1CFGH ; /* */
-sfr at 0xD4 DMA0CFGL ; /* */
-sfr at 0xD5 DMA0CFGH ; /* */
-sfr at 0xD6 DMAARM ; /* */
-sfr at 0xD7 DMAREQ ; /* */
-sfr at 0xD8 TIMIF ; /* */
-sfr at 0xD9 RFD ; /* */
-sfr at 0xDA T1CC0L ; /* */
-sfr at 0xDB T1CC0H ; /* */
-sfr at 0xDC T1CC1L ; /* */
-sfr at 0xDD T1CC1H ; /* */
-sfr at 0xDE T1CC2L ; /* */
-sfr at 0xDF T1CC2H ; /* */
-sfr at 0xE0 ACC ; /* ACCUMULATOR */
-sfr at 0xE1 RFST ; /* */
-sfr at 0xE2 T1CNTL ; /* */
-sfr at 0xE3 T1CNTH ; /* */
-sfr at 0xE4 T1CTL ; /* */
-sfr at 0xE5 T1CCTL0 ; /* */
-sfr at 0xE6 T1CCTL1 ; /* */
-sfr at 0xE7 T1CCTL2 ; /* */
-sfr at 0xE8 IRCON2 ; /* */
-sfr at 0xE9 RFIF ; /* */
-sfr at 0xEA T4CNT ; /* */
-sfr at 0xEB T4CTL ; /* */
-sfr at 0xEC T4CCTL0 ; /* */
-sfr at 0xED T4CC0 ; /* */
-sfr at 0xEE T4CCTL1 ; /* */
-sfr at 0xEF T4CC1 ; /* */
-sfr at 0xF0 B ; /* */
-sfr at 0xF1 PERCFG ; /* */
-sfr at 0xF2 ADCCFG ; /* */
-sfr at 0xF3 P0SEL ; /* */
-sfr at 0xF4 P1SEL ; /* */
-sfr at 0xF5 P2SEL ; /* */
-sfr at 0xF6 P1INP ; /* */
-sfr at 0xF7 P2INP ; /* */
-sfr at 0xF8 U1CSR ; /* */
-sfr at 0xF9 U1DBUF ; /* */
-sfr at 0xFA U1BAUD ; /* */
-sfr at 0xFB U1UCR ; /* */
-sfr at 0xFC U1GCR ; /* */
-sfr at 0xFD P0DIR ; /* */
-sfr at 0xFE P1DIR ; /* */
-sfr at 0xFF P2DIR ; /* */
-
-/* BIT Registers */
-
-/* P0 0x80 */
-sbit at 0x80 P0_0 ;
-sbit at 0x81 P0_1 ;
-sbit at 0x82 P0_2 ;
-sbit at 0x83 P0_3 ;
-sbit at 0x84 P0_4 ;
-sbit at 0x85 P0_5 ;
-sbit at 0x86 P0_6 ;
-sbit at 0x87 P0_7 ;
-
-/* TCON 0x88 */
-sbit at 0x89 RFTXRXIF; /* */
-sbit at 0x8B URX0IF ; /* */
-sbit at 0x8D ADCIF ; /* */
-sbit at 0x8F URX1IF ; /* */
-sbit at 0x8F I2SRXIF ; /* */
-
-/* SCON0 0x98 */
-sbit at 0x98 ENCIF_0 ; /* UART 0 RX INTERRUPT FLAG */
-sbit at 0x99 ENCIF_1 ; /* UART 0 RX INTERRUPT FLAG */
-
-/* IEN0 0xA8 */
-sbit at 0xA8 RFTXRXIE; /* RF TX/RX done interrupt enable */
-sbit at 0xA9 ADCIE ; /* ADC interrupt enable */
-sbit at 0xAA URX0IE ; /* USART0 RX interrupt enable */
-sbit at 0xAB URX1IE ; /* USART1 RX interrupt enable */
-sbit at 0xAB I2SRXIE ; /* I2S RX interrupt enable */
-sbit at 0xAC ENCIE ; /* AES interrupt enable */
-sbit at 0xAD STIE ; /* Sleep Timer interrupt enable */
-sbit at 0xAF EA ; /* GLOBAL INTERRUPT ENABLE */
-
-/* IEN1 0xB8 */
-sbit at 0xB8 DMAIE ; /* DMA transfer interrupt enable */
-sbit at 0xB9 T1IE ; /* Timer 1 interrupt enable */
-sbit at 0xBA T2IE ; /* Timer 2 interrupt enable */
-sbit at 0xBB T3IE ; /* Timer 3 interrupt enable */
-sbit at 0xBC T4IE ; /* Timer 4 interrupt enable */
-sbit at 0xBD P0IE ; /* Port 0 interrupt enable */
-
-/* IRCON 0xC0 */
-sbit at 0xC0 DMAIF ; /* */
-sbit at 0xC1 T1IF ; /* */
-sbit at 0xC2 T2IF ; /* */
-sbit at 0xC3 T3IF ; /* */
-sbit at 0xC4 T4IF ; /* */
-sbit at 0xC5 P0IF ; /* */
-sbit at 0xC7 STIF ; /* */
-
-/* PSW 0xD0 */
-sbit at 0xD0 P ; /* ACCUMULATOR PARITY FLAG */
-sbit at 0xD1 F1 ; /* USER FLAG 1 */
-sbit at 0xD2 OV ; /* OVERFLOW FLAG */
-sbit at 0xD3 RS0 ; /* REGISTER BANK SELECT 0 */
-sbit at 0xD4 RS1 ; /* REGISTER BANK SELECT 1 */
-sbit at 0xD5 F0 ; /* USER FLAG 0 */
-sbit at 0xD6 AC ; /* AUXILIARY CARRY FLAG */
-sbit at 0xD7 CY ; /* CARRY FLAG */
-
-/* TIMIF D8H */
-sbit at 0xD8 T3OVFIF ; /* */
-sbit at 0xD9 T3CH0IF ; /* */
-sbit at 0xDA T3CH1IF ; /* */
-sbit at 0xDB T4OVFIF ; /* */
-sbit at 0xDC T4CH0IF ; /* */
-sbit at 0xDD T4CH1IF ; /* */
-sbit at 0xDE OVFIM ; /* */
-
-/* IRCON2 E8H */
-sbit at 0xE8 P2IF ; /* */
-sbit at 0xE8 USBIF ; /* */
-sbit at 0xE9 UTX0IF ; /* */
-sbit at 0xEA UTX1IF ; /* */
-sbit at 0xEA I2STXIF ; /* */
-sbit at 0xEB P1IF ; /* */
-sbit at 0xEC WDTIF ; /* */
-
-/* U1CSR F8H */
-sbit at 0xF8 U1_ACTIVE ; /* */
-sbit at 0xF9 U1_TX_BYTE ; /* */
-sbit at 0xFA U1_RX_BYTE ; /* */
-sbit at 0xFB U1_ERR ; /* */
-sbit at 0xFC U1_FE ; /* */
-sbit at 0xFD U1_SLAVE ; /* */
-sbit at 0xFE U1_RE ; /* */
-sbit at 0xFF U1_MODE ; /* */
-
-#define T1CTL_MODE_SUSPENDED (0 << 0)
-#define T1CTL_MODE_FREE (1 << 0)
-#define T1CTL_MODE_MODULO (2 << 0)
-#define T1CTL_MODE_UP_DOWN (3 << 0)
-#define T1CTL_MODE_MASK (3 << 0)
-#define T1CTL_DIV_1 (0 << 2)
-#define T1CTL_DIV_8 (1 << 2)
-#define T1CTL_DIV_32 (2 << 2)
-#define T1CTL_DIV_128 (3 << 2)
-#define T1CTL_DIV_MASK (3 << 2)
-#define T1CTL_OVFIF (1 << 4)
-#define T1CTL_CH0IF (1 << 5)
-#define T1CTL_CH1IF (1 << 6)
-#define T1CTL_CH2IF (1 << 7)
-
-#define T1CCTL_NO_CAPTURE (0 << 0)
-#define T1CCTL_CAPTURE_RISING (1 << 0)
-#define T1CCTL_CAPTURE_FALLING (2 << 0)
-#define T1CCTL_CAPTURE_BOTH (3 << 0)
-#define T1CCTL_CAPTURE_MASK (3 << 0)
-
-#define T1CCTL_MODE_CAPTURE (0 << 2)
-#define T1CCTL_MODE_COMPARE (1 << 2)
-
-#define T1CTL_CMP_SET (0 << 3)
-#define T1CTL_CMP_CLEAR (1 << 3)
-#define T1CTL_CMP_TOGGLE (2 << 3)
-#define T1CTL_CMP_SET_CLEAR (3 << 3)
-#define T1CTL_CMP_CLEAR_SET (4 << 3)
-
-#define T1CTL_IM_DISABLED (0 << 6)
-#define T1CTL_IM_ENABLED (1 << 6)
-
-#define T1CTL_CPSEL_NORMAL (0 << 7)
-#define T1CTL_CPSEL_RF (1 << 7)
-
-#endif
+++ /dev/null
-/*
- * Copyright © 2008 Keith Packard <keithp@keithp.com>
- *
- * 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.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "cc1111.h"
-
-unsigned char irqs;
-
-void timer1_isr(void) interrupt 9 __reentrant
-{
- ++irqs;
- if (irqs == 100) {
- P1 ^= 0x2;
- irqs = 0;
- }
-}
-
-int
-main (void) __reentrant
-{
- CLKCON = 0;
- P1DIR = 0x2;
- P1 = 0xff;
-
- T1CTL = 0;
-
- /* 30000 */
- T1CC0H = 0x75;
- T1CC0L = 0x30;
- T1CCTL0 = T1CCTL_MODE_COMPARE;
- T1CCTL1 = 0;
- T1CCTL2 = 0;
-
- /* clear timer value */
- T1CNTL = 0;
- OVFIM = 1;
- T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
- T1IE = 1;
- EA = 1;
- for (;;);
-}
+++ /dev/null
-:03 0000 00 75 FE 02 88
-:03 0003 00 75 90 FF F6
-:02 0006 00 80 FE 7A
-:02 0008 00 80 FE 78
-:00 0000 01 FF
+++ /dev/null
-:03 F000 00 75 FE 02 98
-:03 F003 00 75 90 FF 06
-:02 F006 00 80 FE 8A
-:00000001FF
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# GET_CHIP_ID
-
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-C . R 0
-. . R
-
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# start reading again
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# GET_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# Now read for a while
-#
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# Halt 0x44
-#
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-# status byte
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-# Resume 0x4c
-#
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-C D R 1
-. D R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-# status byte
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# READ_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# status
-#
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# READ_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# status
-#
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# READ_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# status
-#
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# Halt 0x44
-#
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-# status byte
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# READ_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# status
-#
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# GET_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# Now read for a while
-#
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D .
-
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-
-#
-# Ok, we're in debug mode now
-#
-
-#
-# GET_CHIP_ID
-
-#C . R 0
-#. . R
-#C D R 1
-#. D R
-#C D R 1
-#. D R
-#C . R 0
-#. . R
-#
-#C D R 1
-#. D R
-#C . R 0
-#. . R
-#C . R 0
-#. . R
-#C . R 0
-#. . R
-#
-##
-## Read the chip id
-##
-#
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#C D R
-#. D R
-#
-
-#
-# GET_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# Now read for a while
-#
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# Halt 0x44
-#
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-# status byte
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# DEBUG_INSTR
-#
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-# MOV 0xfe, 0x02
-
-# 0x75 0x02 0xfe
-
-# 0x75
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-# 0xfe
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-C . R 0
-. . R
-
-# 0x02
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-
-# status byte
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# DEBUG_INSTR
-#
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-# MOV 0x90, 0xfd
-# 0x75 0xfd 0x90
-
-# 0x75
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-# 0x90
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-
-# 0xff
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-# status byte
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-#
-# DEBUG_INSTR
-#
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-# MOV 0x90, 0xfd
-# 0x75 0xfd 0x90
-
-# 0x75
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-# 0x90
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-
-# 0xfd
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C D R 1
-. D R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-# status byte
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# RD_CONFIG
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# Now read for a while
-#
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# READ_STATUS
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# Now read for a while
-#
-
-C D R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-C - R
-. - R
-
-C D R
+++ /dev/null
-# reset
-C D R
-C D R
-C D R
-C D R
+++ /dev/null
-#
-# Debug mode - drive RESET_N low for two clock cycles
-#
-C D R
-. D .
-C D .
-. D .
-C D .
-. D R
-
-#
-# WR_CONFIG
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-
-C D R 1
-. D R
-C D R 1
-. D R
-C . R 0
-. . R
-C D R 1
-. D R
-
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# Now read for a while
-#
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-
-#
-# RD_CONFIG
-#
-
-C . R 0
-. . R
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-
-C . R 0
-. . R
-C D R 1
-. D R
-C . R 0
-. . R
-C . R 0
-. . R
-
-#
-# Now read for a while
-#
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
-C D R
-. D R
AC_OUTPUT([
Makefile
-aoview/Makefile
-cctools/Makefile
-cctools/lib/Makefile
-cctools/ccload/Makefile
-cctools/s51/Makefile
-cctools/ccmanual/Makefile
-cctools/ccdump/Makefile
-cctools/aoload/Makefile
-utils/Makefile
+ao-view/Makefile
+ao-tools/Makefile
+ao-tools/lib/Makefile
+ao-tools/ao-rawload/Makefile
+ao-tools/ao-dbg/Makefile
+ao-tools/ao-bitbang/Makefile
+ao-tools/ao-eeprom/Makefile
+ao-tools/ao-load/Makefile
+ao-utils/Makefile
])
+++ /dev/null
-dist_bin_SCRIPTS = ejection
+++ /dev/null
-#!/usr/bin/env nickle
-
-void main () {
- real R = 22.16 * 12; /* in lbf / lbm (gas constant for ffff powder */
- real T = 3307; /* combustion temperature for BP */
- real d_mm; /* diameter(mm) */
- real l_mm; /* length(mm) */
- real f_N; /* force(N) */
- real f_lb;
- real A_mm²; /* area of bulkhead (mm²) */
- real A_in²;
- real V_mm³; /* free volume (mm³) */
- real V_in³;
- real M_lb; /* mass of BP in lb */
- real M_g;
- real P_Nmm²; /* pressure (N/mm²) */
- real P_lbin²; /* pressure (psi) */
-
- if (dim(argv) != 4) {
- File::fprintf(stderr,
- "usage: %s diameter(mm) length(mm) force(N)\n",
- argv[0]);
- exit(1);
- }
-
- d_mm = string_to_real(argv[1]);
- l_mm = string_to_real(argv[2]);
- f_N = string_to_real(argv[3]);
- f_lb = f_N * 0.22480894;
-
- A_mm² = pi * (d_mm/2) ** 2;
- V_mm³ = A_mm² * l_mm;
-
- A_in² = A_mm² / (25.4**2);
- V_in³ = V_mm³ / (25.4**3);
-
- P_Nmm² = f_N / A_mm²;
-
- P_lbin² = P_Nmm² * 0.22480894 * (25.4 ** 2);
-
- M_lb = (P_lbin² * V_in³) / (R * T);
- M_g = M_lb * 453.59237;
-
- printf ("Input parameters:\n");
- printf (" Diameter: %.1g (mm) %.3g (in)\n",
- d_mm, d_mm / 25.4);
- printf (" Length: %.1g (mm) %.3g (in)\n",
- l_mm, l_mm / 25.4);
- printf (" Force: %.1g (N) %.3g (lb)\n",
- f_N, f_lb);
-
- printf ("Chamber values:\n");
- printf (" Area: %.0f (mm²) %.3g (in²)\n",
- A_mm², A_in²);
- printf (" Volume: %.0f (mm³) %.3g (in³)\n",
- V_mm³, V_in³);
- printf (" Pressure: %.2g (lb/in²) %.5g (N/mm²)\n",
- P_lbin², P_Nmm²);
-
- printf ("Results:\n");
- printf (" FFFF powder: %.3g (g)\n", M_g);
-}
-
-main();