mrrwa / NmraDcc

NMRA Digital Command Control (DCC) Library
GNU Lesser General Public License v2.1
137 stars 53 forks source link

OPS mode programming for Accessory Decoder does not work for extended address, missing support? #47

Open jmsauer64 opened 3 years ago

jmsauer64 commented 3 years ago

I'm using this Wonderfull library to build out an accessory decoder for my layout. I wanted the ability to use OPS mode programming to change some of my custom defined CV's. I'm not sure if I really understand the NMRA standard for handing accessory addressing. It seem both NCE and JRMI systems use extended addressing. At line 1409 there is this code....

      else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming
      {
        DB_PRINT("eDP: OPS Mode CV Programming Command");
          // Check for unsupported OPS Mode Addressing mode
        if(((pDccMsg->Data[1] & 0b10001001) != 1) && ((pDccMsg->Data[1] & 0b10001111) != 0x80))
        {
          DB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode");
          return;
        }

          // Check if this command is for our address or the broadcast address
        if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
        {
          DB_PRINT("eDP: Check Output Address:%d", OutputAddress);
          if((OutputAddress != getMyAddr()) && ( OutputAddress < 2045 ))
          {
            DB_PRINT("eDP: Output Address Not Matched");
            return;
          }
        }

Both NCE and JMRI seems to send extended addresses for OPS Accessory Decoder programing. If I make the following changes it seems to work, but I'm not sure if I understand the addressing completely

      else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming                       
      {
            DB_PRINT("eDP: OPS Mode CV Programming Command");
          // Check for unsupported OPS Mode Addressing mode     JMS seems like we dont support extended addr
        if((pDccMsg->Data[1] & 0b10001100) == 0b00001100)                    // JMS enabled extended addresses
        {
              myDB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode");                                   
          return;
        }
          // Check if this command is for our address or the broadcast address
        if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
        {
          //JMS new code to fix address if CDDD = 0
          if((pDccMsg->Data[1] & 0b10001111) == 0x80)                        // JMS NEW
          {                                                                                                      // JMS NEW
            OutputAddress = BoardAddress;                                              // JMS NEW
            DB_PRINT("eDP: Updated Address");                                      // JMS NEW
          }                                                                                                     // JMS NEW

Are my changes correct? I can only test with NCE and JMRI with SPROG but so far seems to work as expected.

kiwi64ajs commented 3 years ago

HI,

I finally got some time to take a look at this… ;)

Also, its a lot easier to debug this as I just discovered (don’t know when it was added) that JMRI will generate Accessory OPS Mode CV Programming Commands on DCC Systems that don’t natively support that feature, but sending raw DCC packets to the Command Station to send to the track.

For testing I have been using the JMRI Simple Programmer connected to a Digitrax DCS100

So finally I’ve been able to test this and do some experimenting/debugging.

See below for some comments

On 9/02/2021, at 8:54 AM, jmsauer64 @.***> wrote:

I'm using this Wonderfull library to build out an accessory decoder for my layout. I wanted the ability to use OPS mode programming to change some of my custom defined CV's. I'm not sure if I really understand the NMRA standard for handing accessory addressing. It seem both NCE and JRMI systems use extended addressing. At line 1409 there is this code....

else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming
{
    DB_PRINT("eDP: OPS Mode CV Programming Command");
      // Check for unsupported OPS Mode Addressing mode
  if(((pDccMsg->Data[1] & 0b10001001) != 1) && ((pDccMsg->Data[1] & 0b10001111) != 0x80))
  {
      DB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode");
      return;
    }

      // Check if this command is for our address or the broadcast address
    if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
    {
      DB_PRINT("eDP: Check Output Address:%d", OutputAddress);
      if((OutputAddress != getMyAddr()) && ( OutputAddress < 2045 ))
      {
        DB_PRINT("eDP: Output Address Not Matched");
          return;
      }
    }

Both NCE and JMRI seems to send extended addresses for OPS Accessory Decoder programing. If I make the following changes it seems to work, but I'm not sure if I understand the addressing completely

else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming                       
{
        DB_PRINT("eDP: OPS Mode CV Programming Command");
      // Check for unsupported OPS Mode Addressing mode     JMS seems like we dont support extended addr
  if((pDccMsg->Data[1] & 0b10001100) == 0b00001100)                    // JMS enabled extended addresses
  {
          myDB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode");                                   
      return;
    }
      // Check if this command is for our address or the broadcast address
    if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
    {
      //JMS new code to fix address if CDDD = 0
      if((pDccMsg->Data[1] & 0b10001111) == 0x80)                        // JMS NEW
      {                                                                                                      // JMS NEW
        OutputAddress = BoardAddress;                                              // JMS NEW
        DB_PRINT("eDP: Updated Address");                                      // JMS NEW
      }                                                                                                     // JMS NEW

Are my changes correct? I can only test with NCE and JMRI with SPROG but so far seems to work as expected.

I believe the short answer is: no

AFAICT:

1) the “Basic Accessory Decoder Packet” (see line 473 of the S-9.2.1_2012_07 spec) is for Accessory Decoders in Board or Decoder Addressing mode and my library only supports CDDD = 0000, so the change that you’re suggesting I don’t believe will do the right thing.

2) the “Extended Decoder Control Packet” (see line 485 of the S-9.2.1_2012_07 spec) is for Accessory Decoders in Output Addressing mode.

Anyway I have made some code changes to implement the above assumption and would appreciate it if you could test them on your NCE System and see what it does.

The new code is in Git on the branch: Accessory-OPS-CV here:

https://github.com/mrrwa/NmraDcc/commits/Accessory-OPS-CV/NmraDcc.cpp <https://github.com/mrrwa/NmraDcc/commits/Accessory-OPS-CV/NmraDcc.cpp>

The differences are here:

https://github.com/mrrwa/NmraDcc/commit/6333abf6911eb2e1a6badc5bbc9c423c8b248a91#diff-e3be41da4ebd17540371d9e3529dd22a125d1517e200fbdf47258a03d151f4c0 <https://github.com/mrrwa/NmraDcc/commit/6333abf6911eb2e1a6badc5bbc9c423c8b248a91#diff-e3be41da4ebd17540371d9e3529dd22a125d1517e200fbdf47258a03d151f4c0>

Regards

Alex Shepherd

m: +64-21-777764 e: @.***

jmsauer64 commented 3 years ago

Hi Alex,

Thanks for taking a look into this! Now it was my turn to be slow to respond. :). Took me a while to recreate my environment to test this.

I'm not sure what happening, but when use this branch, my code stops received any accessory commands. What I did to verify is I took the master, rebuilt my code. On my "test Arduino", I sent basic turnout commands and they are received as expected. Both with JMRI and Sprog3 and NCE. If I use the Accessory-OPS-CV branch, my test code does not even receive any accessory commands. I also tested the original OPS programming and that does not seem to work either.

My original changes was based on the 2.0.6 release, not sure if this changes or something in between created this new behavior.

Jonathan

jmsauer64 commented 3 years ago

Quick update... version 2.0.10 or Last release seems to work with accessory commands, but the Accessory-OPS-CV branch does not seem to receive any accessory commands.

kiwi64ajs commented 3 years ago

Hi Jonathan,

Yes, after I responded to you I decided to look harder at the Accessory OPS support and ended up talking to Dave Heap in Aussie about it all as there were things I was confused about and was probably not thinking about this correctly or at least not consistently with how the functionality has been implemented in JMRI.

So I’ve done a bunch of subtle changes subsequently but I don’t think I’m quite “there yet” and need to do some more work and probably create some more example DCC Accessory Sketches that demonstrate the revised support for the different DCC Accessory Modes/types or addressing etc.

Alex

On 23/09/2021, at 6:05 AM, jmsauer64 @.***> wrote:

Quick update... version 2.0.10 or Last release seems to work with accessory commands, but the Accessory-OPS-CV branch does not seem to receive any accessory commands.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mrrwa/NmraDcc/issues/47#issuecomment-925160356, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB5Y53OPDZ5G2BF3FQGKMFDUDILGDANCNFSM4XJTT6OA.

gorillale commented 1 month ago

Into Accessory Decoder Mode ops Mode not work, i can't write CV on POM. Is this library obsolent?

kiwi64ajs commented 1 month ago

On 2 Sep 2024, at 2:34 AM, gorillale @.***> wrote: Into Accessory Decoder Mode ops Mode not work, i can't write CV on POM.

Your situation isn’t uncommon. Unfortunately, the Accessory Decoder OPS Mode Programming specification is ambiguous and not well-defined, and only a few DCC manufacturers provide partial and inconsistent support.

Also, when I developed most of the NmraDcc library, I only had a Digitrax DCS100 Command Station to test with, and it didn’t support Accessory Decoder OPS Mode Programming, which made adding support difficult.

A workaround I did at the time was to allow a Multifunction Accessory Decoder (loco) Address to be defined, which allows OPS Mode Programming to be possible. This is widely supported on different DCC Systems and is partially effective.

Some work was done in JMRI several years back to improve support for Accessory Decoder OPS Mode Programming by using the various ways to send a DCC Command directly to the rails, but I don’t know if this was completed.

If this could be easily solved, it would be done by now. The fact is, it's not that simple, and I don’t have much time to dedicate to doing this as it doesn't solve a problem I have, and I have other hobby objectives that I do want to do… ;)

Is this library obsolent?

Not specifically. It might seem so if something doesn’t work or your use case isn’t supported.

1) What DCC System and Accessory Decoder do you want to use OPS Mode Programming on?

