OSDN Git Service

FTDI + BSL mingw
[stock/stock.osdn.git] / BSL / BSL_IO_FTDI.h
1 // I/O HAL for BSL (FTDI)
2 // Copyright (C) 2012, 2013, 2014, 2016 Pawel Jewstafjew
3
4 #include "BSL_IO.h"
5 #include <assert.h>
6
7 // I/O HAL for BSL
8 class BSL_IO_FTDI final : public BSL_IO
9 {
10 private:
11    FTDI & ftdi;
12    bool bitbang_enabled; // trace bitbang mode state
13
14 public:
15    BSL_IO_FTDI(FTDI & ftdi) : ftdi(ftdi), bitbang_enabled(false) {}
16
17    bool write(const uint8_t * data, unsigned len) override {
18       return (ftdi.write(data, len) == (int)len);
19    }
20
21 #ifdef __linux__
22    bool read(uint8_t * data, unsigned len) override {
23       unsigned index = 0;
24       unsigned sleep = 0;
25       while(index < len) {
26          unsigned left = len - index;
27          int res = ftdi.read(&data[index], left);
28          if (res < 0)
29             return false;
30          if (res == 0) {
31             if (sleep > 300)
32                return false;
33             usleep(1000);
34             ++sleep;
35             continue;
36          }
37          index += res;
38       }
39       return true;
40    }
41 #else
42    bool read(uint8_t * data, unsigned len) override {
43       int res = ftdi.read(data, len);
44       return (res == (int)len);
45    }
46 #endif
47
48    void flush() override {
49 #ifdef __linux__
50       uint8_t ch;
51       while(ftdi.read(&ch, 1) > 0) {}
52 #else
53       ftdi.purge(FT_PURGE_RX);
54 #endif
55    }
56
57    void set_baud_rate(unsigned baud_rate) override {
58 #ifdef __linux__
59       if (bitbang_enabled)
60          baud_rate /= 4; // adjust baud_rate to match strange libftdi behaviour
61 #endif
62
63       assert(ftdi.set_baud_rate(baud_rate));
64       // 8 data bits, Even parity bit, 1 stop bit
65       assert(ftdi.set_serial(8, 'E', 1));
66       assert(ftdi.set_flow_control_off());
67    }
68
69 #ifdef BSL_nDTR_RTS
70 // USB2, SDP
71 // RESET# = not DTR
72 // TEST = RTS
73 // TCK = not RTS
74    bool set_resetn(bool v) override {
75       return ftdi.set_dtr(v ? 0 : 1);
76    }
77    bool set_test(bool v) override {
78       // TCK = not TEST -> RTS = TEST
79       return ftdi.set_rts(v ? 1 : 0);
80    }
81 #endif
82
83 #ifdef BSL_nDTR_nRTS
84 // RESET# = not DTR
85 // TEST = not RTS
86    bool set_resetn(bool v) override {
87       return ftdi.set_dtr(v ? 0 : 1);
88    }
89    bool set_test(bool v) override {
90       return ftdi.set_rts(v ? 0 : 1);
91    }
92 #endif
93
94 #ifdef BSL_CBUS1_RTS
95 // RESET# = CBUS1
96 // TEST = RTS
97 // TCK = not RTS
98    bool set_resetn(bool v) override {
99       bitbang_enabled = true;
100       // ftdi.set_bit_mode(0x20, FT_BITMODE_CBUS_BITBANG); // RSTn = 0
101       // ftdi.set_bit_mode(0x22, FT_BITMODE_CBUS_BITBANG); // RSTn = 1
102       return ftdi.set_bit_mode((v ? 0x22 : 0x20), FT_BITMODE_CBUS_BITBANG) == FT_OK;
103    }
104    bool set_test(bool v) override {
105       // TCK = not TEST -> RTS = TEST
106       return ftdi.set_rts(v ? 1 : 0);
107    }
108 #endif
109
110 };