257 lines
8.7 KiB
C
257 lines
8.7 KiB
C
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include <ftdi.h>
|
|
|
|
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 // number of bytes * 5?
|
|
* [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 <lots and lots of data, 500000 bytes>
|
|
* 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;
|
|
}
|
|
|