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.

N2HET software angle generator gap/revolution detection erratic results

Other Parts Discussed in Thread: TMS570LS1224

Hi all,

I'm trying to use the N2HET SWAG on the TMS570LS1224 (N2HET at 80 MHz) to interface a toothed wheel (1 missing and 7 actual teeth), simulated as a 50% duty cycle 4 KHz signal generated through the RTI.

If I set gapstart and gapend both at 0, the individual teeth-cycles are detected correctly (the missing tooth is seen as an extension of the 7th tooth). However, with a stepsize of 8, the correct gapstart and gapend should be 8 * (7 - 1) + 1 = 49 and 8 * 8 - 1 = 63, according to SPNU515b.


In my understanding, the following code should produce a switch on N2HET pin 20 every revolution (8 teeth):

; Angle Counter
L00   APCNT { next=L01,irq=OFF,type=RISE2RISE,prv=ON,period=0,data=0};
L01   SCNT { next=L02,step=8,gapstart=49,data=0};
L02   ACNT { next=OUT20,edge=RISING,gapend=63,data=0};

; Change OUT20
OUT20   ACMP { next=L00,en_pin_action=ON,cond_addr=OUT20_PULSE_LOW,pin=20,action=SET,reg=B,data=0};

; Switch OUT20
OUT20_PULSE_LOW   MOV64 { next=L00,remote=OUT20,en_pin_action=ON,cond_addr=OUT20_PULSE_HIGH,pin=20,comp_mode=ECMP,action=CLEAR,reg=B,data=0};
OUT20_PULSE_HIGH   MOV64 { next=L00,remote=OUT20,en_pin_action=ON,cond_addr=OUT20_PULSE_LOW,pin=20,comp_mode=ECMP,action=SET,reg=B,data=0};


However, the switches on pin 20 take 11 or 12 teeth instead of 8. The last 3 days I've tried several gapstart and -end settings, several numer of teeth per revolution, with or without missing teeth, but the revolution/gap detection seems to produce inconsistent results. I found https://e2e.ti.com/support/microcontrollers/hercules/f/312/p/411737/1497955, but it quickly goes into the HWAG, while I would like to stay with the SWAG. I ordered a new USB stick and when that arrives, I will add scope traces.

Does anyone know how to get the gap/revolution detection working correctly?