2) I also welcome/accept well-written PRs to resolve issues… ;)

Regards

Alex Shepherd

m: +64-21-777764 e: @.***

gorillale commented 1 month ago

Good day Alex First of all: Unfortunately, I am not able to express myself precisely and that is why there are sometimes a lot of misunderstandings. In English, everything is even more difficult and the translation sometimes doesn't work.

First of all, I would like to thank you for programming the library. It works well so far and you can also program the CVs using the service mode. I just know that reading in POM mode definitely doesn't work because the CPU is too weak/slow and the timing is difficult to achieve.

But at least the writing processes work with APP_DCC (same hardware), which doesn't work with NMRADcc. I think if AP_DCC can do it, why can't NMRAdcc? I just don't understand that.

NMRAdcc supports the ESP32, which is unfortunately not possible with AP_DCC. I have made various attempts with NMRAdcc and AP_DCC library. What I have seen is that there is an identifier that is not supported when the CV is written. Trying to find something in debug mode is very difficult for me because I don't know the whole subject of DCC signals very well. When debugging, I saw that the identifier is returned as «...1100» when writing CVs, but the code only asks for «...0101».

My problem: Unfortunately, I can't remove the device every time I reprogram it and program it in service mode. Or configure the software with the PC via USB. So I used APP_DCC where it works from the hardware.

