TI Launchpad patch from Peter Lorenzen, edited to ease the mergequake.
[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                 txdata(app,verb,len);
68                 break;
69
70         case MONITOR_LIST_APPS:
71                 // transmit firmware build date
72                 txstring(app, verb, build_date);
73
74                 // transmit app descriptions
75                 for(i = 0; i < num_apps; i++)
76                 {
77                         txstring(app, verb, apps[i]->name);
78                         // if full list, then add in description
79                         if(cmddata[0])
80                                 txstring(app, verb, apps[i]->desc);
81                 }
82                 txdata(app, verb, 0);
83                 break;
84
85         case PEEK:
86           #ifdef MSP430
87                 cmddata[0]=memorybyte[cmddataword[0]];
88           #else
89                 debugstr("Monitor peeks are unsupported on this platform.");
90           #endif
91                 txdata(app,verb,1);
92                 break;
93
94         case POKE:
95           #ifdef MSP430
96                 //Todo, make word or byte.
97                 memorybyte[cmddataword[0]] = cmddata[2];
98                 cmddata[0] = memorybyte[cmddataword[0]];
99           #else
100                 debugstr("Monitor pokes are unsupported on this platform.");
101           #endif
102                 txdata(app,verb,1);
103                 break;
104
105         case CALL:
106                 //Set the program counter to cmdword[0];
107                 cmddataword[0]=fncall(cmddataword[0]);
108                 txdata(app,verb,2);
109                 break;
110
111         case EXEC:
112                 //Execute the argument as code from RAM.
113                 cmddataword[0]=fncall((u16) cmddataword);
114                 txdata(app,verb,2);
115                 break;
116
117         case MONITOR_SIZEBUF:
118                 //TODO make the data length target-specific, varying by ram.
119                 cmddataword[0]=0x100;
120                 txdata(app,verb,2);
121                 break;
122
123         case MONITOR_CHANGE_BAUD:
124                 //This command, and ONLY this command, does not reply.
125                 setbaud(cmddata[0]);
126                 //txdata(app,verb,0);
127                 break;
128
129         case MONITOR_RAM_PATTERN:
130                 monitor_ram_pattern();//reboots, will never return
131                 break;
132
133         case MONITOR_RAM_DEPTH:
134                 cmddataword[0]=monitor_ram_depth();
135                 txdata(app,verb,2);
136                 break;
137
138         case MONITOR_DIR:
139           //P5DIR=cmddata[0];
140           debugstr("Command deprecated.");
141           txdata(app,verb,1);
142           break;
143
144         case MONITOR_IN:
145           //cmddata[0]=P5IN;
146           debugstr("Command deprecated.");
147           txdata(app,verb,1);
148           break;
149
150         case MONITOR_OUT:
151           //P5OUT=cmddata[0];
152           debugstr("Command deprecated.");
153           txdata(app,verb,1);
154           break;
155                 
156         case MONITOR_SILENT:
157                 silent=cmddata[0];
158                 txdata(app,verb,1);
159                 break;
160
161         case MONITOR_CONNECTED:
162           #ifdef MSP430
163           msp430_init_dco_done();
164           #endif
165           txdata(app,verb,0);
166           break;
167         }
168 }
169
170 //! Overwrite all of RAM with 0xBEEF, then reboot.
171 void monitor_ram_pattern()
172 {
173         register int *a;
174
175         //Wipe all of ram.
176         for(a=(int*)0x1100;a<(int*)0x2500;a++)
177         {//TODO get these from the linker.
178                 *((int*)a) = 0xBEEF;
179         }
180         txdata(0x00,0x90,0);
181
182 #if (platform == tilaunchpad)
183         longjmp(warmstart,1);
184 #else
185         //Reboot
186 #ifdef MSP430
187         asm("br &0xfffe");
188 #endif
189 #endif
190 }
191
192 //! Return the number of contiguous bytes 0xBEEF, to measure RAM usage.
193 unsigned int monitor_ram_depth()
194 {
195         register int a;
196         register int count=0;
197         for(a=0x1100;a<0x2500;a+=2)
198                 if(*((int*)a)==0xBEEF) count+=2;
199
200         return count;
201 }
202
203 //! Call a function by address.
204 int fncall(unsigned int adr)
205 {
206         int (*machfn)() = 0;
207         machfn = (int (*)()) adr;
208         return machfn();
209 }
210
211