diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..6c1dd378 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,26 @@ +changelog: + exclude: + labels: + - "cleanup" + - "RN: IGNORE" + categories: + - title: Features + labels: + - "RN: FEATURE" + - "RN: MAJOR FEATURE" + - "RN: MINOR FEATURE" + - title: Improvements + labels: + - "RN: IMPROVEMENT" + - "RN: UI" + - "RN: REFACTOR" + - "RN: FONT" + - title: Fixes + labels: + - "RN: BUGFIX" + - title: Translation + labels: + - "RN: TRANSLATION" + - title: Known Issues + labels: + - BUG diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 74406576..00000000 --- a/.github/stale.yml +++ /dev/null @@ -1,55 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 30 - -# Number of days of inactivity before a stale Issue or Pull Request is closed. -# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. -daysUntilClose: 7 - -# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable -exemptLabels: - - BUG - - Feature Request - - Pinned - -# Set to true to ignore issues in a project (defaults to false) -exemptProjects: false - -# Set to true to ignore issues in a milestone (defaults to false) -exemptMilestones: true - -# Label to use when marking as stale -staleLabel: Inactive - -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue / pull request has been automatically marked as stale because it - has not had recent activity. It will be closed if no further activity occurs - within a week. - -# Comment to post when removing the stale label. -# unmarkComment: > -# Your comment here. - -# Comment to post when closing a stale Issue or Pull Request. -closeComment: > - Automatically closing as inactive. - -# Limit the number of actions per hour, from 1-30. Default is 30 -limitPerRun: 30 - -# Limit to only `issues` or `pulls` -# only: issues - -# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': -# pulls: -# daysUntilStale: 30 -# markComment: > -# This pull request has been automatically marked as stale because it has not had -# recent activity. It will be closed if no further activity occurs. Thank you -# for your contributions. - -# issues: -# exemptLabels: -# - confirmed diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml new file mode 100644 index 00000000..74c4c2cd --- /dev/null +++ b/.github/workflows/stale.yaml @@ -0,0 +1,32 @@ +name: 'Close stale issues' + +on: + schedule: + - cron: "30 4 * * *" + +jobs: + stale: + name: 'Check and close stale issues' + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + operations-per-run: 30 + days-before-stale: 30 + days-before-close: 7 + stale-issue-message: > + This issue has been automatically marked as stale because it + has not had recent activity. It will be closed if no further activity occurs + within a week. + close-issue-message: 'Issue closed automatically as inactive.' + exempt-issue-labels: 'BUG,Feature Request,Pinned' + stale-issue-label: 'Inactive' + stale-pr-message: > + This pull request has been automatically marked as stale because it + has not had recent activity. It will be closed if no further activity occurs + within a week. + close-pr-message: 'Pull request closed automatically as inactive.' + exempt-pr-labels: 'Pinned' + stale-pr-label: 'Inactive' + exempt-all-milestones: true diff --git a/.gitignore b/.gitignore index 95b7ddbd..63c3ae72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # Compiled Lua sources luac.out -# luarocks build files +# Luarocks build files *.src.rock *.zip *.tar.gz @@ -42,6 +42,9 @@ luac.out # Eclipse .project -#directories +# Visual Studio Code +.vscode + +# Directories tmp obj diff --git a/README.md b/README.md index eb175806..9e7dd41e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,17 @@ -# Betaflight TX Lua Scripts +![BF lua logo light mode](docs/assets/images/bf_lua_logo_light_mode.png#gh-light-mode-only) +![BF lua logo dark mode](docs/assets/images/bf_lua_logo_dark_mode.png#gh-dark-mode-only) -## Firmware Considerations + [![Latest version](https://img.shields.io/github/v/release/betaflight/betaflight-tx-lua-scripts)](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) [![Build Status](https://api.travis-ci.com/betaflight/betaflight-tx-lua-scripts.svg?branch=master)](https://travis-ci.com/betaflight/betaflight-tx-lua-scripts) [![Build Status](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_apis/build/status/betaflight.betaflight-tx-lua-scripts?branchName=master)](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_build/latest?definitionId=1&branchName=master) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) + +## Requirements - Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; -- OpenTX - 2.3.4 or newer; +- Telemetry - Telemetry has to be enabled and supported by the TX / RX for the scripts to be able to communicate with the flight controller; +- OpenTX - 2.3.12 or newer; +- EdgeTX - 2.4.0 or newer; +- ExpressLRS - 2.0.1 or newer; - Crossfire TX / RX - v2.11 or newer; -- FrSky TX / RX - While most receivers work fine, it's recommended to update the XSR family of receivers to their most recent firmware version to correct any known bugs in SmartPort telemetry. +- FrSky TX / RX with support for SmartPort - While most receivers with SmartPort support work fine, it is recommended to update the receiver to the most recent firmware version to correct any known bugs in telemetry. ## Installing @@ -15,38 +21,64 @@ Download a zip file containing the latest version from the [releases page](https Unzip the files from the link above and drag the contents of the `obj` folder to your radios SD card. If you do this correctly, the `SCRIPTS` directory will merge with your existing directories, placing the scripts in their appropriate paths. You will know if you did this correctly if the `bf.lua` file shows up in your `/SCRIPTS/TOOLS` directory. -### How to install +![Install](docs/assets/images/install.gif) + +## How to use -Bootloader Method +Navigate to the TOOLS menu in OpenTX, select "Betaflight setup" or "Betaflight CMS" and press the [ENTER] button. The first time the script is launched after a clean install or upgrade it will go through it's compile procedure and exit back to the TOOLS menu when it's done. -1. Power off your transmitter and power it back on in boot loader mode. -2. Connect a USB cable and open the SD card drive on your computer. -3. Unzip the file and copy the scripts to the root of the SD card. -4. Unplug the USB cable and power cycle your transmitter. +### Betaflight setup -Manual method (varies, based on the model of your transmitter) +The "Betaflight setup" script lets you configure Betaflight through the MSP protocol. -1. Power off your transmitter. -2. Remove the SD card and plug it into a computer -3. Unzip the file and copy the scripts to the root of the SD card. -4. Reinsert your SD card into the transmitter -5. Power up your transmitter. +![Betaflight setup](docs/assets/images/how_to_use.gif) -If you copied the files correctly, you can now go into the OpenTx Tools screen from the main menu and access the Betaflight Configuration tool. The first time you run the script, a message 'Compiling...' will appear in the display before the script is started - this is normal, and is done to minimise the RAM usage of the script. +#### Controls -### Running the script as a telemetry page +- [+] / [-] / [ROTARY ENCODER] - Used to navigate. +- [PAGE] - Press to move to the next page. Long press to move to the previous page. +- [ENTER] - Press to access the selected element. Long press to open the function menu. +- [EXIT] - Press to go back or exit the script. -Due to issues with input mapping and memory overruns, running the script as a telemetry page **is no longer supported**. The only way to run the script is through the Tools screen in the OpenTX main menu. +#### Saving your changes -### Setting up VTX Tables +Any changes to parameters in the script will not take effect until a save is manually initiated. Change the parameters you want to change, open the function menu by long pressing [ENTER] and select "save page" to send the modified parameters back to the flight controller. + +#### Setting up VTX tables If you are using a VTX that supports the SmartAudio or Tramp protocols then bands and channels etc. are managed using VTX tables since Betaflight version 4.1.0. The script will be downloading and storing the current VTX table for every model the first time the model is connected and the script is run. If you change the VTX table, you have to re-load the updated VTX table in the script, by choosing the 'vtx tables' option in the function menu. +Depending on the size of the vtx tables and the telemetry protocol used, downloading the vtx tables can take a while. + +![Download VTX tables](docs/assets/images/download_vtx_tables.gif) + +### Betaflight CMS + +**!! IMPORTANT: TBS Crossfire/Tracer only !!** + +"Betaflight CMS" lets you access the same CMS menu that is available in the OSD. + +![Betaflight CMS](docs/assets/images/how_to_use_cms.gif) + +#### Controls + +- [PITCH] - Navigate the current menu. +- [ROLL] - Enter menu or change selected parameter. +- [YAW] - Left to go back and right to enter the "SAVE / EXIT" menu. +- [+] / [ENTER] - Manual refresh. Press if the script doesn't update. +- [EXIT] - Close CMS menu and exit script. **!! IMPORTANT: Single press only. Long press will exit the script without closing CMS and as a result you will not be able to arm !!** + ### Background script -The optional background script offers RTC synchronization and RSSI through MSP. It can be setup as a special or global function in OpenTX. The image below shows how to run the background script as a special function. -![Background script setup](docs/assets/images/background_script_setup.png) +The optional background script offers RTC synchronization and RSSI through MSP. RSSI will only be sent if no other RSSI source is detected. It can be setup as a special or global function in OpenTX. The image below shows how to run the background script as a special function. + +![Background script setup](docs/assets/images/background_script_setup.png) + +## Unstable testing versions + +Unstable testing versions of the latest builds of the Lua Script can be downloaded from [here](https://github.com/betaflight/betaflight-tx-lua-scripts-nightlies/releases). +Be aware that these versions are intended for testing / feedback only, and may be buggy or broken. Caution is advised when using these versions. ## Building from source diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 66f7f867..837910b3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -15,21 +15,29 @@ variables: owner: betaflight repoName: betaflight-tx-lua-scripts-nightlies releaseNotes: This is a nightly build off the tip of 'master'. It may be unstable and result in corrupted configurations or data loss. **Use only for testing.** + vmImage: 'ubuntu-20.04' name: $(Date:yyyyMMdd).$(BuildID) + trigger: batch: true branches: include: - master -pr: none + +pr: + drafts: false + branches: + include: + - master + - "*-maintenance" stages: - stage: Build jobs: - job: 'Linux' pool: - vmImage: 'ubuntu-16.04' + vmImage: '$(vmImage)' steps: - script: sudo apt-get -y install lua5.2 displayName: 'Install lua compiler.' @@ -44,6 +52,8 @@ stages: - stage: Release jobs: - job: Release + pool: + vmImage: '$(vmImage)' steps: - task: DownloadPipelineArtifact@2 inputs: diff --git a/bin/build.sh b/bin/build.sh index a58209fa..be6cb2ac 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if [ -d obj ]; then rm -fR obj/* diff --git a/docs/assets/images/background_script_setup.png b/docs/assets/images/background_script_setup.png index fabb458e..09b48066 100644 Binary files a/docs/assets/images/background_script_setup.png and b/docs/assets/images/background_script_setup.png differ diff --git a/docs/assets/images/bf_lua_logo_dark_mode.png b/docs/assets/images/bf_lua_logo_dark_mode.png new file mode 100644 index 00000000..3ff9afa4 Binary files /dev/null and b/docs/assets/images/bf_lua_logo_dark_mode.png differ diff --git a/docs/assets/images/bf_lua_logo_light_mode.png b/docs/assets/images/bf_lua_logo_light_mode.png new file mode 100644 index 00000000..09a1cac2 Binary files /dev/null and b/docs/assets/images/bf_lua_logo_light_mode.png differ diff --git a/docs/assets/images/download_vtx_tables.gif b/docs/assets/images/download_vtx_tables.gif new file mode 100644 index 00000000..350d1200 Binary files /dev/null and b/docs/assets/images/download_vtx_tables.gif differ diff --git a/docs/assets/images/how_to_use.gif b/docs/assets/images/how_to_use.gif new file mode 100644 index 00000000..70b5f252 Binary files /dev/null and b/docs/assets/images/how_to_use.gif differ diff --git a/docs/assets/images/how_to_use_cms.gif b/docs/assets/images/how_to_use_cms.gif new file mode 100644 index 00000000..05014782 Binary files /dev/null and b/docs/assets/images/how_to_use_cms.gif differ diff --git a/docs/assets/images/install.gif b/docs/assets/images/install.gif new file mode 100644 index 00000000..d6f4d0c6 Binary files /dev/null and b/docs/assets/images/install.gif differ diff --git a/src/BF/use_tools_menu_instead_of_this.txt b/src/BF/use_tools_menu_instead_of_this.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/src/SCRIPTS/BF/BOARD_INFO/readme.txt b/src/SCRIPTS/BF/BOARD_INFO/readme.txt new file mode 100644 index 00000000..2fe32c7e --- /dev/null +++ b/src/SCRIPTS/BF/BOARD_INFO/readme.txt @@ -0,0 +1 @@ +Board info downloaded from the flight controller will be stored in this folder. diff --git a/src/SCRIPTS/BF/CMS/common.lua b/src/SCRIPTS/BF/CMS/common.lua new file mode 100644 index 00000000..5581d822 --- /dev/null +++ b/src/SCRIPTS/BF/CMS/common.lua @@ -0,0 +1,121 @@ +local CONST = { + bitmask = { + firstChunk = 0x80, + lastChunk = 0x40, + batchId = 0x3F, + rleCharValueMask = 0x7F, + rleCharRepeatedMask = 0x80 + }, + offset = { + meta = 1, + sequence = 2, + data = 3 + } +} + +local function cRleDecode(buf) + local dest = {} + local rpt = false + local c = nil + for i = 1, #buf do + if (rpt == false) then + c = bit32.band(buf[i], CONST.bitmask.rleCharValueMask) + if (bit32.band(buf[i], CONST.bitmask.rleCharRepeatedMask) > 0) then + rpt = true + else + dest[#dest + 1] = c + end + else + for j = 1, buf[i] do + dest[#dest + 1] = c + end + rpt = false + end + end + return dest +end + +screen = { + config = nil, + buffer = {}, + data = {}, + batchId = 0, + sequence = 0, + redraws = 2, + reset = function() + screen.data = {} + screen.batchId = 0 + screen.sequence = 0 + end, + draw = function() + lcd.clear() + lcd.drawText(screen.config.refresh.left, screen.config.refresh.top, screen.config.refresh.text, screen.config.textSize) + for char = 1, #screen.buffer do + if (screen.buffer[char] ~= 32) then -- skip spaces to avoid CPU spikes + local c = string.char(screen.buffer[char]) + local row = math.ceil(char / screen.config.cols) + local col = char - ((row - 1) * screen.config.cols) + local xPos = ((col - 1) * screen.config.pixelsPerChar) + screen.config.xIndent + 1 + local yPos = ((row - 1) * screen.config.pixelsPerRow) + screen.config.yOffset + 1 + lcd.drawText(xPos, yPos, c, screen.config.textSize) + end + end + end, +} + +cms = { + menuOpen = false, + synced = false, + init = function(cmsConfig) + screen.config = assert(cmsConfig, "Resolution not supported") + screen.reset() + protocol.cms.close() + cms.menuOpen = false + cms.synced = false + end, + open = function() + protocol.cms.open(screen.config.rows, screen.config.cols) + end, + refresh = function() + protocol.cms.refresh() + end, + close = function() + protocol.cms.close() + cms.menuOpen = false + end, + update = function() + local command, data = protocol.cms.poll() + if (command == "update") then + local firstChunk = bit32.btest(data[CONST.offset.meta], CONST.bitmask.firstChunk) + local lastChunk = bit32.btest(data[CONST.offset.meta], CONST.bitmask.lastChunk) + local batchId = bit32.band(data[CONST.offset.meta], CONST.bitmask.batchId) + local sequence = data[CONST.offset.sequence] + if firstChunk then + screen.reset() + screen.batchId = batchId + screen.sequence = 0 + end + if (screen.batchId == batchId) and (screen.sequence == sequence) then + screen.sequence = sequence + 1 + for i = CONST.offset.data, #data do + screen.data[#screen.data + 1] = data[i] + end + if lastChunk then + screen.buffer = cRleDecode(screen.data) + screen.redraws = 2 + screen.reset() + cms.synced = true + end + else + protocol.cms.refresh() + end + cms.menuOpen = true + elseif (command == "clear") then + screen.reset() + end + if screen.redraws > 0 then + screen.draw() + screen.redraws = screen.redraws - 1 + end + end +} diff --git a/src/SCRIPTS/BF/CMS/crsf.lua b/src/SCRIPTS/BF/CMS/crsf.lua new file mode 100644 index 00000000..83c17337 --- /dev/null +++ b/src/SCRIPTS/BF/CMS/crsf.lua @@ -0,0 +1,64 @@ +local CONST = { + frame = { + destination = 1, + source = 2, + command = 3, + content = 4 + }, + address = { + transmitter = 0xEA, + betaflight = 0xC8 + }, + frameType = { + displayPort = 0x7D + }, + command = { + update = 0x01, + clear = 0x02, + open = 0x03, + close = 0x04, + refresh = 0x05 + } +} + +local function crsfDisplayPortCmd(cmd, data) + local payloadOut = { CONST.address.betaflight, CONST.address.transmitter, cmd } + if data ~= nil then + for i = 1, #(data) do + payloadOut[3 + i] = data[i] + end + end + return crossfireTelemetryPush(CONST.frameType.displayPort, payloadOut) +end + +protocol.cms.poll = function() + local command = nil + local dataOut = {} + local frameType, data = crossfireTelemetryPop() + if (data ~= nil) and (#data > 2) then + if (frameType == CONST.frameType.displayPort) and (data[CONST.frame.destination] == CONST.address.transmitter) and (data[CONST.frame.source] == CONST.address.betaflight) then + for k,v in pairs(CONST.command) do + if (v == data[CONST.frame.command]) then + command = k + end + end + for i = CONST.frame.content, #data do + dataOut[#dataOut + 1] = data[i] + end + end + end + return command, dataOut +end + +protocol.cms.open = function(rows, cols) + return crsfDisplayPortCmd(CONST.command.open, { rows, cols }) +end + +protocol.cms.close = function() + return crsfDisplayPortCmd(CONST.command.close, nil) +end + +protocol.cms.refresh = function() + return crsfDisplayPortCmd(CONST.command.refresh, nil) +end + diff --git a/src/SCRIPTS/BF/CONFIRM/acc_cal.lua b/src/SCRIPTS/BF/CONFIRM/acc_cal.lua new file mode 100644 index 00000000..41a3c8de --- /dev/null +++ b/src/SCRIPTS/BF/CONFIRM/acc_cal.lua @@ -0,0 +1,25 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Make sure the craft is level", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "and stable, then press", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[ENTER] to calibrate, or", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[EXIT] to cancel.", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { x = x, y = inc.y(lineSpacing), value = "", ro = true } + +return { + title = "Accelerometer", + labels = labels, + fields = fields, + init = assert(loadScript("acc_cal.lua"))(), +} diff --git a/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua new file mode 100644 index 00000000..5d51e617 --- /dev/null +++ b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua @@ -0,0 +1,24 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Download VTX tables? Press", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[ENTER] to download, or", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[EXIT] to cancel.", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { x = x, y = inc.y(lineSpacing), value = "", ro = true } + +return { + title = "VTX Tables", + labels = labels, + fields = fields, + init = assert(loadScript("vtx_tables.lua"))(), +} diff --git a/src/SCRIPTS/BF/MSP/common.lua b/src/SCRIPTS/BF/MSP/common.lua index 46648991..fb119f6c 100644 --- a/src/SCRIPTS/BF/MSP/common.lua +++ b/src/SCRIPTS/BF/MSP/common.lua @@ -6,6 +6,7 @@ local MSP_STARTFLAG = bit32.lshift(1,4) local mspSeq = 0 local mspRemoteSeq = 0 local mspRxBuf = {} +local mspRxSize = 0 local mspRxCRC = 0 local mspRxReq = 0 local mspStarted = false @@ -37,12 +38,6 @@ function mspProcessTxQ() end if i <= protocol.maxTxBufferSize then payload[i] = mspTxCRC - i = i + 1 - -- zero fill - while i <= protocol.maxTxBufferSize do - payload[i] = 0 - i = i + 1 - end protocol.mspSend(payload) mspTxBuf = {} mspTxIdx = 1 @@ -68,25 +63,30 @@ function mspSendRequest(cmd, payload) end function mspReceivedReply(payload) - local idx = 1 - local head = payload[idx] - local err_flag = (bit32.band(head,0x20) ~= 0) + local idx = 1 + local status = payload[idx] + local err = bit32.btest(status, 0x80) + local version = bit32.rshift(bit32.band(status, 0x60), 5) + local start = bit32.btest(status, 0x10) + local seq = bit32.band(status, 0x0F) idx = idx + 1 - if err_flag then - -- error flag set + if err then mspStarted = false return nil end - local start = (bit32.band(head,0x10) ~= 0) - local seq = bit32.band(head,0x0F) if start then - -- start flag set mspRxBuf = {} mspRxSize = payload[idx] - mspRxCRC = bit32.bxor(mspRxSize,mspLastReq) - mspRxReq = mspLastReq + mspRxReq = mspLastReq idx = idx + 1 - mspStarted = true + if version == 1 then + mspRxReq = payload[idx] + idx = idx + 1 + end + mspRxCRC = bit32.bxor(mspRxSize, mspRxReq) + if mspRxReq == mspLastReq then + mspStarted = true + end elseif not mspStarted then return nil elseif bit32.band(mspRemoteSeq + 1, 0x0F) ~= seq then @@ -95,7 +95,7 @@ function mspReceivedReply(payload) end while (idx <= protocol.maxRxBufferSize) and (#mspRxBuf < mspRxSize) do mspRxBuf[#mspRxBuf + 1] = payload[idx] - mspRxCRC = bit32.bxor(mspRxCRC,payload[idx]) + mspRxCRC = bit32.bxor(mspRxCRC, payload[idx]) idx = idx + 1 end if idx > protocol.maxRxBufferSize then @@ -104,7 +104,7 @@ function mspReceivedReply(payload) end mspStarted = false -- check CRC - if mspRxCRC ~= payload[idx] then + if mspRxCRC ~= payload[idx] and version == 0 then return nil end return mspRxBuf diff --git a/src/SCRIPTS/BF/MSP/sp.lua b/src/SCRIPTS/BF/MSP/sp.lua index eaabe8cd..ecc15b1b 100644 --- a/src/SCRIPTS/BF/MSP/sp.lua +++ b/src/SCRIPTS/BF/MSP/sp.lua @@ -7,9 +7,11 @@ local REPLY_FRAME_ID = 0x32 local lastSensorId, lastFrameId, lastDataId, lastValue protocol.mspSend = function(payload) - local dataId = payload[1] + bit32.lshift(payload[2],8) - local value = payload[3] + bit32.lshift(payload[4],8) - + bit32.lshift(payload[5],16) + bit32.lshift(payload[6],24) + local dataId = payload[1] + bit32.lshift(payload[2], 8) + local value = 0 + for i = 3, #payload do + value = value + bit32.lshift(payload[i], (i - 3) * 8) + end return protocol.push(LOCAL_SENSOR_ID, REQUEST_FRAME_ID, dataId, value) end diff --git a/src/SCRIPTS/BF/PAGES/failsafe.lua b/src/SCRIPTS/BF/PAGES/failsafe.lua new file mode 100644 index 00000000..1ce6fbaa --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/failsafe.lua @@ -0,0 +1,45 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +local procedure = { [0] = "Land", "Drop" } + +if apiVersion >= 1.039 then + procedure[#procedure + 1] = "Rescue" +end + +if apiVersion >= 1.039 then + labels[#labels + 1] = { t = "Failsafe Switch", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Action", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 5 }, table = { [0] = "Stage 1", "Kill", "Stage 2" } } +else + fields[#fields + 1] = { t = "Kill switch", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 5 }, table = { [0] = "OFF", "ON" } } +end + +labels[#labels + 1] = { t = "Stage 2 Settings" , x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Procedure", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #procedure, vals = { 8 }, table = procedure } +fields[#fields + 1] = { t = "Guard Time", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 1 }, scale = 10 } +fields[#fields + 1] = { t = "Thrl Low Delay", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 300, vals = { 6, 7 }, scale = 10 } + +labels[#labels + 1] = { t = "Stage 2 Land Settings", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Thrl Land Value", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 750, max = 2250, vals = { 3, 4 } } +fields[#fields + 1] = { t = "Motor Off Delay", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 2 }, scale = 10 } + +return { + read = 75, -- MSP_FAILSAFE_CONFIG + write = 76, -- MSP_SET_FAILSAFE_CONFIG + title = "Failsafe", + reboot = true, + eepromWrite = true, + minBytes = 8, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/PAGES/filters1.lua b/src/SCRIPTS/BF/PAGES/filters1.lua index d7eb5937..68db6c8e 100644 --- a/src/SCRIPTS/BF/PAGES/filters1.lua +++ b/src/SCRIPTS/BF/PAGES/filters1.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."filters1.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -16,18 +11,33 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local gyroFilterType = { [0] = "PT1", "BIQUAD" } + +if apiVersion >= 1.044 then + gyroFilterType[#gyroFilterType + 1] = "PT2" + gyroFilterType[#gyroFilterType + 1] = "PT3" +end + +local dtermFilterType = gyroFilterType + +if apiVersion >= 1.036 and apiVersion <= 1.038 then + dtermFilterType = { [0] = "PT1", "BIQUAD", "FIR" } +end + +local dtermFilterType2 = gyroFilterType + if apiVersion >= 1.041 then labels[#labels + 1] = { t = "Gyro Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 30, 31 } } fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 32, 33 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 25 }, table = gyroFilterType } end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Gyro Lowpass 1", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.039 then fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 21, 22 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 25 }, table = gyroFilterType } else fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 1 } } end @@ -36,7 +46,7 @@ end if apiVersion >= 1.039 then labels[#labels + 1] = { t = "Gyro Lowpass 2", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 23, 24 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 26 }, table = gyroFilterType } end if apiVersion >= 1.020 then @@ -55,16 +65,14 @@ if apiVersion >= 1.041 then labels[#labels + 1] = { t = "D Term Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 34, 35 } } fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 36, 37 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType, vals = { 18 }, table = dtermFilterType } end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "D Term Lowpass 1", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 2, 3 } } - if apiVersion >= 1.036 and apiVersion <= 1.038 then - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD", [2] = "FIR" } } - elseif apiVersion >= 1.039 then - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + if apiVersion >= 1.036 then + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType, vals = { 18 }, table = dtermFilterType } end end @@ -72,7 +80,7 @@ if apiVersion >= 1.039 then labels[#labels + 1] = { t = "D Term Lowpass 2", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 27, 28 } } if apiVersion >= 1.041 then - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType2, vals = { 29 }, table = dtermFilterType2 } end end diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index 5984a61c..0ba77145 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."filters2.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -24,7 +19,11 @@ if apiVersion >= 1.042 then if apiVersion < 1.043 then fields[#fields + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } end - fields[#fields + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 39 } } + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Count", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 5, vals = { 49 } } + else + fields[#fields + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 39 } } + end fields[#fields + 1] = { t = "Q", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 1000, vals = { 40, 41 } } if apiVersion >= 1.043 then fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 60, max = 250, vals = { 42, 43 } } @@ -47,7 +46,7 @@ return { self.rpmHarmonics = self.values[44] end, preSave = function(self) - self.reboot = self.values[44] == 0 and self.rpmHarmonics ~= 0 + self.reboot = self.values[44] == 0 and self.rpmHarmonics ~= 0 and apiVersion <= 1.043 return self.values end, } diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index dd6af065..95382972 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."gpspids.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index f9250841..5c136d66 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pid_advanced.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -25,17 +20,27 @@ if apiVersion >= 1.040 then end if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Motor Output Limit",x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 100, vals = { 48 } } fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 50 } } end -if apiVersion >= 1.016 then +if apiVersion >= 1.016 and apiVersion <= 1.043 then fields[#fields + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } end +if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Vbat Sag Comp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 56 } } + fields[#fields + 1] = { t = "Thrust Linear", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 57 } } +end + if apiVersion >= 1.040 and apiVersion <= 1.041 then fields[#fields + 1] = { t = "Smart Feedforward", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 27 }, table = { [0] = "OFF", "ON" } } end +if apiVersion >= 1.041 then + fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } +end + if apiVersion >= 1.040 then labels[#labels + 1] = { t = "I Term Relax", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } @@ -47,16 +52,16 @@ if apiVersion >= 1.040 then end end -if apiVersion >= 1.041 then - fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } -end - if apiVersion >= 1.036 then labels[#labels + 1] = { t = "Anti Gravity", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.040 then fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } end - fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + else + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + end fields[#fields + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 1000, vals = { 20, 21 } } end @@ -73,7 +78,7 @@ return { self.dynamicIdle = self.values[50] end, preSave = function(self) - self.reboot = self.values[50] ~= self.dynamicIdle + self.reboot = self.values[50] ~= self.dynamicIdle and apiVersion <= 1.043 return self.values end, } diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index b3e9830f..42c40afd 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pids1.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -16,6 +11,14 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local pidMax = 200 +local dLabel = "D" + +if apiVersion >= 1.044 then + pidMax = 250 + dLabel = "D Max" +end + if apiVersion >= 1.016 then x = margin y = yMinLim - tableSpacing.header @@ -29,26 +32,26 @@ if apiVersion >= 1.016 then y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "P", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 1 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 4 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 7 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 1 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 4 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 7 } } x = x + tableSpacing.col y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "I", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 2 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 5 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 8 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 2 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 5 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 8 } } x = x + tableSpacing.col y = yMinLim - tableSpacing.header - labels[#labels + 1] = { t = "D", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 3 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 6 } } + labels[#labels + 1] = { t = dLabel, x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 3 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 6 } } if apiVersion >= 1.041 then - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 9 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 9 } } end end diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index b4c3a68d..7fdb1d1d 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pids2.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -16,6 +11,12 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local dMinMax = 100 + +if apiVersion >= 1.044 then + dMinMax = 250 +end + if apiVersion >= 1.040 then x = margin y = yMinLim - tableSpacing.header @@ -38,20 +39,25 @@ if apiVersion >= 1.040 then y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 40 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 41 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 42 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = dMinMax, vals = { 40 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = dMinMax, vals = { 41 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = dMinMax, vals = { 42 } } end x = margin y = inc.y(lineSpacing*0.4) end - - if apiVersion >= 1.040 then - labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } + labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Jitter Reduction", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 55 } } + fields[#fields + 1] = { t = "Smoothness", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 75, vals = { 52 } } + fields[#fields + 1] = { t = "Averaging", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 51 }, table = { [0] = "OFF", "2_POINT", "3_POINT", "4_POINT" } } + fields[#fields + 1] = { t = "Boost", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 53 } } + fields[#fields + 1] = { t = "Max Rate Limit", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 54 } } + end + fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } end if apiVersion >= 1.041 then diff --git a/src/SCRIPTS/BF/PAGES/profiles.lua b/src/SCRIPTS/BF/PAGES/profiles.lua new file mode 100644 index 00000000..c59ad529 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/profiles.lua @@ -0,0 +1,46 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +local RATEPROFILE_MASK = bit32.lshift(1, 7) +local profileNumbers = { [0] = "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" } + +fields[#fields + 1] = { t = "PID Profile", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 11 }, table = profileNumbers } +fields[#fields + 1] = { t = "Rate Profile", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 5, vals = { 15 }, table = profileNumbers } + +return { + read = 150, -- MSP_STATUS_EX + write = 210, -- MSP_SELECT_SETTING + title = "Profiles", + reboot = false, + eepromWrite = true, + minBytes = 11, + labels = labels, + fields = fields, + pidProfile = 0, + postLoad = function(self) + local pidProfileCount = self.values[14] + self.fields[1].max = pidProfileCount - 1 + self.pidProfile = self.fields[1].value + end, + preSave = function(self) + local value = 0 + if self.fields[1].value ~= self.pidProfile then + value = self.fields[1].value + else + value = bit32.bor(self.fields[2].value, RATEPROFILE_MASK) + end + self.values = {} + self.values[1] = value + return self.values + end, +} diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 7cb40a4e..5a5c4258 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pwm.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -16,6 +11,12 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local gyroSampleRateKhz + +if apiVersion >= 1.043 then + gyroSampleRateKhz = assert(loadScript("BOARD_INFO/"..mcuId..".lua"))().gyroSampleRateHz / 1000 +end + local escProtocols = { [0] = "PWM", "OS125", "OS42", "MSHOT" } if apiVersion >= 1.020 then @@ -37,23 +38,24 @@ if apiVersion >= 1.043 then escProtocols[#escProtocols + 1] = "DISABLED" end +labels[#labels + 1] = { t = "System Config", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.031 and apiVersion <= 1.040 then - fields[#fields + 1] = { t = "32kHz Sampling", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } + fields[#fields + 1] = { t = "32kHz Sampling", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } end - -if apiVersion >= 1.016 then - if apiVersion <= 1.042 then - fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } - fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {} } - end - fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } - fields[#fields + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } - fields[#fields + 1] = { t = "PWM Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 32000, vals = { 5, 6 }, } +if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1, ro = true } +else + fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1 } end +fields[#fields + 1] = { t = "PID Loop", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {}, mult = -1 } +labels[#labels + 1] = { t = "ESC/Motor", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Protocol", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } if apiVersion >= 1.031 then - fields[#fields + 1] = { t = "Idle Throttle %", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } + fields[#fields + 1] = { t = "Idle Throttle %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } end +fields[#fields + 1] = { t = "Unsynced PWM", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "Frequency", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 32000, vals = { 5, 6 }, } return { read = 90, -- MSP_ADVANCED_CONFIG @@ -81,6 +83,7 @@ return { end, calculateGyroRates = function(self, baseRate) local idx = self.getGyroDenomFieldIndex(self) + baseRate = gyroSampleRateKhz or baseRate for i=1, 32 do self.gyroRates[i] = baseRate/i self.fields[idx].table[i] = string.format("%.2f",baseRate/i) diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 6f348e6b..355674fb 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."rates.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -66,6 +61,10 @@ if apiVersion >= 1.016 then inc.y(lineSpacing*0.4) end +if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Rates Type", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 23 }, table = { [0] = "BF", "RF", "KISS", "ACTUAL", "QUICK"}, postEdit = function(self) self.updateRatesType(self, true) end } +end + if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Mid", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 7 }, scale = 100 } @@ -91,4 +90,49 @@ return { minBytes = 12, labels = labels, fields = fields, + ratesType, + getRatesType = function(self) + for i = 1, #self.fields do + if self.fields[i].vals and self.fields[i].vals[1] == 23 then + return self.fields[i].table[self.fields[i].value] + end + end + end, + updateRatesType = function(self, applyDefaults) + local ratesTable = assert(loadScript("RATETABLES/"..self.getRatesType(self)..".lua"))() + for i = 1, #ratesTable.labels do + self.labels[i].t = ratesTable.labels[i] + end + for i = 1, #ratesTable.fields do + for k, v in pairs(ratesTable.fields[i]) do + self.fields[i][k] = v + end + end + if applyDefaults and self.ratesType ~= self.getRatesType(self) then + for i = 1, #ratesTable.defaults do + local f = self.fields[i] + f.value = ratesTable.defaults[i] + for idx=1, #f.vals do + self.values[f.vals[idx]] = bit32.rshift(math.floor(f.value*(f.scale or 1) + 0.5), (idx-1)*8) + end + end + else + for i = 1, 9 do + local f = self.fields[i] + f.value = 0 + for idx=1, #f.vals do + local raw_val = self.values[f.vals[idx]] or 0 + raw_val = bit32.lshift(raw_val, (idx-1)*8) + f.value = bit32.bor(f.value, raw_val) + end + f.value = f.value/(f.scale or 1) + end + end + self.ratesType = self.getRatesType(self) + end, + postLoad = function(self) + if apiVersion >= 1.043 then + self.updateRatesType(self) + end + end, } diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index ecc9785a..c3bc9a2b 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."rescue.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -24,7 +19,10 @@ if apiVersion >= 1.041 then fields[#fields + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 3000, vals = { 7, 8 } } if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Ascend Rate", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 100, max = 2500, vals = { 17, 18 }, scale = 100 } + fields[#fields + 1] = { t = "Descend Rate", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 100, max = 500, vals = { 19, 20 }, scale = 100 } fields[#fields + 1] = { t = "Arm w/o fix", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"} } + fields[#fields + 1] = { t = "Altitude Mode",x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 22 }, table = { [0]="Maximum", "Fixed", "Current"} } end fields[#fields + 1] = { t = "Sanity Check", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"} } @@ -32,6 +30,10 @@ if apiVersion >= 1.041 then fields[#fields + 1] = { t = "Min", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 9, 10 } } fields[#fields + 1] = { t = "Hover", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 13, 14 } } fields[#fields + 1] = { t = "Max", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 11, 12 } } + + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Min Dth", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 1000, vals = { 23, 24 } } + end end return { diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index f9939b5e..8c6cd8f8 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."rx.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -17,19 +12,45 @@ local labels = {} local fields = {} if apiVersion >= 1.016 then - labels[#labels + 1] = { t = "Stick", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 6, 7 } } - fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 4, 5 } } - fields[#fields + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 2, 3 } } + labels[#labels + 1] = { t = "Stick", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 6, 7 } } + fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 4, 5 } } + fields[#fields + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 2, 3 } } end -if apiVersion >= 1.020 then - fields[#fields + 1] = { t = "Interp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } - fields[#fields + 1] = { t = "Interp Int", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } +if apiVersion >= 1.044 then + labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "ON", "OFF" } } + labels[#labels + 1] = { t = "Cutoffs", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Setpoint", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 26 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Feedforward", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 27 }, table = { [0] = "Auto" } } + labels[#labels + 1] = { t = "Auto Smoothness", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Setpoint", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 250, vals = { 31 } } +else + if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "Interpolation", "Filter" } } + fields[#fields + 1] = { t = "Channels", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 24 }, table = { [0] = "RP", "RPY", "RPYT", "T", "RT" } } + labels[#labels + 1] = { t = "Input Filter", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 26 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 28 }, table = { [0] = "PT1", "BIQUAD"} } + labels[#labels + 1] = { t = "Derivative Filter", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 27 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 29 }, table = { [0] = "Off", "PT1", "BIQUAD", "Auto"} } + end + + if apiVersion >= 1.020 then + fields[#fields + 1] = { t = "Interpolation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } + fields[#fields + 1] = { t = "Interval", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } + end + + if apiVersion >= 1.042 then + fields[#fields + 1] = { t = "Auto Smoothness", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 31 } } + end end if apiVersion >= 1.031 then - fields[#fields + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 90, vals = { 23 } } + fields[#fields + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 90, vals = { 23 } } end return { diff --git a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua new file mode 100644 index 00000000..addaf165 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua @@ -0,0 +1,40 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Simplified PID", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "PID Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 1 }, table = { [0] = "OFF", "RP", "RPY" } } +fields[#fields + 1] = { t = "D Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 5 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "P&I Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 6 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "FF Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 8 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Max", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 7 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "I Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 4 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Pitch:Roll D", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 3 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Pitch:Roll P,I&FF", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 9 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Master Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 2 }, scale = 100, mult = 5 } + +labels[#labels + 1] = { t = "Simplified Filter", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Gyro Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 36 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "Gyro Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 10, max = 200, vals = { 37 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "D Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 10, max = 200, vals = { 19 }, scale = 100, mult = 5 } + +return { + read = 140, -- MSP_SIMPLIFIED_TUNING + write = 141, -- MSP_SET_SIMPLIFIED_TUNING + title = "Simplified Tuning", + reboot = false, + eepromWrite = true, + minBytes = 53, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index dc2168d5..73a035e5 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,18 +1,4 @@ -local md = model.getInfo(); -local vtx_tables = loadScript("/BF/VTX/"..md.name..".lua") -if vtx_tables then - vtx_tables = vtx_tables() -else - vtx_tables = assert(loadScript("/BF/VTX/vtx_defaults.lua"))() -end -local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } -local pitModeTable = { [0]="OFF", "ON" } -local template = loadScript(radio.templateHome.."vtx.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -25,6 +11,15 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local vtx_tables +if apiVersion >= 1.042 then + vtx_tables = assert(loadScript("VTX_TABLES/"..mcuId..".lua"))() +else + vtx_tables = assert(loadScript("VTX_TABLES/vtx_defaults.lua"))() +end +local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } +local pitModeTable = { [0]="OFF", "ON" } + if apiVersion >= 1.036 then fields[#fields + 1] = { t = "Band", x = x, y = inc.y(lineSpacing), sp = x + sp, min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end } fields[#fields + 1] = { t = "Channel", x = x, y = inc.y(lineSpacing), sp = x + sp, min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end } diff --git a/src/SCRIPTS/BF/RATETABLES/ACTUAL.lua b/src/SCRIPTS/BF/RATETABLES/ACTUAL.lua new file mode 100644 index 00000000..42bf533d --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/ACTUAL.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "Cntr", "Sens", "Max", "Rate", "", "Expo" }, + fields = { + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 200, 200, 200, 670, 670, 670, 0.54, 0.54, 0.54 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/BF.lua b/src/SCRIPTS/BF/RATETABLES/BF.lua new file mode 100644 index 00000000..343d6df3 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/BF.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "RC", "Rate", "Super", "Rate", "RC", "Expo" }, + fields = { + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 1.0, 1.0, 1.0, 0.7, 0.7, 0.7, 0.0, 0.0, 0.0 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/KISS.lua b/src/SCRIPTS/BF/RATETABLES/KISS.lua new file mode 100644 index 00000000..f365f270 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/KISS.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "RC", "Rate", "", "Rate", "RC", "Curve" }, + fields = { + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 0, max = 99, scale = 100 }, + { min = 0, max = 99, scale = 100 }, + { min = 0, max = 99, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 1.0, 1.0, 1.0, 0.7, 0.7, 0.7, 0.0, 0.0, 0.0 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/QUICK.lua b/src/SCRIPTS/BF/RATETABLES/QUICK.lua new file mode 100644 index 00000000..367eeef0 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/QUICK.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "RC", "Rate", "Max", "Rate", "", "Expo" }, + fields = { + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 1.0, 1.0, 1.0, 670, 670, 670, 0.0, 0.0, 0.0 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/RF.lua b/src/SCRIPTS/BF/RATETABLES/RF.lua new file mode 100644 index 00000000..12f74f36 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/RF.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "", "Rate", "", "Acro+", "", "Expo" }, + fields = { + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 } + }, + defaults = { 370, 370, 370, 80, 80, 80, 50, 50, 50 } +} diff --git a/src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/128x64.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/128x64.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/128x96.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/128x96.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/212x64.lua b/src/SCRIPTS/BF/TEMPLATES/212x64.lua new file mode 100644 index 00000000..76e110f0 --- /dev/null +++ b/src/SCRIPTS/BF/TEMPLATES/212x64.lua @@ -0,0 +1,7 @@ +return { + margin = 2, + indent = 6, + lineSpacing = 8, + listSpacing = { line = 8, field = 88 }, + tableSpacing = { row = 10, col = 30, header = 8 }, +} diff --git a/src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/320x480.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/320x480.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/480x272.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/480x272.lua diff --git a/src/BF/VTX/vtx_defaults.lua b/src/SCRIPTS/BF/VTX_TABLES/vtx_defaults.lua similarity index 100% rename from src/BF/VTX/vtx_defaults.lua rename to src/SCRIPTS/BF/VTX_TABLES/vtx_defaults.lua diff --git a/src/SCRIPTS/BF/acc_cal.lua b/src/SCRIPTS/BF/acc_cal.lua new file mode 100644 index 00000000..582d459c --- /dev/null +++ b/src/SCRIPTS/BF/acc_cal.lua @@ -0,0 +1,24 @@ +local MSP_ACC_CALIBRATION = 205 +local accCalibrated = false +local lastRunTS = 0 +local INTERVAL = 500 + +local function processMspReply(cmd,rx_buf) + if cmd == MSP_ACC_CALIBRATION then + accCalibrated = true + end +end + +local function accCal() + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + if not accCalibrated then + protocol.mspRead(MSP_ACC_CALIBRATION) + end + end + mspProcessTxQ() + processMspReply(mspPollReply()) + return accCalibrated +end + +return { f = accCal, t = "Calibrating Accelerometer" } diff --git a/src/SCRIPTS/BF/api_version.lua b/src/SCRIPTS/BF/api_version.lua new file mode 100644 index 00000000..366fa500 --- /dev/null +++ b/src/SCRIPTS/BF/api_version.lua @@ -0,0 +1,26 @@ +local MSP_API_VERSION = 1 + +local apiVersionReceived = false +local lastRunTS = 0 +local INTERVAL = 50 + +local function processMspReply(cmd,rx_buf) + if cmd == MSP_API_VERSION and #rx_buf >= 3 then + apiVersion = rx_buf[2] + rx_buf[3] / 1000 + apiVersionReceived = true + end +end + +local function getApiVersion() + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + protocol.mspRead(MSP_API_VERSION) + lastRunTS = getTime() + end + + mspProcessTxQ() + processMspReply(mspPollReply()) + + return apiVersionReceived +end + +return { f = getApiVersion, t = "Waiting for API version" } diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index 203be3e7..239a5698 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -1,58 +1,41 @@ -local sensorId = -1 -local dataInitialised = false -local data_init = nil +local apiVersionReceived = false +local timeIsSet = false +local getApiVersion, setRtc, rssiTask local rssiEnabled = true -local rssiTask = nil - -local function getSensorValue() - if sensorId == -1 then - local sensor = getFieldInfo(protocol.stateSensor) - if type(sensor) == "table" then - sensorId = sensor['id'] or -1 - end - end - return getValue(sensorId) -end - -local function modelActive(sensorValue) - return type(sensorValue) == "number" and sensorValue > 0 -end local function run_bg() - local sensorValue = getSensorValue() - if modelActive(sensorValue) then + if getRSSI() > 0 then -- Send data when the telemetry connection is available -- assuming when sensor value higher than 0 there is an telemetry connection - if not dataInitialised then - if not data_init then - data_init = assert(loadScript("data_init.lua"))() + if not apiVersionReceived then + getApiVersion = getApiVersion or assert(loadScript("api_version.lua"))() + apiVersionReceived = getApiVersion.f() + if apiVersionReceived then + getApiVersion = nil + collectgarbage() end - - dataInitialised = data_init() - - if dataInitialised then - data_init = nil - + elseif not timeIsSet then + setRtc = setRtc or assert(loadScript("rtc.lua"))() + timeIsSet = setRtc.f() + if timeIsSet then + setRtc = nil collectgarbage() end elseif rssiEnabled and apiVersion >= 1.037 then - if not rssiTask then - rssiTask = assert(loadScript("rssi.lua"))() - end - + rssiTask = rssiTask or assert(loadScript("rssi.lua"))() rssiEnabled = rssiTask() - if not rssiEnabled then rssiTask = nil - collectgarbage() end end else - dataInitialised = false + apiVersionReceived = false + timeIsSet = false rssiEnabled = true - if data_init or rssiTask then - data_init = nil + if getApiVersion or setRtc or rssiTask then + getApiVersion = nil + setRtc = nil rssiTask = nil collectgarbage() end diff --git a/src/SCRIPTS/BF/board_info.lua b/src/SCRIPTS/BF/board_info.lua new file mode 100644 index 00000000..1fae01e5 --- /dev/null +++ b/src/SCRIPTS/BF/board_info.lua @@ -0,0 +1,137 @@ +local MSP_BOARD_INFO = 4 + +local boardInfoReceived = false + +local boardIdentifier = "" +local hardwareRevision = 0 +local boardType = 0 +local targetCapabilities = 0 +local targetName = "" +local boardName = "" +local manufacturerId = "" +local signature = {} +local mcuTypeId = 255 +local configurationState = 0 +local gyroSampleRateHz = 0 +local configurationProblems = 0 +local spiRegisteredDeviceCount = 0 +local i2cRegisteredDeviceCount = 0 + +local lastRunTS = 0 +local INTERVAL = 100 + +local function processMspReply(cmd, payload) + if cmd == MSP_BOARD_INFO then + local length + local i = 1 + length = 4 + for c = 1, 4 do + boardIdentifier = boardIdentifier..string.char(payload[i]) + i = i + 1 + end + for idx = 1, 2 do + local raw_val = bit32.lshift(payload[i], (idx-1)*8) + hardwareRevision = bit32.bor(hardwareRevision, raw_val) + i = i + 1 + end + if apiVersion >= 1.035 then + boardType = payload[i] + end + i = i + 1 + if apiVersion >= 1.037 then + targetCapabilities = payload[i] + i = i + 1 + length = payload[i] + i = i + 1 + for c = 1, length do + targetName = targetName..string.char(payload[i]) + i = i + 1 + end + end + if apiVersion >= 1.039 then + length = payload[i] + i = i + 1 + for c = 1, length do + boardName = boardName..string.char(payload[i]) + i = i + 1 + end + length = payload[i] + i = i + 1 + for c = 1, length do + manufacturerId = manufacturerId..string.char(payload[i]) + i = i + 1 + end + length = 32 + for c = 1, 32 do + signature[#signature + 1] = payload[i] + i = i + 1 + end + end + i = i + 1 + if apiVersion >= 1.041 then + mcuTypeId = payload[i] + end + i = i + 1 + if apiVersion >= 1.042 then + configurationState = payload[i] + end + if apiVersion >= 1.043 then + for idx = 1, 2 do + local raw_val = bit32.lshift(payload[i], (idx-1)*8) + gyroSampleRateHz = bit32.bor(gyroSampleRateHz, raw_val) + i = i + 1 + end + for idx = 1, 4 do + local raw_val = bit32.lshift(payload[i], (idx-1)*8) + configurationProblems = bit32.bor(configurationProblems, raw_val) + i = i + 1 + end + end + if apiVersion >= 1.044 then + spiRegisteredDeviceCount = payload[i] + i = i + 1 + i2cRegisteredDeviceCount = payload[i] + end + boardInfoReceived = true + end +end + +local function getBoardInfo() + if lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + if not boardInfoReceived then + protocol.mspRead(MSP_BOARD_INFO) + end + end + mspProcessTxQ() + processMspReply(mspPollReply()) + if boardInfoReceived then + local f = io.open("BOARD_INFO/"..mcuId..".lua", 'w') + io.write(f, "return {", "\n") + io.write(f, " boardIdentifier = "..'"'..boardIdentifier..'"'..",", "\n") + io.write(f, " hardwareRevision = "..tostring(hardwareRevision)..",", "\n") + io.write(f, " boardType = "..tostring(boardType)..",", "\n") + io.write(f, " targetCapabilities = "..tostring(targetCapabilities)..",", "\n") + io.write(f, " targetName = "..'"'..targetName..'"'..",", "\n") + io.write(f, " boardName = "..'"'..boardName..'"'..",", "\n") + io.write(f, " manufacturerId = "..'"'..manufacturerId..'"'..",", "\n") + local signatureString = " signature = { " + for i = 1, #signature do + signatureString = signatureString..tostring(signature[i])..", " + end + signatureString = signatureString.."}," + io.write(f, signatureString, "\n") + io.write(f, " mcuTypeId = "..tostring(mcuTypeId)..",", "\n") + io.write(f, " configurationState = "..tostring(configurationState)..",", "\n") + io.write(f, " gyroSampleRateHz = "..tostring(gyroSampleRateHz)..",", "\n") + io.write(f, " configurationProblems = "..tostring(configurationProblems)..",", "\n") + io.write(f, " spiRegisteredDeviceCount = "..tostring(spiRegisteredDeviceCount)..",", "\n") + io.write(f, " i2cRegisteredDeviceCount = "..tostring(i2cRegisteredDeviceCount)..",", "\n") + io.write(f, "}", "\n") + io.close(f) + assert(loadScript("BOARD_INFO/"..mcuId..".lua", 'c')) + end + return boardInfoReceived +end + +return { f = getBoardInfo, t = "Downloading board info" } diff --git a/src/SCRIPTS/BF/cms.lua b/src/SCRIPTS/BF/cms.lua new file mode 100644 index 00000000..fdb5752c --- /dev/null +++ b/src/SCRIPTS/BF/cms.lua @@ -0,0 +1,35 @@ +local lastMenuEventTime = 0 +local INTERVAL = 80 + +local function init() + cms.init(radio) +end + +local function stickMovement() + local threshold = 30 + return math.abs(getValue('ele')) > threshold or math.abs(getValue('ail')) > threshold or math.abs(getValue('rud')) > threshold +end + +local function run(event) + cms.update() + if cms.menuOpen == false then + cms.open() + end + if event == radio.refresh.event then + cms.synced = false + lastMenuEventTime = 0 + elseif stickMovement() then + cms.synced = false + lastMenuEventTime = getTime() + elseif event == EVT_VIRTUAL_EXIT then + cms.close() + return 1 + end + if lastMenuEventTime + INTERVAL < getTime() and not cms.synced then + lastMenuEventTime = getTime() + cms.refresh() + end + return 0 +end + +return { init=init, run=run } diff --git a/src/SCRIPTS/BF/data_init.lua b/src/SCRIPTS/BF/data_init.lua deleted file mode 100644 index ae4da07f..00000000 --- a/src/SCRIPTS/BF/data_init.lua +++ /dev/null @@ -1,66 +0,0 @@ -local MSP_API_VERSION = 1 -local MSP_SET_RTC = 246 - -local apiVersionReceived = false -local timeIsSet = false -local lastRunTS = 0 -local INTERVAL = 50 - -local function processMspReply(cmd,rx_buf) - if cmd == MSP_API_VERSION and #rx_buf >= 3 then - apiVersion = rx_buf[2] + rx_buf[3] / 1000 - - apiVersionReceived = true - end - if cmd == MSP_SET_RTC then - timeIsSet = true - end -end - -local function init() - if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then - if not apiVersionReceived then - protocol.mspRead(MSP_API_VERSION) - elseif apiVersionReceived and not timeIsSet then - -- only send datetime one time after telemetry connection became available - -- or when connection is restored after e.g. lipo refresh - local values = {} - if apiVersion >= 1.041 then - -- format: seconds after the epoch (32) / milliseconds (16) - local now = getRtcTime() - - for i = 1, 4 do - values[i] = bit32.band(now, 0xFF) - now = bit32.rshift(now, 8) - end - - values[5] = 0 -- we don't have milliseconds - values[6] = 0 - else - -- format: year (16) / month (8) / day (8) / hour (8) / min (8) / sec (8) - local now = getDateTime() - local year = now.year - - values[1] = bit32.band(year, 0xFF) - year = bit32.rshift(year, 8) - values[2] = bit32.band(year, 0xFF) - values[3] = now.mon - values[4] = now.day - values[5] = now.hour - values[6] = now.min - values[7] = now.sec - end - - protocol.mspWrite(MSP_SET_RTC, values) - end - lastRunTS = getTime() - end - - mspProcessTxQ() - - processMspReply(mspPollReply()) - - return apiVersionReceived and timeIsSet -end - -return init diff --git a/src/SCRIPTS/BF/mcu_id.lua b/src/SCRIPTS/BF/mcu_id.lua new file mode 100644 index 00000000..26d1e2ba --- /dev/null +++ b/src/SCRIPTS/BF/mcu_id.lua @@ -0,0 +1,37 @@ +local MSP_UID = 160 + +local MCUIdReceived = false + +local lastRunTS = 0 +local INTERVAL = 100 + +local function processMspReply(cmd, payload) + if cmd == MSP_UID then + local i = 1 + local id = "" + for j = 1, 3 do + local s = "" + for k = 1, 4 do + s = string.format("%02x", payload[i])..s + i = i + 1 + end + id = id..s + end + mcuId = id + MCUIdReceived = true + end +end + +local function getMCUId() + if lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + if not MCUIdReceived then + protocol.mspRead(MSP_UID) + end + end + mspProcessTxQ() + processMspReply(mspPollReply()) + return MCUIdReceived +end + +return { f = getMCUId, t = "Waiting for device ID" } diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 2fcdf6f8..68f95ee8 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -4,6 +4,10 @@ if apiVersion >= 1.036 then PageFiles[#PageFiles + 1] = { title = "VTX Settings", script = "vtx.lua" } end +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Profiles", script = "profiles.lua" } +end + if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "PIDs 1", script = "pids1.lua" } end @@ -20,6 +24,10 @@ if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "Advanced PIDs", script = "pid_advanced.lua" } end +if apiVersion >= 1.044 then + PageFiles[#PageFiles + 1] = { title = "Simplified Tuning", script = "simplified_tuning.lua" } +end + if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "Filters 1", script = "filters1.lua" } end @@ -29,13 +37,17 @@ if apiVersion >= 1.042 then end if apiVersion >= 1.016 then - PageFiles[#PageFiles + 1] = { title = "Gyro / Motor", script = "pwm.lua" } + PageFiles[#PageFiles + 1] = { title = "System / Motor", script = "pwm.lua" } end if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "Receiver", script = "rx.lua" } end +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Failsafe", script = "failsafe.lua" } +end + if apiVersion >= 1.041 then PageFiles[#PageFiles + 1] = { title = "GPS Rescue", script = "rescue.lua" } end diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index d0c1951d..c415104c 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -2,25 +2,24 @@ local supportedProtocols = { smartPort = { - transport = "MSP/sp.lua", - rssi = function() return getValue("RSSI") end, - stateSensor = "Tmp1", + mspTransport = "MSP/sp.lua", push = sportTelemetryPush, maxTxBufferSize = 6, maxRxBufferSize = 6, saveMaxRetries = 2, - saveTimeout = 500 + saveTimeout = 500, + cms = {}, }, crsf = { - transport = "MSP/crsf.lua", - rssi = function() return getValue("TQly") end, - stateSensor = "1RSS", + mspTransport = "MSP/crsf.lua", + cmsTransport = "CMS/crsf.lua", push = crossfireTelemetryPush, maxTxBufferSize = 8, maxRxBufferSize = 58, saveMaxRetries = 2, - saveTimeout = 150 + saveTimeout = 150, + cms = {}, } } diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 6f200e4c..13eecaa8 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -2,45 +2,126 @@ local supportedRadios = { ["128x64"] = { - templateHome = "TEMPLATES/128x64/", - MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, - SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, - NoTelem = { 30, 55, "No Telemetry", BLINK }, - textSize = SMLSIZE, - yMinLimit = 12, - yMaxLimit = 52, + msp = { + template = "TEMPLATES/128x64.lua", + MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 30, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 52, + }, + cms = { + rows = 8, + cols = 26, + pixelsPerRow = 8, + pixelsPerChar = 5, + xIndent = 0, + yOffset = 0, + textSize = SMLSIZE, + refresh = { + event = EVT_VIRTUAL_ENTER, + text = "Refresh: [ENT]", + top = 1, + left = 64, + }, + }, + }, + ["128x96"] = + { + msp = { + template = "TEMPLATES/128x96.lua", + MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 30, 87, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 84, + }, + cms = { + rows = 12, + cols = 26, + pixelsPerRow = 8, + pixelsPerChar = 5, + xIndent = 0, + yOffset = 0, + textSize = SMLSIZE, + refresh = { + event = EVT_VIRTUAL_ENTER, + text = "Refresh: [ENT]", + top = 1, + left = 64, + }, + }, }, ["212x64"] = { - templateHome = "TEMPLATES/212x64/", - MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, - SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, - NoTelem = { 70, 55, "No Telemetry", BLINK }, - textSize = SMLSIZE, - yMinLimit = 12, - yMaxLimit = 52, + msp = { + template = "TEMPLATES/212x64.lua", + MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 70, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 52, + }, + cms = { + rows = 8, + cols = 32, + pixelsPerRow = 8, + pixelsPerChar = 6, + xIndent = 0, + yOffset = 0, + textSize = SMLSIZE, + refresh = { + event = EVT_VIRTUAL_INC, + text = "Refresh: [+]", + top = 1, + left = 156, + } + }, }, ["480x272"] = { - templateHome = "TEMPLATES/480x272/", - highRes = true, - MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, - SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, - textSize = 0, - yMinLimit = 35, - yMaxLimit = 235, + msp = { + template = "TEMPLATES/480x272.lua", + highRes = true, + MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, + textSize = 0, + yMinLimit = 35, + yMaxLimit = 235, + }, + cms = { + rows = 9, + cols = 32, + pixelsPerRow = 24, + pixelsPerChar = 14, + xIndent = 14, + yOffset = 32, + textSize = MIDSIZE, + refresh = { + event = EVT_VIRTUAL_ENTER, + text = "Refresh: [ENT]", + top = 1, + left = 300, + } + }, }, ["320x480"] = { - templateHome = "TEMPLATES/320x480/", - highRes = true, - MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, - SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, - textSize = 0, - yMinLimit = 35, - yMaxLimit = 435, + msp = { + template = "TEMPLATES/320x480.lua", + highRes = true, + MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, + textSize = 0, + yMinLimit = 35, + yMaxLimit = 435, + }, + cms = nil, }, } diff --git a/src/SCRIPTS/BF/rtc.lua b/src/SCRIPTS/BF/rtc.lua new file mode 100644 index 00000000..955c91e9 --- /dev/null +++ b/src/SCRIPTS/BF/rtc.lua @@ -0,0 +1,54 @@ +local MSP_SET_RTC = 246 + +local timeIsSet = false +local lastRunTS = 0 +local INTERVAL = 50 + +local function processMspReply(cmd,rx_buf) + if cmd == MSP_SET_RTC then + timeIsSet = true + end +end + +local function setRtc() + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + -- only send datetime one time after telemetry connection became available + -- or when connection is restored after e.g. lipo refresh + local values = {} + if apiVersion >= 1.041 then + -- format: seconds after the epoch (32) / milliseconds (16) + local now = getRtcTime() + + for i = 1, 4 do + values[i] = bit32.band(now, 0xFF) + now = bit32.rshift(now, 8) + end + + values[5] = 0 -- we don't have milliseconds + values[6] = 0 + else + -- format: year (16) / month (8) / day (8) / hour (8) / min (8) / sec (8) + local now = getDateTime() + local year = now.year + + values[1] = bit32.band(year, 0xFF) + year = bit32.rshift(year, 8) + values[2] = bit32.band(year, 0xFF) + values[3] = now.mon + values[4] = now.day + values[5] = now.hour + values[6] = now.min + values[7] = now.sec + end + + protocol.mspWrite(MSP_SET_RTC, values) + lastRunTS = getTime() + end + + mspProcessTxQ() + processMspReply(mspPollReply()) + + return timeIsSet +end + +return { f = setRtc, t = "" } diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index c65dfd09..01d6e6e1 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -1,25 +1,26 @@ local uiStatus = { init = 1, - pages = 2, - mainMenu = 3, + mainMenu = 2, + pages = 3, + confirm = 4, } local pageStatus = { - display = 2, - editing = 3, - saving = 4, - popupMenu = 5, + display = 1, + editing = 2, + saving = 3, } local uiMsp = { reboot = 68, - eepromWrite = 250 + eepromWrite = 250, } local uiState = uiStatus.init +local prevUiState local pageState = pageStatus.display local requestTimeout = 80 local currentPage = 1 @@ -32,7 +33,7 @@ local popupMenuActive = 1 local killEnterBreak = 0 local pageScrollY = 0 local mainMenuScrollY = 0 -local PageFiles, Page, init, popupMenuList +local PageFiles, Page, init, popupMenu local backgroundFill = TEXT_BGCOLOR or ERASE local foregroundColor = LINE_COLOR or SOLID @@ -72,22 +73,26 @@ local function eepromWrite() protocol.mspRead(uiMsp.eepromWrite) end -local function getVtxTables() - uiState = uiStatus.init - PageFiles = nil +local function confirm(page) + prevUiState = uiState + uiState = uiStatus.confirm invalidatePages() - io.close(io.open("/BF/VTX/"..model.getInfo().name..".lua", 'w')) - return 0 + currentField = 1 + Page = assert(loadScript(page))() + collectgarbage() end local function createPopupMenu() - popupMenuList = { - { t = "save page", f = saveSettings }, - { t = "reload", f = invalidatePages }, - { t = "reboot", f = rebootFc }, - } + popupMenuActive = 1 + popupMenu = {} + if uiState == uiStatus.pages then + popupMenu[#popupMenu + 1] = { t = "save page", f = saveSettings } + popupMenu[#popupMenu + 1] = { t = "reload", f = invalidatePages } + end + popupMenu[#popupMenu + 1] = { t = "reboot", f = rebootFc } + popupMenu[#popupMenu + 1] = { t = "acc cal", f = function() confirm("CONFIRM/acc_cal.lua") end } if apiVersion >= 1.042 then - popupMenuList[#popupMenuList + 1] = { t = "vtx tables", f = getVtxTables } + popupMenu[#popupMenu + 1] = { t = "vtx tables", f = function() confirm("CONFIRM/vtx_tables.lua") end } end end @@ -154,7 +159,7 @@ local function incMainMenu(inc) end local function incPopupMenu(inc) - popupMenuActive = clipValue(popupMenuActive + inc, 1, #popupMenuList) + popupMenuActive = clipValue(popupMenuActive + inc, 1, #popupMenu) end local function requestPage() @@ -169,7 +174,7 @@ local function drawScreenTitle(screenTitle) lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR) lcd.drawText(5,5,screenTitle, MENU_TITLE_COLOR) else - lcd.drawFilledRectangle(0, 0, LCD_W, 10) + lcd.drawFilledRectangle(0, 0, LCD_W, 10, FORCE) lcd.drawText(1,1,screenTitle,INVERS) end end @@ -179,7 +184,6 @@ local function drawScreen() local yMaxLim = radio.yMaxLimit local currentFieldY = Page.fields[currentField].y local textOptions = radio.textSize + globalTextOptions - drawScreenTitle("Betaflight / "..Page.title) if currentFieldY <= Page.fields[1].y then pageScrollY = 0 elseif currentFieldY - pageScrollY <= yMinLim then @@ -190,7 +194,7 @@ local function drawScreen() for i=1,#Page.labels do local f = Page.labels[i] local y = f.y - pageScrollY - if y >= yMinLim and y <= yMaxLim then + if y >= 0 and y <= LCD_H then lcd.drawText(f.x, y, f.t, textOptions) end end @@ -214,13 +218,14 @@ local function drawScreen() end end local y = f.y - pageScrollY - if y >= yMinLim and y <= yMaxLim then + if y >= 0 and y <= LCD_H then if f.t then lcd.drawText(f.x, y, f.t, textOptions) end lcd.drawText(f.sp or f.x, y, val, valueOptions) end end + drawScreenTitle("Betaflight / "..Page.title) end local function incValue(inc) @@ -243,13 +248,13 @@ local function drawPopupMenu() local w = radio.MenuBox.w local h_line = radio.MenuBox.h_line local h_offset = radio.MenuBox.h_offset - local h = #popupMenuList * h_line + h_offset*2 + local h = #popupMenu * h_line + h_offset*2 lcd.drawFilledRectangle(x,y,w,h,backgroundFill) lcd.drawRectangle(x,y,w-1,h-1,foregroundColor) lcd.drawText(x+h_line/2,y+h_offset,"Menu:",globalTextOptions) - for i,e in ipairs(popupMenuList) do + for i,e in ipairs(popupMenu) do local textOptions = globalTextOptions if popupMenuActive == i then textOptions = textOptions + INVERS @@ -259,18 +264,35 @@ local function drawPopupMenu() end local function run_ui(event) - if uiState == uiStatus.init then + if popupMenu then + drawPopupMenu() + if event == EVT_VIRTUAL_EXIT then + popupMenu = nil + elseif event == EVT_VIRTUAL_PREV then + incPopupMenu(-1) + elseif event == EVT_VIRTUAL_NEXT then + incPopupMenu(1) + elseif event == EVT_VIRTUAL_ENTER then + if killEnterBreak == 1 then + killEnterBreak = 0 + else + popupMenu[popupMenuActive].f() + popupMenu = nil + end + end + elseif uiState == uiStatus.init then lcd.clear() drawScreenTitle("Betaflight Config") init = init or assert(loadScript("ui_init.lua"))() - if not init() then + lcd.drawText(6, radio.yMinLimit, init.t) + if not init.f() then return 0 end init = nil - createPopupMenu() PageFiles = assert(loadScript("pages.lua"))() invalidatePages() - uiState = uiStatus.mainMenu + uiState = prevUiState or uiStatus.mainMenu + prevUiState = nil elseif uiState == uiStatus.mainMenu then if event == EVT_VIRTUAL_EXIT then return 2 @@ -280,9 +302,11 @@ local function run_ui(event) incMainMenu(-1) elseif event == EVT_VIRTUAL_ENTER then uiState = uiStatus.pages + elseif event == EVT_VIRTUAL_ENTER_LONG then + killEnterBreak = 1 + createPopupMenu() end lcd.clear() - drawScreenTitle("Betaflight Config") local yMinLim = radio.yMinLimit local yMaxLim = radio.yMaxLimit local lineSpacing = 10 @@ -300,10 +324,11 @@ local function run_ui(event) for i=1, #PageFiles do local attr = currentPage == i and INVERS or 0 local y = (i-1)*lineSpacing + yMinLim - mainMenuScrollY - if y >= yMinLim and y <= yMaxLim then + if y >= 0 and y <= LCD_H then lcd.drawText(6, y, PageFiles[i].title, attr) end end + drawScreenTitle("Betaflight Config") elseif uiState == uiStatus.pages then if pageState == pageStatus.saving then if saveTS + saveTimeout < getTime() then @@ -314,21 +339,6 @@ local function run_ui(event) invalidatePages() end end - elseif pageState == pageStatus.popupMenu then - if event == EVT_VIRTUAL_EXIT then - pageState = pageStatus.display - elseif event == EVT_VIRTUAL_PREV then - incPopupMenu(-1) - elseif event == EVT_VIRTUAL_NEXT then - incPopupMenu(1) - elseif event == EVT_VIRTUAL_ENTER then - if killEnterBreak == 1 then - killEnterBreak = 0 - else - pageState = pageStatus.display - return popupMenuList[popupMenuActive].f() or 0 - end - end elseif pageState == pageStatus.display then if event == EVT_VIRTUAL_PREV_PAGE then incPage(-1) @@ -347,9 +357,8 @@ local function run_ui(event) end end elseif event == EVT_VIRTUAL_ENTER_LONG then - popupMenuActive = 1 killEnterBreak = 1 - pageState = pageStatus.popupMenu + createPopupMenu() elseif event == EVT_VIRTUAL_EXIT then invalidatePages() currentField = 1 @@ -358,6 +367,9 @@ local function run_ui(event) end elseif pageState == pageStatus.editing then if event == EVT_VIRTUAL_EXIT or event == EVT_VIRTUAL_ENTER then + if Page.fields[currentField].postEdit then + Page.fields[currentField].postEdit(Page) + end pageState = pageStatus.display elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then incValue(1) @@ -366,7 +378,7 @@ local function run_ui(event) end end if not Page then - Page = assert(loadScript("Pages/"..PageFiles[currentPage].script))() + Page = assert(loadScript("PAGES/"..PageFiles[currentPage].script))() collectgarbage() end if not Page.values and pageState == pageStatus.display then @@ -374,9 +386,7 @@ local function run_ui(event) end lcd.clear() drawScreen() - if pageState == pageStatus.popupMenu then - drawPopupMenu() - elseif pageState == pageStatus.saving then + if pageState == pageStatus.saving then local saveMsg = "Saving..." if saveRetries > 0 then saveMsg = "Retrying" @@ -385,8 +395,20 @@ local function run_ui(event) lcd.drawRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,SOLID) lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,saveMsg,DBLSIZE + globalTextOptions) end + elseif uiState == uiStatus.confirm then + lcd.clear() + drawScreen() + if event == EVT_VIRTUAL_ENTER then + uiState = uiStatus.init + init = Page.init + invalidatePages() + elseif event == EVT_VIRTUAL_EXIT then + invalidatePages() + uiState = prevUiState + prevUiState = nil + end end - if protocol.rssi() == 0 then + if getRSSI() == 0 then lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) end mspProcessTxQ() diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 8686b5dc..632fea68 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,35 +1,62 @@ local apiVersionReceived = false local vtxTablesReceived = false -local data_init, getVtxTables -local vtxTables = loadScript("/BF/VTX/"..model.getInfo().name..".lua") - -if vtxTables and vtxTables() then - vtxTablesReceived = true - vtxTables = nil - collectgarbage() -end +local mcuIdReceived = false +local boardInfoReceived = false +local getApiVersion, getVtxTables, getMCUId, getBoardInfo +local returnTable = { f = nil, t = "" } local function init() - if apiVersion == 0 then - lcd.drawText(6, radio.yMinLimit, "Initialising") - data_init = data_init or assert(loadScript("data_init.lua"))() - data_init() - elseif apiVersion > 0 and not apiVersionReceived then - data_init = nil - apiVersionReceived = true - collectgarbage() - elseif apiVersion >= 1.042 and not vtxTablesReceived then - lcd.drawText(6, radio.yMinLimit, "Downloading VTX Tables") + if getRSSI() == 0 then + returnTable.t = "Waiting for connection" + elseif not apiVersionReceived then + getApiVersion = getApiVersion or assert(loadScript("api_version.lua"))() + returnTable.t = getApiVersion.t + apiVersionReceived = getApiVersion.f() + if apiVersionReceived then + getApiVersion = nil + collectgarbage() + end + elseif not mcuIdReceived and apiVersion >= 1.042 then + getMCUId = getMCUId or assert(loadScript("mcu_id.lua"))() + returnTable.t = getMCUId.t + mcuIdReceived = getMCUId.f() + if mcuIdReceived then + getMCUId = nil + local f = loadScript("VTX_TABLES/"..mcuId..".lua") + if f and f() then + vtxTablesReceived = true + f = nil + end + collectgarbage() + f = loadScript("BOARD_INFO/"..mcuId..".lua") + if f and f() then + boardInfoReceived = true + f = nil + end + collectgarbage() + end + elseif not vtxTablesReceived and apiVersion >= 1.042 then getVtxTables = getVtxTables or assert(loadScript("vtx_tables.lua"))() - vtxTablesReceived = getVtxTables() + returnTable.t = getVtxTables.t + vtxTablesReceived = getVtxTables.f() if vtxTablesReceived then getVtxTables = nil collectgarbage() end + elseif not boardInfoReceived and apiVersion >= 1.043 then + getBoardInfo = getBoardInfo or assert(loadScript("board_info.lua"))() + returnTable.t = getBoardInfo.t + boardInfoReceived = getBoardInfo.f() + if boardInfoReceived then + getBoardInfo = nil + collectgarbage() + end else return true end - return apiVersionReceived and vtxTablesReceived + return apiVersionReceived and vtxTablesReceived and mcuId and boardInfoReceived end -return init +returnTable.f = init + +return returnTable diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index 83ca15ea..2efa8942 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -82,7 +82,7 @@ local function getVtxTables() end end if vtxTablesReceived then - local f = io.open("/BF/VTX/"..model.getInfo().name..".lua", 'w') + local f = io.open("VTX_TABLES/"..mcuId..".lua", 'w') io.write(f, "return {", "\n") io.write(f, " frequencyTable = {", "\n") for i = 1, #frequencyTable do @@ -109,11 +109,11 @@ local function getVtxTables() io.write(f, powerString, "\n") io.write(f, "}", "\n") io.close(f) - assert(loadScript("/BF/VTX/"..model.getInfo().name..".lua", 'c')) + assert(loadScript("VTX_TABLES/"..mcuId..".lua", 'c')) end mspProcessTxQ() processMspReply(mspPollReply()) return vtxTablesReceived end -return getVtxTables +return { f = getVtxTables, t = "Downloading VTX tables" } diff --git a/src/SCRIPTS/FUNCTIONS/bfbkgd.lua b/src/SCRIPTS/FUNCTIONS/bfbkgd.lua index fcaec519..137000ba 100644 --- a/src/SCRIPTS/FUNCTIONS/bfbkgd.lua +++ b/src/SCRIPTS/FUNCTIONS/bfbkgd.lua @@ -1,7 +1,7 @@ chdir("/SCRIPTS/BF") apiVersion = 0 protocol = assert(loadScript("protocols.lua"))() -assert(loadScript(protocol.transport))() +assert(loadScript(protocol.mspTransport))() assert(loadScript("MSP/common.lua"))() local background = assert(loadScript("background.lua"))() diff --git a/src/SCRIPTS/FUNCTIONS/pids.lua b/src/SCRIPTS/FUNCTIONS/bfpids.lua similarity index 100% rename from src/SCRIPTS/FUNCTIONS/pids.lua rename to src/SCRIPTS/FUNCTIONS/bfpids.lua diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua deleted file mode 100644 index 3b931cfd..00000000 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ /dev/null @@ -1,6 +0,0 @@ -local function run(event) - lcd.clear() - lcd.drawText(2, 2, "Use TOOLS menu instead of this") -end - -return { run=run } diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index af3d420b..3c4ee8b1 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -2,14 +2,15 @@ local toolName = "TNS|Betaflight setup|TNE" chdir("/SCRIPTS/BF") apiVersion = 0 +mcuId = nil local run = nil local scriptsCompiled = assert(loadScript("COMPILE/scripts_compiled.lua"))() if scriptsCompiled then protocol = assert(loadScript("protocols.lua"))() - radio = assert(loadScript("radios.lua"))() - assert(loadScript(protocol.transport))() + radio = assert(loadScript("radios.lua"))().msp + assert(loadScript(protocol.mspTransport))() assert(loadScript("MSP/common.lua"))() run = assert(loadScript("ui.lua"))() else diff --git a/src/SCRIPTS/TOOLS/bfCms.lua b/src/SCRIPTS/TOOLS/bfCms.lua new file mode 100644 index 00000000..d9a8b0ab --- /dev/null +++ b/src/SCRIPTS/TOOLS/bfCms.lua @@ -0,0 +1,20 @@ +local toolName = "TNS|Betaflight CMS|TNE" +chdir("/SCRIPTS/BF") + +apiVersion = 0 + +local cms = { run = nil, init = nil } +local scriptsCompiled = assert(loadScript("COMPILE/scripts_compiled.lua"))() + +if scriptsCompiled then + protocol = assert(loadScript("protocols.lua"))() + local cmsTransport = assert(protocol.cmsTransport, "Telemetry protocol not supported!") + radio = assert(loadScript("radios.lua"))().cms + assert(loadScript(cmsTransport))() + assert(loadScript("CMS/common.lua"))() + cms = assert(loadScript("cms.lua"))() +else + cms = { run = assert(loadScript("COMPILE/compile.lua"))() } +end + +return cms