mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-04 18:48:11 +00:00
Frankie dsm fwrd prg enhancements (#763)
* #751 DSM Enhancements #751 DSM Forward Programming Enhancements (New GUI, etc) * Make both work on EdgeTx and OpenTX * #751 Turn OFF simulation by default Distribution code with RX simulation OFF Simulation should be only for Development * #751 Update Readme Documentation Updated the Readme.txt documentation and removed compiled luac file that was check in by mistake * #751 Fix problems With Reset RX 1. Fix problem when trying to Factory Reset. Enter Bind Mode. Save backup, Restore Backup 2. Found a way to advance on the Gyro initial Setup menus.. a bit of a hack, but works. 3. Handle RX resets properly. It needed after initial setup * #751 Cosmetic and Show Orientation Images #751 1. Fix problems when text contradictions between Menu/Line Headers and List Values 2. Show Images of RX orientations 3. Able to Hack getting into Initial Setup and other menus who was failing before 4. Custumize the way Flight Mode reports the Value on Screen * #751 add check for required libraries Add check that the required files in DSMLIB exist * #751 Write documentation about the protocol so that we don't forget later what we know, and enable others to understand the logs and maybe help solve problems. Co-authored-by: pascallanger <pascal_langer@yahoo.fr>
This commit is contained in:
parent
60047e2c73
commit
7052751261
445
Lua_scripts/DSMLIB/DSM Fwd Prog Protocol.md
Normal file
445
Lua_scripts/DSMLIB/DSM Fwd Prog Protocol.md
Normal file
@ -0,0 +1,445 @@
|
||||
# Forward Programing Protocol
|
||||
|
||||
## Introduction
|
||||
DSM, DSMX and DSM Forward Programming are propietary protocol from the **Spektrum** radio brand. Since they don't make this information public, we have to reverse engineer it by analyzing the data exchanged between the RX and TX.
|
||||
|
||||
This document descrives what we know so far.
|
||||
|
||||
Thanks to **Pascal Langer** (Author of the Multi-Module) for the initial reverse engineering of the protocol and first version of the code that has been used for a while (Version 0.2)
|
||||
|
||||
Thanks to **Francisco Arzu** for taking the time to continue the work on documenting and making the code more understandable, as well as having the capabilities to write log files. Improve the GUI, and reversed engineer a few other smaller things. (Version 0.5)
|
||||
|
||||
# Menu Title and Lines
|
||||
|
||||
The menu to be displayed is stored at the RX, the GUI only renders the menu title and menu lines received. The tipical conversation with the RX will be to ask for a menu (using the menuId number), and then wait for the data to come. The first thing will be the Menu (header) data, later we request the next 6 lines (one at a time), and optionally the values for each line.
|
||||
|
||||
A typical exchange will look like this in the log:
|
||||
|
||||
SEND DSM_getMenu(MenuId=0x1010 LastSelectedLine=0)
|
||||
RESPONSE Menu: M[Id=0x1010 P=0x0 N=0x0 B=0x1000 Text="Gyro settings"[0xF9]]
|
||||
SEND DSM_getFirstMenuLine(MenuId=0x1010)
|
||||
RESPONSE MenuLine: L[#0 T=M VId=0x1011 Text="AS3X Settings"[0x1DD] MId=0x1010 ]
|
||||
SEND DSM_getNextLine(MenuId=0x1010,LastLine=0)
|
||||
RESPONSE MenuLine: L[#1 T=M VId=0x1019 Text="SAFE Settings"[0x1E2] MId=0x1010 ]
|
||||
SEND DSM_getNextLine(MenuId=0x1010,LastLine=1)
|
||||
RESPONSE MenuLine: L[#2 T=M VId=0x1021 Text="F-Mode Setup"[0x87] MId=0x1010 ]
|
||||
SEND DSM_getNextLine(MenuId=0x1010,LastLine=2)
|
||||
RESPONSE MenuLine: L[#3 T=M VId=0x1022 Text="System Setup"[0x86] MId=0x1010 ]
|
||||
|
||||
## Menu
|
||||
|
||||
The menu has the following information:
|
||||
|
||||
Menu: M[Id=0x1010 P=0x0 N=0x0 B=0x1000 Text="Gyro settings"[0xF9]]
|
||||
|
||||
- `MenuId`: The menu ID number of the menu (hex, 16 bit number)
|
||||
- `PrevId`: The menu ID of the previous menu (for navigation), Log show as `"P="`
|
||||
- `NextId`: The menu ID of the next menu (for navigation), Log shows as `"N="`
|
||||
- `BackId`: The menu ID of the back menu (for navigation), Log shows as `"B="`
|
||||
- `TextId`: The message number to display (16 bits, Hex). Log shows as [`0xXX`] after the message.
|
||||
- `Text`: Retrived using the `TextId` from the script message `Text` array.
|
||||
|
||||
## Menu Lines
|
||||
|
||||
The menu lines has the following information:
|
||||
|
||||
L[#0 T=V_NC VId=0x1000 Text="Flight Mode"[0x8001] Val=1 [0->10,0] MId=0x1021 ]
|
||||
L[#1 T=M VId=0x7CA6 Text="FM Channel"[0x78] MId=0x1021 ]
|
||||
L[#2 T=L_m1 VId=0x1002 Text="AS3X"[0x1DC] Val=1|"Act" NL=(0->1,0,S=3) [3->4,3] MId=0x1021 ]
|
||||
|
||||
- `MenuId`: of the menu they beling to. Log show as `"MId="` at the end.
|
||||
- `LineNum`: Line number (0..5). The line number in the screen. Log show as # in the beginning
|
||||
- `Type`: Type of Line, Log shows as `"T="` (explanation later)
|
||||
- `TextId`: The message number to display (16 bits, Hex). Log shows as [`0xXX`] after the message.
|
||||
- `Text`: Retrived using the `TextId` from the script message `Text` array.
|
||||
- `ValueId`: The value or menu ID of the line. Log shows as `"VId="`.
|
||||
- `Value Range`: Shows as [`Min`->`Max`, `Default`]. This is the RAW data comming from the RX
|
||||
- `NL`: Computed Normalized (0 reference) for List Values. Source is the RAW range. For example, for lines of list of values. `[3->4,3]` is tranlated to `NL=(0->1,0,S=3)` since the value is also normalize to 0. `"S="` means the initial entry in the `List_Text` array
|
||||
- `Val`: Current value for line who hold data. Relative to 0 for List Values. For List Values, the log will show the translation of the value to display text. example: `Val=1|"Act"` that is coming from `List_Value[4]`
|
||||
|
||||
## Type of Menu Lines
|
||||
|
||||
- `LINE_TYPE.MENU (Log: "T=M")`: This could be regular text or a navigation to another menu. if `ValueId` is the same as the current MenuId (`MId=`), is a plain text line. If the `ValueId` is different, then `ValueId` is the MenuId to navigate to.
|
||||
|
||||
Example, FM_Channel is a navigation to menuId=0x7CA6.
|
||||
|
||||
L[#1 T=M VId=0x7CA6 Text="FM Channel"[0x78] MId=0x1021 ]
|
||||
|
||||
|
||||
- `LINE_TYPE.VALUE_NOCHANGING (Log: "T=V_NC")`: This is a line with a value that is not editable in the screen. For example, "Flight modes" are usually this type, since the data comes from the RX just to be display and is changed by a TX switch.
|
||||
|
||||
Example, Flight mode comes from Variable ValId=0x1000, with current value of 1. Range of the Value is 0..10.
|
||||
|
||||
L[#0 T=V_NC VId=0x1000 Text="Flight Mode"[0x8001] Val=1 [0->10,0] MId=0x1021 ]
|
||||
|
||||
- `LINE_TYPE.LIST_MENU0 (Log T=L_m0)`: This is a line that shows as text in the GUI. The numeric value is translated to the proper text. The range is important, since it descrives the range of posible values.
|
||||
|
||||
Example: List of Values, List_Text[] starts at 53, ends at 85, with a default of 85. When normalized to 0, is a range from 0->32 for the numeric value. The Display value `Aux1` is retrive from `List_Text[6+53]`.
|
||||
|
||||
L[#0 T=L_m0 VId=0x1000 Text="FM Channel"[0x78] Val=6|"Aux1" NL=(0->32,0,S=53) [53->85,53] MId=0x7CA6 ]
|
||||
|
||||
- `LINE_TYPE.LIST_MENU1 (Log T=L_m1)`: Mostly the same as MENU0, but some times, it comes with a strange range `[0->244,Default]`. Usually this means that the values are not contiguos.
|
||||
|
||||
Example: Valid Values: 3,176->177 (Inh, Self-Level/Angle Dem, Envelope)
|
||||
L[#3 T=L_m1 VId=0x1003 Text="Safe Mode"[0x1F8] Val=176|"Self-Level/Angle Dem" NL=(0->244,3,S=0) [0->244,3] MId=0x1021 ]
|
||||
|
||||
- `LINE_TYPE.LIST_MENU2 (Log T=L_m2)`: Mostly the same as MENU0, but is just 2 values. (ON/OFF, Ihn/Act, etc). Should be a toggle in the GUI.
|
||||
|
||||
L[#2 T=L_m2 VId=0x1002 Text="AS3X"[0x1DC] Val=1|"Act" NL=(0->1,0,S=3) [3->4,3] MId=0x1021 ]
|
||||
|
||||
- `LINE_TYPE.VALUE_NUM_I8 (Log T=V_i8)`: 8 bit number (1 byte)
|
||||
|
||||
- `LINE_TYPE.VALUE_NUM_I16' (Log T=V_i16)`: 16 Bit number (2 bytes)
|
||||
- `LINE_TYPE.VALUE_NUM_SI16 (Log T=V_si16)`: Signed 16 bit number (2 bytes)
|
||||
- `LINE_TYPE.VALUE_PERCENT (Log T=L_%)`: Shows a Percent Value. 1 Byte value.
|
||||
- `LINE_TYPE.VALUE_DEGREES (Log T=L_de)`: Shows a Degrees VAlue. 1 Byte value.
|
||||
|
||||
|
||||
## Important Behavioral differences when updating values
|
||||
|
||||
Values who are editable, are updated to RX as they change. For example, when changing trims, the servo is been moves as we change the value in real-time.
|
||||
|
||||
LIST_MENU0 is an exception. It changes only in the GUI, and only update the RX at the end when confirmed the value.
|
||||
|
||||
After finishing updating a value, a validation command is sent. RX can reject the current value, and will change it to the nearest valid value.
|
||||
|
||||
## Special Menus
|
||||
|
||||
Seems like menuId=0x0001 is special. When you navigate to this menu, the RX reboots.
|
||||
When this happens, we need to start from the beginning as if it was a new connection.
|
||||
|
||||
# Send and Receive messages
|
||||
|
||||
To comunicate with the Multi-Module, Lua scripts in OpenTx/EdgeTx has access to the `Multi_Buffer`. Writting to it will send data to RX, received data will be read from it.
|
||||
|
||||
For our specific case, this is how the Multi_Buffer is used:
|
||||
|
||||
|0..2|3|4..9|10..25
|
||||
|--|--|--|--
|
||||
|DSM|0x70+len|TX->RX data|RX->TX Data
|
||||
|
||||
To write a new DSM Fwd Programing command, write the data to address 4..9, and later set the address 3 with the length.
|
||||
|
||||
When receiving data, address 10 will have the message type we are receiving, or 0 if nothing has been received.
|
||||
|
||||
## Starting a new DSM Forward programming Connection
|
||||
|
||||
- Write 0x00 at address 3
|
||||
- Write 0x00 at address 10
|
||||
- Write "DSM" at address 0..2
|
||||
|
||||
## Disconnect
|
||||
|
||||
- Write 0x00 at address 0
|
||||
|
||||
|
||||
# Request Messages (TX->RX)
|
||||
|
||||
## DSM_sendHeartbeat()
|
||||
keep connection open.. We need to send it every 2-3 seconds, otherwise the RX will force close the connection by sending the TX an Exit_Confirm message.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg| Len? | ?? | ??
|
||||
0x00|0x04|0x00|0x00
|
||||
|
||||
SEND DSM_sendHeartbeat()
|
||||
DSM_SEND: [00 04 00 00 ]
|
||||
|
||||
## DSM_getRxVersion()
|
||||
Request the RX information
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg| Len? | ?? | ?? |??|??
|
||||
0x11|0x06|0x00|0x14|0x00|0x00
|
||||
|
||||
SEND DSM_getRxVersion()
|
||||
DSM_SEND: [11 06 00 14 00 00 ]
|
||||
|
||||
## DSM_getMainMenu()
|
||||
Request data for the main menu of the RX
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg| Len? | ?? | ?? |??|??
|
||||
0x12|0x06|0x00|0x14|0x00|0x00
|
||||
|
||||
SEND DSM_getMainMenu()
|
||||
DSM_SEND: [12 06 00 14 00 00 ]
|
||||
|
||||
|
||||
## DSM_getMenu(menuId, lastSelLine)
|
||||
Request data for Menu with ID=`menuId`. lastSelLine is the line that was selected to navigate to that menu. Most menus works with 0, but for some special "Enter Bind Mode", "Factory Reset", "Save to Backup" they will not work if we send 0, has to be the line who was selected in the confirmation menu line "Apply".
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len? | MSB (menuId) | LSB (MenuId) | MSB (line#)??| LSB (line#)
|
||||
0x16|0x06|0x10|0x60|0x00|0x01
|
||||
|
||||
SEND DSM_getMenu(MenuId=0x1060 LastSelectedLine=1)
|
||||
DSM_SEND: [16 06 10 60 00 01 ]
|
||||
|
||||
## DSM_getFirstMenuLine(menuId)
|
||||
Request the first line of a menu identified as `menuId`. The response will be the first line of the menu. Some times, it return lines shown as `'MenuUknownLine_0x05'` that we still are trying to understand what they are for.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len? | MSB (menuId) | LSB (MenuId)
|
||||
0x13|0x04|0x10|0x60
|
||||
|
||||
SEND DSM_getFirstMenuLine(MenuId=0x1000)
|
||||
DSM_SEND: [13 04 10 00 ]
|
||||
|
||||
## DSM_getNextMenuLine(menuId, curLine)
|
||||
Request the retrival of the next line following the current line. Response is either the next line, or the next value, or nothing.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len? | MSB (menuId) | LSB (MenuId) | MSB (line#)??| LSB (line#)
|
||||
0x14|0x06|0x10|0x60|0x00|0x01
|
||||
|
||||
SEND DSM_getNextLine(MenuId=0x1000,LastLine=1)
|
||||
DSM_SEND: [14 06 10 00 00 01 ]
|
||||
|
||||
## DSM_getNextMenuValue(menuId, valId, text)
|
||||
Retrive the next value after the last `ValId` of the current `menuId`. text is just for debugging purposes to show the header of the value been retrived.
|
||||
The Response is a Menu Value or nothing if no more data.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len? | MSB (menuId) | LSB (MenuId) | MSB (ValId)| LSB (ValId)
|
||||
0x15|0x06|0x10|0x61|0x10|0x00
|
||||
|
||||
SEND DSM_getNextMenuValue(MenuId=0x1061, LastValueId=0x1000) Extra: Text="Outputs"
|
||||
DSM_SEND: [15 06 10 61 10 00 ]
|
||||
|
||||
## DSM_updateMenuValue(valId, val, text, line)
|
||||
Updates the value identified as `valId` with the numeric value `val`. `text` and `line` are there to add debugging info. No response is expected.
|
||||
|
||||
If the value is negative, it has to be translated to the proper DSM negative representaion.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len? | MSB (ValId) | LSB (ValId) | MSB (Value)| LSB (Value)
|
||||
0x18|0x06|0x??|0x??|0x??|0x??
|
||||
|
||||
DSM_updateMenuValue(valId, val, text, line)
|
||||
-->DSM_send(0x18, 0x06, int16_MSB(valId), int16_LSB(valId), int16_MSB(value), int16_LSB(value))
|
||||
|
||||
## DSM_validateMenuValue(valId, text, line)
|
||||
Validates the value identified as `valId`. `text` and `line` are there to add debugging info. The RX can response an Update value if the value is not valid and needs to be corrected.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len? | MSB (ValId) | LSB (ValId)
|
||||
0x19|0x06|0x??|0x??
|
||||
|
||||
|
||||
DSM_validateMenuValue(valId, text, line)
|
||||
-> DSM_send(0x19, 0x06, int16_MSB(valId), int16_LSB(valId))
|
||||
|
||||
## DSM_menuValueChangingWait(valId, text, line)
|
||||
Durin editing, this serves as a heartbeat that we are editing the value. The value identified as `valId`. `text` and `line` are there to add debugging info. The RX can response an Update value or a NUL response.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len?? | MSB (ValId) | LSB (ValId)
|
||||
0x1A|0x06|0x??|0x??
|
||||
|
||||
DSM_menuValueChangingWait(valId, text, line)
|
||||
->DSM_send(0x1A, 0x06, int16_MSB(valId), int16_LSB(valId))
|
||||
|
||||
## DSM_exitRequest()
|
||||
Request to end the DSM Frd Prog connection. Will reponse with an exit confirmation.
|
||||
|
||||
|4|5|6|7|8|9|10
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len?? | ??
|
||||
0x1F|0x02|0xAA
|
||||
|
||||
CALL DSM_exitRequest()
|
||||
DSM_SEND: [1F 02 AA ]
|
||||
|
||||
# Response Messages (RX->TX)
|
||||
|
||||
All responses will have the a response byte in Multi_Buffer[10]=0x09, and the type of message in Multi_Buffer[11].
|
||||
|
||||
## RX Version Response
|
||||
|
||||
Returns the information about the current RX.
|
||||
|
||||
The Display text of name name of the RX is retrive from the `RX_Name` array.
|
||||
|
||||
|10|11|12|13|14|15|16
|
||||
|--|--|--|--|--|--|--
|
||||
|Resp|Msg|?? |RxId|Major|Minor|Patch
|
||||
|0x09|0x01|0x00|0x1E|0x02|0x26|0x05
|
||||
|
||||
RESPONSE RX: 09 01 00 1E 02 26 05
|
||||
RESPONSE Receiver=AR631 Version 2.38.5
|
||||
|
||||
## Menu Response
|
||||
Returns the menu information to display and navigation.
|
||||
The Display text for the menu is retrive from the `Text` array.
|
||||
|
||||
|
||||
|10|11|12|13|14|15|16|17|18|19|20|21
|
||||
|--|--|--|--|--|--|--|--|--|--|--|--
|
||||
|Resp|Msg|LSB (menuId)|MSB (menuId)|LSB (TextId)|MSB (TextId)|LSB (PrevId)|MSB (PrevId)|LSB (NextId)|MSB (NextId)|LSB (BackId)|MSB (BackId)
|
||||
|0x09|0x02|0x5E|0x10|0x27|0x02|0x00|0x00|0x00|0x00|0x00|0x10
|
||||
|
||||
RESPONSE RX: 09 02 5E 10 27 02 00 00 00 00 00 10 00 00 00 00
|
||||
RESPONSE Menu: M[Id=0x105E P=0x0 N=0x0 B=0x1000 Text="Other settings"[0x227]]
|
||||
|
||||
|
||||
|
||||
## Menu Line Response
|
||||
Returns the menu line information.
|
||||
|
||||
The Display text for the menu line is retrive from the `Text` array.
|
||||
`Min`,`Max` and `Default` can be signed numbers.
|
||||
|
||||
|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25
|
||||
|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--
|
||||
|Resp|Msg|LSB (menuId)|MSB (menuId)|Line#|Line Type|LSB (TextId)|MSB (TextId)|LSB (ValId)|MSB (ValId)|LSB (Min)|MSB (Min)|LSB (Max)|MSB (Max)|LSB (Def)|MSB (Def)
|
||||
|0x09|0x03|0x61|0x10|0x00|0x6C|0x50|0x00|0x00|0x10|0x36|0x00|0x49|0x00|0x36|0x00
|
||||
|
||||
RESPONSE RX: 09 03 61 10 00 6C 50 00 00 10 36 00 49 00 36 00
|
||||
RESPONSE MenuLine: L[#0 T=L_m0 VId=0x1000 Text="Outputs"[0x50] Val=nil NL=(0->19,0,S=54) [54->73,54] MId=0x1061 ]
|
||||
|
||||
## Menu Line Value Response
|
||||
Returns the Value for a line.
|
||||
|
||||
The response updates the Value in the line identified by `ValId`.
|
||||
The Display text for the Value, when it is a list, is retrive from the `List_Text` array.
|
||||
|
||||
|10|11|12|13|14|15|16|17
|
||||
|--|--|--|--|--|--|--|--
|
||||
|Resp|Msg|LSB (menuId)|MSB (menuId)|LSB (ValId)|MSB (ValId)|LSB (Value)|MSB (Value)
|
||||
|0x09|0x04|0x61|0x10|0x00|0x10|0x00|0x00
|
||||
|
||||
RESPONSE RX: 09 04 61 10 00 10 00 00
|
||||
RESPONSE MenuValue: UPDATED: L[#0 T=L_m0 VId=0x1000 Text="Outputs"[0x50] Val=0|"Throttle" NL=(0->19,0,S=54) [54->73,54] MId=0x1061 ]
|
||||
|
||||
## Exit Response
|
||||
Response from a Exit Request.
|
||||
|
||||
|10|11
|
||||
|--|--
|
||||
|Resp|Msg
|
||||
|0x09|0x07
|
||||
|
||||
RESPONSE RX: 09 A7
|
||||
RESPONSE Exit Confirm
|
||||
|
||||
## NULL Response
|
||||
Can be use as a response, or heartbeat from the RX to keep the connection open.
|
||||
|
||||
|10|11
|
||||
|--|--
|
||||
|Resp|Msg
|
||||
|0x09|0x00
|
||||
|
||||
RESPONSE RX: 09 00
|
||||
RESPONSE NULL
|
||||
|
||||
|
||||
# Unknown Lines
|
||||
TOTALLY UNKNOWN WHAT THIS ARE FOR.. but only works for the Main Menu..
|
||||
Other menus they just loop on line=0 forever.
|
||||
|
||||
## DSM_getNextUknownLine_0x05(menuId, curLine)
|
||||
|
||||
|
||||
Request the retrival of the next Unknown line following the current line. Response is either the next unknow line, next menu line, or the next value, or nothing.
|
||||
|
||||
|4|5|6|7|8|9| Comment
|
||||
|--|--|--|--|--|--|--
|
||||
Msg|Len? | Line# | Line# | 0x00 | Formula(line#)??
|
||||
0x20|0x06|0x00|0x00|0x00|0x40 | LastLineLine=0 retrieval
|
||||
0x20|0x06|0x01|0x01|0x00|0x01| LastLineLine=1 retrieval
|
||||
0x20|0x06|0x02|0x02|0x00|0x02| LastLineLine=2 retrieval
|
||||
0x20|0x06|0x03|0x03|0x00|0x04| LastLineLine=3 retrieval
|
||||
0x20|0x06|0x04|0x04|0x00|0x00| LastLineLine=4 retrieval
|
||||
0x20|0x06|0x05|0x05|0x00|0x00| LastLineLine=5 retrieval
|
||||
|
||||
## Unknown Line Response
|
||||
We still don't know what is this for, but we have to retrive them and skip then. Works for main menu, but when it happens in another menus, usually we stay in an infinite loop retrieving line=0
|
||||
|
||||
|10|11|12|13|14|15|16|17
|
||||
|--|--|--|--|--|--|--|--
|
||||
|Resp|Msg|LSB (line#)
|
||||
|0x09|0x05|0x00|0x01|0x00|0x00|0x00|0x07
|
||||
|0x09|0x05|0x01|0x01|0x00|0x00|0x00|0x07
|
||||
|
||||
## Interaction on Main Menu
|
||||
This is the normal interaction for the main menu. As you can see, it iterates on the 6 Unknow lines (0..5), and afterwards, it starts sending normal menu lines.
|
||||
|
||||
SEND DSM_getFirstMenuLine(MenuId=0x1000)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 00 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=0)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=1 DATA=RX: 09 05 01 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=1)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=2 DATA=RX: 09 05 02 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=2)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=3 DATA=RX: 09 05 03 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=3)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=4 DATA=RX: 09 05 04 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=4)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=5 DATA=RX: 09 05 05 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=5)
|
||||
RESPONSE MenuLine: L[#0 T=M VId=0x1010 Text="Gyro settings"[0xF9] MId=0x1000 ]
|
||||
|
||||
## Other menus
|
||||
If it hapen on other menus. Usualy stays in an infinite loop until it crash/exits.
|
||||
The screen will show **"Error: Cannot Load Menu Lines from RX"**
|
||||
|
||||
The log will look like:
|
||||
|
||||
DSM_getMenu(MenuId=0x104F LastSelectedLine=1)
|
||||
RESPONSE Menu: M[Id=0x104F P=0x0 N=0x0 B=0x1000 Text="First Time Setup"[0x4A]]
|
||||
SEND DSM_getFirstMenuLine(MenuId=0x104F)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 00 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=0)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 00 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
ERROR: Received Same menu line
|
||||
CALL DSM_getNextUknownLine_0x05(LastLine=0)
|
||||
RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 00 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
ERROR: Received Same menu line
|
||||
|
||||
We found that sometimes, Overriding LastSelectedLine to 0 solves the problem for some specific menus. Not for all (for other, is the oposite (0->1)). But at least no unknown lines are returned with this hack for AR631/AR637. Maybe others also needed.
|
||||
|
||||
**Overriding to Zero is not a good solution for every menu. Some menus needs the LastLine to know the behaviour (for example, Factory Reset the RX, Save Backup, Restore Backup, Enter Bind Mode, Some sensor Calibration). Thats why we cannot do it blindly.**
|
||||
|
||||
Here is the current code to fix some of this problems in AR631/AR637.
|
||||
Function `DSM_SelLine_HACK()`
|
||||
|
||||
if (ctx.RX.Id == RX.AR637T or ctx.RX.Id == RX.AR637TA or ctx.RX.Id == RX.AR631) then
|
||||
-- AR631/AR637 Hack for "First time Setup" or
|
||||
-- "First Time AS3X Setup", use 0 instead of the ctx.SelLine=5
|
||||
if (ctx.Menu.MenuId == 0x104F or ctx.Menu.MenuId==0x1055) then
|
||||
LOG_write("First time Setup Menu HACK: Overrideing LastSelectedLine to ZERO\n")
|
||||
ctx.SelLine = 0
|
||||
end
|
||||
-- AR631/AR637 Hack for "Relearn Servo Settings", use 1 instead
|
||||
-- of the ctx.SelLine=0
|
||||
if (ctx.Menu.MenuId == 0x1023) then
|
||||
LOG_write("Relearn Servo Settings HACK: Overrideing LastSelectedLine to 1\n")
|
||||
ctx.SelLine = 1
|
||||
end
|
||||
|
||||
Now it retrives properly the menu:
|
||||
|
||||
Log shows:
|
||||
|
||||
First time Setup Menu HACK: Overrideing LastSelectedLine to ZERO
|
||||
DSM_getMenu(MenuId=0x104F LastSelectedLine=0)
|
||||
RESPONSE Menu: M[Id=0x104F P=0x0 N=0x0 B=0x105E Text="First Time Setup"[0x4A]]
|
||||
SEND DSM_getFirstMenuLine(MenuId=0x104F)
|
||||
.. Good menu data
|
||||
|
||||
|
||||
|
||||
|
||||
|
169
Lua_scripts/DSMLIB/readme.md
Normal file
169
Lua_scripts/DSMLIB/readme.md
Normal file
@ -0,0 +1,169 @@
|
||||
# Credits
|
||||
Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
|
||||
Rewrite/Enhancements By: Francisco Arzu
|
||||
|
||||
# Introduction
|
||||
|
||||
This script library is a rewrite of the original DSM forward programming Lua
|
||||
Script. The goal was to make it easier to understand, mantain, and to
|
||||
separate the GUI from the DSM Forward programming engine/logic.
|
||||
In this way, GUIs can evolve independent. Color/Touch Gui, Text only GUI, etc.
|
||||
|
||||
Most of the changes has been cometic, but fixed a few operational ones
|
||||
1. Make "Gyro Settings"->"Initial Setup" works (Tested on AR631,AR637xx)
|
||||
2. Properly reset and restart after initial configuration and SAFE changes.
|
||||
3. Write Log of the conversation between RX/TX. To be use for debugging when some reports a problem.
|
||||
4. Provide a simulation of RX to do GUI development in Companion, and undestand patterns of how the data is organized.
|
||||
|
||||
# Tested RXs
|
||||
- AR631/AR637xx Coded a hack to be able to make `Initial Setup` to work
|
||||
- FC6250HX (Helicopter)
|
||||
|
||||
Most RX will run without problems, it could be that some others receivers will need to apply the same hack as the AR631 for some specific menus to work.
|
||||
Since is RX and Menu specific, we cannot create a general hack.
|
||||
|
||||
Please report of you have test it with other receivers to update the documentation.
|
||||
|
||||
If you get `"Unable to Load menu lines"` when trying to navidate to a menu, could be that the code needs to be specially adapter to mandle that menu in a different way than others. We did that HACK for AR631/AR637 for the `Initial Setup` and `Initial Safe Setup` menus. Before starting the script again, the problem shouls show at the log. Usually not been able to process some `Unknown_0x5` lines who has not been fully reversed engineered (you can share the logs with us to try to understand what is going on.
|
||||
|
||||
|
||||
# Deployment
|
||||
|
||||
/SCRIPTS/TOOLS/DsmFwdPrg_05_BW.lua -- black/white text only radios
|
||||
/SCRIPTS/TOOLS/DsmFwdPrg_05_Color.lua -- Color+touch radios
|
||||
/SCRIPTS/TOOLS/DSMLIB/ -- (ALL CAPITALS) Libraries ane extra files
|
||||
/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lua -- DSM Protocol Message and Menu engine
|
||||
SCRIPTS/TOOLS/DSMLIB/DsmFwPrgSIMLib.lua -- Simulation of AR631, FC6250HX
|
||||
SCRIPTS/TOOLS/DSMLIB/img --Images for RX orientations
|
||||
LOGS/dsm_log.txt --Readable log of the last RX/TX session, usefull for debuging new RX
|
||||
|
||||
# Messages Displayed in the GUI
|
||||
|
||||
If in a screen you get text that looks like `Unknown_XX` (ex: Unknown_D3), that message has not been setup in the script in english. If you can get what is the proper message, you can send us a message to be added to the library.
|
||||
The `XX` represents a Hex Number (0..9,A..F) message ID.
|
||||
|
||||
If you want to fix it in your local copy, all messages are towards the end in the file `SCRIPT\TOOS\DSMLIB\DsmFwPrgLib.lua`. Messages for Haders are stored in `Text` and messages for Options are stored in `List_Text`. Lua scripts are text files, and can be editted with Notepad or equivalent.
|
||||
|
||||
Portion of DsmFwPrgLib.lua:
|
||||
|
||||
Text[0x0097] = "Factory Reset"
|
||||
Text[0x0098] = "Factory Reset" -- FC6250HX: Title
|
||||
Text[0x0099] = "Advanced Setup"
|
||||
Text[0x009A] = "Capture Failsafe Positions"
|
||||
Text[0x009C] = "Custom Failsafe"
|
||||
|
||||
Text[0x009F] = "Save & Reset RX" -- TODO: Find the Proper Spektrum Value ??
|
||||
|
||||
Text[0x00A5] = "First Time Setup"
|
||||
Text[0x00AA] = "Capture Gyro Gains"
|
||||
Text[0x00AD] = "Gain Channel Select"
|
||||
|
||||
-- Safe mode options, Ihnibit + thi values
|
||||
local safeModeOptions = {0x0003,0x00B0,0x00B1} -- inh (gap), "Self-Level/Angle Dem, Envelope
|
||||
List_Text[0x00B0] = "Self-Level/Angle Dem"
|
||||
List_Text[0x00B1] = "Envelope"
|
||||
|
||||
For example, if you get `Unknown_9D` in the GUI and your now that it should say **NEW Text**, you can edit the lua script to look like this:
|
||||
|
||||
Text[0x009A] = "Capture Failsafe Positions"
|
||||
Text[0x009C] = "Custom Failsafe"
|
||||
|
||||
Text[0x009D] = "NEW Text" -- NEW Text added for AR98xx
|
||||
|
||||
Text[0x009F] = "Save & Reset RX" -- TODO: Find the proper Spektrum text
|
||||
|
||||
|
||||
# LOG File
|
||||
|
||||
The log file of the last use of the script is located at `/LOGS/dsm_log.txt`. **It is overriden on every start to avoid filling up the SD card**. So if you want to keep it, copy or rename it before starting the script again. (can be renamed in the TX by browsing the SD card)
|
||||
|
||||
The log is human readable. The first number is the number of seconds since the start, and then what is the current state of the Library, and what is been sent and received. The info in the log can be easilly used to create a new simulation for that RX in the future.
|
||||
|
||||
Example Log:
|
||||
|
||||
5.340 WAIT_CMD: DSM_GotoMenu(0x1010,LastSelectedLine=0)
|
||||
5.350 MENU_TITLE: SEND DSM_getMenu(MenuId=0x1010 LastSelectedLine=0)
|
||||
5.440 MENU_TITLE: RESPONSE Menu: M[Id=0x1010 P=0x0 N=0x0 B=0x1000 Text="Gyro settings"[0xF9]]
|
||||
5.490 MENU_LINES: SEND DSM_getFirstMenuLine(MenuId=0x1010)
|
||||
5.590 MENU_LINES: RESPONSE MenuLine: L[#0 T=M VId=0x1011 Text="AS3X Settings"[0x1DD] MId=0x1010 ]
|
||||
5.640 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=0)
|
||||
5.740 MENU_LINES: RESPONSE MenuLine: L[#1 T=M VId=0x1019 Text="SAFE Settings"[0x1E2] MId=0x1010 ]
|
||||
5.790 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=1)
|
||||
5.850 MENU_LINES: RESPONSE MenuLine: L[#2 T=M VId=0x1021 Text="F-Mode Setup"[0x87] MId=0x1010 ]
|
||||
5.910 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=2)
|
||||
5.970 MENU_LINES: RESPONSE MenuLine: L[#3 T=M VId=0x1022 Text="System Setup"[0x86] MId=0x1010 ]
|
||||
6.020 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=3
|
||||
|
||||
Exmple of the Unknown_0x05 Lines correctly processed (receiving lines 0..5):
|
||||
|
||||
0.130 MENU_TITLE: SEND DSM_getMainMenu()
|
||||
0.230 MENU_TITLE: RESPONSE Menu: M[Id=0x1000 P=0x0 N=0x0 B=0x0 Text="Main Menu"[0x4B]]
|
||||
0.280 MENU_LINES: SEND DSM_getFirstMenuLine(MenuId=0x1000)
|
||||
0.400 MENU_LINES: RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 00 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
0.460 MENU_UNKNOWN_LINES: CALL DSM_getNextUknownLine_0x05(LastLine=0)
|
||||
0.550 MENU_UNKNOWN_LINES: RESPONSE MenuUknownLine_0x05: LineNum=1 DATA=RX: 09 05 01 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
0.600 MENU_UNKNOWN_LINES: CALL DSM_getNextUknownLine_0x05(LastLine=1)
|
||||
0.700 MENU_UNKNOWN_LINES: RESPONSE MenuUknownLine_0x05: LineNum=2 DATA=RX: 09 05 02 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
0.760 MENU_UNKNOWN_LINES: CALL DSM_getNextUknownLine_0x05(LastLine=2)
|
||||
|
||||
Example when it will not be able to load the menu (gets stuck in line 0).
|
||||
After nor advancing on the lines, it will show in the UI as `"Unable to load menu lines"`
|
||||
|
||||
0.280 MENU_LINES: SEND DSM_getFirstMenuLine(MenuId=0x1022)
|
||||
0.400 MENU_LINES: RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 00 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
0.460 MENU_UNKNOWN_LINES: CALL DSM_getNextUknownLine_0x05(LastLine=0)
|
||||
0.550 MENU_UNKNOWN_LINES: RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 00 01 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
0.600 MENU_UNKNOWN_LINES: CALL DSM_getNextUknownLine_0x05(LastLine=0)
|
||||
0.700 MENU_UNKNOWN_LINES: RESPONSE MenuUknownLine_0x05: LineNum=0 DATA=RX: 09 05 02 00 00 00 00 07 00 00 00 00 00 00 00 00
|
||||
0.760 MENU_UNKNOWN_LINES: CALL DSM_getNextUknownLine_0x05(LastLine=0)
|
||||
|
||||
|
||||
# Validation of data by the RX
|
||||
|
||||
When you change a value in the GUI, the RX validates that the value is valid.
|
||||
For example, I ran into a case where trying to set Aux2 or Aux3 for flight mode, but the RX was correcting it to Aux1.. the RX only was allowing Gear or Aux1 (AR631/AR637).
|
||||
|
||||
If you go to the logs, you can see that the RX was correcting the value:
|
||||
|
||||
20.520 VALUE_CHANGE_END: SEND DSM_updateMenuValue(ValueId=0x1000,val=7) Extra: Text="FM Channel" Value=7|"Aux2"
|
||||
20.570 VALUE_CHANGE_END: SEND DSM_validateMenuValue(ValueId=0x1000) Extra: Text="FM Channel" Value=7|"Aux2"
|
||||
20.680 VALUE_CHANGE_END: RESPONSE MenuValue: UPDATED: L[#0 T=L_m1 VId=0x1000 Text="FM Channel"[0x78] Val=6|"Aux1" NL=(0->32,0,S=53) [53->85,53] MId=0x7CA6 ]
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Version 0.5
|
||||
|
||||
- Make the code more readable and understadable
|
||||
- Separate the DSM Forwards Programing logic from the GUI
|
||||
- Log the comunnication with the RX on a /LOGS/dsm_log.txt to allow to debug it easier
|
||||
and see the exchange of data between the RX/TX
|
||||
- Created a black/white Text only version with only Key/Roller Inputs
|
||||
- Created a nicer GUI for EdgeTX touchscreen color Radios
|
||||
- RX simulation for GUI development: turn on `SIMULATION_ON=true` in the beginning of the lua file
|
||||
- Test it on AR631, AR637xx, FC6250HX (Helicopter)
|
||||
|
||||
|
||||
### Some settings that can change (top of Lua file):
|
||||
SIMULATION_ON = false -- FALSE: use real communication to DSM RX (DEFAULT), TRUE: use a simulated version of RX
|
||||
DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm_log.txt)
|
||||
DEBUG_ON_LCD = false -- Interactive Information on LCD of Menu data from RX
|
||||
USE_SPECKTRUM_COLORS = true -- true: Use spectrum colors, false: use theme colors (default on OpenTX, OpenTX handle colors different)
|
||||
|
||||
|
||||
### Known Problems:
|
||||
1. **Incorrect List Value Options:** Some Menu List line (`LINE_TYPE.LIST_MENU1` or `L_m1` in logs), the range (min/max) of valid values seems to be incorrect, but cannot see in the data how to fix it.
|
||||
Some of the valid values are not even sequential, very spread apart. There has to be a list of valid options somewhere. Currently fixed some by overriding the valid values in the script code (config for each field).
|
||||
|
||||
2. **Unable to Load menu lines**: The RX return unknow lines when requesting menu lines. **Realy don't understand what they are for**. Some menus
|
||||
seems to stay stuck in the same return line or no response to the request, making the RX reset/close the connection and terminate.
|
||||
Was able to hack it for AR631/AR637 `"First Time Setup"`, `"First Time SAFE Setup"`, and `"Servo Realm"`. Maybe this hack will work in other RX, so let us know if you get this problem.
|
||||
|
||||
|
||||
|
||||
# Version 0.2
|
||||
Original Version from Pascal Langer
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
This script library is a rewrite of the original DSM forward programming Lua
|
||||
Script. The goal is to make it easier to understand, mantain, and to
|
||||
separate the GUI from the DSM Forward programming engine/logic
|
||||
in this way, GUIs can evolve independent. OpenTX Gui, EdgeTx GUI, etc.
|
||||
|
||||
Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
Rewrite/Enhancements By: Francisco Arzu
|
||||
|
||||
|
||||
|
||||
Deployment:
|
||||
/SCRIPTS/TOOLS/DsmFwdPrg_05_BaW.lua -- OpenTX/EdgeTx version, no touch (black/white radios)
|
||||
/SCRIPTS/TOOLS/DsmFwdPrg_05_Color.lua -- EdgeTX/OpenTx Color version, +touch
|
||||
/SCRIPTS/TOOLS/DSMLIB/ -- Libraries (ALL CAPITALS) to hide them from the Tools menu
|
||||
/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lub -- DSM Protocol Message and Menu engine
|
||||
/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgSIMLib.lub -- Simulation of AR631 for GUI Development in Companion
|
||||
|
||||
/LOGS/dsm_log.txt -- Readable log of the last RX session, usefull for debuging new RX
|
||||
|
||||
|
||||
Version 0.5
|
||||
- Make the code more readable and understadable
|
||||
- Separate the DSM Forwards Programing logic from the GUI
|
||||
- Log the comunnication with the RX on a /LOGS/dsm_log.txt to allow to debug it easier
|
||||
and see the exchange of data between the RX/TX
|
||||
- Created a black/white Text only version with only Key/Roller Inputs
|
||||
- Created a nicer GUI for EdgeTX touchscreen color Radios
|
||||
- RX simulation for GUI development: turn on SIMULATION_ON=true in the beginning of the lua file
|
||||
|
||||
|
||||
Some settings that can change (top of Lua file):
|
||||
SIMULATION_ON = false -- FALSE: use real communication to DSM RX (DEFAULT), TRUE: use a simulated version of RX
|
||||
DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm_log.txt)
|
||||
DEBUG_ON_LCD = false -- Interactive Information on LCD of Menu data from RX
|
||||
USE_SPECKTRUM_COLORS = true -- true: Use spectrum colors, false: use theme colors (default on OpenTX, OpenTX handle colors different)
|
||||
|
||||
|
||||
Known Problems:
|
||||
1. Some Menu List line types (LINE_TYPE.LIST_MENU1 or "L_m1" in logs), the range (min/max) seems to be incorrect, but cannot see in the data how to fix it
|
||||
Some of the valid values are not even sequential, very spread apart. There has to be a list of valid options somewhere (in RX or config for each field).
|
||||
2. The RX return unknow lines when requesting the Lines for a menu. Realy don't understand what they are for.
|
||||
in some menus, seems to stay stuck in the same return line or no response to the request, making the RX reset/close the connection.
|
||||
Was able to hack it for AR631 "First Time Setup" and "First Time SAFE Setup", and "Servo Realm" (don't know if it works here)
|
||||
|
||||
|
||||
Version 0.2
|
||||
Original Version from Pascal Langer
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user