changes to the GUI to allow for better loading and writing as well as tested our...
[goodfet] / firmware / lib / command.c
1 /*! \file command.c
2   \author Travis Goodspeed
3   \brief These functions manage command interpretation and timing.
4 */
5
6 #include "command.h"
7 #include "platform.h"
8 #include <string.h>
9
10 unsigned char cmddata[CMDDATALEN];
11 unsigned char silent=0;
12
13 //! Transmit a string.
14 void txstring(unsigned char app,
15               unsigned char verb,
16               const char *str){
17   unsigned long len=strlen(str);
18   txhead(app,verb,len);
19   while(len--)
20     serial_tx(*(str++));
21 }
22
23 /*! \brief Transmit a debug string.
24   
25   Transmits a debugging string that is to be printed
26   out of line by the client.  This is just for record-keeping;
27   it is not considered a proper reply to a query.
28  */
29 void debugstr(const char *str){
30   txstring(0xFF,0xFF,str);
31 }
32
33 //! brief Debug a hex word string.
34 void debughex(u16 v) {
35   debugbytes((void *)&v, 2);
36 }
37
38 //! brief Debug a hex word string.
39 void debughex32(u32 v) {
40   debugbytes((void *)&v, 4);
41 }
42
43 /*! \brief Transmit debug bytes.
44   
45   Transmits bytes for debugging.
46 */
47 void debugbytes(const char *bytes, unsigned int len){
48   u16 i;
49   txhead(0xFF,0xFE,len);
50   for(i=0;i<len;i++)
51     serial_tx(bytes[i]);
52 }
53
54
55 //! Transmit a header.
56 void txhead(unsigned char app,
57             unsigned char verb,
58             unsigned long len){
59   serial_tx(app);
60   serial_tx(verb);
61   //serial_tx(len); //old protocol
62   txword(len);
63 }
64
65 //! Transmit data.
66 void txdata(unsigned char app,
67             unsigned char verb,
68             unsigned long len){
69   unsigned long i=0;
70   if(silent)
71     return;
72   txhead(app,verb,len);
73   for(i=0;i<len;i++){
74     serial_tx(cmddata[i]);
75   }
76 }
77
78 //! Receive a long.
79 unsigned long rxlong(){
80   unsigned long toret=0;
81   toret=serial_rx();
82   toret|=(((long)serial_rx())<<8);
83   toret|=(((long)serial_rx())<<16);
84   toret|=(((long)serial_rx())<<24);
85   return toret;
86 }
87 //! Receive a word.
88 unsigned int rxword(){
89   unsigned long toret=0;
90   toret=serial_rx();
91   toret|=(((long)serial_rx())<<8);
92   return toret;
93 }
94 //! Transmit a long.
95 void txlong(unsigned long l){
96   serial_tx(l&0xFF);
97   l>>=8;
98   serial_tx(l&0xFF);
99   l>>=8;
100   serial_tx(l&0xFF);
101   l>>=8;
102   serial_tx(l&0xFF);
103   l>>=8;
104 }
105 //! Transmit a word.
106 void txword(unsigned int l){
107   serial_tx(l&0xFF);
108   l>>=8;
109   serial_tx(l&0xFF);
110   l>>=8;
111 }
112
113 //Be very careful changing delay().
114 //It was chosen poorly by trial and error.
115
116 //! Delay for a count.
117 void delay(unsigned int count){
118   volatile unsigned int i=count;
119   while(i--) asm("nop");
120 }
121 //! MSDelay
122 void msdelay(unsigned int ms){
123   volatile unsigned int i,j;
124   i=100;
125   while(i--){
126     j=ms;
127     while(j--) asm("nop");
128   }
129   //Using TimerA might be cleaner.
130 }
131
132
133 /* To better satisfy the somewhat odd timing requirements for
134    PIC33F/24H/24F ICSP programming, and for better control of GoodFET
135    timing more generally, here are a few delay routines that use Timer B.
136
137    Note that I wrote these referring only to the MSP430x2xx family
138    manual. Beware on MSP430x1xx chips. Further note that, assuming
139    some minor errors will be made, I try to err on the side of
140    delaying slightly longer than requested. */
141 void prep_timer()
142 {
143   #ifdef MSP430
144   BCSCTL2 = 0x00; /* In particular, use DCOCLK as SMCLK source with
145                      divider 1. Hence, Timer B ticks with system
146                      clock at 16 MHz. */
147
148   TBCTL = 0x0204; /* Driven by SMCLK; disable Timer B interrupts;
149                      reset timer in case it was previously in use */
150   #else
151   #warning "prep_timer() unimplemented for this platform."
152   #endif
153 }
154 #if (platform != tilaunchpad)
155 //! Delay for specified number of milliseconds (given 16 MHz clock)
156 void delay_ms( unsigned int ms )
157 {
158   #ifdef MSP430
159   // 16000 ticks = 1 ms
160   TBCTL |= 0x20; // Start timer!
161   while (ms--) {
162     while (TBR < 16000)
163       asm( "nop" );
164     TBCTL = 0x0224;
165   }
166   TBCTL = 0x0204; // Reset Timer B, till next time
167   #else
168   debugstr("delay_ms unimplemented");
169   #endif
170 }
171
172 //! Delay for specified number of microseconds (given 16 MHz clock)
173 void delay_us( unsigned int us )
174 {
175   #ifdef MSP430
176   // 16 ticks = 1 us
177   TBCTL |= 0x20; // Start timer!
178   while (us--) {
179     while (TBR < 16)
180       asm( "nop" );
181     TBCTL = 0x0224;
182   }
183   TBCTL = 0x0204; // Reset Timer B, till next time
184   #else
185   debugstr("delay_us unimplemented");
186   #endif
187 }
188
189 //! Delay for specified number of clock ticks (16 MHz clock implies 62.5 ns per tick).
190 void delay_ticks( unsigned int num_ticks )
191 {
192   #ifdef MSP430
193   TBCTL |= 0x20; // Start timer
194   while (TBR < num_ticks)
195     asm( "nop" );
196   TBCTL = 0x0204; // Reset Timer B, till next time
197   #else
198   debugstr("delay_ticks unimplemented");
199   #endif
200 }
201 #endif