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