ShikOfTheRa / scarab-osd

MWOSD - UAV HUD
http://www.mwosd.com
418 stars 203 forks source link

Smart audio support #315

Closed aee74 closed 7 years ago

aee74 commented 7 years ago

Is it possible to get smart audio (tbs unify pro hv) working on this osd?

jflyper commented 7 years ago

In theory, yes.

How: Bit-banging 2400 4800bps serial one-wire protocol using one (or two) unused digital pin(s).

Caveat: You need to do non-trivial micro-soldering as seen in #278 to break out the digital pin(s). Minimal code addition is required.

Other factors: Support for the SmartAudio is been discussed in betaflight/betaflight#1029, and will eventually interact with generic OSD menu support such as the one discussed in cleanflight/cleanflight#2014.

So, the SmartAudio will eventually be supported by FC firmware itself. Do you want the support as a part of the stand alone OSD?

Machtap commented 7 years ago

I'd love to see smartaudio implemented directly on the OSD to allow for an actual interface to configure things such as pitmode and custom frequencies. You could also have an option to display the exact broadcast frequency on the OSD which would help in some group flying situations. SmartAudio on the OSD itself would also allow KISSFC users to take advantage of these features without swapping to different flight control firmware like CF of BF.

aee74 commented 7 years ago

It would be a great feature on the osd itself. Channel changing and pitmode at the control off a stick!

Machtap commented 7 years ago

14350890_1788052044774190_1707048544_n

Soldering was easy, what's next?

jflyper commented 7 years ago

@Machtap Wow!

You can help us finding out the nature of the SmartAudio electrical characteristics!

Machtap commented 7 years ago

https://www.dropbox.com/s/aj5no72zbag61oe/smartaudio.logicdata?dl=0

Here is a logic analyzer capture-- I am bitbanging hardcoded hex strings from a 3.3v arduino nano at 4800 baud with 0x00 padding in front and behind each frame. The first string is the command to change frequency to 5865, the second is to get the status. The smartaudio reply appears to fire ~65ms after the request and replies for both requests appear to be in the expected format and with the expected data. However, the transmitter itself does not seem to respond.

Here is the arduino code used if anyone would like to help me verify it's working: http://pastebin.com/raw/s7JwypKC

dustin commented 7 years ago

Where did you get that protocol stuff?

I'd expect setting to 5865 to look like this: {0x00, 0xAA, 0x55, 0x07, 0x01, 0x00, 0x00, 0x00}

I'd expect get status to look like this: {0x00, 0xAA, 0x55, 0x03, 0x00, 0x00, 0x00}

I also don't see the 0s on both sides of the packets in your trace, so something might not be working right there.

On Tue, Sep 13, 2016 at 7:55 PM Andrew Macht notifications@github.com wrote:

https://www.dropbox.com/s/aj5no72zbag61oe/smartaudio.logicdata?dl=0

Here is a logic analyzer capture-- I am bitbanging hardcoded hex strings from a 3.3v arduino nano at 4800 baud with 0x00 padding in front and behind each frame. The first string is the command to change frequency to 5865, the second is to get the status. The smartaudio reply appears to fire ~65ms after the request and replies for both requests appear to be in the expected format and with the expected data. However, the transmitter itself does not seem to respond.

Here is the arduino code used if anyone would like to help me verify it's working: http://pastebin.com/raw/s7JwypKC

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ShikOfTheRa/scarab-osd/issues/315#issuecomment-246891315, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAG88qEx7R0x5qx2r-faUv8IpftNf6kks5qp2IugaJpZM4J565X .

Machtap commented 7 years ago

my get status request is {0x00, 0xAA, 0x55, 0x03, 0x00, 0x9F, 0x00} the response is {0xAA, 0x55, 0x04, 0x04, 0x16, 0xE9, 0x01, 0xF8, 0x00}

These values match the examples in the docs for a VTX set to 5865 {0x16, 0xE9} == 5865: https://github.com/betaflight/betaflight/files/430302/TBS.SmartAudio.Rev07.pdf

but the VTX itself still blinks 4 and 4 for 5800 and broadcasts on 5800.

jflyper commented 7 years ago

@Machtap We already know the framing (L2) and above, and are more concerned with electrical specification of the SmartAudio. Take a look at the beta flight issue mentioned in the second comment.

dustin commented 7 years ago