So is the NMRAdcc library actually still up to date?!

Thanks for your help anyway, I'll keep trying to solve the problem. Although I don't understand how the OPS mode and the address to be passed on work at all. I haven't found any acceptable instructions anywhere (or understood them) on how to pass it on and what exactly happens in the background. It's all very unclear to me.

I used opendcc system and dcc-ex.

Regards Andrew

gorillale commented 1 month ago

I have debuged this. before i have removed the return. The cv will be written!

DB_PRINT ("eDP: OPS Mode CV Programming Command");
// Check for unsupported OPS Mode Addressing mode
if ( ( (pDccMsg->Data[1] & 0b10001001) != 1) && ( (pDccMsg->Data[1] & 0b10001111) != 0x80))
{
  DB_PRINT("%d", pDccMsg->Data[1]);
    DB_PRINT ("eDP: Unsupported OPS Mode CV Addressing Mode");
   **// return;**
}

Debug result:

eDP: AccCmd: 8F FE EC 23 04 BA 
eDP: BAddr:15, Index:3
eDP: OAddr:60
eDP: OPS Mode CV Programming Command
254
eDP: Unsupported OPS Mode CV Addressing Mode
eDP: Check Output Address:60
eDP: OPS Mode Instruction:3
eDP: CV:36 Value:4
notifyDccCVChange cv:36 val:4
eDP: AccCmd: 8F FE EC 23 04 BA 
eDP: BAddr:15, Index:3
eDP: OAddr:60
eDP: OPS Mode CV Programming Command
254
eDP: Unsupported OPS Mode CV Addressing Mode
eDP: Check Output Address:60
eDP: OPS Mode Instruction:3
eDP: CV:36 Value:4
eDP: AccCmd: 8F FE EC 23 04 BA 
eDP: BAddr:15, Index:3
eDP: OAddr:60
eDP: OPS Mode CV Programming Command
254
eDP: Unsupported OPS Mode CV Addressing Mode
eDP: Check Output Address:60
eDP: OPS Mode Instruction:3
eDP: CV:36 Value:4

