Rev 1134 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | // Z-Controller by KOE |
2 | // Only SD-card |
||
3 | #include "std.h" |
||
4 | #include "emul.h" |
||
5 | #include "vars.h" |
||
6 | #include "sdcard.h" |
||
7 | #include "zc.h" |
||
1140 | dimkam | 8 | #include "util.h" |
716 | lvd | 9 | |
1140 | dimkam | 10 | typedef ULONG (WINAPI *CH341GetVersion_t)(); // Get the DLL version number and return the version number |
11 | static CH341GetVersion_t CH341GetVersion = nullptr; |
||
12 | typedef ULONG (WINAPI *CH341GetDrvVersion_t)(); // Get the DLL version number and return the version number |
||
13 | static CH341GetDrvVersion_t CH341GetDrvVersion = nullptr; |
||
14 | typedef HANDLE (WINAPI *CH341OpenDevice_t)(ULONG); |
||
15 | static CH341OpenDevice_t CH341OpenDevice = nullptr; |
||
16 | typedef VOID (WINAPI *CH341CloseDevice_t)(ULONG); |
||
17 | static CH341CloseDevice_t CH341CloseDevice = nullptr; |
||
18 | typedef BOOL (WINAPI *CH341StreamSPI4_t)( |
||
19 | ULONG iIndex, // Specify CH341 device serial number |
||
20 | ULONG iChipSelect, // Chip select control, if bit 7 is 0, the chip select control is ignored, if bit 7 is 1, the parameters are valid: Bit 1 and bit 0 are 00/01/10, respectively, select the D0/D1/D2 pin as low level. valid chip select |
||
21 | ULONG iLength, // Number of data bytes to be transmitted |
||
22 | PVOID ioBuffer ); |
||
23 | static CH341StreamSPI4_t CH341StreamSPI4 = nullptr; |
||
24 | typedef BOOL (WINAPI *CH341Set_D5_D0_t)(ULONG,ULONG,ULONG); |
||
25 | static CH341Set_D5_D0_t CH341Set_D5_D0 = nullptr; |
||
26 | typedef PVOID (WINAPI *CH341GetDeviceName_t)(ULONG); |
||
27 | static CH341GetDeviceName_t CH341GetDeviceName = nullptr; |
||
28 | typedef BOOL (WINAPI *CH341SetStream_t)(ULONG,ULONG);// To specify the mode, see Downlink |
||
29 | // Bit 1-bit 0: I2C interface speed /SCL frequency, 00= low speed /20KHz,01= standard /100KHz(default),10= fast /400KHz,11= high speed /750KHz |
||
30 | // Bit 2: SPI I/O number /IO pins, 0= single in/single out (D3 clock /D5 out /D7 in)(default),1= double in/double out (D3 clock /D5 out D4 out /D7 in D6 in) |
||
31 | // Bit 7: Bit order in SPI bytes, 0= low first, 1= high first |
||
32 | // All other reservations must be 0 |
||
33 | static CH341SetStream_t CH341SetStream = nullptr; |
||
34 | |||
35 | static HMODULE spiDll = nullptr; |
||
36 | //static int SpiDllInited = 0; |
||
37 | static HANDLE ch341 = NULL; |
||
38 | |||
716 | lvd | 39 | void TZc::Reset() |
40 | { |
||
752 | DimkaM | 41 | SdCard.Reset(); |
1140 | dimkam | 42 | Cfg = 0; |
752 | DimkaM | 43 | Status = 0; |
44 | RdBuff = 0xff; |
||
716 | lvd | 45 | } |
46 | |||
1140 | dimkam | 47 | void TZc::Open(const char *Name) |
48 | { |
||
49 | if ( strcmp(Name, "<CH341>") != 0 ) |
||
50 | { |
||
51 | // монтирование образа |
||
52 | SdCard.Open(Name); |
||
53 | IsCh341 = 0; |
||
54 | } |
||
55 | else |
||
56 | { |
||
57 | // инициализация ch341 |
||
58 | |||
59 | IsCh341 = 1; |
||
60 | if ( ch341 == NULL ) |
||
61 | { |
||
62 | // ULONG iDevIndex = 0; |
||
63 | if( CH341GetVersion == nullptr ) |
||
64 | { |
||
65 | #ifdef __amd64__ |
||
66 | spiDll = LoadLibrary("CH341DLLA64.DLL"); |
||
67 | #else |
||
68 | spiDll = LoadLibrary("CH341DLL.DLL"); |
||
69 | #endif |
||
70 | if (!spiDll) |
||
71 | { |
||
72 | #ifdef __amd64__ |
||
73 | errmsg("failed to load CH341DLLA64.DLL"); |
||
74 | #else |
||
75 | errmsg("failed to load CH341DLL.DLL"); |
||
76 | #endif |
||
77 | err_win32(); |
||
78 | exit(1); |
||
79 | } |
||
80 | |||
81 | CH341GetVersion = (CH341GetVersion_t)GetProcAddress(spiDll, "CH341GetVersion"); |
||
82 | CH341GetDrvVersion = (CH341GetDrvVersion_t)GetProcAddress(spiDll, "CH341GetDrvVersion"); |
||
83 | CH341OpenDevice = (CH341OpenDevice_t)GetProcAddress(spiDll, "CH341OpenDevice"); |
||
84 | CH341CloseDevice = (CH341CloseDevice_t)GetProcAddress(spiDll, "CH341CloseDevice"); |
||
85 | CH341StreamSPI4 = (CH341StreamSPI4_t)GetProcAddress(spiDll, "CH341StreamSPI4"); |
||
86 | CH341Set_D5_D0 = (CH341Set_D5_D0_t)GetProcAddress(spiDll, "CH341Set_D5_D0"); |
||
87 | CH341GetDeviceName = (CH341GetDeviceName_t)GetProcAddress(spiDll, "CH341GetDeviceName"); |
||
88 | CH341SetStream = (CH341SetStream_t)GetProcAddress(spiDll, "CH341SetStream"); |
||
89 | } |
||
90 | printf("CH341 version: %lu\r\n", CH341GetVersion( )); |
||
91 | |||
92 | char * n = (char*)CH341GetDeviceName(0); |
||
93 | if ( n != 0 )printf("CH341 name: %s\r\n", n); |
||
94 | |||
95 | if ( CH341OpenDevice == 0 ) |
||
96 | { |
||
97 | errmsg("failed to load CH341OpenDevice"); |
||
98 | err_win32(); |
||
99 | exit(1); |
||
100 | } |
||
101 | ch341 = CH341OpenDevice(0); |
||
102 | |||
103 | if ( ch341 == 0 ){ |
||
104 | errmsg("OpenDevice ch341 failed"); |
||
105 | err_win32(); |
||
106 | exit(1); |
||
107 | } |
||
108 | printf("CH341 drv version: %lu\r\n", CH341GetDrvVersion( )); |
||
109 | |||
110 | CH341SetStream(0, 0x80); |
||
111 | CH341Set_D5_D0(0, 0x29, 0x21); |
||
112 | Cfg = 0x01; |
||
113 | |||
114 | CH341Set_D5_D0(0, 0x29, 0x20); |
||
115 | u8 spi_str[20] = "DimkaM"; |
||
116 | CH341StreamSPI4(0, 0x00, sizeof(spi_str), &spi_str); |
||
117 | CH341Set_D5_D0(0, 0x29, 0x21); |
||
118 | } |
||
119 | } |
||
120 | } |
||
121 | |||
122 | void TZc::Close() |
||
123 | { |
||
124 | // закрытия образа |
||
125 | SdCard.Close(); |
||
126 | |||
127 | if ( ch341 != 0 ) |
||
128 | { |
||
129 | // закрытие ch341 |
||
130 | CH341CloseDevice(0); |
||
131 | ch341 = 0; |
||
132 | IsCh341 = 0; |
||
133 | } |
||
134 | } |
||
135 | |||
716 | lvd | 136 | void TZc::Wr(u32 Port, u8 Val) |
137 | { |
||
752 | DimkaM | 138 | switch(Port & 0xFF) |
139 | { |
||
716 | lvd | 140 | case 0x77: // config |
1140 | dimkam | 141 | if ( Cfg != ( Val & 3 ) ) |
142 | { |
||
143 | Cfg = Val & 3; |
||
144 | |||
145 | if ( IsCh341 != 0 ) |
||
146 | { |
||
147 | CH341Set_D5_D0(0, 0x29, ((Cfg>>1) & 0x01)|0x20); |
||
148 | } |
||
149 | } |
||
716 | lvd | 150 | break; |
752 | DimkaM | 151 | |
716 | lvd | 152 | case 0x57: // data |
1140 | dimkam | 153 | if ( IsCh341 == 0 ) |
154 | { |
||
155 | if (!(Cfg & 2)) // SD card selected |
||
156 | { |
||
157 | RdBuff = SdCard.Rd(); |
||
158 | SdCard.Wr(Val); |
||
159 | } |
||
160 | else |
||
161 | RdBuff = 255; |
||
162 | } |
||
163 | else |
||
164 | { |
||
165 | RdBuff = Val; |
||
166 | CH341StreamSPI4(0, 0, 1, &RdBuff); |
||
167 | } |
||
752 | DimkaM | 168 | //printf("\nOUT %02X in %02X",Val,RdBuff); |
716 | lvd | 169 | break; |
752 | DimkaM | 170 | } |
716 | lvd | 171 | } |
172 | |||
173 | u8 TZc::Rd(u32 Port) |
||
174 | { |
||
752 | DimkaM | 175 | switch(Port & 0xFF) |
176 | { |
||
716 | lvd | 177 | case 0x77: // status |
752 | DimkaM | 178 | return Status; // always returns 0 |
716 | lvd | 179 | |
180 | case 0x57: // data |
||
1124 | dimkam | 181 | u8 tmp = RdBuff; |
752 | DimkaM | 182 | |
1140 | dimkam | 183 | if ( IsCh341 == 0 ) |
184 | { |
||
185 | if (!(Cfg & 2)) // SD card selected |
||
186 | { |
||
187 | RdBuff = SdCard.Rd(); |
||
188 | SdCard.Wr(0xff); |
||
189 | } |
||
190 | else |
||
191 | RdBuff = 255; |
||
192 | } |
||
193 | else |
||
194 | { |
||
195 | RdBuff = 0xff; |
||
196 | CH341StreamSPI4(0, 0, 1, &RdBuff); |
||
197 | } |
||
752 | DimkaM | 198 | |
1140 | dimkam | 199 | //printf("\nout FF IN %02X (next %02X)",tmp,RdBuff); |
200 | return tmp; |
||
752 | DimkaM | 201 | } |
202 | |||
203 | return 0xFF; |
||
716 | lvd | 204 | } |
205 | |||
206 | TZc Zc; |