One thing I noticed is that the spec says "4800bps 1 Start bit and 2 Stop bit" Your trace is valid with one stop bit, but not two.

On Tue, Sep 13, 2016 at 8:27 PM Andrew Macht notifications@github.com wrote:

my get status request is {0x00, 0xAA, 0x55, 0x03, 0x00, 0x9F, 0x00} the response is {0xAA, 0x55, 0x04, 0x04, 0x16, 0xE9, 0x01, 0xF8, 0x00}

These values match the examples in the docs for a VTX set to 5865 {0x16, 0xE9} == 5865: https://github.com/betaflight/betaflight/files/430302/TBS.SmartAudio.Rev07.pdf

but the VTX itself still blinks 4 and 4 for 5800 and broadcasts on 5800.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ShikOfTheRa/scarab-osd/issues/315#issuecomment-246895788, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAG86zIYuc8yP9ngJsx46Mdyq152Pfoks5qp2magaJpZM4J565X .

Machtap commented 7 years ago

@dustin My requests have a single stop bit but the replies have two.

Ideally requests would be sent with 2 stop bits as well but since it's replying I'm not sure this is the issue?

jflyper commented 7 years ago

@dustin What a catch (sic)!

dustin commented 7 years ago

I don't have a TBS VTX, but I was looking at dRonin's implementation since I keep hearing wonderful success stories from that.

It configures a UART up for 5000 baud. That's odd, but kind of consistent with the drift I heard people talking about given errors/drift.

On Tue, Sep 13, 2016 at 8:52 PM Andrew Macht notifications@github.com wrote:

@dustin https://github.com/dustin My requests have a single stop bit but the replies have two

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/ShikOfTheRa/scarab-osd/issues/315#issuecomment-246899271, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAG8wOvT94-wyxl0uot8n4xSfjmcAQrks5qp2-OgaJpZM4J565X .

jflyper commented 7 years ago

@dustin Yeah, NightHawk32 said it would go up to 4900, which is 2% faster. People at d-Ronin might have found out some faster case. And, we should also consider controller side errors.

jflyper commented 7 years ago

@Machtap Can you give us with your experimental wiring? Just connect RX+TX? And, what's on channel 7 in your capture? Channel 7 is 13?

Machtap commented 7 years ago

just smartaudio --> arduino TX pin 11 with an inline 1k resistor.

I am disregarding the responses in my test arduino sketch entirely at the moment, just trying to get blind channel / power changes working so I'm only able to see the unify responses over the logic analyzer.

I have the LED on the arduino set to alternate on and off when the two requests are sent, so I'm watching pin 13 on channel 7 mostly as a sanity check on where to expect requests and replies. My logic analyzer has not seen much use prior to this so I am trying to learn quickly~

jflyper commented 7 years ago

I am trying to observe how unify drive the bus, by bringing the TX to Hi-Z after frame transmission is complete...

Machtap commented 7 years ago

@jflyper Anything I can do to assist?

jflyper commented 7 years ago

I think I've got it.

EDIT: Aarrrrgghhh ... response data below are all "out of sync" !!! It's transmitted at around 5000bps, but receive decoded at 4800bps.

Overview of REQUEST-RESPONSE pair

smartaudio_rxnopu_tx_idle_hiz-overview

REQUEST

smartaudio_rxnopu_tx_idle_hiz-request

RESPONSE

smartaudio_rxnopu_tx_idle_hiz-response

So the bus turned out to be a simple push-pull with no one driving (sourcing) the bus when not transmitting. On the Unify side, this is natural because it's an audio input with 17Kohm DC impedance. On the Arduino side, TX and RX are both floating, but are pulled to GND through the Unify's DC impedance.

A reason for request peak (3V12) been bit lower than response peak (3V3) is that I put 1Kohm series register on TX; 3.3 * 17/18 = 3.12 which matches with what's observed. The Unify is probably disconnecting the 17K load and driving the bus at 3.3V when transmitting.

Here's what I have done: (1) Modified SoftwareSerial::setRX(rxpin) not to pull-up the rxpin.

  void SoftwareSerial::setRX(uint8_t rx)
  {
    pinMode(rx, INPUT);
  #if 0
    if (!_inverse_logic)
      digitalWrite(rx, HIGH);  // pullup for normal logic!
  #endif
    _receivePin = rx;
    _receiveBitMask = digitalPinToBitMask(rx);
    uint8_t port = digitalPinToPort(rx);
    _receivePortRegister = portInputRegister(port);
  }

