Repaired MSP430 and MSP430X support.
[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                 txdata(app,verb,1);
128                 break;
129
130         case MONITOR_IN:
131                 cmddata[0]=P5IN;
132                 txdata(app,verb,1);
133                 break;
134
135         case MONITOR_OUT:
136                 P5OUT=cmddata[0];
137                 txdata(app,verb,1);
138                 break;
139                 
140         case MONITOR_SILENT:
141                 silent=cmddata[0];
142                 txdata(app,verb,1);
143                 break;
144
145         case MONITOR_CONNECTED:
146                 msp430_init_dco_done();
147                 txdata(app,verb,0);
148                 break;
149         }
150 }
151
152 //! Overwrite all of RAM with 0xBEEF, then reboot.
153 void monitor_ram_pattern()
154 {
155         register int *a;
156
157         //Wipe all of ram.
158         for(a=(int*)0x1100;a<(int*)0x2500;a++)
159         {//TODO get these from the linker.
160                 *((int*)a) = 0xBEEF;
161         }
162         txdata(0x00,0x90,0);
163
164         //Reboot
165 #ifdef MSP430
166         asm("br &0xfffe");
167 #endif
168 }
169
170 //! Return the number of contiguous bytes 0xBEEF, to measure RAM usage.
171 unsigned int monitor_ram_depth()
172 {
173         register int a;
174         register int count=0;
175         for(a=0x1100;a<0x2500;a+=2)
176                 if(*((int*)a)==0xBEEF) count+=2;
177
178         return count;
179 }
180
181 //! Call a function by address.
182 int fncall(unsigned int adr)
183 {
184         int (*machfn)() = 0;
185         machfn = (int (*)()) adr;
186         return machfn();
187 }
188
189