2 * Copyright © 2016 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.
30 static uint32_t dfu_crc;
31 static FILE *dfu_file;
32 static int dfu_failed;
35 static uint32_t update_crc(uint32_t crc, uint8_t byte)
41 for (j = 0; j < 8; j++) {
43 crc = (crc >> 1) ^ (0xEDB88320 & mask);
48 static void dfu_init(FILE *file)
56 static int dfu_fini(void)
58 if (fflush(dfu_file) == EOF) {
69 static void dfu_8(uint8_t byte) {
70 if (putc(byte, dfu_file) == EOF) {
76 dfu_crc = update_crc(dfu_crc, byte);
79 static void dfu_pad(int len) {
84 static void dfu_string(char *string) {
87 while ((c = *string++))
91 static void dfu_string_pad(char *string, int len) {
94 while ((c = *string++)) {
101 static void dfu_block(uint8_t *bytes, int len) {
106 static void dfu_lsb16(uint16_t value) {
111 static void dfu_lsb32(uint32_t value) {
118 static uint32_t dfu_image_size(struct ao_hex_image *image) {
119 return 8 + image->length;
122 static uint32_t dfu_images_size(int num_image, struct ao_hex_image images[])
127 for (i = 0; i < num_image; i++)
128 size += dfu_image_size(&images[i]);
132 static void dfu_image(struct ao_hex_image *image)
134 dfu_lsb32(image->address);
135 dfu_lsb32(image->length);
136 dfu_block(image->data, image->length);
139 static void dfu_target(char *name, int num_image, struct ao_hex_image images[])
141 uint32_t images_size = dfu_images_size(num_image, images);
144 dfu_string("Target");
149 dfu_string_pad(name, 255);
155 dfu_lsb32(images_size);
156 dfu_lsb32(num_image);
157 for (i = 0; i < num_image; i++)
158 dfu_image(&images[i]);
161 static uint32_t dfu_target_size(int num_image, struct ao_hex_image images[])
163 return 274 + dfu_images_size(num_image, images);
167 dfu_size(int num_image, struct ao_hex_image images[])
170 size += 11; /* DFU Prefix */
172 size += dfu_target_size(num_image, images);
178 ao_dfu_write(FILE *file, struct ao_dfu_info *info, int num_image, struct ao_hex_image images[])
182 total_size = dfu_size(num_image, images);
186 dfu_string(DFU_SIGNATURE);
188 dfu_lsb32(total_size);
191 dfu_target("ST...", num_image, images);
194 dfu_lsb16(info->bcdDevice);
195 dfu_lsb16(info->idProduct);
196 dfu_lsb16(info->idVendor);
197 dfu_lsb16(DFU_SPEC_VERSION);