-
Notifications
You must be signed in to change notification settings - Fork 3
/
BoardDriver.sbp
295 lines (254 loc) · 9.14 KB
/
BoardDriver.sbp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
' デバイスドライバ
'--------------------------------- MCP23S17 AREA ----------------------------------------------
#include"MCP23017_Lib.sbp"
Const MCP_CONTROLBYTE_WRITE = &H40
Const MCP_CONTROLBYTE_READ = &H41
'dir: 1 = input 0 = output
Sub MCP_SetPort(dir As Word, value As Word)
Dim spi_out_buf[3] As Byte
SPI_CS(SPI_CS_LOW)
spi_out_buf[0] = MCP_CONTROLBYTE_WRITE
spi_out_buf[1] = MCP23017_IODIRA
spi_out_buf[2] = dir and &H00FF
spi_out_buf[3] = dir>>8
MakeSendData(spi_out_buf, 4)
SPI_CS(SPI_CS_HIGH)
SPI_CS(SPI_CS_LOW)
spi_out_buf[0] = MCP_CONTROLBYTE_WRITE
spi_out_buf[1] = MCP23017_GPIOA
spi_out_buf[2] = value and &H00FF
spi_out_buf[3] = value>>8
MakeSendData(spi_out_buf, 4)
SPI_CS(SPI_CS_HIGH)
End Sub
Sub MCP_WriteRegister(reg As Byte, value As Byte)
Dim spi_out_buf[2] As Byte
SPI_CS(SPI_CS_LOW)
spi_out_buf[0] = MCP_CONTROLBYTE_WRITE
spi_out_buf[1] = reg
spi_out_buf[2] = value' and &H00FF
MakeSendData(spi_out_buf, 3)
SPI_CS(SPI_CS_HIGH)
End Sub
Sub MCP_ReadPortAB()
Dim spi_out_buf[2] As Byte
SPI_CS(SPI_CS_LOW)
spi_out_buf[0] = MCP_CONTROLBYTE_READ
spi_out_buf[1] = MCP23017_GPIOA
MakeSendData(spi_out_buf, 2)
RequestData(2)
SPI_CS(SPI_CS_HIGH)
End Sub
Sub MCP_ReadRegister(reg As Byte)
Dim spi_out_buf[2] As Byte
SPI_CS(SPI_CS_LOW)
spi_out_buf[0] = MCP_CONTROLBYTE_READ
spi_out_buf[1] = reg
MakeSendData(spi_out_buf, 2)
RequestData(1)
SPI_CS(SPI_CS_HIGH)
End Sub
'------------------------------ SPI AREA -------------------------------------------------
'バッファためる系
Sub InitSPI()
/* Setting device by MPSSE command
* [85]LoopBackDisable
* [97]Disable adaptive clocking
* [8c]Enable 3 Phase Data Clocking
* [8A]Disables the clk divide by 5 to allow for a 60MHz master clock
* [86]Set TCK Clock [0002]->10MHz
*/
' memcpy(outbuf+c, ex"\x85\x97\x8c\x8A\x86\x02\x00", 7) : c+ = 7 '10MHz NormalSpeed For MaskROM
' memcpy(outbuf+c, ex"\x85\x97\x8c\x8A\x86\x03\x00", 7) : c+ = 7 '7.5MHz SlowSpeed For FlashCart
' memcpy(outbuf+c, ex"\x85\x97\x8c\x8A\x86\x01\x00", 7) : c+ = 7 '15MHz OverSpeed
memcpy(outbuf+c, ex"\x85\x97\x8c\x8A\x86\x00\x00", 7) : c+ = 7 '30MHz OverSpeed
SPI_CS(1)
End Sub
Const PORT_SCLK = &H01
Const PORT_DO = &H02
Const PORT_DI = &H04
Const PORT_ALERT = &H20 'ADBUS5
Const PORT_THERM = &H80 'ADBUS7
Const MSB_FALLING_EDGE_CLOCK_BYTE_OUT = &H11
Const MSB_RISING_EDGE_CLOCK_BIT_IN = &H22
Const MSB_RISING_EDGE_CLOCK_BYTE_IN = &H20
Const SET_DATA_BITS_LOW_BYTE = &H80
Const READ_DATA_BITS_LOW_BYTE = &H81
Const SPI_ADBUS_DIR = &HFB '0b11 11 10 11
Const SPI_CS_LOW = 0
Const SPI_CS_HIGH = 8
Sub SPI_CS(bHL As Byte)
memcpy(outbuf+c, ex"\x80\x00\xFB", 3)
if bHL = 0 then
FTDI_GPIOA = SPI_CS_LOW or (FTDI_GPIOA And &HF0)
else
FTDI_GPIOA = SPI_CS_HIGH or (FTDI_GPIOA And &HF0)
endif
outbuf[c+1] = FTDI_GPIOA
c+ = 3
End Sub
Sub MakeSendData(data As BytePtr, length As Word)
if length = 0 then ExitFunction
length--
outbuf[c+0] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT
outbuf[c+1] = length and &H00FF
outbuf[c+2] = length>>8
memcpy(outbuf+c+3, data, length+1)
c+ = 3+length+1
End Sub
Sub RequestData(length As Word)
length--
outbuf[c+0] = MSB_RISING_EDGE_CLOCK_BYTE_IN
outbuf[c+1] = (length and &H00FF) As Byte
outbuf[c+2] = (length>>8) As Byte
c+ = 3
End Sub
'---------------------------------------- FT232HL AREA -------------------------------------------------
Function SetupFTDI_Device(hFT As FT_HANDLE) As Long
'セットアップ
Dim ftStatus As Long, bufsize As DWord, buf As BytePtr
ftStatus = ftStatus or FT_GetQueueStatus(hFT, bufsize) ' Get the number of bytes in the FT2232H receive buffer
buf = calloc(bufsize)
if (ftStatus = FT_OK) And (bufsize > 0) then _
FT_Read(hFT, buf, bufsize, dwAB) 'Read out the data from FT2232H receive buffer
free(buf)
' ftStatus = ftStatus or FT_SetFlowControl(hFT, FT_FLOW_DTR_DSR or FT_FLOW_RTS_CTS, 0, 0)
ftStatus = ftStatus or FT_SetUSBParameters(hFT, USB_BUFFER_SIZE, USB_BUFFER_SIZE) 'Set USB request transfer size
ftStatus = ftStatus or FT_SetChars(hFT, FALSE, 0, FALSE, 0) 'Disable event and error characters
ftStatus = ftStatus or FT_SetTimeouts(hFT, 0, 5000) 'Sets the read and write timeouts in milliseconds for the FT2232H
ftStatus = ftStatus or FT_SetLatencyTimer(hFT, FT_USB_LATENCY) 'Set the latency timer '小さくしすぎると他のUSB機器に影響
ftStatus = ftStatus or FT_SetBitMode(hFT, &H0, FT_BITMODE_RESET) 'Reset controller
ftStatus = ftStatus or FT_SetBitMode(hFT, &H0, FT_BITMODE_MPSSE) 'Enable MPSSE mode
Sleep(10)
if ftStatus <> 0 then
Print "fail on initialize FT2232H device! "
SetupFTDI_Device = FALSE
ExitFunction
endif
SetupFTDI_Device = TRUE
End Function
Function FTDI_SendCommand() As Long
FTDI_SendCommand = FT_Write(hFT, outbuf, c, dwAB)
c = 0
End Function
Function ListUpFTDI_Devices() As Long
ListUpFTDI_Devices = -1
Dim devCount As Long
if FT_GetNumDevices(devCount, NULL, FT_LIST_BY_NUMBER_ONLY) <> FT_OK then Print "FTDI Driver Error." : ExitFunction
if devCount = 0 then Print "FTDI Device not found.":ExitFunction
printf(ex"Found FTDI Devices : %d\n", devCount)
Dim i As Long
Dim serial[64] As Byte, desc[64] As Byte
For i = 0 To devCount-1
if FT_ListDevices(i, serial, FT_LIST_BY_INDEX or FT_OPEN_BY_SERIAL_NUMBER) <> FT_OK then continue
if FT_ListDevices(i, desc , FT_LIST_BY_INDEX or FT_OPEN_BY_DESCRIPTION) <> FT_OK then continue
printf(ex" [%02d]%s - %s\n", i, serial, desc)
Next i
Print
ListUpFTDI_Devices = devCount
End Function
Sub FT_WAIT(val As Word)
outbuf[c] = &H9c : c++
outbuf[c] = val As Byte : c++
outbuf[c] = (val>>8) As Byte : c++
End Sub
Function FT_InitRomAccess(hFT As HANDLE) As BOOL
' if FT_SetBitMode(hFT, &H0, FT_BITMODE_MPSSE) <> FT_OK then ExitFunction
if SetupFTDI_Device(hFT) <> TRUE then ExitFunction
InitSPI()
FTDI_SendCommand()
FT_InitRomAccess = TRUE
End Function
' ============= JOYBUS ==============
' idea by http://www.qwertymodo.com/hardware-projects/n64/n64-controller
Function FT_InitJoybusAccessEEPROM(hFT As HANDLE) As BOOL
if FT_SetBitMode(hFT, &H0, FT_BITMODE_RESET) <> FT_OK then ExitFunction
' if FT_SetBaudRate(hFT, 4500000) <> FT_OK then ExitFunction/*for 7.5MHz*/
if FT_SetBaudRate(hFT, 1150000) <> FT_OK then ExitFunction /* for 1.875MHz */
if FT_SetChars(hFT, FALSE, 0, FALSE, 0) <> FT_OK then ExitFunction
if FT_SetTimeouts(hFT, 300, 300) <> FT_OK then ExitFunction
FT_Purge(hFT, FT_PURGE_TX or FT_PURGE_RX)
FT_InitJoybusAccessEEPROM = TRUE
End Function
Function FT_InitJoybusAccessController(hFT As HANDLE) As BOOL
if FT_SetBitMode(hFT, &H0, FT_BITMODE_RESET) <> FT_OK then ExitFunction
if FT_SetBaudRate(hFT, 1250000) <> FT_OK then ExitFunction
if FT_SetChars(hFT, FALSE, 0, FALSE, 0) <> FT_OK then ExitFunction
if FT_SetTimeouts(hFT, 300, 300) <> FT_OK then ExitFunction
FT_InitJoybusAccessController = TRUE
End Function
/*
Function FT_JoybusDecode2Bit(in As Byte, ByRef err As DWord) As DWord
Dim out As Byte
if (in And &HF0) = &HF0 then
FT_JoybusDecode2Bit = 1
else if (in And &HF0) = &H00 then
else
err++
endif
if (in And &H0F) = &H0E then
FT_JoybusDecode2Bit or = 2
else if (in And &H0F) = &H08 then
else
err++
endif
End Function
*/
Function FT_JoybusDecode2Bit(in As Byte, ByRef err As DWord) As DWord
Dim out As Byte
' if (in And &HF0) = &HE0 then
' if (in And &H60) then ' 寛容
if (in And &HF0 Or &H20) = &HE0 then
FT_JoybusDecode2Bit = 1
else if (in And &HF0) = &H00 then
else
err++
endif
if ((in And &H0F Or &H01) = &H0F) then
' if ((in And &H0F) = &H0F) then
FT_JoybusDecode2Bit or = 2
else if (in And &H0F) = &H08 then
else
err++
endif
if err>0 And err<2 then printf(ex"JOYBUS LOGIC: first err %02X\n", in As Byte)
End Function
Function FT_JoybusEncode2Bit(in As Byte) As Byte
Select Case (in And 3)
Case 0
FT_JoybusEncode2Bit = &H08
Case 1
FT_JoybusEncode2Bit = &HE8
Case 2
FT_JoybusEncode2Bit = &H0F
Case 3
FT_JoybusEncode2Bit = &HEF
End Select
End Function
function FT_JoybusDecode(input As BytePtr, inputSize As DWord, output As BytePtr, outputSize As DWord) As BOOL
Dim i As DWord, loop_num As DWord, err As DWord
' Dump(input, inputSize)
loop_num = inputSize / 4
if outputSize < loop_num then loop_num = outputSize
for i = 0 to loop_num-1
output[i] = FT_JoybusDecode2Bit(input[i*4+0], err)<<6 _
or FT_JoybusDecode2Bit(input[i*4+1], err)<<4 _
or FT_JoybusDecode2Bit(input[i*4+2], err)<<2 _
or FT_JoybusDecode2Bit(input[i*4+3], err)
next i
if err then ExitFunction
FT_JoybusDecode = TRUE
End Function
function FT_JoybusEncode(input As BytePtr, inputSize As DWord, ByRef output As BufferClass) As BOOL
Dim i As DWord, buf[4] As Byte
output.alloc(inputSize*4 + 1)
for i = 0 To inputSize-1
buf[0] = FT_JoybusEncode2Bit(input[i]>>6)
buf[1] = FT_JoybusEncode2Bit(input[i]>>4)
buf[2] = FT_JoybusEncode2Bit(input[i]>>2)
buf[3] = FT_JoybusEncode2Bit(input[i])
output.cat(buf, 4)
Next i
output.cat(ex"\x00", 1) 'STOP BIT
FT_JoybusEncode = TRUE
End Function