]>
Commit | Line | Data |
---|---|---|
35edb766 | 1 | /* |
2d914b45 | 2 | * (C) Copyright 2014,2016 Leo C. <erbl259-lmu@yahoo.de> |
35edb766 | 3 | * |
8ed66016 | 4 | * SPDX-License-Identifier: GPL-2.0 |
35edb766 L |
5 | */ |
6 | ||
8ed66016 | 7 | #include "debug.h" |
92b46605 | 8 | #include "common.h" |
2d914b45 | 9 | #include <stdlib.h> /* __malloc_margin */ |
f338df2a | 10 | #include <string.h> |
92b46605 L |
11 | #include <ctype.h> |
12 | #include <avr/eeprom.h> | |
13 | ||
14 | #include "command.h" | |
ad9bc17c | 15 | #include "cli_readline.h" |
2d914b45 | 16 | #include "eval_arg.h" |
e39cd2a2 | 17 | #include "print-utils.h" |
35edb766 | 18 | |
92b46605 L |
19 | /* |
20 | * Debugging | |
21 | */ | |
e39cd2a2 | 22 | |
92b46605 L |
23 | #ifdef DEBUG |
24 | ||
92b46605 | 25 | |
f338df2a | 26 | #if 0 |
92b46605 L |
27 | void dump_heap(void) |
28 | { | |
29 | extern unsigned int __brkval; | |
30 | ||
e39cd2a2 | 31 | dump_ram(__malloc_heap_start, |
92b46605 L |
32 | __brkval - (unsigned int) __malloc_heap_start, |
33 | "=== Heap:"); | |
34 | } | |
f338df2a | 35 | #endif |
92b46605 | 36 | |
92b46605 L |
37 | |
38 | /* | |
61b0cfe9 | 39 | * Memory Display |
92b46605 L |
40 | * md addr {len} |
41 | */ | |
d0581f88 | 42 | command_ret_t do_dump_mem(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
92b46605 | 43 | { |
d9d8de47 | 44 | int (*readwhat)(uint8_t *buf, uint32_t addr, uint8_t count); |
507d25e2 | 45 | |
f338df2a | 46 | (void) cmdtp; (void) flag; |
92b46605 L |
47 | |
48 | if (argc < 2) | |
49 | return CMD_RET_USAGE; | |
50 | ||
e39cd2a2 L |
51 | uint32_t addr; |
52 | uint32_t length = 128; | |
507d25e2 | 53 | |
c748023e L |
54 | switch (argv[0][3]) { |
55 | case 'r': | |
ad9bc17c | 56 | readwhat = ram_read_buf; |
c748023e L |
57 | break; |
58 | case 'e': | |
ad9bc17c | 59 | readwhat = eeprom_read_buf; |
c748023e L |
60 | break; |
61 | case 'f': | |
ad9bc17c | 62 | readwhat = flash_read_buf; |
c748023e L |
63 | break; |
64 | default: | |
f338df2a | 65 | return CMD_RET_USAGE; |
c748023e | 66 | } |
92b46605 | 67 | |
f338df2a | 68 | /* Address is specified since argc > 1 */ |
2d914b45 | 69 | addr = eval_arg(argv[1], NULL); |
f338df2a L |
70 | |
71 | /* If another parameter, it is the length to display. */ | |
72 | if (argc > 2) | |
2d914b45 | 73 | length = (uint16_t) eval_arg(argv[2], NULL); |
92b46605 L |
74 | |
75 | /* Print the lines. */ | |
ad9bc17c | 76 | dump_mem(addr, addr, length, readwhat, NULL); |
92b46605 | 77 | |
d0581f88 | 78 | return CMD_RET_SUCCESS; |
92b46605 L |
79 | } |
80 | ||
d0581f88 | 81 | command_ret_t do_eep_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
92b46605 L |
82 | { |
83 | uint16_t src, dest, count; | |
84 | int_fast8_t step; | |
85 | ||
86 | (void) cmdtp; | |
87 | (void) flag; | |
88 | ||
89 | if (argc != 4) | |
90 | return CMD_RET_USAGE; | |
91 | ||
2d914b45 L |
92 | src = (size_t) eval_arg(argv[1], NULL); |
93 | dest = (size_t) eval_arg(argv[2], NULL); | |
94 | count = (size_t) eval_arg(argv[3], NULL); | |
92b46605 L |
95 | |
96 | if (src > E2END) { | |
97 | debug("src > EEPROM size: 0x%04x\n", src); | |
d0581f88 | 98 | return CMD_RET_FAILURE; |
92b46605 L |
99 | } |
100 | if (dest > E2END) { | |
101 | debug("dest > EEPROM size: 0x%04x\n", dest); | |
d0581f88 | 102 | return CMD_RET_FAILURE; |
92b46605 L |
103 | } |
104 | if (count > E2END+1) { | |
105 | debug("count > EEPROM size: 0x%04x\n", count); | |
d0581f88 | 106 | return CMD_RET_FAILURE; |
92b46605 L |
107 | } |
108 | if (count == 0) { | |
69988dc1 | 109 | debug("Zero length?\n"); |
d0581f88 | 110 | return CMD_RET_FAILURE; |
92b46605 L |
111 | } |
112 | ||
113 | if (dest > src) { | |
114 | src += count - 1; | |
115 | dest += count - 1; | |
116 | step = -1; | |
117 | } else | |
118 | step = 1; | |
119 | ||
120 | while (count-- > 0) { | |
121 | uint8_t data; | |
122 | data = eeprom_read_byte((uint8_t *) src); | |
123 | eeprom_write_byte((uint8_t *) dest, data); | |
124 | src += step; | |
125 | dest += step; | |
126 | ||
127 | } | |
d0581f88 | 128 | return CMD_RET_SUCCESS; |
92b46605 | 129 | } |
69988dc1 | 130 | |
4565be9a | 131 | |
ad9bc17c L |
132 | /* Modify memory. |
133 | * | |
134 | * Syntax: | |
135 | * !mm {addr} | |
136 | * !nm {addr} | |
137 | */ | |
138 | ||
139 | static uint8_t *mm_last_addr; | |
140 | ||
141 | static command_ret_t | |
142 | mod_mem_avr(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) | |
143 | { | |
144 | uint8_t *addr; | |
145 | uint8_t data; | |
146 | int nbytes; | |
147 | ||
148 | (void) cmdtp; | |
149 | ||
150 | if (argc != 2) | |
151 | return CMD_RET_USAGE; | |
152 | ||
153 | /* We use the last specified parameters, unless new ones are | |
154 | * entered. | |
155 | */ | |
156 | addr = mm_last_addr; | |
157 | ||
158 | if ((flag & CMD_FLAG_REPEAT) == 0) { | |
159 | /* New command specified. | |
160 | */ | |
161 | ||
162 | /* Address is specified since argc > 1 | |
163 | */ | |
2d914b45 | 164 | addr = (uint8_t *) (size_t) eval_arg(argv[1], NULL); |
ad9bc17c L |
165 | } |
166 | ||
167 | /* Print the address, followed by value. Then accept input for | |
168 | * the next value. A non-converted value exits. | |
169 | */ | |
170 | do { | |
171 | data = *addr; | |
172 | printf_P(PSTR("%04x: %02x"), addr, data); | |
173 | ||
8ed66016 | 174 | nbytes = cli_readline(PSTR(" ? "), 0); |
ad9bc17c L |
175 | if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) { |
176 | /* <CR> pressed as only input, don't modify current | |
177 | * location and move to next. "-" pressed will go back. | |
178 | */ | |
179 | if (incrflag) | |
180 | addr += nbytes ? -1 : 1; | |
181 | nbytes = 1; | |
182 | ||
183 | } else { | |
184 | char *endp; | |
2d914b45 | 185 | data = eval_arg(console_buffer, &endp); |
ad9bc17c L |
186 | nbytes = endp - console_buffer; |
187 | if (nbytes) { | |
188 | *addr = data; | |
189 | if (incrflag) | |
190 | addr++; | |
191 | } | |
192 | } | |
13e88ed5 | 193 | } while (nbytes > 0); |
ad9bc17c L |
194 | |
195 | mm_last_addr = addr; | |
196 | return CMD_RET_SUCCESS; | |
197 | } | |
198 | ||
199 | ||
200 | command_ret_t do_mem_mm_avr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
201 | { | |
202 | return mod_mem_avr (cmdtp, 1, flag, argc, argv); | |
203 | } | |
204 | command_ret_t do_mem_nm_avr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
205 | { | |
206 | return mod_mem_avr (cmdtp, 0, flag, argc, argv); | |
207 | } | |
208 | ||
4565be9a L |
209 | /*------------------------------------------------------------------------------*/ |
210 | ||
507d25e2 | 211 | #if 1 |
dea9a315 | 212 | |
69988dc1 L |
213 | struct __freelist { |
214 | size_t sz; | |
215 | struct __freelist *nx; | |
216 | }; | |
217 | ||
218 | extern char *__brkval; /* first location not yet allocated */ | |
219 | extern struct __freelist *__flp; /* freelist pointer (head of freelist) */ | |
220 | ||
221 | #define STACK_POINTER() ((char *)AVR_STACK_POINTER_REG) | |
222 | ||
223 | void | |
224 | printfreelist(const char * title) | |
225 | { | |
226 | struct __freelist *fp1; | |
227 | int i; | |
228 | unsigned int freesum = 0; | |
229 | ||
507d25e2 L |
230 | /* TODO: printf_P */ |
231 | ||
69988dc1 L |
232 | if (!__flp) { |
233 | printf("%s no free list\n", title ? title : ""); | |
234 | } else { | |
235 | printf("Free list: %s\n", title ? title : ""); | |
236 | for (i = 0, fp1 = __flp; fp1; i++, fp1 = fp1->nx) { | |
237 | printf(" entry %d @ %04x: size %4u, next ", | |
238 | i, (size_t)fp1, fp1->sz); | |
239 | if (fp1->nx) | |
240 | printf("%04x\n", (size_t)fp1->nx); | |
241 | else | |
242 | printf("NULL\n"); | |
243 | freesum += fp1->sz; | |
244 | } | |
245 | } | |
507d25e2 | 246 | |
69988dc1 L |
247 | freesum += (size_t) STACK_POINTER() - __malloc_margin - (size_t) __brkval; |
248 | ||
249 | printf("SP: %04x, __brkval: %04x, Total free: %04u\n", | |
250 | (size_t) STACK_POINTER(), (size_t) __brkval, freesum); | |
251 | } | |
252 | ||
dea9a315 | 253 | #endif |
69988dc1 | 254 | |
92b46605 | 255 | #endif /* DEBUG */ |