(2) Surrounded each write() with pinMode(txpin, OUTPUT) and pinMode(txpin, INPUT) to bring txpin to Hi-Z when the txpin is idle.

  pinMode(11, OUTPUT);
  mySerial.write(command, 9);
  pinMode(11, INPUT);

Now we have to come up with a way to properly level-shift between 3V3 and 5V logic. With simple push-pull, I believe larger series resister (around 8.5K, 10K might work) on TX is all we need. RX should accept 3V3 as logic high (Vih = 0.6 * Vcc = 0.6 * 5V = 3V0).

jflyper commented 7 years ago

Okay, I've got a new screen shots.

Overview

smartaudio_rxnopu_tx_idle_hiz-overview

Request

smartaudio_rxnopu_tx_idle_hiz-request

Response

smartaudio_rxnopu_tx_idle_hiz-response
jflyper commented 7 years ago

We have couples of problems.

  1. The level shifting with serial register doesn't work. Unify doesn't respond to 5V pro mini running the exact same sketch. (The 3V3 was tested with 5V pro mini fed with 3V3.) Here's a wave form with 8K (4K7+3K3) series register. It successfully limits the peak at 3V34, but the edges are not clean; sharp rising stops at 1V8 or so, sharp falling also stops at 1V8 or so. It's probably making the edge detector nuts. levelshifting_series8k

    Some active level shifting is required.

  2. The current "SoftwareSerial.cpp" does not support 2 stop bits. I really don't know the consequence of this. Remember that we never had a good control over the Unify.
  3. The current "SoftwareSerial.cpp" has an atomic section (cli-sei) for 1-char time. This is actually undesirable, especially at slow 4800bps. As there are faster inputs such as 115200bps serial running concurrently, non-interruptible period of 2msec (equivalent to 24 bytes @ 115200bps) is not permissible. However, we might be able to get a way with scheduling hardware and software serial i/o.
  4. CRC specification is confused. In the protocol specification examples, CRC for requests seem to cover start sequences, which is consistent with the statement about the range of CRC (p.3):

CRC SmartAudio uses 8bit CRC. Used polynom is 0xD5. The CRC includes all bytes of the frame.

Example 1: Get Settings example frames are: Request: 0xAA, 0x55, 0x03, 0x00, 0x9F Computed CRC for the first 4 bytes is 0x9F, which is consistent with the example.

Response (V1): 0xAA, 0x55, 0x01, 0x06, 0x00, 0x00, 0x01, 0x16, 0xE9, 0x4D Computed CRC for the first 9 bytes is 0xB8, which is different from 0x4D. Computed CRC without the start sequence (0xAA, 0x55) is 0x4D, which matches with the indicated CRC value.

Example 2: Set Power examples frames are: Request: 0xAA, 0x55, 0x05, 0x01, 0x00, 0x6B Computed CRC for the first 5 bytes is 0x6B, which is consistent with the example.

Response (V2): 0xAA, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0x0F (pic is not consistent with text for this example) Computed CRC for the first 7 bytes is 0x3B != 0x0F Computed CRC without the start sequence is 0x20 != 0x0F WTF!?

Example 3: An actual response from the Unify, sampled with 3V3-duino

smartaudio_rxnopu_tx_idle_hiz-response

Response: 0xAA, 0x55, 0x04, 0x04, 0x16, 0xe9, 0x01, 0xf8, 0x00 Computed CRC for the first 8bytes is 0xD1 != 0x00 Computed CRC without the start sequence is 0x00 == 0x00

So, phenomenologically speaking, it is either

(a) Request accounts start sequence in CRC. Response does not. (b) Request does not account start sequence in CRC. Response does not either.

In either case, the protocol specification document is unreliable and also poorly written. Are we expecting this kind of quality with this product?

NightHawk32 commented 7 years ago

@jflyper you are right the protocol is just poorly documented. Request requires to calculate crc looking at all bytes transmitted. On response the start code is left out. The first byte for crc calculation is the command byte.