Edit: added scope traces for gapstart == 49 and gapend == 63

  • Hi Tim,

    I started looking at this but hit a bit of an issue w. the HET IDE that I need to work through.
    (I tried creating the stimulus to match your test input - but for some reason it looks like some of the
    stimulus pulses are being dropped so I need to get a debug build of the HET IDE and figure out what's going on..) I think if we can simulate this on the HET IDE that'll be the best course of action as everything will be visible.
  • Hi Tim,

    Think I just got the HET IDE issue fixed - some of the stimulus commands were being dropped between the GUI and the backend simulator ...  simulator wasn't assuming commands could be split across multiple recv() calls.

    Anyway got this picture now for stimulus:

    The stimulus is setup to repeat at 2ms so there's 7 teeth, gap and then two teeth from the next cycle in the picture (more would appear if I ran the sim longer).

    Here's a picture numerically of the stimulus -  all are set to repeat at 2000us intervals even though it doesn't show the repeat in this top level view:

    So pls. let me know if this stimulus matches your expectation.  If so we can trace through your SWAG program execution and figure out what's going on.

    Best Regards,

    Anthony

  • Hi Anthony,

    Thanks for the effort, the stimulus pattern indeed matches what I generated with the RTI. I only have the free version of WaveViewer, so I think I cannot generate a custom stimulus.

    Best,

    Tim

  • Hi Tim,

    So far, here's what I see when I run your program in the HET IDE, along with some of my personal 'commentary'.

    Note the NAF  (het.flag_naf trace) and how angle increments are counted off too fast during the initial interval..

    I think the program needs some 'startup help'.  For example the PCNT instruction (not sure why I don't see this for APCNT) has a reminder that the measurement captured at the first edge has to be discarded.  It's measuring an interval (rise 2 rise) at every rising edge,  but the measurement at the first rising edge is from an unknown reference and needs to be discarded.

    You can see that the step count during the interval in red seems to be counting off angle ticks too fast.   So that's one issue.

    I think this could be corrected by adding an instruction or two that protects angle counter during the startup interval,  i.e.. waits until the 2nd edge on the angle input is detected before executing the SCNT, ACNT, ACMP.

    The other place that the counter may need startup help is in the synchronization to the intial GAP.   This could be done with the help of the CPU or the HET again,  and I'm sure there's a bit of an art form to how this is handled in real world situations which I don't claim to be an expert on.   But I'm suspecting that just starting out the GAP may not be in the right place either during the sync up period.

    I still haven't digested the waveforms that you sent ... on silicon you've probably run a lot more cycles than I just ran in the simulator and it may have sync'd itself by the time you got you capture - so these things may be completely unrelated.    Not sure if the bad startup will continue to propogate,  but in any case it's interesting.

    The screen shot is about all that I can simulate with the free license for Synapticad.  We've purchased a floating license but the server needs a reboot so gotta wait till that happens to simulate more cycles.   Looks like unforutunately we only get 1 rotation within the memory limit of the viewer. 

    If we can speed up the angle input say by a factor of 10 and still have the experiment in the simulator be 'valid' though -- that might be something to try.

    Best Regards,

    Anthony

  • Hi Anthony,

    I adjusted the HET program to discard the first several NAFs:

    L00   APCNT { next=NAF_STARTUP_PROTECTION,irq=OFF,type=RISE2RISE,prv=OFF,period=0,data=0};
    
    NAF_STARTUP_PROTECTION   MCMP { brk=OFF,next=NAF_BR,request=NOREQ,hr_lr=LOW,angle_comp=OFF,savesub=OFF,control=OFF,en_pin_action=OFF,cond_addr=L01,pin=2,order=REG_GE_DATA,reg=S,data=2};
    NAF_BR   BR { next=L00,prv=OFF,cond_addr=NAF_INC,pin=2,event=NAF};
    NAF_INC   ADD { src1=IMM,src2=S,dest=S,next=L00,remote=NAF_INC,data=1};
    
    L01   SCNT { next=L02,step=8,gapstart=49,data=0};
    L02   ACNT { next=OUT20,edge=RISING,gapend=63,data=0};
    
    OUT20   ACMP { next=L00,en_pin_action=ON,cond_addr=OUT20_PULSE_LOW,pin=20,action=SET,reg=B,data=0};
    
    OUT20_PULSE_LOW   MOV64 { next=BACKUP_REG_A,remote=OUT20,en_pin_action=ON,cond_addr=OUT20_PULSE_HIGH,pin=20,comp_mode=ECMP,action=CLEAR,reg=B,data=0};
    OUT20_PULSE_HIGH   MOV64 { next=BACKUP_REG_A,remote=OUT20,en_pin_action=ON,cond_addr=OUT20_PULSE_LOW,pin=20,comp_mode=ECMP,action=SET,reg=B,data=0};

    This resulted in not getting output on the launchpad if NAF_STARTUP_PROTECTION.data != 0. In the simulator, if NAF_STARTUP_PROTECTION.data != 0, it seems NAF_BR always evaluates to true though, even if the NAF flags are false.

    If I drive hetm.watch_2.in with "((250us=1 250us=0)*7 500us=0) * 10", I see the waveform, but no response on pin 20 as I expected. I tried to speed up the simulation by 10x, with "((25us=1 25us=0)*7 50us=0) * 10" as input, but I still got no output, so I assume my method for signal input is incorrect (hetm.watch_2.in -> edit  selected signals -> set to drive -> enter equation). How do I correctly generate input for the simulator?

  • Hi Tim,
    Sorry - I think the simulator is a dead-end at the moment when it comes to SWAG instructions (APCNT, SCNT, ACNT, ACMP)- the SWAG instructions are likely not completely functional. I got pretty deep into a simulation yesterday and SCNT was not counting for long periods (in the simultor - which we *know* doens't match hardware). Then we looked at the validation suite and noted that the angle instructions are notably absent from the validation. Not sure what the history is there. I'm sure we can fix this but it'll take some time.
    If you *see* the stimulus you enter in the simulator show up in the waveform, then it's happening. So from what it sounds like the issue is in the output. I did get output from pin 20 with your program the other day but it was at seemingly odd times and took quite a while to appear (multiple cycles of the wheel before output started), and this I tracked down to SCNT not working in the simulator.
    The good news from all this is that one of my colleagues Charles Tsai has done some work on the SWAG and has a test case that will generate angles-reference outputs correctly provided he synchronizes to the GAP. He used the CPU and a 2nd N2HET to do this.
    This should be able to be done in the N2HET as well. But I think there's two issues. First the initial APCNT result needs to be always discarded as it's not a full period / interval measurement. Then, we need to loop comparing the next 3 apcnt results till a gap is detected. To detect the gap we would actually measure the intervals and do some math rather than relying on the gap start / gap end instrucitons of the SWAG. Then after that we'd count off teeth until the next gap and if that occurs in the correct location - let the ACMP loose.
    Will work on some code for this... what I've got so far is below in case you want to experiment with it, but it's not working yet.
    As it is the code multiples the middle tooth by a factor 1.75 but it should be multiplying by 1/1.75 so I am working on a mod right now for that ..

    NTEETH      .equ 7
    STEP_FACTOR .equ 8
    GAP_START   .equ (NTEETH-1)*STEP_FACTOR + 1
    GAP_END     .equ (NTEETH+1)*STEP_FACTOR - 1
    
    ; Angle Counter
    L00   APCNT {irq=OFF,type=RISE2RISE,prv=ON,period=0,data=0, next=G00};
    L01   SCNT { step=STEP_FACTOR,gapstart=GAP_START,data=0};
    L02   ACNT { edge=RISING,gapend=GAP_END,data=0, next=G01};
    
    ; Change OUT20
    OUT20   ACMP { next=L00,en_pin_action=ON,cond_addr=OUT20_PULSE_LOW,pin=20,action=SET,reg=B,data=22};
    
    ; Switch OUT20
    OUT20_PULSE_LOW    MOV64 { next=L00,remote=OUT20,en_pin_action=ON,cond_addr=OUT20_PULSE_HIGH,pin=20,comp_mode=ECMP,action=CLEAR,reg=B,data=40};
    OUT20_PULSE_HIGH   MOV64 { next=L00,remote=OUT20,en_pin_action=ON,cond_addr=OUT20_PULSE_LOW, pin=20,comp_mode=ECMP,action=SET,  reg=B,data=22};
    
    ; Gate to SCNT, ACNT
    G00   DJZ  {cond_addr=L01,   next=S00, data=1}
    
    ; Gate to ACMP
    G01   DJZ  {cond_addr=OUT20, next=L00, data=1}
    
    ; Synchronize start of SWAG
    ; NB: DJZ doesn't modify Z Flag, so BR 
    S00   BR   {event=NZ, cond_addr=CG00, next=S01}
    S01   DJZ  {cond_addr=S02, next=CG00, data=1}      ;discard 1st APCNT - it is invalid
    
    ; FIFO holding last three measurements  (S02 is oldest, S04 is newest)
    S02   ADD  {src1=REM, src2=ZERO, dest=IMM, data=0, hr_data=0, remote=S03}  ;N2
    S03   ADD  {src1=REM, src2=ZERO, dest=IMM, data=0, hr_data=0, remote=S04}  ;N1
    S04   ADD  {src1=T,   src2=ZERO, dest=IMM, data=0, hr_data=0}              ;N
    
    ; Calculate 0.057 * N1  
    ; NB: compute 0.057 * N1 = (8192*N1 + 1024*N1 + 128*N1) / 16384
    S05   ADD  {src1=REM, src2=ZERO, dest=R,   data=0, hr_data=0, remote=S03, smode=LSL, scount=7}
    S06   ADD  {src1=R,   src2=ZERO, dest=S,   data=0, hr_data=0, smode=LSL, scount=3}
    S07   SUB  {src1=S,   src2=R,    dest=R,   data=0, hr_data=0, smode=LSR, scount=2}
    
    ; Test N2 < 1.75 N1
    S08   SUB  {src1=REM, src2=R,    dest=NONE, data=0, hr_data=0, remote=S02}
    S09   BR   {event=N, cond_addr=S11, next=S13}
    
    ; Test 1.75 N-2 > N
    S10   SUB  {src1=R,   src2=T     dest=NONE, data=0, hr_data=0}
    S11   BR   {event=N, cond_addr=S14, next=S12}
    
    ; Not a GAP
    ; If first gap has not been detected, we are done.
    ; Otherwise, execute between gaps count
    S12   ADD  {src1=IMM, src2=ZERO, dest=NONE, data=0, hr_data=0}
    S13   BR   {event=Z, cond_addr=CG00, next=S18}
    
    ; GAP Detected
    ; First gap or second gap? 
    S14   ADD  {src1=IMM, src2=ZERO, dest=NONE, data=0, hr_data=0}
    S15   BR   {event=Z, cond_addr=S16, next=S19}
    
    ; First Gap
    ; Set flag in S14 to indicate 1st gap has been detected
    ; And initialize Between Gap Counter
    S16   MOV32 {type=IMTOREG&REM, reg=NONE, data=1, hr_data=0, remote=S14}
    S17   MOV32 {type=IMTOREG&REM, reg=NONE, data=0, hr_data=0, remote=S18, next=CG01}
    
    ; Between Gaps
    ; Increment Gap Count (NB: Subtract -1 to increment)
    S18   SUB   {src1=IMM, src2=ONES, dest=IMM, data=0, hr_data=0, next=CG01}
    
    ; Second Gap
    ; Did we detect the correct number of teeth between the first and 2nd gap? 
    S19   SUB   {src1=REM, src2=IMM, dest=NONE, data=0, hr_data=NTEETH}
    S20   BR    {event=Z, cond_addr=S21, next=S22}
    
    ; Second Gap As Expected - Start Angle Count at end of 1st tooth
    S21   MOV32 {type=IMTOREG&REM, reg=NONE, remote=L02, data=STEP_FACTOR, hr_data=0, next=L00}
    
    ; Second Gap Not As Expected
    ; Start Sync Again..
    S22   MOV32 {type=IMTOREG&REM, reg=NONE, remote=S12, data=0, hr_data=0}
    S23   MOV32 {type=IMTOREG&REM, reg=NONE, remote=S14, data=0, hr_data=0, next=CG00}
    
    ; Close 1st and 2nd Gates
    CG00   MOV32 {type=IMTOREG&REM, reg=NONE, remote=G00, data=1, hr_data=0}
    ; Close 2nd Gate Only
    CG01   MOV32 {type=IMTOREG&REM, reg=NONE, remote=G01, data=1, hr_data=0, next=L00}
    


    EDIT:  pasted code in a couple times to get it to look ok.   Also note that the code is in transition from a factor of 1.75 to 1/1.75 (0.57)..

  • Hi Anthony,

    With the following settings I got it to work, more or less:

    NTEETH .equ 8
    STEP_FACTOR .equ 8
    GAP_START .equ ((NTEETH - 3) * STEP_FACTOR + 1)
    GAP_END .equ ((NTEETH - 1) * STEP_FACTOR - 1)

    I changed the event of NAF_BR to rise instead of NAF and skipped an extra first (NTEETH - 1) * 2 rising edges (+ the first complete rotation, which is always skipped):

    It works at different speeds, although I still have to try the slowly adjusting the speed and see if it stays in sync. The disadvantage is the relatively slow start up. I wonder if the starter engine will be able to provide three rotations before the ignition kicks in?

    The first rotation was always skipped anyway, but with only NTEETH - 1 rising edges skipped extra, it sometimes worked correctly and sometimes the signal would lag behind and get in sync after around 8 rotations. This would result in misfires, hence the 3 skipped rotations.

  • I adjusted the stimulus to accelerate 5% per revolution after 10 constant revolutions to give it chance to sync, which resulted in the characteristic lagging we saw before:

    Even with 1%, the same behaviour was observed:


    Has anyone successfully used the SWAG? Especially for variable speed measurements?

  • Hi Anthony,

    Any updates on this?

    Thanks in advance!

    Tim
  • Anyone else with experience with the N2HET SWAG?
  • Hi Tim,
    Sorry there's another thread here: e2e.ti.com/.../1613500
    that's similar...
    I'd try to follow with what Charles is doing. He's looking at the angle generator now and I am working on getting the HET IDE update out. Charles is actually in better shape to analyze the instructions as he was one of the NHET designers.
    The bad news with the SWAG is that the TRM has errors in the psuedo-code, we need to work through those and get them fixed up. We think that the psuedo-code in the TMS470R1x HET user's guides are more 'correct' when it comes to the software angle instructions - but these all need to be audited. As far as we know - these instructions are the 'same' as they were for the R1x HET. The HWAG is where the newer development effort went.
    Best Regards,Anthony
  • Hi Anthony,


    Any updates on this? I do not want to use the ISR to sync the N2HET, because I have other interrupts on the system and do not want to delay those/risk missing a sync. The main reason for using the N2HET was its relative independence. It would be a shame to change that.


    Best regards, Tim

  • Hi Tim,

    No updates from me on this. Charles Tsai is working on the angle generator though.
    I'll cc' him on this post to see how far he's gotten.