X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Flib%2Fcommand.c;h=6388c643b366a82b2f1384c2b0e6b1960098d944;hp=415171b732d9bc011f1c559acc8d6b1409d7a2ef;hb=f244df1b2d3010548ed2cceabdde44f36089a29a;hpb=d7ad826230d336ad7b7bd20e47dccc26d7ad456f diff --git a/firmware/lib/command.c b/firmware/lib/command.c index 415171b..6388c64 100644 --- a/firmware/lib/command.c +++ b/firmware/lib/command.c @@ -1,6 +1,6 @@ /*! \file command.c \author Travis Goodspeed - \brief These functions manage command interpretation. + \brief These functions manage command interpretation and timing. */ #include "command.h" @@ -32,24 +32,12 @@ void debugstr(const char *str){ //! brief Debug a hex word string. void debughex(u16 v) { - unsigned char a[7]; - a[0]='0'; a[1]='x'; - - a[2]=0xf&(v>>12); - a[2]+=(a[2]>9)?('a'-10):'0'; - - a[3]=0xf&(v>>8); - a[3]+=(a[3]>9)?('a'-10):'0'; - - a[4]=0xf&(v>>4); - a[4]+=(a[4]>9)?('a'-10):'0'; - - a[5]=0xf&(v>>0); - a[5]+=(a[5]>9)?('a'-10):'0'; - - a[6]=0; + debugbytes((void *)&v, 2); +} - txstring(0xFF,0xFF,a); +//! brief Debug a hex word string. +void debughex32(u32 v) { + debugbytes((void *)&v, 4); } /*! \brief Transmit debug bytes. @@ -78,7 +66,7 @@ void txhead(unsigned char app, void txdata(unsigned char app, unsigned char verb, unsigned long len){ - unsigned int i=0; + unsigned long i=0; if(silent) return; txhead(app,verb,len); @@ -140,3 +128,74 @@ void msdelay(unsigned int ms){ } //Using TimerA might be cleaner. } + + +/* To better satisfy the somewhat odd timing requirements for + PIC33F/24H/24F ICSP programming, and for better control of GoodFET + timing more generally, here are a few delay routines that use Timer B. + + 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() +{ + #ifdef MSP430 + BCSCTL2 = 0x00; /* In particular, use DCOCLK as SMCLK source with + divider 1. Hence, Timer B ticks with system + clock at 16 MHz. */ + + TBCTL = 0x0204; /* Driven by SMCLK; disable Timer B interrupts; + reset timer in case it was previously in use */ + #else + #warning "prep_timer() unimplemented for this platform." + #endif +} +#if (platform != tilaunchpad) +//! Delay for specified number of milliseconds (given 16 MHz clock) +void delay_ms( unsigned int ms ) +{ + #ifdef MSP430 + // 16000 ticks = 1 ms + TBCTL |= 0x20; // Start timer! + while (ms--) { + while (TBR < 16000) + asm( "nop" ); + TBCTL = 0x0224; + } + TBCTL = 0x0204; // Reset Timer B, till next time + #else + debugstr("delay_ms unimplemented"); + #endif +} + +//! Delay for specified number of microseconds (given 16 MHz clock) +void delay_us( unsigned int us ) +{ + #ifdef MSP430 + // 16 ticks = 1 us + TBCTL |= 0x20; // Start timer! + while (us--) { + while (TBR < 16) + asm( "nop" ); + TBCTL = 0x0224; + } + TBCTL = 0x0204; // Reset Timer B, till next time + #else + debugstr("delay_us unimplemented"); + #endif +} + +//! Delay for specified number of clock ticks (16 MHz clock implies 62.5 ns per tick). +void delay_ticks( unsigned int num_ticks ) +{ + #ifdef MSP430 + TBCTL |= 0x20; // Start timer + while (TBR < num_ticks) + asm( "nop" ); + TBCTL = 0x0204; // Reset Timer B, till next time + #else + debugstr("delay_ticks unimplemented"); + #endif +} +#endif