Semi-decennial update. 50% code inflation.
[cbaos.git] / cbashell / command.c
blob80490de374b30a92b0d5a0aba839ad891db80c8c
1 /* Author: Domen Puncer <domen@cba.si>. License: WTFPL, see file LICENSE */
2 #include <ctype.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include "command.h"
7 #include "types.h"
8 #ifdef ARCH_ARM_CORTEX_M3
9 #include <arch/cm3_regs.h>
10 #endif
13 // for spi
14 #include <drivers/spi.h>
15 #include <drivers/spi_tmp124.h>
17 #ifdef BOARD_LPCXPRESSO
18 #include <mach/lpc13xx_gpio.h>
19 #include <mach/board_lpcxpresso.h>
20 #define GPIO_CS0 GPIO_2_10
21 #define COMMAND_SPI
22 #endif
25 #ifdef COMMAND_SPI
26 static int command_spi(const char *_cmd)
28 char *cmd = (char*)_cmd; /* we don't change it, but strtol is idiotic */
29 static struct spi_device dev = {
30 .mode = 0,
31 .cs_pin = GPIO_CS0,
32 .clock = 10*1000*1000, /* 10 MHz max */
34 static u8 buf[128];
36 if (strncmp(cmd, "spi ", 4) != 0)
37 return 0;
39 cmd += 4;
41 if (strncmp(cmd, "init", 4) == 0) {
42 // TODO hardcoded - how to configure gpio easily? same problem will be with command_gpio
43 spi_register_device(&spi0, &dev);
46 if (strncmp(cmd, "data ", 5) == 0) {
47 struct spi_transfer transfer;
48 int len;
49 int idx = 0;
51 cmd += 5;
52 transfer.tx_buf = buf;
53 transfer.rx_buf = buf;
54 len = strtoul(cmd, &cmd, 0);
55 transfer.len = len;
57 while (cmd && idx < len) {
58 u8 data = strtoul(cmd, &cmd, 0);
59 buf[idx++] = data;
61 /* pad the rest with 0xff */
62 while (idx < len)
63 buf[idx++] = 0xff;
65 spi_transfer(&dev, &transfer);
67 printf("spi data:");
68 for (idx = 0; idx < len; idx++)
69 printf(" %02x", buf[idx]);
70 printf("\n");
73 return 1;
75 #endif
77 static int command_x(const char *_cmd)
79 static int len = 1;
80 static int size = 4;
81 static u32 addr;
82 char *cmd = (char*)_cmd; /* we don't change it, but strtol is idiotic */
84 if (cmd[0] != 'x' || isalpha(cmd[1]))
85 return 0;
87 cmd++;
88 if (*cmd == '/') {
89 cmd++;
90 if (isdigit(*cmd)) {
91 len = strtoul(cmd, &cmd, 0);
92 /* just some sanity */
93 if (len > 1024)
94 len = 1024;
96 // while, check for xs...
97 if (isalpha(*cmd)) {
98 if (*cmd == 'b')
99 size = 1;
100 else if (*cmd == 'h')
101 size = 2;
102 else if (*cmd == 'w')
103 size = 4;
104 else {
105 printf("E: invalid argument for size\n");
106 return -1;
108 cmd++;
111 if (*cmd == ' ') {
112 cmd++;
113 if (isdigit(*cmd))
114 addr = strtoul(cmd, NULL, 0);
117 /* currently it only works for hex, with size 4 */
118 int i;
119 printf("%#010x: ", addr);
120 for (i=0; i<len; i++) {
121 if (i % 8 == 0 && i) {
122 printf("\n%#010x: ", addr);
124 printf("%#010x ", *(u32*)addr);
125 addr += size;
127 printf("\n");
129 return 1;
132 static int command_boot(const char *cmd)
134 if (strcmp(cmd, "boot") != 0)
135 return 0;
137 #ifdef ARCH_ARM_CORTEX_M3
138 AIRCR = (AIRCR & 0x8700) | 0x05FA<<16 /* magic */ | 1<<2 /* SYSRESETREQ */;
139 #endif
141 while (1)
145 static int command_fail(const char *cmd)
147 volatile u32 *tmp = (volatile u32*)0x12345678;
148 void (*f)() = (void (*)())0x23456789;
150 if (strncmp(cmd, "fail ", 5) != 0)
151 return 0;
153 switch (cmd[5]) {
154 case '0':
155 /* invalid pointer deference */
156 *tmp = 0xcba;
157 break;
158 case '1':
159 /* invalid pointer deference */
160 f();
161 break;
162 case 's':
163 /* invalid stack pointer */
164 #ifdef ARCH_ARM_CORTEX_M3
165 asm volatile ("ldr sp, =#0x87654321\n\t");
166 #endif
167 break;
168 case 'u':
169 /* undefined instruction */
170 #ifdef ARCH_ARM_CORTEX_M3
171 *(u32*)0xe000ed24 |= 1<<18; /* enable usage fault */
172 /* http://www.keil.com/support/man/docs/armasm/armasm_cihjijca.htm */
173 asm volatile (".short 0xdead\n\t"); /* arm arm says, 0xdexx for thumb */
174 /* some other document said 1101 011... 1 xxxx for arm mode */
175 #endif
176 break;
177 case '2':
178 /* svc */
179 #ifdef ARCH_ARM_CORTEX_M3
180 asm volatile ("svc #0\n");
181 #endif
182 break;
183 default:
184 if (cmd[5])
185 printf("%s: unknown argument %c\n", __func__, cmd[5]);
186 printf("fail arguments: \n"
187 "\t0 - write to invalid pointer\n"
188 "\t1 - call invalid function\n"
189 "\ts - corrupt stack pointer\n"
190 "\tu - undefined instruction\n"
193 return 1;
196 static int command_test(const char *cmd)
198 if (strncmp(cmd, "test ", 5) != 0)
199 return 0;
200 char foo[16];
201 strncpy(foo, cmd+5, 16);
202 foo[15] = 0;
203 //eprom_test(foo);
205 printf("%s: %02x %02x %02x %02x\n", __func__, foo[0], foo[1], foo[2], foo[3]);
206 return 1;
209 static int command_help(const char *cmd)
211 if (strcmp(cmd, "help") != 0)
212 return 0;
213 printf("something helpful should be written here\n");
214 return 1;
216 static int command_invalid(const char *cmd)
218 if (*cmd)
219 printf("invalid command\n");
220 return 1;
223 /* 1 for handled, 0 for not handled, negative for error (should abort handling) */
224 int (* const command_list[])(const char *cmd) = {
225 command_x,
226 command_boot,
227 command_fail,
228 #ifdef COMMAND_SPI
229 command_spi,
230 #endif
231 command_test,
232 command_help,
233 command_invalid,
234 NULL