sq50-re/ftdidrv.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;
}