X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Flib%2Fcommand.c;h=8b83d475491e405be88ca74a54536be7d4d85a15;hp=9a9421ddfcb2c3277af36d0f1a295afd36ac4853;hb=ea94279f763800d71e86d9bb25d140bf78dfb4ea;hpb=a653ba1562dc444e4be791e22264a89a3c6b4a19 diff --git a/firmware/lib/command.c b/firmware/lib/command.c index 9a9421d..8b83d47 100644 --- a/firmware/lib/command.c +++ b/firmware/lib/command.c @@ -1,23 +1,184 @@ -//! Different command handling functions. +/*! \file command.c + \author Travis Goodspeed + \brief These functions manage command interpretation and timing. +*/ -unsigned char cmddata[256]; +#include "command.h" +#include "platform.h" +#include + +unsigned char cmddata[CMDDATALEN]; +unsigned char silent=0; + +//! Transmit a string. +void txstring(unsigned char app, + unsigned char verb, + const char *str){ + unsigned long len=strlen(str); + txhead(app,verb,len); + while(len--) + serial_tx(*(str++)); +} + +/*! \brief Transmit a debug string. + + Transmits a debugging string that is to be printed + out of line by the client. This is just for record-keeping; + it is not considered a proper reply to a query. + */ +void debugstr(const char *str){ + txstring(0xFF,0xFF,str); +} + +//! brief Debug a hex word string. +void debughex(u16 v) { + debugbytes((void *)&v, 2); +} + +//! brief Debug a hex word string. +void debughex32(u32 v) { + debugbytes((void *)&v, 4); +} + +/*! \brief Transmit debug bytes. + + Transmits bytes for debugging. +*/ +void debugbytes(const char *bytes, unsigned int len){ + u16 i; + txhead(0xFF,0xFE,len); + for(i=0;i>=8; + serial_tx(l&0xFF); + l>>=8; + serial_tx(l&0xFF); + l>>=8; + serial_tx(l&0xFF); + l>>=8; +} +//! Transmit a word. +void txword(unsigned int l){ + serial_tx(l&0xFF); + l>>=8; + serial_tx(l&0xFF); + l>>=8; +} + +//Be very careful changing delay(). +//It was chosen poorly by trial and error. //! Delay for a count. void delay(unsigned int count){ volatile unsigned int i=count; while(i--) asm("nop"); } +//! MSDelay +void msdelay(unsigned int ms){ + volatile unsigned int i,j; + i=100; + while(i--){ + j=ms; + while(j--) asm("nop"); + } + //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() +{ + 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 */ +} + +//! Delay for specified number of milliseconds (given 16 MHz clock) +void delay_ms( unsigned int ms ) +{ + // 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 +} + +//! Delay for specified number of microseconds (given 16 MHz clock) +void delay_us( unsigned int us ) +{ + // 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 +} + +//! Delay for specified number of clock ticks (16 MHz clock implies 62.5 ns per tick). +void delay_ticks( unsigned int num_ticks ) +{ + TBCTL |= 0x20; // Start timer + while (TBR < num_ticks) + asm( "nop" ); + TBCTL = 0x0204; // Reset Timer B, till next time +}