2 * Copyright © 2013 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 #include "ao-selfload.h"
27 #include "ao-verbose.h"
29 #define TRACE(...) ao_printf(AO_VERBOSE_SELF, __VA_ARGS__)
32 ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256])
36 cc_usb_printf(cc, "R %x\n", address);
37 for (byte = 0; byte < 0x100; byte++) {
38 block[byte] = cc_usb_getchar(cc);
40 TRACE ("\nread %08x\n", address);
41 for (byte = 0; byte < 0x100; byte++) {
42 TRACE (" %02x", block[byte]);
43 if ((byte & 0xf) == 0xf)
49 ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256])
53 cc_usb_printf(cc, "W %x\n", address);
54 TRACE ("write %08x\n", address);
55 for (byte = 0; byte < 0x100; byte++) {
56 TRACE (" %02x", block[byte]);
57 if ((byte & 0xf) == 0xf)
60 for (byte = 0; byte < 0x100; byte++) {
61 cc_usb_printf(cc, "%c", block[byte]);
66 ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length)
68 struct ao_hex_image *image;
71 uint32_t base = address & ~0xff;
72 uint32_t bound = (address + length + 0xff) & ~0xff;
74 image = calloc(sizeof (struct ao_hex_image) + (bound - base), 1);
75 image->address = base;
76 image->length = bound - base;
77 pages = image->length / 0x100;
78 for (page = 0; page < pages; page++)
79 ao_self_block_read(cc, image->address + page * 0x100, image->data + page * 0x100);
84 ao_self_write(struct cc_usb *cc, struct ao_hex_image *image)
88 uint32_t base, bound, length, address;
92 base = image->address & ~0xff;
93 bound = (image->address + image->length + 0xff) & ~0xff;
96 length = bound - base;
98 pages = length / 0x100;
99 printf ("Write %08x %d pages: ", address, length/0x100); fflush(stdout);
100 for (page = 0; page < pages; page++) {
101 uint32_t start, stop;
102 address = base + page * 0x100;
104 if (address < image->address || address + 0x100 > image->address + image->length) {
105 ao_self_block_read(cc, address, block);
108 stop = address + 0x100;
109 if (start < image->address)
110 start = image->address;
111 if (stop > image->address + image->length)
112 stop = image->address + image->length;
113 memset(block, 0xff, 0x100);
114 memcpy(block + start - address, image->data + start - image->address, stop - start);
115 ao_self_block_write(cc, address, block);
116 ao_self_block_read(cc, address, check);
117 if (memcmp(block, check, 0x100) != 0) {
118 fprintf(stderr, "Block at 0x%08x doesn't match\n", address);
121 putchar('.'); fflush(stdout);
124 cc_usb_printf(cc,"a\n");
129 * Read a 16-bit value from the USB target
133 ao_self_get_uint16(struct cc_usb *cc, uint32_t addr)
135 struct ao_hex_image *hex = ao_self_read(cc, addr, 2);
141 data = hex->data + addr - hex->address;
142 v = data[0] | (data[1] << 8);
148 ao_self_get_uint32(struct cc_usb *cc, uint32_t addr)
150 struct ao_hex_image *hex = ao_self_read(cc, addr, 4);
156 data = hex->data + addr - hex->address;
157 v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
163 ao_self_get_usb_id(struct cc_usb *cc, struct ao_usb_id *id)
165 struct ao_hex_image *hex;
168 if (!AO_USB_DESCRIPTORS)
171 hex = ao_self_read(cc, AO_USB_DESCRIPTORS, 512);
175 ret = ao_heximage_usb_id(hex, id);
181 ao_self_get_usb_product(struct cc_usb *cc)
183 struct ao_hex_image *hex;
186 if (!AO_USB_DESCRIPTORS)
189 hex = ao_self_read(cc, AO_USB_DESCRIPTORS, 512);
193 ret = ao_heximage_usb_product(hex);