This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

A program N2HET works at one N2HET RAM address but not at another address

Other Parts Discussed in Thread: STRIKE

Hello.
I wrote N2HET program to control the speed of DC motor. The program is fully tested at address 0xFF460000 and address 0xFF460190. But this program does not work at the address 0xFF4602D0 - 0xFF460420.
I tried with another program (control of step by step motor) and it’s exactly the same thing.
What can I do?
Thanks for your help.
Jerome

  • Jerome,

    Is this program a set of N2HET instructions that you are integrating into a larger N2HET program?

    (i.e. this would be why it moves around in memory...)

    If so you should check that your program in question is actually running, and that it's not being bypassed by instructions before it.

    You can watch the NHETADDR register in CCS with automatic refresh and see if any of the addresses in your program show up there while the N2HET is running.  This method could be quick but is crude as the update rate is very slow compared to the HET program execution and it may take a while to catch the program in that range.

    A better way would be to set the BRK bit (22 of program field) in one or more of the instructions of this program segment - there are instructions for this in the TRM  N2HET chapter xx.2.1.7 Debug Capability   (xx = N2HET chapter which varies from TRM to TRM).

    If your confirm your program is running you can also check that there is no overflow - which happens when you try to execute too many instructions within a given loop resolution period - and you are not back at address 0x0000 before the end of the LRP.    The overflow bit is in the HETEXC2 register.

    Next thing to check is -- are you using the ECMP instruction or another such hi-res instruction in your motor code?  If so are you attempting to perform a hires instruction [or even another low res instruction** some errata on this..] on the *same pin* earlier in the program.  The hi-res logic is a limited resource, and the N2HET is designed to ignore the second instruction that touches the hi-res logic on a given pin within the same loop resolution period.   

    Another thing to check is whether your program is using interrupts.  The interrupt number that an instruction generates is tied to it's address - so it's possible that moving an instruction which generates an interrupt has changed it's request number, perhaps to a request that is not enabled or to one that conflicts with another interrupt generating instruction later in your program.

    Some additional things to check:

       - if you added code to your working program -are there any instructions in the added code that modify the instructions of the working program?

       - does your program depend on a register like "T" - that may be implicitly changed by the execution of a previous instruction.  For example if an earlier "ECMP" triggers,  it updates T with the compare value.  If you then get to your previously working program but T no longer contains the count value but instead the ECMP match value of the earlier code - it would behave differently.   fix for this is to add an instruction that loads the counter value back into "T" before executing your working code.

      - does your program use any MOV64, DADM64, RADM64 instructions to modify the control field of another instruction?
        if so did you remember to update any critical conditional address fields when you relocated your program

      - can you reproduce the problem in the HET IDE?   This is always a help if you can.

      - consider adding or changing an instruction or two in your working program to write something to memory that you can watch change in the CCS IDE memory window.  For example write back a state or a count value - something to give you an indication that the program is running correctly (or not).
        Kind of like 'printf' debugging for N2HET.

  • Hi Antony,
    Thanks a lot for your fast reply.
    In my applications there are 2 DC motors and 1 step by step motor.
    So I built 2 blocks of identical N2HET instructions for the DC motors and one block of N2HET instructions for the step by step motor.
    First step I placed the two blocks of code for the two DC motors, I tested it and it’s working well.
    Then I tested individually the N2HET Program for the step by step motor.
    Then I inserted the SbS motor program before the two DC motors program and it’s the reason the CD motor program moves around. The code never changes except for the last instruction to jump or not to the first instruction.
    In the configuration SBS-DC1-DC2 the DC2 program does not work and crashes the SBS program.

    In that case only DC1 works well.

    In the configuration DC1-DC2- SBS the SBS program does not work and crashes the DC1 program.
    In that case only DC2 works well.
    The resolution loop is 8*7cycles, I tried 8*9 cycles. SBS program = 21 cycles max, DC program= 14 cycles max.
    Yes I use ECMP code.
    I need to install the interrupts system but it’s not already done. 
    Yes, my programs use RADM64, DADM64, ADD, MOV32 to modify the control field and data field of other instructions, especially for the step by step motor control. The conditional address field is always identified by a label. The codes for DC motor are identical. I just replace a prefix dcm1 by dcm2 and all labels are updated.
    I never used the BRK and debug capability for N2HET, it seems to be necessary.
    I will try to use your recommendations.
    Thanks a lot.
    Jerome

  • Hi Antony,
    One more thing:
    In the configuration SBS-DC1-DC2 I replaced the first SBS instruction by a BR to the first DC1 instruction. So the SBS program was completely strapped. And the DC2 program does not work. If I remove completely the SBS program, there are just DC1-DC2 program in memory, all is working well.
    Thanks for all.
    Jerome
  • Hi Jerome,

    So this probably rules out a hi-res structure resource conflict, because DC1 & DC2 work ok together ... simply moving the two codes and branching to them from address 0 wouldn't create the hi-res conflict.

    And if you also replaced your SBS first instruction w. a branch to DC1 then I think this would rule out an implicit dependence on a register, because the br wouldn't use a register.

    Sounds like you're able to rule out interrupts as well.

    Sounding more like it may be a 'build' problem rather than a runtime problem the way you describe it. Perhaps something in the RADM64/MOV64/ etc isn't recomputing correctly or automatically updating based on the label.

    This can happen easily if you use the form of these instructions where you specify 'cntlval=xxx' where xxx is some hex number you have to define.

    This may be a dumb question - but when you 'move' these programs around you are always creating a single combined .het assembly file and running the combination through the HET assembler again - correct? You are not assembling SBS, DC1, DC2 separately and then combining them at runtime by copying the segments to different base addresses in the HET RAM...
  • Hi Antony,
    Thanks a lot for all your explanations.
    You are right, I specified four times the “cntl_val=0xhexvalue” in DADM64 instruction of SBS program. So the SBS program cannot be moved around in memory.
    But I never specified it in DC motor program. And DC2 program is a DC1 program moved around in memory, and it works correctly.
    Of course, when I 'move' these programs around I am always creating a single combined .het assembly file and running the combination through the HET assembler again.
    Ok now I will continue to find a solution, with your explanation It will be easier.
    I will tell you the final result
    Kind regards
    Jerome
  • Hello Anthony,  
    DC1 and DC2 have the same behavior.
    When we move around it up to 31 N2HET instructions it works very well.
    If we move around it to 32 N2HET instructions and above it does not work.
    32 N2HET instructions = 256 bytes = 2 pwr 8.
    Have you an idea?
    I’m trying to debug it with HET-IDE.
    Thanks for your help.
    Kind regards
    Jerome

  • Hi Jerome,

    Interesting data point. 32 instructions is the modulus for the interrupt scheme - other than that I can't think of anything. All of the addressing in the next=, cond_addr=, and remote= are absolute not relative, and can span the entire address space of the HET RAM which is small - so they don't strike me as related to modulo 32.

    Debugging in the IDE is probably the best step to take next. The other thing you might do is to let your program 'crash' / not work - and just confirm that the instructions haven't been unexpectedly modified by the CPU or DMA ... i.e. compare the program field especially against the intial load.

    Best Regards,
    Anthony
  • Hi Anthony,

    I debugged the two programs (configuration SBS,DC1,DC2 and configuration DC1,DC2,SBS) with HET-IDE.

    In the second case I had to update the value of “cntl_val=0xhexvalue”. So the two programs are OK in simulation.

    On silicon the second program works well but not the first program.

    I tried to isolate the DC2 instruction which interferes with the SBS program in the configuration SBS,DC1,DC2. I saw the problem occurs when the 4 first instructions are executed in DC2 program:

    The instruction PCNT measures the period of the DC2 feed-back signal. When the motor is stopped the instructions “dcm2_rfp” and “dcm2 tnc” are never executed and the SBS motor don’t stop (that’s OK).
    When I move manually the motor the SBS motor stops (that’s the problem).

    I tried to modify the "ADD" and "SUB" instructions (change the register, remote, etc) but the problem always occurs. Finally I replaced the two instructions by BR instructions.

    In the following cases the problem does not occur:

    And In the following cases the problem occurs:

    Is the problem comes from PCNT instruction?

    I tried to move upward (in the first 32 instructions area) the two PCNT instructions (DC1 and DC2). The interferences with step by step motor continue but in different ways: the motor does not stop but accelerations are not executed.

    Do you think it’s possible to debug this with NHET debug tools?

    Thanks for your Help.

    Jerome

  • Hi Jerome, I'm having a hard time following but I think I'm catching up.
    To summarize (let me know if this is the correct picture): Your 'problem statement' is that you have DC1,DC2,SBS now working both on the simulator and silicon, but SBS,DC1,DC2 works only on the simulator (and not on silicon).
    To debug the problem on silicon, you notice that if the PCNT instruction at dcm2_mfb never matches (no rising edges) then SBS works, but by simply moving the motor to cause an edge, you can make SBS fail.
    So you did a few more experiments and have been able to comment out the ADD/SUB instrucitons at dcm2_tnf and dcm2_rfp and make the SBS continue to work. *but* if you add one more dummy BR instruction (dcm2_bnc) then the SBS program fails again. Of course this occurs without moving SBS at all...
    And now the bigger issue is that you can't reproduce this particular problem in the IDE, so it's very difficult to debug to the level of understanding exactly *how* these DCM2 instructions interfere with the SBS.
    Is that an accurate summary?
    If so I'm about as puzzled as you are. And at this point I would be double checking some basic things - like what silicon are you testing on (part # and revision). I'd want to make sure that you're not mixing N2HET code on NHET or maybe using an N2HET with less memory than you have the simultor configured for (like on the RM42 series).
    Then I'd have to try to understand more why the SBS program doesn't work on silicon. I might start watching the HET RAM while the program is running, looking for instructions in the SBS portion of RAM that should be updating their data fields (like a count or a DJZ) and watching to see if they stop updating, as an indication that a portion of the SBS program got turned off. Or I might modify the SBS program slightly to write some state to RAM on every loop - so I could watch this state and diagnose what's going wrong inside SBS.
    Honestly it's really hard to envision how these problems could occur. Adding an extra instruciton would make me think overflow. I believe if there is a program overflow than none of the pin updates that were scheduled during a loop will occur, and this is about the only way that I can see an SBS program which executes *before* the DC1,DC2, being impacted by DC1, DC2. Even if it's a resource conflict on the hr structure of the pin, the first instruction using the HR structure should 'win' meaning it'd be your DC1, DC2 that would fail not SBS.
    Assume you have checked the overflow flag in the HET registers to make sure that it's not set?
    Sorry if this isn't more helpful but this does sound like a difficult problem.
    Best Regards,Anthony
  • Hi Anyhony and Thanks for your fast reply.
    Your summary is very accurate. It’s exactly what I wanted to say.
    I use the RM48 USB Stick Development Kit ( Cortex-R4 ) and I am pretty sure there is a N2HET integrated in the product.
    No I have not checked the overflow flag in the HET registers to make sure that it's not set. And I will do it.
    I think we must forget the SBS program because the problem occurs with only DC1 and DC2 programs when I move around DC2 forward up to 32 instructions. (With 31 instructions it’s OK). This does not occur with HET-IDE but only on silicon.
    Now I prepare myself to use the integrated HET debug tool.
    I will let you know about the evolution of the project. 
    Thanks again for your suggestions.
    Jerome

  • Hi Jerome,

    Great - Let me know then where you get stuck next. -- although it would probably be best to understand where the interference between the programs is coming from. If you do get the overflow flag then you may be really close to the cycle count limit and depending on how you order things - sometimes you can pick up a cycle penalty. For example, there's an +1 penalty in execution if remote=next .. it's not listed in each instruction summary but is listed before the instruction table for all instructions.

    The RM48 definitely has the N2HET. And it's got 160 words of instruction RAM so if you're running in the simulator you should be able to run on silicon.

    Good luck & Best Regards,
    Anthony
  • Hi Anthony
    Yes I had N2HET program overflow, not because extra cycle but because core CPU bug.
    The next address field of the instruction “dcm2_tnf BR { next=dcm2_tnc, cond_addr=dcm2_cnt, event=NZ}” is modified by core CPU to enable or disable the regulation behavior.
    This is necessary when the core CPU stop the motor to avoid that a last N2HET cycle restarts it.
    The bug concerned a mask which is used to calculate the next address field. So it was working on the first 32 instructions and was failing after. Instead of to branch to instruction 33 it branched to instruction 1. This the reason of the crash of SBS program or DC1 program located in the top of N2HET RAM.

    Furthermore the problem does not occur in HET-IDE because there was not interaction with core CPU. The tests are static, not dynamic with HET-IDE.
    So now all is clear and works well. It was a hard work for a wrong mask. But I am initiated to N2HET debug and I will definitively check the N2HET program overflow in all my future developments.
    Thanks a lot for your help and suggestion and encouragements 
    Kind Regards

  • Ah - that makes sense. Glad you were able to find out what the issue was Jerome.

    Just as an FYI, in the HET IDE you can setup a 'Memory Trigger' to create a write to HET RAM during the simulation. This gives the ability to mimic the CPU writing a value like enable/disable of a function so you can simulate a graceful start up or shutdown. You can also use it to change a period value or direction so you can simulate transitions of these type of CPU controlled options.
  • Hi Anthony,
    Thanks for this information.
    May be at an other time.
    Jerome

  • Hi Jerome,

    In case you want to try it sometime - here is some XML from one of my project files that has memory triggers setup:

    <MemoryTriggers>
    <Trigger Unit="NS" ActionAddress="58" Type="Time" ActionValue="0x80000000" Id="0" Value="2000"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0xF80" Id="1" Value="4000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x11C0000a" Id="2" Value="4200"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0xF80" Id="3" Value="60000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x1F80000a" Id="4" Value="62000"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0x2000" Id="5" Value="590000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x11000010" Id="6" Value="592000"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0x1000" Id="7" Value="1400000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x1Fc0000b" Id="8" Value="1400200"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0x10000" Id="9" Value="2200000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x10000001" Id="10" Value="2200200"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0x1200" Id="11" Value="3050000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x1180000a" Id="12" Value="3050200"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0x10000" Id="13" Value="3250000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x10000001" Id="14" Value="3250000"/>
    <Trigger Unit="NS" ActionAddress="e8" Type="Time" ActionValue="0x1f80000a" Id="15" Value="3550200"/>
    <Trigger Unit="NS" ActionAddress="d8" Type="Time" ActionValue="0x2000" Id="16" Value="3250000"/>
    </MemoryTriggers>

    Your HET project file probably has an empty 'MemoryTriggers' section.

    You can add these triggers through the GUI and that may be the safest but after a while I find notepad++ a lot easier ;).

    To do a quick interpretation, at 2000ns the first trigger writes 0x80000000 to a location in HET RAM. It's actually the 'data' field of instruction #5 (or 6 depending on how you count) in other words the instruction that shows up at address 0x50 in the disassembly. The program field would be '50' the control '54' and the data in this case is '58'.

    Then periodically I'm writing to 'e8' and 'd8' which are commands - d8 is a an initial period in counts and the value at e8 is a bunch of bit fields (valid, direction (fwd/rev/none), acclerate/decelerate/constant speed, and number of steps.

    So in a sense I'm simulating what may happen if the HTU is programmed to pull these 2-word commands from memory to the HET.

    I had to figure out the right time by watching the simulation and tweek the time value. But the nice thing is I can test a bunch of commands as well as the transition from one mode to another - for example from fwd to rev. with this and once it's setup your subsequent simulation runs are fast and repeatable.

    Thanks and Best Regards,
    Anthony
  • Hi Antony,
    I am happy to read news from you.
    Thanks for your method that I store in my knowledge data base.
    Now I leave the N2HET development to make interrupt drivers. That is the next step of the project.
    The next time that I will have a complex N2HET project I will begin to look at this method.
    Thanks a lot for your help.
    Jerome