The exmaple in the spec regarding set power response is just wrong. The unify always responds with the same frame format it received. So in set power response there will only appear power level in the response, but no channel. Request: 0xAA 0x55 (sync) 0x05 (CMD2<<1) 0x01 (len) 0x00 (power) 0x6B (crc) Response: 0xAA 0x55 (sync) 0x02 (CMD2) 0x03 (len) 0x00 (power) 0x01 (reserved) 0x0F (crc) The screenshot on page 6 in the document is right, they just added the channel by mistake in the text above. I've verified this using a logic analyzer and a Unify.

There are also strange things happening for the length field. For get settings: Request: Length always 0 Response: Length tells the SmartAudio version (no reserved byte 0x01 transmitted before CRC)

For all other commands: Request: Length is only the real payload, without CRC Response: Length is payload+reserved+CRC (reserved byte is transmitted just before the CRC)

I've done some rough implementation here: https://github.com/NightHawk32/SmartAudio-testing/blob/master/tbs_test.ino

jflyper commented 7 years ago

@NightHawk32 You rock! Can you substitute table based crc8 with a computational one? (It actually really doesn't matter for a test code, but makes me feel guilty to use a large table for the task; we usually have less than 4K flash and 400 bytes ram here:))

BTW, I pulled out my leonardo and found out the i/o are 5V. Is yours 3V3 clone?

uint8_t crc8(const uint8_t *data, uint8_t len)
{
#define POLYGEN 0xd5
  uint8_t crc = 0;
  uint8_t currByte;

  for (int i = 0 ; i < len ; i++) {
    currByte = data[i];
    crc ^= currByte;
    for (int i = 0; i < 8; i++) {
      if ((crc & 0x80) != 0) {
        crc = (byte)((crc << 1) ^ POLYGEN);
      } else {
        crc <<= 1;
      }
    }
  }
  return crc;
}
Machtap commented 7 years ago

@jpflyer: are you powering it with 5v or 3v?

jflyper commented 7 years ago

I was using the Pro mini 16MHz@5V powered by 3V3 FTDI, but pulled out the Leonardo and power it through USB to see how NightHawk32's code runs (and found out it's still 5V i/o).

Machtap commented 7 years ago

I have a logic level shifter but no leonardo, alas~

NightHawk32 commented 7 years ago

Thanks for pointing that out. I just thought it was 3.3V, because it has a 3.3V regulator on it but that is just used for powering an IMU. So I have to add a level shifter :) I have the situation that my oscilloscope is being repaired at the moment. Unfortunately my logic analyzer does not have the ability to record analog data. I guess you have a new one from Saleae @jflyper? So I feel a little blind :)

Got som new results: Sent a get settings command: get_settings_request Response (as excpected): get_settings_response

But if I send the same command and just send the wrong crc (correct crc+1) there is no response at all. I guess the Unfiy just responds to correct data packets: get_settings_request_wrong

Thanks for the computational crc. Added it to the code.

jflyper commented 7 years ago

@NightHawk32 You mean you were driving your Unify at 5V all this time? Tested 5V tolerance? :) I wonder how you hooked it up.

But if I send the same command and just send the wrong crc (correct crc+1) there is no response at all. I guess the Unfiy just responds to correct data packets:

Da**!!! Then we have to blind search for the speed.

P.S. And the magic 5,000 in d-Ronin is no magic at all. It goes up to 5,000 in few minutes at room temp.

Machtap commented 7 years ago

I tested 5v tolerance this evening, Unify handles the 5v high logic signal fine and appears to be obeying commands as usual. (still bitbanging at 4800 baud, ignoring the 2 stop bit on commands)

No longer able to observe the responses but that's likely due to the logic analyzer seeing 5v logic and filtering the 3v3 stuff-- will experiment more later with a logic level converter to nail this down.

Also seems custom frequency support is very wide-- 5600 to 6000 tested tonight and seems work on anything in between. This could open up interesting possibilities.

aee74 commented 7 years ago

For all you programmers. Is this helpfull. https://github-cloud.s3.amazonaws.com/assets/repositories/37060852/479793?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAISTNZFOVBIJMK3TQ%2F20160920%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20160920T181527Z&X-Amz-Expires=300&X-Amz-Signature=ad26b366be99554a829c74c49b886cd3f2f60a1fc0927cc42045e8155dd04219&X-Amz-SignedHeaders=host&actor_id=18537333&response-content-disposition=attachment%3Bfilename%3DTBS.SmartAudio.Rev07.pdf&response-content-type=application%2Fpdf

