Wait for a while when switching the RESET_N line
authorKeith Packard <keithp@keithp.com>
Sat, 7 Mar 2009 06:52:35 +0000 (22:52 -0800)
committerKeith Packard <keithp@keithp.com>
Sat, 7 Mar 2009 06:56:47 +0000 (22:56 -0800)
The cc1111 manual suggests placing a 2.7kΩ resister and 1nF capacitor on the
RESET_N line to filter out noise. This increases the time necessary to reset
the chip to several microseconds which is longer than the interval between
two USB packets. Flush the USB packet queue and sleep for a while after
changing the value on the RESET_N line to make sure the chip sees the state
change.

Signed-off-by: Keith Packard <keithp@keithp.com>
lib/ccdbg-command.c
lib/ccdbg-io.c
lib/ccdbg.h

index d99e8ff3155cd5ea00add5e37d88953c9023d972..74313bdf8ebbd0aea3485f32232b786aaafecc67 100644 (file)
@@ -27,11 +27,12 @@ ccdbg_debug_mode(struct ccdbg *dbg)
        ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N,          CC_DATA           );
        ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N,          CC_DATA           );
+       ccdbg_wait_reset(dbg);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N,          CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N,          CC_DATA|CC_RESET_N);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N,          CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N,          CC_DATA|CC_RESET_N);
-       ccdbg_sync_io(dbg);
+       ccdbg_wait_reset(dbg);
 }
 
 void
 }
 
 void
@@ -42,11 +43,12 @@ ccdbg_reset(struct ccdbg *dbg)
        ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_debug(CC_DEBUG_COMMAND, "#\n");
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
+       ccdbg_wait_reset(dbg);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA           );
        ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N);
-       ccdbg_sync_io(dbg);
+       ccdbg_wait_reset(dbg);
 }
 
 uint8_t
 }
 
 uint8_t
index e5e85e4390ff1220c3eebf12f30fe42a820b2d9e..3606c57cf960461d9a19ecfb879e070385c097bb 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 static uint32_t        cc_clock_us = CC_CLOCK_US;
 #endif
 
 static uint32_t        cc_clock_us = CC_CLOCK_US;
+static uint32_t        cc_reset_us = CC_RESET_US;
 
 void
 ccdbg_set_clock(uint32_t us)
 
 void
 ccdbg_set_clock(uint32_t us)
@@ -41,6 +42,17 @@ ccdbg_half_clock(struct ccdbg *dbg)
        nanosleep(&req, &rem);
 }
 
        nanosleep(&req, &rem);
 }
 
+void
+ccdbg_wait_reset(struct ccdbg *dbg)
+{
+       struct timespec req, rem;
+       
+       ccdbg_sync_io(dbg);
+       req.tv_sec = (cc_reset_us) / 1000000;
+       req.tv_nsec = ((cc_reset_us) % 1000000) * 1000;
+       nanosleep(&req, &rem);
+}
+       
 struct ccdbg *
 ccdbg_open(void)
 {
 struct ccdbg *
 ccdbg_open(void)
 {
index 037d8ff574c11386231f7aa1d93b37e018248493..8bc9444a2e00269230624c9674b54354488dea8d 100644 (file)
 #define CC_RESET_N     0x4
 #define CC_CLOCK_US    (0)
 
 #define CC_RESET_N     0x4
 #define CC_CLOCK_US    (0)
 
+/* 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)
+
 /* 8051 instructions
  */
 #define NOP                    0x00
 /* 8051 instructions
  */
 #define NOP                    0x00
@@ -264,6 +270,9 @@ ccdbg_set_clock(uint32_t us);
 void
 ccdbg_half_clock(struct ccdbg *dbg);
 
 void
 ccdbg_half_clock(struct ccdbg *dbg);
 
+void
+ccdbg_wait_reset(struct ccdbg *dbg);
+
 int
 ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value);
 
 int
 ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value);