#include #include #include #include #include static struct ftdi_context* ft; static int do_spi_cmd(const uint8_t *wpart, uint32_t wlen, uint8_t* rpart, uint32_t rlen) { int stat; static const uint8_t start[2]={0x90,0x00}; //printf(" start\n"); stat = ftdi_write_data(ft, start, sizeof start); if (stat < 0) return stat; uint8_t wbuf[2]; uint8_t rbuf[1]; for (uint32_t i = 0; i < wlen; ++i) { wbuf[0] = 0x92; wbuf[1] = wpart[i]; //printf(" write %02x\n", wpart[i]); stat = ftdi_write_data(ft, wbuf, sizeof wbuf); if (stat < 0) return stat; stat = ftdi_read_data (ft, rbuf, sizeof rbuf); if (stat < 0) return stat; //printf(" wres %02x\n", rbuf[0]); } for (uint32_t i = 0; i < rlen; ++i) { wbuf[0] = 0x92; wbuf[1] = 0xff; stat = ftdi_write_data(ft, wbuf, sizeof wbuf); if (stat < 0) return stat; stat = ftdi_read_data (ft, rbuf, sizeof rbuf); if (stat < 0) return stat; rpart[i] = rbuf[0]; //printf(" read %02x\n", rpart[i]); } static const uint8_t stop [2]={0x91,0x00}; //printf(" stop\n"); stat = ftdi_write_data(ft, stop, sizeof stop); if (stat < 0) return stat; return stat; } int main(int argc, char* argv[]) { int stat, rv = 0; if (!(ft = ftdi_new())) { printf("can't init ftdi\n"); return 1; } ftdi_set_interface(ft, INTERFACE_ANY); stat = ftdi_usb_open(ft, 0x0403, 0x7fd0); if(stat<0){printf("ftdi_usb_open failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} static const char* typtbl[] = {"am","bm","2232c","r","2232h","4232h","232h","230x"}; printf("chiptype=%d (%s), itf=%d index=%d in ep=%d out ep=%d\n", ft->type, typtbl[ft->type], ft->interface, ft->index, ft->in_ep, ft->out_ep); ftdi_set_latency_timer(ft, 2); // ??? printf("get status\n"); const uint8_t wdata[5] = {0xfd,0x00,0x01,0x02,0xfe}; stat = ftdi_write_data(ft, wdata, sizeof wdata); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} uint8_t rdata[4]={0}; stat = ftdi_read_data(ft, rdata, sizeof rdata); if (stat<0){printf("ftdi_read_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("got rdata: %02x %02x %02x %02x\n", rdata[0], rdata[1], rdata[2], rdata[3]); stat = ftdi_write_data(ft, wdata, sizeof wdata); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} stat = ftdi_read_data(ft, rdata, sizeof rdata); if (stat<0){printf("ftdi_read_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("got rdata: %02x %02x %02x %02x\n", rdata[0], rdata[1], rdata[2], rdata[3]); //const uint8_t rstcapt[]={0xf0,0x00}; uint8_t gobloader = 0x94; printf("go to bootloader (%02x)\n", gobloader); stat = ftdi_write_data(ft, &gobloader, 1); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("get status\n"); stat = ftdi_write_data(ft, wdata, sizeof wdata); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} stat = ftdi_read_data(ft, rdata, sizeof rdata); if (stat<0){printf("ftdi_read_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("got rdata: %02x %02x %02x %02x\n", rdata[0], rdata[1], rdata[2], rdata[3]); stat = ftdi_write_data(ft, wdata, sizeof wdata); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} stat = ftdi_read_data(ft, rdata, sizeof rdata); if (stat<0){printf("ftdi_read_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("got rdata: %02x %02x %02x %02x\n", rdata[0], rdata[1], rdata[2], rdata[3]); const uint8_t unlockseq[27]={0xf1,0x62, 0xa7, 0x7e,0}; printf("send magic sequence\n"); stat = ftdi_write_data(ft, unlockseq, sizeof unlockseq); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("get status\n"); stat = ftdi_write_data(ft, wdata, sizeof wdata); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} stat = ftdi_read_data(ft, rdata, sizeof rdata); if (stat<0){printf("ftdi_read_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("got rdata: %02x %02x %02x %02x\n", rdata[0], rdata[1], rdata[2], rdata[3]); stat = ftdi_write_data(ft, wdata, sizeof wdata); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} stat = ftdi_read_data(ft, rdata, sizeof rdata); if (stat<0){printf("ftdi_read_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("got rdata: %02x %02x %02x %02x\n", rdata[0], rdata[1], rdata[2], rdata[3]); printf("do spiflash id\n"); uint8_t spiidwr[] = {0x9f}; uint8_t spiidrd[2]; do_spi_cmd(spiidwr, sizeof spiidwr, spiidrd, sizeof spiidrd); printf("spiflash id=%02x %02x\n", spiidrd[0], spiidrd[1]); printf("do spiflash stat\n"); uint8_t spistatwr[] = {0xd7}; uint8_t spistatrd[1]; do_spi_cmd(spistatwr, sizeof spistatwr, spistatrd, sizeof spistatrd); printf("spiflash stat=%02x\n", spistatrd[0]); /*gobloader = 0x93; printf("go to application (%02x)\n", gobloader); stat = ftdi_write_data(ft, &gobloader, 1); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;}*/ printf("get status\n"); stat = ftdi_write_data(ft, wdata, sizeof wdata); if(stat<0){printf("ftdi_write_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} stat = ftdi_read_data(ft, rdata, sizeof rdata); if (stat<0){printf("ftdi_read_data failed: %d %s\n",stat,ftdi_get_error_string(ft));rv=1;goto finish;} printf("got rdata: %02x %02x %02x %02x\n", rdata[0], rdata[1], rdata[2], rdata[3]); // bitstream: 0x000000..0x019fff // userdata1: 0x01a000..0x01ffff // multiboot: 0x020000..0x039fff // userdata2: 0x03a000..0x03ffff // 2Mbit in size printf("spiflash dump!\n"); const uint8_t spifastread0[]={0x0b,0x00,0x00,0x00}; #define nbytes 0x040000 static uint8_t spifastreadbuf[1+nbytes]; // data back has an extra "don't care" bit... do_spi_cmd(spifastread0, sizeof spifastread0, spifastreadbuf, sizeof spifastreadbuf); FILE* f = fopen("spiflash.bin", "wb+"); fwrite(&spifastreadbuf[1], 1, nbytes, f); #undef nbytes fclose(f); /* * W f1 01 04 00 00 00 90 d0 03 90 d0 03 e8 6e f3 00 00 f0 0f 0f 81 4b 32 01 00 * set settings (spurious?) * [ 0]: normal * [1:2]: clock freq 0004: 25 MHz * [3:4]: trigger PW scale: no scale (0) * [5:7]: 90 d0 03: memsetting 1: 250000*mem usage * [8:a]: 90 d0 03: memsetting 2 * [b:d]: e8 6e f3: MS1*(1-pre_trigger_samples) * [ e]: fixed 00? * [ f]: 00: no trigger * [ 10]: fixed f0? * [ 11]: fixed 0f? * [ 12]: 0f: capture mode * [13:14]: voltage: 81 4b: 3v3 * [ 15]: fixed 32? * [ 16]: !abort (0x01) * [ 17]: abort (0x00) * ReadEE 0x20 -> 0x8888 * ??? location * W f0 00 * capture state reset? * W fd 00 01 02 fe * status * R 09 09 09 09 || 22 22 22 22 * retval: uninited(?) || application * W 94 * reset to bootloader * ~ * ReadEE 0x12 -> 0xa762 * ReadEE 0x13 -> 0x037e * read magic 24bit code * W f1 62 a7 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * bootloader: enable device(?) * W fd 00 01 02 fe * R 01 01 01 01 * status -> bootloader * W fd 00 01 02 fe * R 01 01 01 01 * status -> bootloader (spurious double?) * 93 * reset to application * ~ * W fd 00 01 02 fe * R 22 22 22 22 * status -> application * ~ * W f1 01 04 00 00 00 90 d0 03 90 d0 03 e8 6e f3 00 00 f0 0f 0f 81 4b 32 01 00 * set settings (same as in begin) * W f0 00 * capture state reset? * W fd 00 01 02 fe * R 22 22 22 22 * status -> application * W f1 01 04 00 00 00 90 d0 03 90 d0 03 e8 6e f3 00 00 f0 0f 0f 81 4b 32 01 00 * W f1 01 04 00 00 00 90 d0 03 90 d0 03 90 6e f3 00 00 f0 0f 0f 81 4b 32 01 00 * ^^ * set settings * W fd 00 01 02 fe * R 22 22 22 22 * status -> application * W f0 00 * capture state reset? * W f0 01 * start capture/wait for trigger * R 11 00 00 * "trig instant" * R dd * status byte: complete * W f0 00 * capture state reset? * W f0 06 * read acquired data * R * W f0 00 * capture state reset? * W f1 01 04 00 00 00 90 d0 03 90 d0 03 e8 6e f3 00 00 f0 0f 0f 81 4b 32 01 00 * set settings * W fd 00 01 02 fe * R 22 22 22 22 * status -> application */ finish: ftdi_usb_close(ft); ftdi_free(ft); return rv; }