X-Git-Url: http://git.rot13.org//?a=blobdiff_plain;f=firmware%2Flib%2Fcommand.c;h=1de6f0a682ec0587304165bb0a517d1a6c7972a3;hb=dbcedaa279472080a2585e959a3146f3c5859556;hp=415171b732d9bc011f1c559acc8d6b1409d7a2ef;hpb=3924e6c10611bfeb4c3970a91bbe66c5ba7de6f2;p=goodfet diff --git a/firmware/lib/command.c b/firmware/lib/command.c index 415171b..1de6f0a 100644 --- a/firmware/lib/command.c +++ b/firmware/lib/command.c @@ -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 +}