Not known what value i musst be add to the "if" of pDccMsg->Data[1] to accept this command cv write. regards

gorillale commented 1 month ago

?:

      // PoM messages (long form)
      // Basic Accesory:    10AA AAAA 1AAA-1AA0 1110-CCVV VVVV-VVVV DDDD-DDDD EEEE-EEEE
      // Extended Accesory: 10AA-AAAA 0AAA-0AA1 1110-CCVV VVVV-VVVV DDDD-DDDD EEEE-EEEE
      if ( ( (pDccMsg->Data[1] & 0b10001001) != 1) 
          && ( (pDccMsg->Data[1] & 0b10001111) != 0x80) // include AA ????
          && ( (pDccMsg->Data[1] & 0b10001001) != 0x88)) 
kiwi64ajs commented 1 month ago

Hi Andrew,

I used opendcc system and dcc-ex.

I want to try replicating your testing; however, and I have a DCC-EX system, but don’t have an OpenDCC Command Station.

Which system did you use to perform the DCC Accessory OPS Mode CV Programming operations on your Accessory Decoder?

If you were using the DCC-EX System, can you describe precisely how you did this? Perhaps by typing commands on the DCC-EX Console or using JMRI?

Regards

Alex

gorillale commented 1 month ago

I used only DCC-EX with iTrain to send the CV change code: Address 60, CV 36 = 4, with opsmode 0 on dcc.init (last param) AccCmd: 8F FE EC 23 04 BA (6 Byte Accessory Command) On Menus you can find Decoder programing and DCC-EX is supportet on interface. On layout drop a signal with dcc addr 60.

You can download iTrain for testing free: (https://www.berros.eu/de/itrain/)

I not have a command station for open-dcc only a roco maus over wifi and itrain. the if2 i not use at this time.

kiwi64ajs commented 1 month ago

Hi Andrew,Ok, that’s helpful to know how you were testing or trying to do the Accessory Decoder OPS Mode CV programming.I’ve applied for an iTrain trail license and I’ll see if I can recreate your environment and hopefully come up with a solution to support this. RegardsAlex ShepherdOn 2 Sep 2024, at 10:42 PM, gorillale @.***> wrote: I used only DCC-EX with iTrain to send the CV change code: Address 60, CV 36 = 4, with opsmode 0 on dcc.init (last param) AccCmd: 8F FE EC 23 04 BA (6 Byte Accessory Command) On Menus you can find Decoder programing and DCC-EX is supportet on interface. On layout drop a signal with dcc addr 60. You can download iTrain for testing free: (https://www.berros.eu/de/itrain/) I not have a command station for open-dcc only a roco maus over wifi and itrain. the if2 i not use at this time.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

gorillale commented 1 month ago

hi, i have tested again yesterday and found this solution for me. But not known is this right. And unknow if 0b10001111 what you make with this.

      if ( ( (pDccMsg->Data[1] & 0b10001001) != 0b00000001) 
          && ( (pDccMsg->Data[1] & 0b10001001) != 0x10001000)        /////!!!!!andrew add 
          && ( (pDccMsg->Data[2] &  0b11110000) != 0b11100000))         /////!!!!!andrew add 
          //&& ( (pDccMsg->Data[1] & 0b10001111) != 0x80))                /////!!!!!andrew remove, why include AA ????

is this the solution? regards