jflyper commented 7 years ago

@aee74 ACL?

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>AccessDenied</Code>
<Message>Request has expired</Message>
<X-Amz-Expires>300</X-Amz-Expires>
<Expires>2016-09-20T18:20:27Z</Expires>
<ServerTime>2016-09-21T05:17:40Z</ServerTime>
<RequestId>E2C29D55F69DDF2D</RequestId>
<HostId>
VZXj1HNm3q25PRIv/+UQ59PCvrw4ourhdKDxNb66fjO2W3wndTAeuwdwjuAZ2eF/ZUREtRxIC4A=
</HostId>
</Error>

EDIT: The URL seems to point to "TBS.SmartAudio.Rev07.pdf", which we have already been referring to...?

jflyper commented 7 years ago

What's the use of the "Quit Pit Mode without unsetting the pit mode flag" commands?

To turn on the pit mode, we have to write either in-range or out-of-range pit mode flags, which automatically set the corresponding pit mode flag. Then, what is the significance of the "quit without" command? Is there any way to turn on the pit mode without writing to the flags???

jflyper commented 7 years ago

I can't get my non-HV into pit mode.

Also strange that Get Settings returns V2. I thought the V2 depends on the hardware itself, like direct access to PA DAC v.s. table lookup.

Trying my HV now...

Da\ ... Signal (and power) orders on the connectors are different between HV and non-HV ...

Is there any design justification other than inducing magic smokes and more sales for this??? :very angry:

EDIT: Okay, I made a new harness for HV and tried. Can't get it into pit mode.

To turn on the pit mode, we have to write either in-range or out-of-range pit mode flags, which automatically set the corresponding pit mode flag.

This assumption was wrong.

Activating Pit Mode 0xAA 0x55 0x0B(Command 5) 0x01(Length) 0x01(IN RANGE PIT FLAG) 0xXX(CRC8)

This doesn't turn on the pit mode, but just set the IN RANGE PIT FLAG.

How do we turn it on...?

jflyper commented 7 years ago

Updates

jflyper commented 7 years ago

Updates I've got a response from the dev, and the PIT mode behavior is completely explained.

Other way of saying the above is:

awolf78 commented 7 years ago

Did you have any luck with the AltSoftSerialLibrary? I'm about to try this myself - if I can find someone soldering pins 8+9 :(

jflyper commented 7 years ago

@awolf78 I'm almost done with the Betaflight version.

I will be using an arduino based prototype for testing ;)

chilly24 commented 7 years ago

hey guys thanks for developing this feature ; ) Whats the current status and when is the release planed? i am having a tbs unify pro race hv version

advancetom commented 7 years ago

Hey today im tested 1.6.5.0 And Works Fine Till i changed the Font to dguz or Else ! After restart it will start with the Standard Font Im Used this in 1.6.4.0 and Works whats wrong?

jflyper commented 7 years ago

@chilly24 BF version to be included in the 3.1 release. Are you waiting for the MWOSD-native support?

jflyper commented 7 years ago

@advancetom Can you open a new issue?

chilly24 commented 7 years ago

@jflyper: yes would be nice until the 3.1 is released I am having a F3 Board with OSD build in from banggood: http://www.banggood.com/F3-Flight-Controll-with-Integrated-OSD-6DOF-Acro-10DOF-Deluxe-Version-with-Pins-p-1054995.html?rmmds=search

I think they just put the chips from the MWOSD to the platine, so i connected now the Smart Audio Port to RX and TX of UART 2: http://dronetech.esy.es/techreview/wp-content/uploads/2016/06/f3.jpg

EDIT: I saw it has a built in minimOSD or the OSD is not connected to the FC because you have sparte FTDI Connection to the F3 and the OSD. So i would need a solution as standalone for it

jflyper commented 7 years ago

@chilly24 The MinimOSD portion of this board is not capable of driving the smartaudio directly.

For BF controlled application, you can connect your smartaudio wire to UART2 TX. (No RX connection necessary; it's ignored on F3.)

The BF smartaudio support was merged few hours ago, and the configurator is updated to allow easy setup. You can download the dev versions if you want to give it a try.

ShikOfTheRa commented 7 years ago

Thanks. Closing as this is not on MWOSD dev list and Jflyper has provided an alternative solution.