-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathCROSSFIRE.bas
184 lines (142 loc) · 4.32 KB
/
CROSSFIRE.bas
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
array byte deviceIds[6]
array byte deviceNames[100]
array byte deviceParameterCounts[6]
array byte deviceParameterVersionNumbers[6]
array deviceTimeouts[6]
array byte receiveBuffer[64]
array byte transmitBuffer[64]
if init = 0
init = 1
deviceIndex = 0
deviceCount = 0
devicesRefreshTimeout = 0
STATE_DEVICE_LIST = 0
STATE_DEVICE_SETUP = 1
state = STATE_DEVICE_LIST
DEVICE_ID_BROADCAST = 0
DEVICE_ID_RADIO_TX = 0xEA
FRAME_POLL_DEVICES = 0x28
FRAME_DEVICE_INFO = 0x29
POLL_INTERVAL = 100
DEVICE_TIMEOUT = 3000
rem -- including terminating zero
rem -- @todo should be 45 according to spec, change later
kMaxDeviceNameLength = 16
rem -- dictated by the number of device names we could fit, will be raised later
kMaxDeviceCount = 6
end
goto main
previousDevice:
if deviceCount > 0 then deviceIndex = (deviceIndex - 1 + deviceCount) % deviceCount
return
nextDevice:
if deviceCount > 0 then deviceIndex = (deviceIndex + 1) % deviceCount
return
refreshNext:
let command = 0
let count = 0
result = crossfirereceive(count, command, receiveBuffer)
if result = 1
if command = FRAME_DEVICE_INFO
gosub parseDeviceInfo
end
else
gosub pollDevices
end
return
pollDevices:
let time = gettime()
if time > devicesRefreshTimeout
devicesRefreshTimeout = time + POLL_INTERVAL
transmitBuffer[0] = DEVICE_ID_BROADCAST
transmitBuffer[1] = DEVICE_ID_RADIO_TX
result = crossfiresend(FRAME_POLL_DEVICES, 2, transmitBuffer)
end
return
parseDeviceInfo:
rem -- payload format:
rem -- uint8_t Destination node address
rem -- uint8_t Device node address
rem -- char[] Device name ( Null-terminated string )
rem -- uint32_t Serial number
rem -- uint32_t Hardware ID
rem -- uint32_t Firmware ID
rem -- uint8_t Parameters count
rem -- uint8_t Parameter version number
let id = receiveBuffer[1]
let index = 0
let break = 0
while (index < deviceCount) & (id != deviceIds[index])
index += 1
end
rem -- add new device
if index = deviceCount
if deviceCount < kMaxDeviceCount
rem -- device fits
deviceCount += 1
else
rem -- have to evict one of the devices to fit
index -= 1
end
end
rem -- fill device entry
deviceIds[index] = id
let nameOffset = kMaxDeviceNameLength * index
let i = 0
rem -- copy device name string
rem -- @todo remove whitespace or trim the string to allow more devices in one array
while (receiveBuffer[i + 2] != 0) & (i < kMaxDeviceNameLength - 1)
deviceNames[nameOffset + i] = receiveBuffer[i + 2]
i += 1
end
rem -- add terminating zero
deviceNames[nameOffset + i] = 0
deviceParameterCounts[index] = receiveBuffer[i + 15]
deviceParameterVersionNumbers[index] = receiveBuffer[i + 16]
deviceTimeouts[index] = gettime() + DEVICE_TIMEOUT
return
deviceListPage:
if Event = EVT_EXIT_BREAK
goto exit
elseif (Event = EVT_DOWN_FIRST) | (Event = EVT_DOWN_REPT)
gosub nextDevice
elseif (Event = EVT_UP_FIRST) | (Event = EVT_UP_REPT)
gosub previousDevice
elseif Event = EVT_MENU_BREAK
rem # go into device setup for selected device
state = STATE_DEVICE_SETUP
end
drawtext(0, 0, "CROSSFIRE SETUP", INVERS)
if deviceCount > 0
let i = 0
while i < deviceCount
let attr = 0
if i = deviceIndex then attr = INVERS
let nameOffset = kMaxDeviceNameLength * i
drawtext(0, i * 8 + 9, deviceNames[nameOffset], attr)
i += 1
end
else
drawtext(0, 28, "Waiting for devices...")
end
gosub refreshNext
return
deviceSetupPage:
if Event = EVT_EXIT_BREAK
state = STATE_DEVICE_LIST
end
let nameOffset = kMaxDeviceNameLength * deviceIndex
drawtext(0, 0, deviceNames[nameOffset], INVERS)
drawnumber(0, 9, deviceParameterCounts[deviceIndex])
drawnumber(0, 18, deviceParameterVersionNumbers[deviceIndex])
return
main:
drawclear()
if state = STATE_DEVICE_LIST
gosub deviceListPage
elseif state = STATE_DEVICE_SETUP
gosub deviceSetupPage
end
stop
exit:
finish