1 /* Appotech ax203 picframe access library
3 * Copyright (c) 2010 Hans de Goede <hdegoede@redhat.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; either version 2.1 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <sys/types.h>
35 #include <gphoto2/gphoto2-result.h>
38 #include "jpeg_memsrcdest.h"
41 static const struct eeprom_info {
46 } ax203_eeprom_info[] = {
47 { "AMIC A25L040", 0x37133037, 524288, 1 },
48 { "AMIC A25L080", 0x37143037, 1048576, 1 },
49 { "AMIC A25L40P", 0x1320377f, 524288, 0 },
50 { "AMIC A25L80P", 0x1420377f, 1048576, 0 },
51 { "AMIC A25L16P", 0x1520377f, 2097152, 0 },
53 /* Note the ATmel AT26DF041 id:0x0000441f is fsck-ed up. It doesn't
54 support ERASE_64K, (only 4K) and SPI_EEPROM_PP is 0x11 rather then
55 0x02 (0x02 only programs a single byte). */
56 /* I cannot find a datasheet for the ATmel AT26DF081 id:0x0000451f */
57 { "ATmel AT26DF161", 0x0000461f, 2097152, 1 },
58 { "ATmel AT26DF081A", 0x0001451f, 1048576, 1 },
59 { "ATmel AT26DF161A", 0x0001461f, 2097152, 1 },
60 { "ATmel AT25DF081", 0x0002451f, 1048576, 1 },
61 { "ATmel AT25DF161", 0x0002461f, 2097152, 1 },
63 { "EON EN25B16", 0x1c15201c, 2097152, 0 },
64 { "EON EN25B32", 0x1c16201c, 4194304, 0 },
65 { "EON EN25F80", 0x1c14311c, 1048576, 1 },
66 { "EON EN25F16", 0x1c15311c, 2097152, 1 },
68 { "ESI ES25P80", 0x0014204a, 1048576, 0 },
69 { "ESI ES25P16", 0x0015204a, 2097152, 0 },
71 { "ESMT F25L008 (top)", 0x8c14208c, 1048576, 1 },
72 { "ESMT F25L008 (bottom)", 0x8c14218c, 1048576, 1 },
74 { "GigaDevice GD25Q40", 0xc81340c8, 524288, 1 },
75 { "GigaDevice GD25Q80", 0xc81440c8, 1048576, 1 },
76 { "GigaDevice GD25Q16", 0xc81540c8, 2097152, 1 },
78 { "MXIC MX25L4005A", 0xc21320c2, 524288, 1 },
79 { "MXIC MX25L8005A", 0xc21420c2, 1048576, 1 },
80 { "MXIC MX25L1605A", 0xc21520c2, 2097152, 1 },
82 { "PMC Pm25LV010", 0x007e9d7f, 524288, 0 },
84 { "Spansion S25FL004A", 0x00120201, 524288, 0 },
85 { "Spansion S25FL008A", 0x00130201, 1048576, 0 },
86 { "Spansion S25FL016A", 0x00140201, 2097152, 0 },
88 /* The SST25VF080 and SST25VF016 (id:0xbf8e25bf & 0xbf4125bf) PP
89 instruction can only program a single byte at a time. Thus they
92 { "ST M25P08", 0x7f142020, 1048576, 0 },
93 { "ST M25P16", 0x7f152020, 2097152, 0 },
94 { "ST M25P32", 0x7f162020, 4194304, 0 },
95 { "ST M25P64", 0x7f172020, 8388608, 0 },
97 { "Winbond W25P80", 0x001420ef, 1048576, 0 },
98 { "Winbond W25P16", 0x001520ef, 2097152, 0 },
100 { "Winbond W25X40", 0x001330ef, 524288, 1 },
101 { "Winbond W25X80", 0x001430ef, 1048576, 1 },
102 { "Winbond W25X16", 0x001530ef, 2097152, 1 },
103 { "Winbond W25X32", 0x001630ef, 4194304, 1 },
104 { "Winbond W25X64", 0x001730ef, 8388608, 1 },
106 { "Winbond W25Q80", 0x001440ef, 1048576, 1 },
107 { "Winbond W25Q16", 0x001540ef, 2097152, 1 },
108 { "Winbond W25Q32", 0x001640ef, 4194304, 1 },
114 ax203_send_cmd(Camera *camera, int to_dev, char *cmd, int cmd_size,
115 char *data, int data_size)
117 char sense_buffer[32];
119 return gp_port_send_scsi_cmd (camera->port, to_dev, cmd, cmd_size,
120 sense_buffer, sizeof(sense_buffer), data, data_size);
124 ax203_send_eeprom_cmd(Camera *camera, int to_dev,
125 char *eeprom_cmd, int eeprom_cmd_size,
126 char *data, int data_size)
131 memset (cmd_buffer, 0, sizeof (cmd_buffer));
133 cmd_buffer[0] = AX203_TO_DEV;
135 cmd_buffer[0] = AX203_FROM_DEV;
137 cmd_buffer[5] = AX203_EEPROM_CMD;
138 cmd_buffer[6] = eeprom_cmd_size;
139 cmd_buffer[7] = (data_size >> 16) & 0xff;
140 cmd_buffer[8] = (data_size >> 8) & 0xff;
141 cmd_buffer[9] = (data_size) & 0xff;
143 for (i = 0; i < eeprom_cmd_size; i++)
144 cmd_buffer[10 + i] = eeprom_cmd[i];
146 return ax203_send_cmd (camera, to_dev, cmd_buffer, sizeof(cmd_buffer),
151 ax203_get_version(Camera *camera, char *buf)
156 memset (cmd_buffer, 0, sizeof (cmd_buffer));
158 cmd_buffer[0] = AX203_FROM_DEV;
159 cmd_buffer[5] = AX203_GET_VERSION;
161 cmd_buffer[10] = AX203_GET_VERSION;
163 ret = ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
165 buf[63] = 0; /* ensure 0 termination */
170 /* This would be very nice, if only not all devices would answer that they
171 are a 128x128 pixels device */
174 ax203_get_lcd_size(Camera *camera)
177 uint8_t data_buffer[4];
179 memset (cmd_buffer, 0, sizeof (cmd_buffer));
181 cmd_buffer[0] = AX203_FROM_DEV;
182 cmd_buffer[5] = AX203_GET_LCD_SIZE;
183 cmd_buffer[6] = 0x01;
184 cmd_buffer[10] = AX203_GET_LCD_SIZE;
186 CHECK (ax203_send_cmd (camera, 0, cmd_buffer, sizeof (cmd_buffer),
187 (char *)data_buffer, sizeof (data_buffer)))
189 camera->pl->width = le16atoh (data_buffer);
190 camera->pl->height = le16atoh (data_buffer + 2);
197 ax3003_get_frame_id(Camera *camera)
203 memset (cmd_buffer, 0, sizeof (cmd_buffer));
205 cmd_buffer[0] = AX3003_FRAME_CMD;
206 cmd_buffer[1] = AX3003_GET_FRAME_ID;
208 ret = ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
210 if (ret < 0) return ret;
216 ax3003_get_abfs_start(Camera *camera)
222 memset (cmd_buffer, 0, sizeof (cmd_buffer));
224 cmd_buffer[0] = AX3003_FRAME_CMD;
225 cmd_buffer[1] = AX3003_GET_ABFS_START;
227 ret = ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
229 if (ret < 0) return ret;
231 return be16atoh(buf) * 0x100;
235 ax203_set_time_and_date(Camera *camera, struct tm *t)
239 memset (cmd_buffer, 0, sizeof (cmd_buffer));
241 cmd_buffer[0] = AX203_SET_TIME;
243 cmd_buffer[5] = t->tm_year % 100;
245 switch (camera->pl->frame_version) {
246 case AX3003_FIRMWARE_3_5_x:
247 /* Note this is what the windows software does, with the
248 one AX3003 frame I have this does not do anything */
249 cmd_buffer[0] = AX3003_FRAME_CMD;
250 cmd_buffer[1] = AX3003_SET_TIME;
252 case AX203_FIRMWARE_3_3_x:
253 case AX203_FIRMWARE_3_4_x:
254 cmd_buffer[6] = t->tm_mon + 1;
255 cmd_buffer[7] = t->tm_wday;
257 case AX206_FIRMWARE_3_5_x:
258 cmd_buffer[6] = 19 + t->tm_year / 100;
259 cmd_buffer[7] = t->tm_mon + 1;
262 cmd_buffer[8] = t->tm_mday;
263 cmd_buffer[9] = t->tm_hour;
264 cmd_buffer[10] = t->tm_min;
265 cmd_buffer[11] = t->tm_sec;
267 return ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
272 ax203_eeprom_device_identification(Camera *camera, char *buf)
274 char cmd = SPI_EEPROM_RDID;
276 return ax203_send_eeprom_cmd (camera, 0, &cmd, 1, buf, 4);
280 ax203_eeprom_release_from_deep_powerdown(Camera *camera)
282 char cmd = SPI_EEPROM_RDP;
284 return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0);
288 ax203_eeprom_read(Camera *camera, int address, char *buf, int buf_size)
292 cmd[0] = SPI_EEPROM_READ;
293 cmd[1] = (address >> 16) & 0xff;
294 cmd[2] = (address >> 8) & 0xff;
295 cmd[3] = (address) & 0xff;
297 return ax203_send_eeprom_cmd (camera, 0, cmd, sizeof(cmd), buf,
302 ax203_eeprom_program_page(Camera *camera, int address, char *buf, int buf_size)
306 cmd[0] = SPI_EEPROM_PP;
307 cmd[1] = (address >> 16) & 0xff;
308 cmd[2] = (address >> 8) & 0xff;
309 cmd[3] = (address) & 0xff;
311 return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), buf,
316 ax203_eeprom_write_enable(Camera *camera)
318 char cmd = SPI_EEPROM_WREN;
320 return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0);
324 ax203_eeprom_clear_block_protection(Camera *camera)
328 cmd[0] = SPI_EEPROM_WRSR;
331 return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
335 ax203_eeprom_erase_4k_sector(Camera *camera, int address)
339 cmd[0] = SPI_EEPROM_ERASE_4K;
340 cmd[1] = (address >> 16) & 0xff;
341 cmd[2] = (address >> 8) & 0xff;
342 cmd[3] = (address) & 0xff;
344 return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
348 ax203_eeprom_erase_64k_sector(Camera *camera, int address)
352 cmd[0] = SPI_EEPROM_ERASE_64K;
353 cmd[1] = (address >> 16) & 0xff;
354 cmd[2] = (address >> 8) & 0xff;
355 cmd[3] = (address) & 0xff;
357 return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
361 ax203_eeprom_wait_ready(Camera *camera)
363 char cmd = SPI_EEPROM_RDSR; /* Read status */
367 switch (camera->pl->frame_version) {
368 case AX203_FIRMWARE_3_3_x:
369 case AX203_FIRMWARE_3_4_x:
370 case AX206_FIRMWARE_3_5_x:
371 /* Do as windows does, read the status word 64 times,
375 case AX3003_FIRMWARE_3_5_x:
376 /* On the ax3003 contineously reading the status word
383 CHECK (ax203_send_eeprom_cmd (camera, 0, &cmd, 1, buf, count))
384 /* We only need to check the last read */
385 if (!(buf[count - 1] & 0x01)) /* Check write in progress bit */
386 break; /* No write in progress, done waiting */
392 ax203_read_sector(Camera *camera, int sector, char *buf)
395 if (camera->pl->mem_dump) {
396 ret = fseek (camera->pl->mem_dump,
397 sector * SPI_EEPROM_SECTOR_SIZE, SEEK_SET);
399 gp_log (GP_LOG_ERROR, "ax203",
400 "seeking in memdump: %s", strerror(errno));
401 return GP_ERROR_IO_READ;
403 ret = fread (buf, 1, SPI_EEPROM_SECTOR_SIZE,
404 camera->pl->mem_dump);
405 if (ret != SPI_EEPROM_SECTOR_SIZE) {
407 gp_log (GP_LOG_ERROR, "ax203",
408 "reading memdump: %s",
411 gp_log (GP_LOG_ERROR, "ax203",
412 "short read reading from memdump");
413 return GP_ERROR_IO_READ;
416 CHECK (ax203_eeprom_read (camera,
417 sector * SPI_EEPROM_SECTOR_SIZE,
418 buf, SPI_EEPROM_SECTOR_SIZE))
424 ax203_write_sector(Camera *camera, int sector, char *buf)
427 if (camera->pl->mem_dump) {
428 ret = fseek (camera->pl->mem_dump,
429 sector * SPI_EEPROM_SECTOR_SIZE, SEEK_SET);
431 gp_log (GP_LOG_ERROR, "ax203",
432 "seeking in memdump: %s", strerror(errno));
433 return GP_ERROR_IO_WRITE;
435 ret = fwrite (buf, 1, SPI_EEPROM_SECTOR_SIZE,
436 camera->pl->mem_dump);
437 if (ret != SPI_EEPROM_SECTOR_SIZE) {
438 gp_log (GP_LOG_ERROR, "ax203",
439 "writing memdump: %s", strerror(errno));
440 return GP_ERROR_IO_WRITE;
443 int i, base = sector * SPI_EEPROM_SECTOR_SIZE;
445 for (i = 0; i < SPI_EEPROM_SECTOR_SIZE; i += 256) {
446 CHECK (ax203_eeprom_write_enable (camera))
447 CHECK (ax203_eeprom_program_page (camera, base + i,
449 CHECK (ax203_eeprom_wait_ready (camera))
456 ax203_erase4k_sector(Camera *camera, int sector)
458 if (camera->pl->mem_dump)
461 CHECK (ax203_eeprom_write_enable (camera))
462 CHECK (ax203_eeprom_erase_4k_sector (camera,
463 sector * SPI_EEPROM_SECTOR_SIZE))
464 CHECK (ax203_eeprom_wait_ready (camera))
470 ax203_erase64k_sector(Camera *camera, int sector)
472 if (camera->pl->mem_dump)
475 CHECK (ax203_eeprom_write_enable (camera))
476 CHECK (ax203_eeprom_erase_64k_sector (camera,
477 sector * SPI_EEPROM_SECTOR_SIZE))
478 CHECK (ax203_eeprom_wait_ready (camera))
484 ax203_check_sector_present(Camera *camera, int sector)
488 if ((sector + 1) * SPI_EEPROM_SECTOR_SIZE > camera->pl->mem_size) {
489 gp_log (GP_LOG_ERROR, "ax203", "access beyond end of memory");
490 return GP_ERROR_CORRUPTED_DATA;
493 if (camera->pl->sector_is_present[sector])
496 ret = ax203_read_sector(camera, sector, camera->pl->mem +
497 sector * SPI_EEPROM_SECTOR_SIZE);
499 camera->pl->sector_is_present[sector] = 1;
505 ax203_read_mem(Camera *camera, int offset,
508 int to_copy, sector = offset / SPI_EEPROM_SECTOR_SIZE;
511 CHECK (ax203_check_sector_present (camera, sector))
513 to_copy = SPI_EEPROM_SECTOR_SIZE -
514 (offset % SPI_EEPROM_SECTOR_SIZE);
518 memcpy(buf, camera->pl->mem + offset, to_copy);
528 ax203_write_mem(Camera *camera, int offset,
531 int to_copy, sector = offset / SPI_EEPROM_SECTOR_SIZE;
534 CHECK (ax203_check_sector_present (camera, sector))
536 to_copy = SPI_EEPROM_SECTOR_SIZE -
537 (offset % SPI_EEPROM_SECTOR_SIZE);
541 memcpy(camera->pl->mem + offset, buf, to_copy);
542 camera->pl->sector_dirty[sector] = 1;
552 /* This function reads the parameter block from the eeprom and:
553 1) checks some hopefully constant bytes to make sure it is not reading
555 2) Gets the lcd size from the paramter block (ax203_get_lcd_size seems
556 to result in all frames being detected as being 128x128 pixels).
557 3) Determines the compression type for v3.4.x frames
558 4) Determines the start of the ABFS
560 static int ax203_read_parameter_block(Camera *camera)
562 uint8_t buf[32], expect[32];
563 int i, param_offset = 0, resolution_offset = 0;
564 int compression_offset = -1, abfs_start_offset = 0, expect_size = 0;
565 const int valid_resolutions[][2] = {
577 const uint8_t expect_33x[] = {
578 0x13, 0x15, 0, 0, 0x02, 0x01, 0x02, 0x01,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
580 const uint8_t expect_34x[] = {
581 0x13, 0x15, 0, 0, 0, 0, 0, 0x01,
582 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
583 const uint8_t expect_35x[] = {
584 0x00, 0x00, 0, 0, 0, 0, 0, 0xd8 };
586 switch (camera->pl->frame_version) {
587 case AX203_FIRMWARE_3_3_x:
589 resolution_offset = 2;
590 abfs_start_offset = 16;
591 memcpy (expect, expect_33x, sizeof(expect_33x));
592 expect_size = sizeof(expect_33x);
593 /* Byte 4 of the parameter block probably is the compression
594 type like with v3.4.x, but this needs confirmation. */
595 camera->pl->compression_version = AX203_COMPRESSION_YUV;
597 case AX203_FIRMWARE_3_4_x:
599 resolution_offset = 2;
600 compression_offset = 6;
601 abfs_start_offset = 16;
602 memcpy (expect, expect_34x, sizeof(expect_34x));
603 expect_size = sizeof(expect_34x);
605 case AX206_FIRMWARE_3_5_x:
607 abfs_start_offset = 2;
608 resolution_offset = 3;
609 memcpy (expect, expect_35x, sizeof(expect_35x));
610 expect_size = sizeof(expect_35x);
611 /* ax206 + 3.5.x firmware has a fixed compression type */
612 camera->pl->compression_version = AX206_COMPRESSION_JPEG;
614 case AX3003_FIRMWARE_3_5_x:
615 i = ax3003_get_frame_id (camera);
619 camera->pl->width = 320;
620 camera->pl->height = 240;
623 gp_log (GP_LOG_ERROR, "ax203",
624 "unknown ax3003 frame id: %d", i);
625 return GP_ERROR_MODEL_NOT_FOUND;
628 i = ax3003_get_abfs_start (camera);
630 camera->pl->fs_start = i;
632 camera->pl->compression_version = AX3003_COMPRESSION_JPEG;
634 goto verify_parameters;
637 CHECK (ax203_read_mem (camera, param_offset, buf, sizeof(buf)))
639 switch (camera->pl->frame_version) {
640 case AX203_FIRMWARE_3_3_x:
641 /* 1 byte width / height */
642 camera->pl->width = buf[resolution_offset ];
643 camera->pl->height = buf[resolution_offset + 1];
644 expect[resolution_offset ] = camera->pl->width;
645 expect[resolution_offset + 1] = camera->pl->height;
647 case AX203_FIRMWARE_3_4_x:
648 case AX206_FIRMWARE_3_5_x:
649 /* 2 byte little endian width / height */
650 camera->pl->width = le16atoh (buf + resolution_offset);
651 camera->pl->height = le16atoh (buf + resolution_offset + 2);
652 htole16a(expect + resolution_offset , camera->pl->width);
653 htole16a(expect + resolution_offset + 2, camera->pl->height);
655 case AX3003_FIRMWARE_3_5_x:
656 /* Never reached, here to silence a compiler warning */
660 if (compression_offset != -1) {
661 i = buf[compression_offset];
664 camera->pl->compression_version =
665 AX203_COMPRESSION_YUV;
668 camera->pl->compression_version =
669 AX203_COMPRESSION_YUV_DELTA;
672 gp_log (GP_LOG_ERROR, "ax203",
673 "unknown compression version: %d", i);
674 return GP_ERROR_MODEL_NOT_FOUND;
676 expect[compression_offset] = i;
679 i = buf[abfs_start_offset];
680 camera->pl->fs_start = i * 0x10000;
681 expect[abfs_start_offset] = i;
683 if (memcmp (buf, expect, expect_size)) {
684 gp_log (GP_LOG_ERROR, "ax203",
685 "unexpected contents of parameter block");
686 return GP_ERROR_MODEL_NOT_FOUND;
690 for (i = 0; valid_resolutions[i][0]; i++)
691 if (valid_resolutions[i][0] == camera->pl->width &&
692 valid_resolutions[i][1] == camera->pl->height)
695 if (!valid_resolutions[i][0]) {
696 gp_log (GP_LOG_ERROR, "ax203", "unknown resolution: %dx%d",
697 camera->pl->width, camera->pl->height);
698 return GP_ERROR_MODEL_NOT_FOUND;
701 CHECK (ax203_read_mem (camera, camera->pl->fs_start, buf, 4))
702 if (memcmp (buf, AX203_ABFS_MAGIC, 4)) {
703 gp_log (GP_LOG_ERROR, "ax203", "ABFS magic not found at: %x",
704 camera->pl->fs_start);
705 return GP_ERROR_MODEL_NOT_FOUND;
708 GP_DEBUG ("lcd size %dx%d, compression ver: %d, fs-start: %x",
709 camera->pl->width, camera->pl->height,
710 camera->pl->compression_version, camera->pl->fs_start);
715 static int ax203_check_file_index(Camera *camera, int idx)
720 gp_log (GP_LOG_ERROR, "ax203",
722 return GP_ERROR_BAD_PARAMETERS;
725 count = ax203_read_filecount (camera);
726 if (count < 0) return count;
729 gp_log (GP_LOG_ERROR, "ax203",
730 "file index beyond end of ABFS");
731 return GP_ERROR_BAD_PARAMETERS;
738 ax203_filesize(Camera *camera)
740 switch (camera->pl->compression_version) {
741 case AX203_COMPRESSION_YUV:
742 return camera->pl->width * camera->pl->height;
743 case AX203_COMPRESSION_YUV_DELTA:
744 return camera->pl->width * camera->pl->height * 3 / 4;
745 case AX206_COMPRESSION_JPEG:
746 case AX3003_COMPRESSION_JPEG:
751 return GP_ERROR_NOT_SUPPORTED;
755 ax203_max_filecount(Camera *camera)
757 switch (camera->pl->frame_version) {
758 case AX203_FIRMWARE_3_3_x:
759 case AX203_FIRMWARE_3_4_x:
760 return (AX203_ABFS_SIZE - AX203_ABFS_FILE_OFFSET (0)) / 2;
761 case AX206_FIRMWARE_3_5_x:
762 return (AX203_ABFS_SIZE - AX206_ABFS_FILE_OFFSET (0)) /
763 sizeof(struct ax206_v3_5_x_raw_fileinfo);
764 case AX3003_FIRMWARE_3_5_x:
765 return (AX203_ABFS_SIZE - AX3003_ABFS_FILE_OFFSET (0)) /
766 sizeof(struct ax3003_v3_5_x_raw_fileinfo);
769 return GP_ERROR_NOT_SUPPORTED;
773 ax203_read_v3_3_x_v3_4_x_filecount(Camera *camera)
775 /* The v3.3.x and v3.4.x firmware ABFS keeps a single byte file count
776 at (camera->pl->fs_start + AX203_ABFS_COUNT_OFFSET) However the
777 frame does not seem to care about this.
778 So always return the maximum number of entries the ABFS can contain
779 (and rely on fileinfo.present to figure out how many files there
781 return ax203_max_filecount (camera);
785 ax203_write_v3_3_x_v3_4_x_filecount(Camera *camera, int count)
789 /* Despite the frame not caring, we do write the filecount just
790 like windows does. */
791 CHECK (ax203_write_mem (camera,
792 camera->pl->fs_start + AX203_ABFS_COUNT_OFFSET,
798 ax203_read_v3_5_x_filecount(Camera *camera)
800 /* The v3.5.x firmware ABFS does not contain a separate file count,
801 so always return the maximum number of entries it can contain
802 (and rely on fileinfo.present to figure out how many files there
804 return ax203_max_filecount (camera);
808 ax203_write_v3_5_x_filecount(Camera *camera, int count)
810 /* This is a no-op as the v3.5.x firmware ABFS does not contain a
811 separate file count */
816 int ax203_read_v3_3_x_v3_4_x_fileinfo(Camera *camera, int idx,
817 struct ax203_fileinfo *fileinfo)
821 CHECK (ax203_read_mem (camera,
822 camera->pl->fs_start +
823 AX203_ABFS_FILE_OFFSET (idx),
826 fileinfo->address = le16atoh (buf) << 8;
827 fileinfo->size = ax203_filesize (camera);
828 fileinfo->present = fileinfo->address? 1 : 0;
834 int ax203_write_v3_3_x_v3_4_x_fileinfo(Camera *camera, int idx,
835 struct ax203_fileinfo *fileinfo)
839 if (fileinfo->address & 0xff) {
840 gp_log (GP_LOG_ERROR, "ax203", "LSB of address is not 0");
841 return GP_ERROR_BAD_PARAMETERS;
844 if (!fileinfo->present)
845 fileinfo->address = 0;
847 htole16a(buf, fileinfo->address >> 8);
848 CHECK (ax203_write_mem (camera,
849 camera->pl->fs_start +
850 AX203_ABFS_FILE_OFFSET (idx),
857 int ax206_read_v3_5_x_fileinfo(Camera *camera, int idx,
858 struct ax203_fileinfo *fileinfo)
860 struct ax206_v3_5_x_raw_fileinfo raw;
862 CHECK (ax203_read_mem (camera,
863 camera->pl->fs_start +
864 AX206_ABFS_FILE_OFFSET (idx),
867 fileinfo->present = raw.present == 0x01;
868 fileinfo->address = le32toh (raw.address);
869 fileinfo->size = le16toh (raw.size);
875 int ax206_write_v3_5_x_fileinfo(Camera *camera, int idx,
876 struct ax203_fileinfo *fileinfo)
878 struct ax206_v3_5_x_raw_fileinfo raw;
880 raw.present = fileinfo->present;
881 raw.address = htole32(fileinfo->address);
882 raw.size = htole16(fileinfo->size);
884 CHECK (ax203_write_mem (camera,
885 camera->pl->fs_start +
886 AX206_ABFS_FILE_OFFSET (idx),
893 int ax3003_read_v3_5_x_fileinfo(Camera *camera, int idx,
894 struct ax203_fileinfo *fileinfo)
896 struct ax3003_v3_5_x_raw_fileinfo raw;
898 CHECK (ax203_read_mem (camera,
899 camera->pl->fs_start +
900 AX3003_ABFS_FILE_OFFSET (idx),
903 fileinfo->present = raw.address && raw.size;
904 fileinfo->address = be16toh (raw.address) * 0x100;
905 fileinfo->size = be16toh (raw.size) * 0x100;
911 int ax3003_write_v3_5_x_fileinfo(Camera *camera, int idx,
912 struct ax203_fileinfo *fileinfo)
914 struct ax3003_v3_5_x_raw_fileinfo raw;
916 if (fileinfo->address & 0xff) {
917 gp_log (GP_LOG_ERROR, "ax203", "LSB of address is not 0");
918 return GP_ERROR_BAD_PARAMETERS;
921 if (fileinfo->size & 0xff) {
922 gp_log (GP_LOG_ERROR, "ax203", "LSB of size is not 0");
923 return GP_ERROR_BAD_PARAMETERS;
926 if (fileinfo->present) {
927 raw.address = htobe16(fileinfo->address / 0x100);
928 raw.size = htobe16(fileinfo->size / 0x100);
934 CHECK (ax203_write_mem (camera,
935 camera->pl->fs_start +
936 AX3003_ABFS_FILE_OFFSET (idx),
942 /***************** Begin "public" functions *****************/
945 ax203_read_filecount(Camera *camera)
947 switch (camera->pl->frame_version) {
948 case AX203_FIRMWARE_3_3_x:
949 case AX203_FIRMWARE_3_4_x:
950 return ax203_read_v3_3_x_v3_4_x_filecount (camera);
951 case AX206_FIRMWARE_3_5_x:
952 case AX3003_FIRMWARE_3_5_x:
953 return ax203_read_v3_5_x_filecount (camera);;
956 return GP_ERROR_NOT_SUPPORTED;
960 ax203_update_filecount(Camera *camera)
962 int i, max, count = 0;
964 /* "Calculate" the real file count */
965 max = ax203_max_filecount (camera);
966 for (i = 0; i < max; i++) {
967 if (ax203_file_present (camera, i))
971 switch (camera->pl->frame_version) {
972 case AX203_FIRMWARE_3_3_x:
973 case AX203_FIRMWARE_3_4_x:
974 return ax203_write_v3_3_x_v3_4_x_filecount (camera, count);
975 case AX206_FIRMWARE_3_5_x:
976 case AX3003_FIRMWARE_3_5_x:
977 return ax203_write_v3_5_x_filecount (camera, count);
980 return GP_ERROR_NOT_SUPPORTED;
984 int ax203_read_fileinfo(Camera *camera, int idx,
985 struct ax203_fileinfo *fileinfo)
987 CHECK (ax203_check_file_index (camera, idx))
989 switch (camera->pl->frame_version) {
990 case AX203_FIRMWARE_3_3_x:
991 case AX203_FIRMWARE_3_4_x:
992 return ax203_read_v3_3_x_v3_4_x_fileinfo (camera, idx,
994 case AX206_FIRMWARE_3_5_x:
995 return ax206_read_v3_5_x_fileinfo (camera, idx, fileinfo);
996 case AX3003_FIRMWARE_3_5_x:
997 return ax3003_read_v3_5_x_fileinfo (camera, idx, fileinfo);
1000 return GP_ERROR_NOT_SUPPORTED;
1004 int ax203_write_fileinfo(Camera *camera, int idx,
1005 struct ax203_fileinfo *fileinfo)
1007 switch (camera->pl->frame_version) {
1008 case AX203_FIRMWARE_3_3_x:
1009 case AX203_FIRMWARE_3_4_x:
1010 return ax203_write_v3_3_x_v3_4_x_fileinfo (camera, idx,
1012 case AX206_FIRMWARE_3_5_x:
1013 return ax206_write_v3_5_x_fileinfo (camera, idx, fileinfo);
1014 case AX3003_FIRMWARE_3_5_x:
1015 return ax3003_write_v3_5_x_fileinfo (camera, idx, fileinfo);
1018 return GP_ERROR_NOT_SUPPORTED;
1022 ax203_file_present(Camera *camera, int idx)
1024 struct ax203_fileinfo fileinfo;
1026 CHECK (ax203_read_fileinfo (camera, idx, &fileinfo))
1028 return fileinfo.present;
1032 ax203_decode_image(Camera *camera, char *src, int src_size, int **dest)
1036 unsigned int x, y, width, height, row_skip = 0;
1037 unsigned char *components[3];
1039 struct jpeg_decompress_struct dinfo;
1040 struct jpeg_error_mgr jderr;
1041 JSAMPLE row[camera->pl->width * 3];
1042 JSAMPROW row_pointer[1] = { row };
1045 switch (camera->pl->compression_version) {
1046 case AX203_COMPRESSION_YUV:
1047 ax203_decode_yuv (src, dest, camera->pl->width,
1048 camera->pl->height);
1050 case AX203_COMPRESSION_YUV_DELTA:
1051 ax203_decode_yuv_delta (src, dest, camera->pl->width,
1052 camera->pl->height);
1054 case AX206_COMPRESSION_JPEG:
1055 /* Note this uses a modified tinyjpeg which was modified to
1056 handle the AX206' custom JPEG format (the AX3003 uses
1057 normal JPEG compression). */
1058 if (!camera->pl->jdec) {
1059 camera->pl->jdec = tinyjpeg_init ();
1060 if (!camera->pl->jdec)
1061 return GP_ERROR_NO_MEMORY;
1064 /* Hack for width / heights which are not a multiple of 16 */
1065 if (camera->pl->width % 16 || camera->pl->height % 16) {
1066 width = (camera->pl->width + 15) & ~15;
1067 height = (camera->pl->height + 15) & ~15;
1068 htobe16a(src, width);
1069 htobe16a(src + 2, height);
1070 row_skip = (width - camera->pl->width) * 3;
1072 ret = tinyjpeg_parse_header (camera->pl->jdec,
1073 (unsigned char *)src, src_size);
1075 gp_log (GP_LOG_ERROR, "ax203",
1076 "Error parsing header: %s",
1077 tinyjpeg_get_errorstring (camera->pl->jdec));
1078 return GP_ERROR_CORRUPTED_DATA;
1081 tinyjpeg_get_size (camera->pl->jdec, &width, &height);
1082 if ((int)width != camera->pl->width ||
1083 (int)height != camera->pl->height) {
1084 gp_log (GP_LOG_ERROR, "ax203",
1085 "Hdr dimensions %ux%u don't match lcd %dx%d",
1087 camera->pl->width, camera->pl->height);
1088 return GP_ERROR_CORRUPTED_DATA;
1091 ret = tinyjpeg_decode (camera->pl->jdec);
1093 gp_log (GP_LOG_ERROR, "ax203",
1094 "Error decoding JPEG data: %s",
1095 tinyjpeg_get_errorstring (camera->pl->jdec));
1096 return GP_ERROR_CORRUPTED_DATA;
1098 tinyjpeg_get_components (camera->pl->jdec, components);
1099 for (y = 0; y < camera->pl->height; y++) {
1100 for (x = 0; x < camera->pl->width; x++) {
1101 dest[y][x] = gdTrueColor (components[0][0],
1106 components[0] += row_skip;
1109 case AX3003_COMPRESSION_JPEG:
1111 dinfo.err = jpeg_std_error (&jderr);
1112 jpeg_create_decompress (&dinfo);
1113 jpeg_mem_src (&dinfo, (unsigned char *)src, src_size);
1114 jpeg_read_header (&dinfo, TRUE);
1115 jpeg_start_decompress (&dinfo);
1116 if (dinfo.output_width != camera->pl->width ||
1117 dinfo.output_height != camera->pl->height ||
1118 dinfo.output_components != 3 ||
1119 dinfo.out_color_space != JCS_RGB) {
1120 gp_log (GP_LOG_ERROR, "ax203",
1121 "Wrong JPEG header parameters: %dx%d, "
1122 "%d components, colorspace: %d",
1123 dinfo.output_width, dinfo.output_height,
1124 dinfo.output_components,
1125 dinfo.out_color_space);
1126 return GP_ERROR_CORRUPTED_DATA;
1129 for (y = 0; y < dinfo.output_height; y++) {
1130 jpeg_read_scanlines (&dinfo, row_pointer, 1);
1131 for (x = 0; x < dinfo.output_width; x++) {
1132 dest[y][x] = gdTrueColor (row[x * 3 + 0],
1137 jpeg_finish_decompress (&dinfo);
1138 jpeg_destroy_decompress (&dinfo);
1141 gp_log(GP_LOG_ERROR,"ax203", "jpeg decompression not supported - no libjpeg during build");
1142 return GP_ERROR_NOT_SUPPORTED;
1147 gp_log(GP_LOG_ERROR,"ax203", "GD decompression not supported - no libGD present during build");
1149 return GP_ERROR_NOT_SUPPORTED;
1152 /* Returns the number of bytes of dest used or a negative error code */
1154 ax203_encode_image(Camera *camera, int **src, char *dest, int dest_size)
1157 int size = ax203_filesize (camera);
1160 struct jpeg_compress_struct cinfo;
1161 struct jpeg_error_mgr jcerr;
1162 JOCTET *jpeg_dest = NULL;
1163 unsigned long jpeg_size = 0;
1164 JSAMPLE row[camera->pl->width * 3];
1165 JSAMPROW row_pointer[1] = { row };
1168 if (dest_size < size)
1169 return GP_ERROR_FIXED_LIMIT_EXCEEDED;
1171 switch (camera->pl->compression_version) {
1172 case AX203_COMPRESSION_YUV:
1173 ax203_encode_yuv (src, dest, camera->pl->width,
1174 camera->pl->height);
1176 case AX203_COMPRESSION_YUV_DELTA:
1177 ax203_encode_yuv_delta (src, dest, camera->pl->width,
1178 camera->pl->height);
1180 case AX206_COMPRESSION_JPEG:
1181 return ax206_compress_jpeg (camera, src,
1182 (uint8_t *)dest, dest_size,
1184 camera->pl->height);
1185 case AX3003_COMPRESSION_JPEG:
1187 cinfo.err = jpeg_std_error (&jcerr);
1188 jpeg_create_compress (&cinfo);
1189 jpeg_mem_dest (&cinfo, &jpeg_dest, &jpeg_size);
1190 cinfo.image_width = camera->pl->width;
1191 cinfo.image_height = camera->pl->height;
1192 cinfo.input_components = 3;
1193 cinfo.in_color_space = JCS_RGB;
1194 jpeg_set_defaults (&cinfo);
1195 jpeg_start_compress (&cinfo, TRUE);
1196 for (y = 0; y < cinfo.image_height; y++) {
1197 for (x = 0; x < cinfo.image_width; x++) {
1199 row[x * 3 + 0] = gdTrueColorGetRed(p);
1200 row[x * 3 + 1] = gdTrueColorGetGreen(p);
1201 row[x * 3 + 2] = gdTrueColorGetBlue(p);
1203 jpeg_write_scanlines (&cinfo, row_pointer, 1);
1205 jpeg_finish_compress (&cinfo);
1206 jpeg_destroy_compress (&cinfo);
1208 if (jpeg_size > dest_size) {
1210 gp_log (GP_LOG_ERROR, "ax203",
1211 "JPEG is bigger then buffer");
1212 return GP_ERROR_FIXED_LIMIT_EXCEEDED;
1214 memcpy (dest, jpeg_dest, jpeg_size);
1216 /* Round size up to a multiple of 256 because of ax3003
1217 abfs size granularity. */
1218 return (jpeg_size + 0xff) & ~0xff;
1220 return GP_ERROR_NOT_SUPPORTED;
1225 gp_log(GP_LOG_ERROR,"ax203", "GD decompression not supported - no libGD present during build");
1226 return GP_ERROR_NOT_SUPPORTED;
1230 ax203_defrag_memory(Camera *camera)
1232 char **raw_pictures;
1233 struct ax203_fileinfo *fileinfo;
1234 int i, count, ret = GP_OK;
1236 count = ax203_read_filecount (camera);
1237 if (count < 0) return count;
1239 raw_pictures = calloc (count, sizeof (char *));
1240 fileinfo = calloc (count, sizeof (struct ax203_fileinfo));
1241 if (!raw_pictures || !fileinfo) {
1242 free (raw_pictures); free (fileinfo);
1243 gp_log (GP_LOG_ERROR, "ax203", "allocating memory");
1244 return GP_ERROR_NO_MEMORY;
1247 /* First read all pictures in raw format */
1248 for (i = 0; i < count; i++) {
1249 ret = ax203_read_fileinfo (camera, i, &fileinfo[i]);
1250 if (ret < 0) goto cleanup;
1252 if (!fileinfo[i].present)
1255 ret = ax203_read_raw_file(camera, i, &raw_pictures[i]);
1256 if (ret < 0) goto cleanup;
1259 /* Delete all pictures from the frame */
1260 ret = ax203_delete_all (camera);
1261 if (ret < 0) goto cleanup;
1263 /* An last write them back (in one contineous block) */
1264 for (i = 0; i < count; i++) {
1265 if (!fileinfo[i].present)
1268 ret = ax203_write_raw_file (camera, i, raw_pictures[i],
1271 gp_log (GP_LOG_ERROR, "ax203",
1272 "AAI error writing back images during "
1273 "defragmentation some images will be lost!");
1278 for (i = 0; i < count; i++)
1279 free (raw_pictures[i]);
1280 free (raw_pictures);
1287 ax203_read_raw_file(Camera *camera, int idx, char **raw)
1289 struct ax203_fileinfo fileinfo;
1294 CHECK (ax203_read_fileinfo (camera, idx, &fileinfo))
1296 if (!fileinfo.present) {
1297 gp_log (GP_LOG_ERROR, "ax203",
1298 "trying to read a deleted file");
1299 return GP_ERROR_BAD_PARAMETERS;
1302 /* Allocate 1 extra byte as tinyjpeg's huffman decoding sometimes
1303 reads a few bits more then it needs */
1304 *raw = malloc (fileinfo.size + 1);
1306 gp_log (GP_LOG_ERROR, "ax203", "allocating memory");
1307 return GP_ERROR_NO_MEMORY;
1310 ret = ax203_read_mem (camera, fileinfo.address, *raw, fileinfo.size);
1317 return fileinfo.size;
1321 ax203_read_file(Camera *camera, int idx, int **rgb24)
1326 ret = ax203_read_raw_file (camera, idx, &src);
1327 if (ret < 0) return ret;
1329 ret = ax203_decode_image (camera, src, ret + 1, rgb24);
1335 /* ax203_write_file() helper functions */
1337 /* The picture table in ABFS does not necessarily lists the pictures
1338 in the order they are stored in memory, but when looking for a hole
1339 in memory to store a new picture we need a list of used memory blocks
1340 in memory order. So we build one here. */
1342 ax203_fileinfo_cmp(const void *p1, const void *p2)
1344 const struct ax203_fileinfo *f1 = p1;
1345 const struct ax203_fileinfo *f2 = p2;
1346 return f1->address - f2->address;
1350 ax203_build_used_mem_table(Camera *camera, struct ax203_fileinfo *table)
1352 int i, count, found = 0;
1353 struct ax203_fileinfo fileinfo;
1355 count = ax203_read_filecount (camera);
1356 if (count < 0) return count;
1358 /* The beginning of the memory is used by the CD image and stuff */
1359 fileinfo.address = 0;
1360 switch (camera->pl->frame_version) {
1361 case AX203_FIRMWARE_3_3_x:
1362 case AX203_FIRMWARE_3_4_x:
1363 fileinfo.size = camera->pl->fs_start + AX203_PICTURE_OFFSET;
1365 case AX206_FIRMWARE_3_5_x:
1366 fileinfo.size = camera->pl->fs_start + AX206_PICTURE_OFFSET;
1368 case AX3003_FIRMWARE_3_5_x:
1369 fileinfo.size = camera->pl->fs_start + AX3003_PICTURE_OFFSET;
1372 fileinfo.present = 1;
1373 table[found++] = fileinfo;
1375 for (i = 0; i < count; i++) {
1376 CHECK (ax203_read_fileinfo (camera, i, &fileinfo))
1377 if (!fileinfo.present)
1379 table[found++] = fileinfo;
1381 qsort (table, found, sizeof(struct ax203_fileinfo),
1382 ax203_fileinfo_cmp);
1384 /* Add a last memory used region which starts at the end of memory
1385 the size does not matter as this is the last entry. */
1386 switch (camera->pl->frame_version) {
1387 case AX203_FIRMWARE_3_3_x:
1388 case AX203_FIRMWARE_3_4_x:
1389 case AX206_FIRMWARE_3_5_x:
1390 fileinfo.address = camera->pl->mem_size;
1392 case AX3003_FIRMWARE_3_5_x:
1393 fileinfo.address = camera->pl->mem_size - AX3003_BL_SIZE;
1398 fileinfo.present = 1;
1399 table[found++] = fileinfo;
1404 /* Find a free slot in the ABFS table to store the fileinfo */
1406 ax203_find_free_abfs_slot(Camera *camera)
1409 struct ax203_fileinfo fileinfo;
1411 max = ax203_max_filecount (camera);
1412 for (i = 0; i < max; i++) {
1413 CHECK (ax203_read_fileinfo (camera, i, &fileinfo))
1414 if (!fileinfo.present)
1418 gp_log (GP_LOG_ERROR, "ax203", "no free slot in ABFS ??");
1419 return GP_ERROR_NO_SPACE;
1423 ax203_write_raw_file(Camera *camera, int idx, char *buf, int size)
1425 struct ax203_fileinfo fileinfo;
1426 struct ax203_fileinfo used_mem[AX203_ABFS_SIZE / 2];
1427 int i, hole_size, used_mem_count, prev_end, free;
1430 used_mem_count = ax203_build_used_mem_table (camera, used_mem);
1431 if (used_mem_count < 0) return used_mem_count;
1433 /* Try to find a large enough "hole" in the memory */
1434 for (i = 1, free = 0; i < used_mem_count; i++, free += hole_size) {
1435 prev_end = used_mem[i - 1].address + used_mem[i - 1].size;
1436 hole_size = used_mem[i].address - prev_end;
1438 GP_DEBUG ("found a hole at: %08x, of %d bytes "
1439 "(need %d)\n", prev_end, hole_size, size);
1440 if (hole_size >= size) {
1441 /* bingo we have a large enough hole */
1442 fileinfo.address = prev_end;
1443 fileinfo.size = size;
1444 fileinfo.present = 1;
1445 CHECK (ax203_write_fileinfo (camera, idx,
1447 CHECK (ax203_update_filecount (camera))
1448 CHECK (ax203_write_mem (camera, fileinfo.address,
1455 gp_log (GP_LOG_DEBUG, "ax203",
1456 "not enough contineous freespace to add file, "
1457 "defragmenting memory");
1458 CHECK (ax203_defrag_memory (camera))
1462 gp_log (GP_LOG_ERROR, "ax203", "not enough freespace to add file");
1463 return GP_ERROR_NO_SPACE;
1467 ax203_write_file(Camera *camera, int **rgb24)
1469 const int buf_size = camera->pl->width * camera->pl->height;
1471 int size, abfs_slot;
1473 size = ax203_encode_image (camera, rgb24, buf, buf_size);
1474 if (size < 0) return size;
1476 abfs_slot = ax203_find_free_abfs_slot (camera);
1477 if (abfs_slot < 0) return abfs_slot;
1479 CHECK (ax203_write_raw_file (camera, abfs_slot, buf, size))
1485 ax203_delete_file(Camera *camera, int idx)
1487 struct ax203_fileinfo fileinfo;
1489 CHECK (ax203_read_fileinfo (camera, idx, &fileinfo))
1491 if (!fileinfo.present) {
1492 gp_log (GP_LOG_ERROR, "ax203",
1493 "trying to delete an already deleted file");
1494 return GP_ERROR_BAD_PARAMETERS;
1497 fileinfo.present = 0;
1498 CHECK (ax203_write_fileinfo (camera, idx, &fileinfo))
1499 CHECK (ax203_update_filecount (camera))
1505 ax203_delete_all(Camera *camera)
1507 char buf[AX203_ABFS_SIZE];
1508 int size, file0_offset = 0;
1510 switch (camera->pl->frame_version) {
1511 case AX203_FIRMWARE_3_3_x:
1512 case AX203_FIRMWARE_3_4_x:
1513 file0_offset = AX203_ABFS_FILE_OFFSET (0);
1515 case AX206_FIRMWARE_3_5_x:
1516 file0_offset = AX206_ABFS_FILE_OFFSET (0);
1518 case AX3003_FIRMWARE_3_5_x:
1519 file0_offset = AX3003_ABFS_FILE_OFFSET (0);
1523 size = AX203_ABFS_SIZE - file0_offset;
1524 memset(buf, 0, size);
1525 CHECK (ax203_write_mem (camera, camera->pl->fs_start + file0_offset,
1527 CHECK (ax203_update_filecount (camera))
1532 /* bss = block start sector */
1534 ax203_commit_block_4k(Camera *camera, int bss)
1536 int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1539 for (i = 0; i < block_sector_size; i++) {
1540 if (!camera->pl->sector_dirty[bss + i])
1543 CHECK (ax203_erase4k_sector (camera, bss + i))
1544 CHECK (ax203_write_sector (camera, bss + i,
1547 SPI_EEPROM_SECTOR_SIZE))
1548 camera->pl->sector_dirty[bss + i] = 0;
1554 ax203_commit_block_64k(Camera *camera, int bss)
1556 int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1559 /* Make sure we have read the entire block before erasing it !! */
1560 for (i = 0; i < block_sector_size; i++)
1561 CHECK (ax203_check_sector_present (camera, bss + i))
1563 /* Erase the block */
1564 CHECK (ax203_erase64k_sector (camera, bss))
1566 /* And re-program all sectors in the block */
1567 for (i = 0; i < block_sector_size; i++) {
1568 CHECK (ax203_write_sector (camera, bss + i,
1571 SPI_EEPROM_SECTOR_SIZE))
1572 camera->pl->sector_dirty[bss + i] = 0;
1578 ax203_commit_block_ax3003(Camera *camera, int bss)
1580 int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1581 int i, address = bss * SPI_EEPROM_SECTOR_SIZE;
1583 /* Make sure we have read the entire block before erasing it !! */
1584 for (i = 0; i < block_sector_size; i++)
1585 CHECK (ax203_check_sector_present (camera, bss + i))
1587 if (!camera->pl->block_protection_removed) {
1588 CHECK (ax203_eeprom_write_enable (camera))
1589 CHECK (ax203_eeprom_clear_block_protection (camera))
1590 CHECK (ax203_eeprom_wait_ready (camera))
1591 camera->pl->block_protection_removed = 1;
1594 /* Erase the block */
1595 CHECK (ax203_erase64k_sector (camera, bss))
1597 /* And program the block in one large 64k page write, the ax3003
1598 probably emulates this in firmware, to avoid usb bus overhead. */
1599 CHECK (ax203_eeprom_write_enable (camera))
1600 CHECK (ax203_eeprom_program_page (camera, address,
1601 camera->pl->mem + address,
1602 SPI_EEPROM_BLOCK_SIZE))
1603 CHECK (ax203_eeprom_wait_ready (camera))
1605 for (i = 0; i < block_sector_size; i++)
1606 camera->pl->sector_dirty[bss + i] = 0;
1612 ax203_commit(Camera *camera)
1615 int mem_sector_size = camera->pl->mem_size / SPI_EEPROM_SECTOR_SIZE;
1616 int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1619 /* We first check each 64k block for dirty sectors. If the block
1620 contains dirty sectors, decide wether to use 4k sector erase
1621 commands (if the eeprom supports it), or to erase and reprogram
1623 for (i = 0; i < mem_sector_size; i += block_sector_size) {
1625 for (j = 0; j < block_sector_size; j++)
1626 if (camera->pl->sector_dirty[i + j])
1629 /* If we have no dirty sectors in this block continue */
1633 if (camera->pl->frame_version == AX3003_FIRMWARE_3_5_x)
1634 CHECK (ax203_commit_block_ax3003 (camera, i))
1635 /* There are 16 4k sectors per 64k block, when we need to
1636 program 12 or more sectors, programming the entire block
1638 else if (dirty_sectors < 12 && camera->pl->has_4k_sectors)
1639 CHECK (ax203_commit_block_4k (camera, i))
1641 CHECK (ax203_commit_block_64k (camera, i))
1647 ax203_init(Camera *camera)
1649 GP_DEBUG ("ax203_init called");
1651 camera->pl->mem = malloc(camera->pl->mem_size);
1652 if (!camera->pl->mem)
1653 return GP_ERROR_NO_MEMORY;
1655 CHECK (ax203_read_parameter_block (camera))
1657 if ((camera->pl->width % 4) || (camera->pl->height % 4)) {
1658 gp_log (GP_LOG_ERROR, "ax203",
1659 "lcd width and height must be a multiple of 4");
1667 ax203_exit(Camera *camera)
1669 if (camera->pl->jdec) {
1670 tinyjpeg_free (camera->pl->jdec);
1671 camera->pl->jdec = NULL;
1673 free (camera->pl->mem);
1674 camera->pl->mem = NULL;
1678 ax203_open_device(Camera *camera)
1684 CHECK (ax203_get_version (camera, buf))
1685 GP_DEBUG ("Appotech ax203 picframe firmware version: %s", buf);
1687 /* Not sure if this is necessary, but the windows software does it */
1688 CHECK (ax203_eeprom_release_from_deep_powerdown (camera))
1689 CHECK (ax203_eeprom_device_identification (camera, buf))
1690 id = le32atoh((uint8_t *)buf);
1691 for (i = 0; ax203_eeprom_info[i].name; i++) {
1692 if (ax203_eeprom_info[i].id == id)
1696 if (!ax203_eeprom_info[i].name) {
1697 gp_log (GP_LOG_ERROR, "ax203", "unknown eeprom id: %08x", id);
1698 return GP_ERROR_MODEL_NOT_FOUND;
1701 camera->pl->mem_size = ax203_eeprom_info[i].mem_size;
1702 camera->pl->has_4k_sectors = ax203_eeprom_info[i].has_4k_sectors;
1703 GP_DEBUG ("%s EEPROM found, capacity: %d, has 4k sectors: %d",
1704 ax203_eeprom_info[i].name, camera->pl->mem_size,
1705 camera->pl->has_4k_sectors);
1707 return ax203_init (camera);
1711 ax203_open_dump(Camera *camera, const char *dump)
1713 camera->pl->mem_dump = fopen(dump, "r+");
1714 if (!camera->pl->mem_dump) {
1715 gp_log (GP_LOG_ERROR, "ax203", "opening memdump file: %s: %s",
1716 dump, strerror(errno));
1717 return GP_ERROR_IO_INIT;
1720 if (fseek (camera->pl->mem_dump, 0, SEEK_END)) {
1721 gp_log (GP_LOG_ERROR, "ax203", "seeking memdump file: %s: %s",
1722 dump, strerror(errno));
1723 return GP_ERROR_IO_INIT;
1725 camera->pl->mem_size = ftell (camera->pl->mem_dump);
1726 camera->pl->has_4k_sectors = 1;
1728 return ax203_init (camera);
1731 void ax203_close(Camera *camera)
1733 ax203_exit (camera);
1734 if (camera->pl->mem_dump) {
1735 fclose (camera->pl->mem_dump);
1736 camera->pl->mem_dump = NULL;
1741 ax203_get_mem_size(Camera *camera)
1743 return camera->pl->mem_size;
1747 ax203_get_free_mem_size(Camera *camera)
1749 struct ax203_fileinfo used_mem[AX203_ABFS_SIZE / 2];
1750 int i, used_mem_count, prev_end, free = 0;
1752 used_mem_count = ax203_build_used_mem_table (camera, used_mem);
1753 if (used_mem_count < 0) return used_mem_count;
1755 /* Add the size of all holes in memory together */
1756 for (i = 1; i < used_mem_count; i++) {
1757 prev_end = used_mem[i - 1].address + used_mem[i - 1].size;
1758 free += used_mem[i].address - prev_end;