First addition of dsPIC33F/PIC24H chip family programmer!
[goodfet] / firmware / lib / command.c
index 415171b..1de6f0a 100644 (file)
@@ -140,3 +140,57 @@ void msdelay(unsigned int ms){
   }
   //Using TimerA might be cleaner.
 }
+
+
+/* To better satisfy the somewhat odd timing requirements for
+   dsPIC33F/PIC24H ICSP programming, and for better control of GoodFET
+   timing more generally, here are a few delay routines that use Timer A.
+
+   Note that I wrote these referring only to the MSP430x2xx family
+   manual. Beware on MSP430x1xx chips. Further note that, assuming
+   some minor errors will be made, I try to err on the side of
+   delaying slightly longer than requested. */
+void prep_timer()
+{
+       BCSCTL2 = 0x00; /* In particular, use DCOCLK as SMCLK source with
+                                          divider 1. Hence, Timer A ticks with system
+                                          clock at 16 MHz. */
+
+       TACTL = 0x0204; /* Driven by SMCLK; disable Timer A interrupts;
+                                          reset timer in case it was previously in use */
+}
+
+//! Delay for specified number of milliseconds (given 16 MHz clock)
+void delay_ms( unsigned int ms )
+{
+       // 16000 ticks = 1 ms
+       TACTL |= 0x20; // Start timer!
+       while (ms--) {
+               while (TAR < 16000)
+                       asm( "nop" );
+               TACTL = 0x0224;
+       }
+       TACTL = 0x0204; // Reset Timer A, till next time
+}
+
+//! Delay for specified number of microseconds (given 16 MHz clock)
+void delay_us( unsigned int us )
+{
+       // 16 ticks = 1 us
+       TACTL |= 0x20; // Start timer!
+       while (us--) {
+               while (TAR < 16)
+                       asm( "nop" );
+               TACTL = 0x0224;
+       }
+       TACTL = 0x0204; // Reset Timer A, till next time
+}
+
+//! Delay for specified number of clock ticks (16 MHz clock implies 62.5 ns per tick).
+void delay_ticks( unsigned int num_ticks )
+{
+       TACTL |= 0x20; // Start timer
+       while (TAR < num_ticks)
+               asm( "nop" );
+       TACTL = 0x0204; // Reset Timer A, till next time
+}