Accelerometer-based velocity values are invalid after apogee
[fw/altos] / ao_dbg.c
index 3ccfa0528aa70b5adc9ebcb467d45c48c6ea43ff..8a11a444a786c7c9058098cc48b4210282ea04c0 100644 (file)
--- a/ao_dbg.c
+++ b/ao_dbg.c
@@ -3,8 +3,7 @@
  *
  * 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.
+ * 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
@@ -30,10 +29,12 @@ static void
 ao_dbg_send_bits(uint8_t msk, uint8_t val)
 {
        P0 = (P0 & ~msk) | (val & msk);
+       _asm
+               nop
+               nop
+       _endasm;
 }
 
-#define ao_dbg_pause() do { _asm nop; nop; nop _endasm; } while (0);
-
 void
 ao_dbg_send_byte(uint8_t byte)
 {
@@ -47,9 +48,7 @@ ao_dbg_send_byte(uint8_t byte)
                        d = DBG_DATA;
                byte <<= 1;
                ao_dbg_send_bits(DBG_CLOCK|DBG_DATA, DBG_CLOCK|d);
-               ao_dbg_pause();
                ao_dbg_send_bits(DBG_CLOCK|DBG_DATA,     0    |d);
-               ao_dbg_pause();
        }
        P0DIR &= ~DBG_DATA;
 }
@@ -63,11 +62,9 @@ ao_dbg_recv_byte(void)
        for (b = 0; b < 8; b++) {
                byte = byte << 1;
                ao_dbg_send_bits(DBG_CLOCK, DBG_CLOCK);
-               ao_dbg_pause();
                if (DBG_DATA_PIN)
                        byte |= 1;
                ao_dbg_send_bits(DBG_CLOCK, 0);
-               ao_dbg_pause();
        }
        return byte;
 }
@@ -107,7 +104,7 @@ __xdata uint8_t save_dpl1;
 __xdata uint8_t save_dph1;
 
 static uint8_t
-ao_dbg_inst1(uint8_t a)
+ao_dbg_inst1(uint8_t a) __reentrant
 {
        ao_dbg_send_byte(DEBUG_INSTR(1));
        ao_dbg_send_byte(a);
@@ -115,7 +112,7 @@ ao_dbg_inst1(uint8_t a)
 }
 
 static uint8_t
-ao_dbg_inst2(uint8_t a, uint8_t b)
+ao_dbg_inst2(uint8_t a, uint8_t b) __reentrant
 {
        ao_dbg_send_byte(DEBUG_INSTR(2));
        ao_dbg_send_byte(a);
@@ -124,7 +121,7 @@ ao_dbg_inst2(uint8_t a, uint8_t b)
 }
 
 static uint8_t
-ao_dbg_inst3(uint8_t a, uint8_t b, uint8_t c)
+ao_dbg_inst3(uint8_t a, uint8_t b, uint8_t c) __reentrant
 {
        ao_dbg_send_byte(DEBUG_INSTR(3));
        ao_dbg_send_byte(a);
@@ -190,27 +187,181 @@ ao_dbg_set_pins(void)
        P0DIR = DBG_RESET_N | DBG_CLOCK;
 }
 
+static void
+ao_dbg_long_delay(void)
+{
+       uint8_t n;
+
+       for (n = 0; n < 20; n++)
+               _asm nop _endasm;
+}
+
 void
 ao_dbg_debug_mode(void)
 {
        ao_dbg_set_pins();
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
 }
 
 void
 ao_dbg_reset(void)
 {
        ao_dbg_set_pins();
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
        ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
+}
+
+static void
+debug_enable(void)
+{
+       ao_dbg_debug_mode();
+}
+
+static void
+debug_reset(void)
+{
+       ao_dbg_reset();
+}
+
+static void
+debug_put(void)
+{
+       for (;;) {
+               ao_cmd_white ();
+               if (ao_cmd_lex_c == '\n')
+                       break;
+               ao_cmd_hex();
+               if (ao_cmd_status != ao_cmd_success)
+                       break;
+               ao_dbg_send_byte(ao_cmd_lex_i);
+       }
+}
+
+static void
+debug_get(void)
+{
+       __xdata uint16_t count;
+       __xdata uint16_t i;
+       __xdata uint8_t byte;
+       ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       count = ao_cmd_lex_i;
+       if (count > 256) {
+               ao_cmd_status = ao_cmd_syntax_error;
+               return;
+       }
+       for (i = 0; i < count; i++) {
+               if (i && (i & 7) == 0)
+                       putchar('\n');
+               byte = ao_dbg_recv_byte();
+               ao_cmd_put8(byte);
+               putchar(' ');
+       }
+       putchar('\n');
+}
+
+static uint8_t
+getnibble(void)
+{
+       __xdata char    c;
+
+       c = getchar();
+       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);
+       ao_cmd_status = ao_cmd_lex_error;
+       return 0;
 }
 
+static void
+debug_input(void)
+{
+       __xdata uint16_t count;
+       __xdata uint16_t addr;
+       __xdata uint8_t b;
+       __xdata uint8_t i;
+
+       ao_cmd_hex();
+       count = ao_cmd_lex_i;
+       ao_cmd_hex();
+       addr = ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_dbg_start_transfer(addr);
+       i = 0;
+       while (count--) {
+               if (!(i++ & 7))
+                       putchar('\n');
+               b = ao_dbg_read_byte();
+               ao_cmd_put8(b);
+       }
+       ao_dbg_end_transfer();
+       putchar('\n');
+}
+
+static void
+debug_output(void)
+{
+       __xdata uint16_t count;
+       __xdata uint16_t addr;
+       __xdata uint8_t b;
+
+       ao_cmd_hex();
+       count = ao_cmd_lex_i;
+       ao_cmd_hex();
+       addr = ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_dbg_start_transfer(addr);
+       while (count--) {
+               b = getnibble() << 4;
+               b |= getnibble();
+               if (ao_cmd_status != ao_cmd_success)
+                       return;
+               ao_dbg_write_byte(b);
+       }
+       ao_dbg_end_transfer();
+}
+
+__code struct ao_cmds ao_dbg_cmds[7] = {
+       { 'D',  debug_enable,   "D                                  Enable debug mode" },
+       { 'G',  debug_get,      "G <count>                          Get data from debug port" },
+       { 'I',  debug_input,    "I <count> <addr>                   Input <count> bytes to target at <addr>" },
+       { 'O',  debug_output,   "O <count> <addr>                   Output <count> bytes to target at <addr>" },
+       { 'P',  debug_put,      "P <byte> ...                       Put data to debug port" },
+       { 'R',  debug_reset,    "R                                  Reset target" },
+       { 0, debug_reset,       0 },
+};
+
+void
+ao_dbg_init(void)
+{
+       ao_cmd_register(&ao_dbg_cmds[0]);
+}