Skip to content

Commit 0719752

Browse files
committed
Added CMS framework (CRSF Only)
1 parent 61a860f commit 0719752

File tree

8 files changed

+321
-37
lines changed

8 files changed

+321
-37
lines changed

src/SCRIPTS/BF/CMS/common.lua

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
local CONST = {
2+
bitmask = {
3+
firstChunk = 0x80,
4+
lastChunk = 0x40,
5+
batchId = 0x3F,
6+
rleCharValueMask = 0x7F,
7+
rleCharRepeatedMask = 0x80
8+
},
9+
offset = {
10+
meta = 1,
11+
sequence = 2,
12+
data = 3
13+
}
14+
}
15+
16+
local function cRleDecode(buf)
17+
local dest = {}
18+
local rpt = false
19+
local c = nil
20+
for i = 1, #buf do
21+
if (rpt == false) then
22+
c = bit32.band(buf[i], CONST.bitmask.rleCharValueMask)
23+
if (bit32.band(buf[i], CONST.bitmask.rleCharRepeatedMask) > 0) then
24+
rpt = true
25+
else
26+
dest[#dest + 1] = c
27+
end
28+
else
29+
for j = 1, buf[i] do
30+
dest[#dest + 1] = c
31+
end
32+
rpt = false
33+
end
34+
end
35+
return dest
36+
end
37+
38+
screen = {
39+
config = nil,
40+
buffer = {},
41+
data = {},
42+
batchId = 0,
43+
sequence = 0,
44+
reset = function()
45+
screen.buffer = {}
46+
screen.data = {}
47+
screen.batchId = 0
48+
screen.sequence = 0
49+
end,
50+
draw = function()
51+
if (screen.buffer ~= nil and screen.config ~= nil and #screen.buffer > 0) then
52+
lcd.clear()
53+
for char = 1, #screen.buffer do
54+
if (screen.buffer[char] ~= 32) then -- skip spaces to avoid CPU spikes
55+
c = string.char(screen.buffer[char])
56+
row = math.ceil(char / screen.config.cols)
57+
col = char - ((row - 1) * screen.config.cols)
58+
xPos = ((col - 1) * screen.config.pixelsPerChar) + screen.config.xIndent + 1
59+
yPos = ((row - 1) * screen.config.pixelsPerRow) + screen.config.yOffset + 1
60+
lcd.drawText(xPos, yPos, c, screen.config.textSize)
61+
end
62+
end
63+
lcd.drawText(screen.config.refresh.left, screen.config.refresh.top, screen.config.refresh.text, screen.config.textSize)
64+
end
65+
end
66+
}
67+
68+
cms = {
69+
menuOpen = false,
70+
init = function(cmsConfig)
71+
screen.config = assert(cmsConfig, "Resolution not supported")
72+
screen.reset()
73+
protocol.cms.close()
74+
cms.menuOpen = false
75+
end,
76+
open = function()
77+
protocol.cms.open(screen.config.rows, screen.config.cols)
78+
end,
79+
refresh = function()
80+
protocol.cms.refresh()
81+
end,
82+
close = function()
83+
protocol.cms.close()
84+
cms.menuOpen = false
85+
end,
86+
update = function()
87+
local command, data = protocol.cms.poll()
88+
if (command == "update") then
89+
local firstChunk = bit32.band(data[CONST.offset.meta], CONST.bitmask.firstChunk)
90+
local lastChunk = bit32.band(data[CONST.offset.meta], CONST.bitmask.lastChunk)
91+
local batchId = bit32.band(data[CONST.offset.meta], CONST.bitmask.batchId)
92+
local sequence = data[CONST.offset.sequence]
93+
local frameData = {}
94+
for i = CONST.offset.data, #data do
95+
frameData[#frameData + 1] = data[i]
96+
end
97+
if (firstChunk ~= 0) then
98+
screen.reset()
99+
screen.batchId = batchId
100+
screen.sequence = 0
101+
end
102+
if (screen.batchId == batchId) and (screen.sequence == sequence) then
103+
screen.sequence = sequence + 1
104+
for i = 1, #frameData do
105+
screen.data[#screen.data + 1] = frameData[i]
106+
end
107+
if (lastChunk ~= 0) then
108+
screen.buffer = cRleDecode(screen.data)
109+
screen.draw()
110+
screen.reset()
111+
end
112+
else
113+
protocol.cms.refresh()
114+
end
115+
cms.menuOpen = true
116+
elseif (command == "clear") then
117+
screen.reset()
118+
end
119+
end
120+
}

src/SCRIPTS/BF/CMS/crsf.lua

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
local CONST = {
2+
frame = {
3+
destination = 1,
4+
source = 2,
5+
command = 3,
6+
content = 4
7+
},
8+
address = {
9+
transmitter = 0xEA,
10+
betaflight = 0xC8
11+
},
12+
frameType = {
13+
displayPort = 0x7D
14+
},
15+
command = {
16+
update = 0x01,
17+
clear = 0x02,
18+
open = 0x03,
19+
close = 0x04,
20+
refresh = 0x05
21+
}
22+
}
23+
24+
local function crsfDisplayPortCmd(cmd, data)
25+
local payloadOut = { CONST.address.betaflight, CONST.address.transmitter, cmd }
26+
if data ~= nil then
27+
for i = 1, #(data) do
28+
payloadOut[3 + i] = data[i]
29+
end
30+
end
31+
return crossfireTelemetryPush(CONST.frameType.displayPort, payloadOut)
32+
end
33+
34+
protocol.cms.poll = function()
35+
local command = nil
36+
local dataOut = {}
37+
local frameType, data = crossfireTelemetryPop()
38+
if (data ~= nil) and (#data > 2) then
39+
if (frameType == CONST.frameType.displayPort) and (data[CONST.frame.destination] == CONST.address.transmitter) and (data[CONST.frame.source] == CONST.address.betaflight) then
40+
for k,v in pairs(CONST.command) do
41+
if (v == data[CONST.frame.command]) then
42+
command = k
43+
end
44+
end
45+
for i = CONST.frame.content, #data do
46+
dataOut[#dataOut + 1] = data[i]
47+
end
48+
end
49+
end
50+
return command, dataOut
51+
end
52+
53+
protocol.cms.open = function(rows, cols)
54+
return crsfDisplayPortCmd(CONST.command.open, { rows, cols })
55+
end
56+
57+
protocol.cms.close = function()
58+
return crsfDisplayPortCmd(CONST.command.close, nil)
59+
end
60+
61+
protocol.cms.refresh = function()
62+
return crsfDisplayPortCmd(CONST.command.refresh, nil)
63+
end
64+

src/SCRIPTS/BF/cms.lua

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
lastMenuEventTime = 0
2+
3+
local function init()
4+
cms.init(radio)
5+
end
6+
7+
local function run(event)
8+
lastMenuEventTime = getTime()
9+
cms.update()
10+
if (cms.menuOpen == false) then
11+
cms.open()
12+
end
13+
if (event == radio.refresh.event) then
14+
cms.refresh()
15+
end
16+
if (event == EVT_VIRTUAL_EXIT) then
17+
cms.close()
18+
return 1
19+
end
20+
return 0
21+
end
22+
23+
return { init=init, run=run }

src/SCRIPTS/BF/protocols.lua

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,28 @@ local supportedProtocols =
22
{
33
smartPort =
44
{
5-
transport = "MSP/sp.lua",
5+
mspTransport = "MSP/sp.lua",
66
rssi = function() return getValue("RSSI") end,
77
stateSensor = "Tmp1",
88
push = sportTelemetryPush,
99
maxTxBufferSize = 6,
1010
maxRxBufferSize = 6,
1111
saveMaxRetries = 2,
12-
saveTimeout = 500
12+
saveTimeout = 500,
13+
cms = {},
1314
},
1415
crsf =
1516
{
16-
transport = "MSP/crsf.lua",
17+
mspTransport = "MSP/crsf.lua",
18+
cmsTransport = "CMS/crsf.lua",
1719
rssi = function() return getValue("TQly") end,
1820
stateSensor = "1RSS",
1921
push = crossfireTelemetryPush,
2022
maxTxBufferSize = 8,
2123
maxRxBufferSize = 58,
2224
saveMaxRetries = 2,
23-
saveTimeout = 150
25+
saveTimeout = 150,
26+
cms = {},
2427
}
2528
}
2629

src/SCRIPTS/BF/radios.lua

Lines changed: 84 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,99 @@ local supportedRadios =
22
{
33
["128x64"] =
44
{
5-
templateHome = "TEMPLATES/128x64/",
6-
MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 },
7-
SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 },
8-
NoTelem = { 30, 55, "No Telemetry", BLINK },
9-
textSize = SMLSIZE,
10-
yMinLimit = 12,
11-
yMaxLimit = 52,
5+
msp = {
6+
templateHome = "TEMPLATES/128x64/",
7+
MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 },
8+
SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 },
9+
NoTelem = { 30, 55, "No Telemetry", BLINK },
10+
textSize = SMLSIZE,
11+
yMinLimit = 12,
12+
yMaxLimit = 52,
13+
},
14+
cms = {
15+
rows = 8,
16+
cols = 26,
17+
pixelsPerRow = 8,
18+
pixelsPerChar = 5,
19+
xIndent = 0,
20+
yOffset = 0,
21+
textSize = SMLSIZE,
22+
refresh = {
23+
event = EVT_VIRTUAL_ENTER,
24+
text = "Refresh: [ENT]",
25+
top = 1,
26+
left = 64,
27+
},
28+
},
1229
},
1330
["212x64"] =
1431
{
15-
templateHome = "TEMPLATES/212x64/",
16-
MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 },
17-
SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 },
18-
NoTelem = { 70, 55, "No Telemetry", BLINK },
19-
textSize = SMLSIZE,
20-
yMinLimit = 12,
21-
yMaxLimit = 52,
32+
msp = {
33+
templateHome = "TEMPLATES/212x64/",
34+
MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 },
35+
SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 },
36+
NoTelem = { 70, 55, "No Telemetry", BLINK },
37+
textSize = SMLSIZE,
38+
yMinLimit = 12,
39+
yMaxLimit = 52,
40+
},
41+
cms = {
42+
rows = 8,
43+
cols = 32,
44+
pixelsPerRow = 8,
45+
pixelsPerChar = 6,
46+
xIndent = 0,
47+
yOffset = 0,
48+
textSize = SMLSIZE,
49+
refresh = {
50+
event = EVT_VIRTUAL_INC,
51+
text = "Refresh: [+]",
52+
top = 1,
53+
left = 156,
54+
}
55+
},
2256
},
2357
["480x272"] =
2458
{
25-
templateHome = "TEMPLATES/480x272/",
26-
highRes = true,
27-
MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 },
28-
SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 },
29-
NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK },
30-
textSize = 0,
31-
yMinLimit = 35,
32-
yMaxLimit = 235,
59+
msp = {
60+
templateHome = "TEMPLATES/480x272/",
61+
highRes = true,
62+
MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 },
63+
SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 },
64+
NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK },
65+
textSize = 0,
66+
yMinLimit = 35,
67+
yMaxLimit = 235,
68+
},
69+
cms = {
70+
rows = 9,
71+
cols = 32,
72+
pixelsPerRow = 24,
73+
pixelsPerChar = 14,
74+
xIndent = 14,
75+
yOffset = 32,
76+
textSize = MIDSIZE,
77+
refresh = {
78+
event = EVT_VIRTUAL_ENTER,
79+
text = "Refresh: [ENT]",
80+
top = 1,
81+
left = 300,
82+
}
83+
},
3384
},
3485
["320x480"] =
3586
{
36-
templateHome = "TEMPLATES/320x480/",
37-
highRes = true,
38-
MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 },
39-
SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 },
40-
NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK },
41-
textSize = 0,
42-
yMinLimit = 35,
43-
yMaxLimit = 435,
87+
msp = {
88+
templateHome = "TEMPLATES/320x480/",
89+
highRes = true,
90+
MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 },
91+
SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 },
92+
NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK },
93+
textSize = 0,
94+
yMinLimit = 35,
95+
yMaxLimit = 435,
96+
},
97+
cms = nil,
4498
},
4599
}
46100

src/SCRIPTS/FUNCTIONS/bfbkgd.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
chdir("/SCRIPTS/BF")
22
apiVersion = 0
33
protocol = assert(loadScript("protocols.lua"))()
4-
assert(loadScript(protocol.transport))()
4+
assert(loadScript(protocol.mspTransport))()
55
assert(loadScript("MSP/common.lua"))()
66
local background = assert(loadScript("background.lua"))()
77

src/SCRIPTS/TOOLS/bf.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ local scriptsCompiled = assert(loadScript("COMPILE/scripts_compiled.lua"))()
88

99
if scriptsCompiled then
1010
protocol = assert(loadScript("protocols.lua"))()
11-
radio = assert(loadScript("radios.lua"))()
12-
assert(loadScript(protocol.transport))()
11+
radio = assert(loadScript("radios.lua"))().msp
12+
assert(loadScript(protocol.mspTransport))()
1313
assert(loadScript("MSP/common.lua"))()
1414
run = assert(loadScript("ui.lua"))()
1515
else

0 commit comments

Comments
 (0)