/* Tenx tp6801 picframe memory dump tool * * Copyright (c) 2011 Hans de Goede * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #define READ 0 #define WRITE 1 void tp6801_send_cmd(int fd, int rw, int cmd, int offset, unsigned char *data, int data_size) { int i; sg_io_hdr_t io_hdr; unsigned char sense_buffer[32]; unsigned char cmd_buffer[16]; memset(cmd_buffer, 0, sizeof(cmd_buffer)); cmd_buffer[0] = cmd; cmd_buffer[1] = 0x11; cmd_buffer[2] = 0x31; cmd_buffer[3] = 0x0f; cmd_buffer[4] = 0x30; cmd_buffer[5] = 0x01; /* cmd 0xca hour not bcd! */ cmd_buffer[6] = data_size >> 8; /* cmd 0xca min */ cmd_buffer[7] = data_size & 0xff; /* cmd 0xca sec */ cmd_buffer[8] = (offset >> 16) & 0xff; cmd_buffer[9] = (offset >> 8) & 0xff; cmd_buffer[10] = offset & 0xff; memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); if (rw == READ) io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; else io_hdr.dxfer_direction = SG_DXFER_TO_DEV; io_hdr.interface_id = 'S'; io_hdr.dxfer_len = data_size; io_hdr.dxferp = (unsigned char *)data; io_hdr.cmdp = cmd_buffer; io_hdr.cmd_len = sizeof(cmd_buffer); io_hdr.sbp = sense_buffer; io_hdr.mx_sb_len = sizeof(sense_buffer); io_hdr.timeout = 1000; if(ioctl(fd, SG_IO, &io_hdr) < 0) { printf("error status: %d, errno: %s\n", io_hdr.status, strerror(errno)); exit (1); } } void eeprom_read(int fd, int offset, unsigned char *data, int data_size) { tp6801_send_cmd(fd, READ, 0xc1, offset, data, data_size); } void eeprom_erase_block(int fd, int offset) { tp6801_send_cmd(fd, READ, 0xc6, offset, NULL, 0); } void eeprom_program_page(int fd, int offset, unsigned char *data) { tp6801_send_cmd(fd, WRITE, 0xcb, offset, data, 256); } int main(int argc, char* argv[]) { int i, j, fd; FILE* f; unsigned char data[0x10000]; /* 64k */ fd = open(argv[1], O_RDWR); if(fd < 0) { printf("Cannot open %s: %s\n", argv[1], strerror(errno)); exit(-1); } #if 1 f = fopen("dump.bin", "w"); /* We can read max 32k at a time */ for(i = 0; i < (4160*1024); i += 0x8000) { eeprom_read(fd, i, data, 0x8000); fwrite(data, 1, 0x8000, f); } #else f = fopen("dump.bin", "r"); /* programming is done in blocks of 64k */ /* Note this is only restores the 64k block as that often gets mangled during development */ for(i = 0; i < 0x10000; i += 0x10000) { fread(data, 1, 0x10000, f); eeprom_erase_block(fd, i); for (j = 0; j < 0x10000; j += 256) eeprom_program_page(fd, i + j, data + j); } #endif fclose(f); close(fd); return 0; }