4f36833d10d2d24d23fec4c2ca0a587ff2def804
[goodfet] / firmware / apps / monitor / monitor.c
1 /*! \file monitor.c
2   \author Travis Goodspeed
3   \brief Local debug monitor.
4 */
5
6 #include "command.h"
7 #include "platform.h"
8 #include "monitor.h"
9 #include "builddate.h"
10 #if (platform == tilaunchpad)
11 #include <setjmp.h>
12 extern jmp_buf warmstart;
13
14 #endif
15
16 #define MONITOR_APP
17
18 //! Handles a monitor command.
19 void monitor_handle_fn(uint8_t const app,
20                                            uint8_t const verb,
21                                            uint32_t const len);
22
23 //! Overwrite all of RAM with 0xBEEF, then reboot.
24 void monitor_ram_pattern();
25
26 //! Return the number of contiguous bytes 0xBEEF, to measure RAM usage.
27 unsigned int monitor_ram_depth();
28
29 //! Call a function by address.
30 int fncall(unsigned int adr);
31
32
33 // define the monitor app's app_t
34 app_t const monitor_app = {
35
36         /* app number */
37         MONITOR,
38
39         /* handle fn */
40         monitor_handle_fn,
41
42         /* name */
43         "Monitor",
44
45         /* desc */
46         "\tThe monitor app handles basic operations on the MSP430\n"
47         "\tsuch as peeking and poking memory, calling functions and\n"
48         "\tmanaging the baud rate.\n"
49 };
50
51
52 //! Handles a monitor command.
53 void monitor_handle_fn(uint8_t const app,
54                        uint8_t const verb,
55                        uint32_t const len)
56 {
57         int i;
58
59         switch(verb)
60         {
61         default:
62                 debugstr("ERROR: Command unsupported by debug monitor.");
63                 break;
64
65         case MONITOR_ECHO:
66           //Echo back the same buffer.
67           debugstr("About to monitor echo.");
68           txdata(app,verb,len);
69           break;
70
71         case MONITOR_LIST_APPS:
72                 // transmit firmware build date
73                 txstring(app, verb, build_date);
74
75                 // transmit app descriptions
76                 for(i = 0; i < num_apps; i++)
77                 {
78                         txstring(app, verb, apps[i]->name);
79                         // if full list, then add in description
80                         if(cmddata[0])
81                                 txstring(app, verb, apps[i]->desc);
82                 }
83                 txdata(app, verb, 0);
84                 break;
85
86         case PEEK:
87           #ifdef MSP430
88                 cmddata[0]=memorybyte[cmddataword[0]];
89           #else
90                 debugstr("Monitor peeks are unsupported on this platform.");
91                 debughex(cmddataword[0]);
92                 cmddata[0]=0x00;
93           #endif
94                 txdata(app,verb,1);
95                 break;
96
97         case POKE:
98           #ifdef MSP430
99                 //Todo, make word or byte.
100                 memorybyte[cmddataword[0]] = cmddata[2];
101                 cmddata[0] = memorybyte[cmddataword[0]];
102           #else
103                 debugstr("Monitor pokes are unsupported on this platform.");
104                 debughex(cmddataword[0]);
105                 cmddata[0]=0x00;
106           #endif
107                 txdata(app,verb,1);
108                 break;
109
110         case CALL:
111                 //Set the program counter to cmdword[0];
112                 cmddataword[0]=fncall(cmddataword[0]);
113                 txdata(app,verb,2);
114                 break;
115
116         case EXEC:
117                 //Execute the argument as code from RAM.
118                 cmddataword[0]=fncall((u16) cmddataword);
119                 txdata(app,verb,2);
120                 break;
121
122         case MONITOR_SIZEBUF:
123                 //TODO make the data length target-specific, varying by ram.
124                 cmddataword[0]=0x100;
125                 txdata(app,verb,2);
126                 break;
127
128         case MONITOR_CHANGE_BAUD:
129                 //This command, and ONLY this command, does not reply.
130                 setbaud(cmddata[0]);
131                 //txdata(app,verb,0);
132                 break;
133
134         case MONITOR_RAM_PATTERN:
135                 monitor_ram_pattern();//reboots, will never return
136                 break;
137
138         case MONITOR_RAM_DEPTH:
139                 cmddataword[0]=monitor_ram_depth();
140                 txdata(app,verb,2);
141                 break;
142
143         case MONITOR_DIR:
144         case MONITOR_IN:
145         case MONITOR_OUT:
146           debugstr("Command deprecated.");
147           txdata(app,verb,1);
148           break;
149                 
150         case MONITOR_SILENT:
151                 silent=cmddata[0];
152                 txdata(app,verb,1);
153                 break;
154
155         case MONITOR_CONNECTED:
156           #ifdef MSP430
157           msp430_init_dco_done();
158           #endif
159           txdata(app,verb,0);
160           break;
161         }
162 }
163
164 //! Overwrite all of RAM with 0xBEEF, then reboot.
165 void monitor_ram_pattern()
166 {
167         register int *a;
168
169         //Wipe all of ram.
170         for(a=(int*)0x1100;a<(int*)0x2500;a++)
171         {//TODO get these from the linker.
172                 *((int*)a) = 0xBEEF;
173         }
174         txdata(0x00,0x90,0);
175
176 #if (platform == tilaunchpad)
177         longjmp(warmstart,1);
178 #else
179         //Reboot
180 #ifdef MSP430
181         asm("br &0xfffe");
182 #endif
183 #endif
184 }
185
186 //! Return the number of contiguous bytes 0xBEEF, to measure RAM usage.
187 unsigned int monitor_ram_depth()
188 {
189         register int a;
190         register int count=0;
191         for(a=0x1100;a<0x2500;a+=2)
192                 if(*((int*)a)==0xBEEF) count+=2;
193
194         return count;
195 }
196
197 //! Call a function by address.
198 int fncall(unsigned int adr)
199 {
200         int (*machfn)() = 0;
201         machfn = (int (*)()) adr;
202         return machfn();
203 }
204
205