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 quadrature encoder

Other Parts Discussed in Thread: HALCOGEN, TMS570LS1224

I was thinking on using the application note: http://www.ti.com/lit/an/spna228/spna228.pdf  which uses the N2HET assembler IDE. The encoders give 1440 pulses per

revolution and the motors work at 11RPM. Here I have one question:

- Do I need to configure something on the HALCogen fot the N2HET to work properly? Or with the configuration on the IDE is enough?

I saw this post https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/305646 which uses the HALCogen Edge Detect configuration. Would it be too difficult to

modify the source and the include of the N2HET to male it work with the 22 pins? How the HETDIN register works?? 

Is there any other way to use the N2HET pins to get the encoders data? 

thanks and best regards

  • Miguel,

    Which device are you using?

    So to be clear this is 12 encoders but there are only 1440 pulses/rev and the motors only run 11 RPM?

    Meaning that the time between pulses is ~3.78ms?

    Then I would use the QEP example code on HET and just scale it to 12 instances.   You should be able to do this for all 12 unless for some reason you are
      in a smaller Hercules w. limited HET memory and pins, but if you have 2 EQEP on the device then I don't think this is the case.. 

    -Anthony

  • Hi Anthony

    Im using the TMS570LS1224

    And..... yes, thats the time between pulses of each encoder. 

    Mike

  • Hi Anthony
    I have been looking for that example but can't find it... Is on HALCOGEN or on the HET IDE??
    best regards
  • I just checked the link to the appnote SPNA228 in the first post, and was able to download it. Are you having an issue doing so?
  • aaaah is that example?? no no, I already download it =)
    thanks!!
  • Hi Anthony

    Hope you are doing great

    (Just to remember) My application has 12 independant quadrature encoders. 11 go to N2HET pins ans 1 go to ECAP pins. (I know I know... but I ran out of N2HET pins because of the PWM, which are also 12 hehehe)

    I found this gorgeous post: e2e.ti.com/.../318762

    and also the applicaton note about quadrature encoders (www.ti.com/.../spna228.pdf). I have a couple of questions:

    AFL BR { next = FOR, cond_addr = BAC, event = Low, pin = Pin_B} ---->line from app. note*

    AFL1     BR      { next = BAC1, cond_addr = FOR1, event = Low, pin = Pin_B1} ---->line from post **

    On * we have the "next=FOR, cond_addr = BAC" but in ** we have "next = BAC1, cond_addr = FOR1" I was wondering about the difference between each line.  (This happens on many lines)

    Second: 

    This lines came from the post

    ;----------------------------Turn Backward--------------------------------------

    BAC1 MOV32 { next = LIM1, remote = FOR1, type = REMTOREG, reg = A}

    LIM1 ECMP { next = SSUB1, cond_addr= HIL1, hr_lr=LOW, en_pin_action=off, pin=CC25, reg= A, data=0}

    HIL1 ADM32 { next = AFE2, remote = FOR1, type = IM&REGTOREM, reg = A, data = ENCODER_MAX_STEPS_VALUE}

    SSUB1 ADM32 { next = AFE2, remote = FOR1, type = IM&REGTOREM, reg = A, data = ENCODER_MINUS_ONE_STEP} 

    These line came from the app. note

    BAC MOV32 { next = LIM, remote = FOR, type = REMTOREG, reg = A}
    LIM ECMP { next = SSUB, cond_addr= HIL, hr_lr=LOW, en_pin_action=off, pin=CC0, reg= A,
    data=0}
    HIL ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x0000FA0}
    SSUB ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x1FFFFFF}

    Here the last two lines differ. He used AFE2, which corresponds to the second encoder (and the second encoder has the AFE1 instead), Texas used START, which corresponds to having reached the max count  and restart it, so I don't know what it does... And if I dont have an INDEX pin, how can it be done?? 

    What is reg=A?? its ok if I leave it like that for the 11 encoders Im using or do I need to change something?

    I read that the CC25 is just notation to pin 25 of the N2HET module right?

    and the last question. .eq X indicate the pin of the module to be used or is just a sequencial number? I made myself clear: do I need to write .eq PIN TO BE USED even when ther are not sequencial?, like:

    .eq 2

    .eq 20

    .eq 4

    and so on?

    Thanks!!!  

  • Miguel, as far as I can tell BAC and BAC1 are just different labels. As long as the program is consistent it shouldn't matter. The instructions look exactly the same.

    The difference between AFE and START just is probably due to a different number of pieces of the code.

    When you reach the end of the HET code you for any loop you need to jump back to address 0. So the one that goes to START means it's finished for that loop in that instruction. The one that goes to the second AFE has more work to do in that loop. In any case all programs on het need to jump back to address 0 before the loop resolution clock period expires or you will get an overrun error and all pin actions scheduled that loop will be canceled.

    The .equ is an assembler directive. You can substitute a symbol for a numeric value using this directive.
    Doesn't need to be a pin.

    Reg=A, kind of depends. Some of these instructions might write to a register but never use the value.
    You have to study the code to figure it out.
    With the QEP code though I think it's just a state machine that checks for an edge on each pin and then if detected, checks the other pin state and jumps to a +1 or -1 at the end.

    Also you can look at
    www.ti.com/.../tidm-hahscpto

    The HSC has a quadrature counter. It does more than you probably need though ... but what might be interesting to see are some ideas in how the macros are used to compose a large HET program from smaller segments. We used Macros for this because HET doesn't have the ability to execute a subroutine with parameters, But in the Macro language you can make a macro that looks like a subroutine but expands to HET code and then is assembled to run on HET as the fully expanded code. But then you only have to maintain the single Macro. Might be helpful for you if you are trying 12 instances of the same code...
  • Anthony F. Seely said:
    Miguel, as far as I can tell BAC and BAC1 are just different labels. As long as the program is consistent it shouldn't matter. The instructions look exactly the same.

     

    Here I meat what was the difference between having " next = FOR, cond_addr = BAC "  instead of  "next = BAC, cond_addr = FOR" 

    Anthony F. Seely said:
    The difference between AFE and START just is probably due to a different number of pieces of the code.

    When you reach the end of the HET code you for any loop you need to jump back to address 0. So the one that goes to START means it's finished for that loop in that instruction. The one that goes to the second AFE has more work to do in that loop. In any case all programs on het need to jump back to address 0 before the loop resolution clock period expires or you will get an overrun error and all pin actions scheduled that loop will be canceled.

    This lines comes from the app. note: 

    START ECNT { next = AFE, cond_addr = CLRCNT, event = Fall, pin = INDEX, reg = NONE, data = 0}

    CLRCNT MOV32 { next = AFE, remote = FOR, type = IMTOREG&REM, reg = A, Data = 0}

    The start is just a parameter for the index pin, which I dont have. Is not a start for the loop... I need that when the count reaches the maximum, the data goes to 0. 

    Anthony F. Seely said:
    Also you can look at
    www.ti.com/.../tidm-hahscpto

    The HSC has a quadrature counter. It does more than you probably need though ... but what might be interesting to see are some ideas in how the macros are used to compose a large HET program from smaller segments. We used Macros for this because HET doesn't have the ability to execute a subroutine with parameters, But in the Macro language you can make a macro that looks like a subroutine but expands to HET code and then is assembled to run on HET as the fully expanded code. But then you only have to maintain the single Macro. Might be helpful for you if you are trying 12 instances of the same code...

    The board Im using has already all the inputs for the encoders... I cannot use an aditional board... (I saw the link and I only saw the design files for a board)

  • This is just the difference in state machine encoding, which edges you want to count as +1 and which as -1.

    -Anthony

  • Hi Anthony

    but what is the difference between having " next = FOR, cond_addr = BAC "  instead of  "next = BAC, cond_addr = FOR" ?? That what I don't understand...

    And about the other question... I don't know why this man wrote the value AFE from the other encoders instead of sending it to 0... of how that line works??

    (the red lines)

    best regards!

  • Miguel,

    So let's focus on SPNA228 then you will understand the other program as well.

    First, look at the state diagram in figure 3 on page 3.

    Now the way the HET program is written, section 2.2 page 4, you have the edge detection

    AFE- checks for a falling edge on pin A
    ARE - checks for a rising edge on pin A
    BFE - checks for a falling edge on pin B
    BRE - checks for a rising edge on pin B

    The assumption is that only one of these four edges occurs within the HET loop resolution period.

    So as each edge is looked for, if the edge is found, then the *level* of the other pin is checked.

    So if AFE detects a falling edge on Pin A, then it is up to the level of Pin B to determine whether the count should be +1 or -1.

    This is tested by AFL .. see how AFL tests pin B. If Pin A falls, but pin B is Low, then this causes a count of -1 (branch to BAC).
    Otherwise, if B is high, then this causes a count of +1 (branch to FOR).

    You can refer to figure 3 to see where this comes from.

    Look at the state transitions for the falling edge of A.
    These are 10 -> 00 which is a decrement in the figure. This means A fell (1->0) but B was low the whole time (0->0).
    And the other one is 11 -> 01 which is an increment in the figure.

    The case 10 -> 01 isn't handled because this is when there are two edges on pins A and B in the same period.
    You *could* add another BR instruction on pin B to the state machine if you ish, so that you take the dashed line state transition too, but this would be up to you and imperfect as well...

    -Anthony
  • Anthony
    I hope you're doing great
    With the code I posted, the start means the count is cleared. but in the other, the one on the post, goes to check the variable of the next encoder in line, or the last. How couls I make a Clear count when not having the Index pin?
    best regards
  • You can clear the counter by writing a value to it's data field.
    However, you have to decide when the right time to do this is.
    That's what the index pin might be used for.

    If you are not going to clear by the index pin, you need to write a host side driver function on the ARM that writes a zero value to the data field of the counter.

  • basically the counter gets gleard when the count reaches its max value, in this case 1440.
    I dont get that about "write a host side driver function on the ARM that..."
    The idea is that, if for some reason the motor reaches the limit, the counters restarts. The mechanism is intended for just half to 3/4 round but Murphy says you need to get prepared for any event. Because this code, the one posted on the other post, goes and checks the value on AFE on the last encoder. and I was wondering on how to do the START lines without the index pin. lets say, make it by software (if count==X) then count=0;
    thanks!!
  • This is one of the capabilities that is in the HSC code from the TI design I'd pointed to you before.
    It supports either saturating the counter at the max or rolling over. Please take a look at that example.
  • the problem is that I did not found that example on the halcogen examples... and neither on the HET IDE...
  • I am not sure I understand the problem.
  • Ok. there are two problems:

    1)i could not find the example you told me. I found an application note but not the example for halcogen

    2) the source code i get for HET module contains only like memory directions pr something. I could not copy those and extend them to all the encoders i have because the code doent have functions  just like addresses for something else. I dont know...

  • Miguel

    Firmware is on the bottom of the TI design page.   See:

  • Hi Anthony
    Hope you're doing great

    I already have the code working. Just one question...
    I tested one with only one encoder. It worked, and I have this configuration: 20MHz,HR=1,LR=32 on the HET IDE. I have a couple of questions...

    1)I dont have that option on Halcogen so... what would be the best configuration for the timer??

    2)Do I need to activate interrupts for the code to work? or is the stare machine works on polling??

    3)how can I retreive the data from each variable to the MCU CPU??

    4)how can I reset the variables if for some reason they reached the limit??

    5)When changing the direction of the signals (inverting the pins) the value just go to 0 ot to 1440, which is the limit. Why is this happening?? It does the same with the TI app note...


    Thanks!

  • ooh 6th question
    how can I tell the direction of the motor??

    thanks!!
  • Miguel,

    If you have a quadrature encoder, then the direction of the motor is encoded into the state transitions of the two signals;  for each current state, one transition means forward, the other means reverse.  (third one means you probably missed a transition).

    At 1440 pulses/revolution and 11 RPM though you are talking > 3.5ms for each pulse and that's many times the HET's loop resolution (like a few thousand times) so the HET shouldn't miss edges.

    Now, I don't really understand your first question.   The HalCoGen HET program doesn't include quadrature decoding.  So your choices if you use it are just to interrupt the CPU on every edge and implement the state machine on the CPU in hardware (not a good idea) or load a custom HET program to do quadrature decode (there is an appnote for this).

    If you have a more specific question that I missed; please elaborate.

    -Anthony

  • Hi Miguel,

    Miguel Amezcua Peregrina said:

    1)I dont have that option on Halcogen so... what would be the best configuration for the timer??

    Which option?   20MHz,HR=1,LR=32 ??


    So I would say you do have this option, but I think you need to slow the CPU down because there is some maximum divide value between the CPU clock and the HET clock (VCLK).   I'd need to scour the device datasheets for this but anyway not critical.


    I would say you should just run the HET as fast as possible so at the default frequency.

    If you are using the EDGE detect based QEP code then this just means you sample the data pins more often and you will be able to track a faster input signal.  

    Miguel Amezcua Peregrina said:
    2)Do I need to activate interrupts for the code to work? or is the stare machine works on polling??

    Which code exactly?   The appnote, or the HAHSCPTO example code?     But generally I'd say for the QEP you wouldn't use interrupts, you would instead read the position when needed probably based on some other interrupt (not directly coming from the QEP edge, but say when it's time to update your controller with new inputs).

    Miguel Amezcua Peregrina said:

    3)how can I retreive the data from each variable to the MCU CPU??

    Do you mean how to read the HET RAM from a CPU program?  There is a data structure that is generated by the HET assembler in the <your_program>.h output file which gives you several views on your program in C that can be used to read program, control and data fields generically (just the raw 32-bit values) or in an instruction specific way where the bit fields of the underlying HET instruction are decoded and accessible as members of the struct.   Just depends on what you want to do.

    Miguel Amezcua Peregrina said:
    4)how can I reset the variables if for some reason they reached the limit??

    I would suggest checking for the limit in the HET code and automatically rolling over when the limit is reached.  This is demonstrated in the HAHSCPTO code.

    Miguel Amezcua Peregrina said:
    5)When changing the direction of the signals (inverting the pins) the value just go to 0 ot to 1440, which is the limit. Why is this happening?? It does the same with the TI app note...

    I don't understand the question ..

  • I have the appnote on the quadrature encoder and thats what Im using =)
    I meant there is no option on halcogen for the prescalers to be the same that on the IDE
  • Anthony F. Seely said:
    Which option?   20MHz,HR=1,LR=32 ??

    Yees that option. I meant, I saw that the LR prescaler on Halcogen doesnt reach more than 7, or that the max value I could achieve just changing the time loop

     

    Anthony F. Seely said:

    So I would say you do have this option, but I think you need to slow the CPU down because there is some maximum divide value between the CPU clock and the HET clock (VCLK).   I'd need to scour the device datasheets for this but anyway not critical.


    I would say you should just run the HET as fast as possible so at the default frequency.

    If you are using the EDGE detect based QEP code then this just means you sample the data pins more often and you will be able to track a faster input signal.  

    So.. I could just run it to 20MHz, which gives me a time of 3.4us per loop, which is ~1000 times the encoders signals no? 

    Anthony F. Seely said:
    Which code exactly?   The appnote, or the  example code?     But generally I'd say for the QEP you wouldn't use interrupts, you would instead read the position when needed probably based on some other interrupt (not directly coming from the QEP edge, but say when it's time to update your controller with new inputs).

    Sorry, I was talking about the appnote that implements the quadrature encoder as a state machine. The state machine just works as a polling right? so no need to configure interrupts for this on Halcogen right??

    Anthony F. Seely said:
    Do you mean how to read the HET RAM from a CPU program?  There is a data structure that is generated by the HET assembler in the <your_program>.h output file which gives you several views on your program in C that can be used to read program, control and data fields generically (just the raw 32-bit values) or in an instruction specific way where the bit fields of the underlying HET instruction are decoded and accessible as members of the struct.   Just depends on what you want to do.

    yes. How to read the RAM. I saw the files but.... they only have as you said, 32 bits numbers on it...(the .c) the .h has many defines for each of the variables. I most use those defines to read the HET RAM?? could you pls give me an example like the line I need to use?

     

    Anthony F. Seely said:
    I would suggest checking for the limit in the HET code and automatically rolling over when the limit is reached.  This is demonstrated in the HAHSCPTO code.

    ok ok I will look for it to see how to implement that

     

    Anthony F. Seely said:
    Miguel Amezcua Peregrina
    5)When changing the direction of the signals (inverting the pins) the value just go to 0 ot to 1440, which is the limit. Why is this happening?? It does the same with the TI app note...

    I don't understand the question ..

    humm..... ok. I had first the signals going forward(signal A rising before signal B), so the count incremented 1 each X cycles, which is whats its supposed to. BUT if I modify the signals to go backwards (signal B rising before signal A), the count on the FOR label from the queadrature appnote just took values of 0 and of 4000.... And I dont know why....

    thanks!

  • ok Anthony... I already checked the HAHSCPTO and...
    1)Did not find that part
    2)I really didnt understand the codes haha

    Yesterday I saw, and on HAHSCPTO that they use the SHIFT function to do so. But how could I write on HALCOGEN
    If(count==MAX_VALUE)
    count=0;

    And... Thinking on what you said about the direction I think I could just do something like
    if(value2>value1)
    motor is turning forward
    else
    motor is turning backwards

    But for that to work, I need to know why the counter only goes from 0 to 4000 and back to 0 when the motor is turning backwards...
  • Miguel,

    Did you see the document  'tidua43'?

    Page 15 of the PDF explains how the counter features of either saturate or rollover are implemented.

    Regarding your other question - inverting the QEP A, B signals isn't the same as changing direction.

    See this part of the code:

    ;--------------------------------------------------------------------------------------------
    ; H1 COUNTER DECODING
    ;
    ; Count Up if:
    ; (A Rise && B Low) || (A Fall && B High) || (B Rise && A High) || (B Fall && A Low)
    ;
    ; Count Down if:
    ; (A Rise && B High) || (A Fall && B Low) || (B Rise && A Low) || (B Fall && A High

    Note that if you invert  A&B inputs then a condition:  

      (A Rise && B Low)  

    turns into

       (A Fall && B High)

    But both these are COUNT UP conditions.

    Likewise (B Rise && A High) || (B Fall && A Low) are inverse of each other and both count up as well.

    So inverting *Both* A,B doesn't change anything.

    You can see the same relationship among the COUNT DOWN conditions too.. but I won't list them.

    -Anthony

  • What I did was to create two signals. One without offset and the other with an offset of half the period, as an encoder works. Then I assigned the first to PIN_A and the second to PIN_B. It counted forward. BUT then I put PIN_A to the second signal and PIN_B to the first one, making a change of the direction of the motor. But it worked as I said...

    I already checked the code. But for what I saw, that part is on the state machine... write different but is the same.... but I don't know maybe I didnt use the signals properly but...

    look: here is my code with the signals. They are already set to be working backwards.And there you can see what I say. If you invert the pins, it count from 0 to 1440 but did not clear the count

    7612.encoder_5.rar

  • For backwards steps, I would expect the code to go to these lines:
    ;----------------------------Turn Backward--------------------------------------

    BAC5 MOV32 { next = LIM5, remote = FOR5, type = REMTOREG, reg = A}

    LIM5 ECMP { next= SSUB5, cond_addr= HIL5, hr_lr=LOW, en_pin_action=off, pin=CC0, reg= A, data=0}

    HIL5 ADM32 { next = AFE5, remote = FOR5, type = IM&REGTOREM, reg = A, data = ENCODER_MAX_STEPS_VALUE}

    SSUB5 ADM32 { next = AFE5, remote = FOR5, type = IM&REGTOREM, reg = A, data = ENCODER_MINUS_ONE_STEP}

    ;---------------------------------End Channel 5---------------------------------

    I don't quite understand the "SSUB5" line. It seems to me that it is adding '-1' modulo (ENCODER_MAX_STEPS_VALUE) because ENCODER_MINUS_ONE_STEP is 0x000059F which is one
    less than 0x00005A0. That part is OK but i am not seeing where the 'modulo 0x00005A0' part is done next.
    It seems like this will result in a counter value that is greater the max.

    Did you try to simulate this code in the HET IDE?

    Also, The device you are using also has N2HET with newer instructions including a subtract instruction.

    -Anthony
  • Ok so I looked at the appnote and it's got:

    HIL ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x0000FA0}
    SSUB ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x1FFFFFF}

    You should be able to use the value 0x1FFFFFF even with your range-limited counter; because it just represents -1 using the full width of the hardware adder.

    This will only be used when the count value is nonzero. When the counter value is zero, the line above it at HIL5 will set the count to it's maximum and you'll still get your range-limited counter from 0x0000000 to 0x5A0.
  • Ok so I looked at the appnote and it's got:

    HIL ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x0000FA0}

    SSUB ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x1FFFFFF}

    You should be able to use the value 0x1FFFFFF  even with your range-limited counter;  because it just represents -1 using the full width of the hardware adder.  

    This will only be used when the count value is nonzero.   When the counter value is zero, the line above it at HIL5 will set the count to it's maximum and you'll still get your range-limited counter from 0x0000000 to 0x5A0.

  • This are the same lines comming from the app note:
    BAC MOV32 { next = LIM, remote = FOR, type = REMTOREG, reg = A}
    LIM ECMP { next = SSUB, cond_addr= HIL, hr_lr=LOW, en_pin_action=off, pin=CC0, reg= A,
    data=0}
    HIL ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x0000FA0}
    SSUB ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x1FFFFFF}

    I just take away the START and added a 5, which is the encoder number. The max count is 1440 and if the motor were turning backwards I would expect to go to 1439 and then 1438 and so on.

    I did simulate it on HET IDE. This code and the App. note code to see if the behaviour was the same. And it is....

    I know... but where should I write it? in SSUB?

    Here is the code from the App. note:

    Pin_A .equ 0 ; Signal A from QEP encoder
    Pin_B .equ 1 ; Signal B from QEP encoder
    INDEX .equ 2 ; Index from QEP encoder
    ;---------------------------INDEX-CLR Counter ----------------------------------
    START ECNT { next = AFE, cond_addr = CLRCNT, event = Fall, pin = INDEX, reg = NONE, data =
    0}
    CLRCNT MOV32 { next = AFE, remote = FOR, type = IMTOREG&REM, reg = A, Data = 0}
    ;---------------------------check: aFbL / aFbH ------------------------------
    AFE BR { next = ARE, cond_addr = AFL, event = Fall, pin = Pin_A}
    AFL BR { next = FOR, cond_addr = BAC, event = Low, pin = Pin_B}
    ;---------------------------check: aRbL / aRbH ------------------------------
    ARE BR { next = BFE, cond_addr = ARL, event = rise, pin = Pin_A}
    ARL BR { next = FOR, cond_addr = BAC, event = high, pin = Pin_B}
    ;---------------------------check: bFaL / bFaH ------------------------------
    BFE BR { next = BRE, cond_addr = BFL, event = Fall, pin = Pin_B}
    BFL BR { next = FOR, cond_addr = BAC, event = high, pin = Pin_A}
    ;---------------------------check: bRaL / bRaH ------------------------------
    BRE BR { next = START, cond_addr = BRL, event = rise, pin = Pin_B}
    BRL BR { next = FOR, cond_addr = BAC, event = low, pin = Pin_A}
    ;-------------------------------------------------------------------------------
    FOR CNT { next = START, reg = NONE, max = 0x0FA0}
    ;-------------------------------------------------------------------------------
    BAC MOV32 { next = LIM, remote = FOR, type = REMTOREG, reg = A}
    LIM ECMP { next = SSUB, cond_addr= HIL, hr_lr=LOW, en_pin_action=off, pin=CC0, reg= A,
    data=0}
    HIL ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x0000FA0}
    SSUB ADM32 { next = START, remote = FOR, type = IM<REGTOREM, reg = A, data = 0x1FFFFFF}

    As you can see is the same as mine, with the only difference of the name of the labels and the START part, since I don't have an Index pin. To test it I changed the pin_B to 18 on the code I sent you before.
    I don't know why when backwards, just go to the count limit and 0...
  • I dont understand
    "You should be able to use the value 0x1FFFFFF even with your range-limited counter; because it just represents -1 using the full width of the hardware adder.

    This will only be used when the count value is nonzero. When the counter value is zero, the line above it at HIL5 will set the count to it's maximum and you'll still get your range-limited counter from 0x0000000 to 0x5A0."

    But are your saying that those two lines make the subtraction??
  • Yes. 0x1FF FFFF is the 25 bit integer representation of -1. (twos complement).
    The adder for "A" is 25-bits so you would use this value when you want to subtract one.

    You will never roll over from 0x000 0000 -1 -> 0x1FF FFFF this way, because 0 is a special case
    and it executes the HIL instruction that sets the counter to it's maximum value of 0x5A0 instead of
    adding 0x1FF FFFF.

    Trying to use the value 0x59F is problematic for a couple reasons so I would avoid it.

    BTW the N2HET you are using has an instruction for subtraction now, so you could use that instruction to make the code more clear.

    -Anthony
  • okok so I just keep the 0x1FFFFFF.

    so.. If HIL takes it to the max value, in this case 1440, but only enters when turning backwards, should not be better to write there 1439?

    And when the value goes to the max value, it goes back to zero instead of subtracting one... why??what am I missing?

    I saw the function... but it needs two sources and a dest. so Im not sure how to use it... because I would need to subtrat 1 from the FOR label every pulse. and I think that would be the SSUB line. no??

    Actually now there is a PULSE COUNT, which could replace the FOR CNT but.... lets keep it that way for now haha

    sorry for asking this much about this part...

    thanks Anthony
  • Miguel,

    Yes you need to make sure the range of the CNT instruction (which is the forward counter) and the max value that is written in HIL5, are the same.  

    The max value for CNT is reached,  because it is checked against 'max' before setting its value to 0 or before incrementing.   So when it reaches max-1 it will increment to 'max'.   Then on the next execution time it will check GE or == max and roll over from max->0.    The psuedo-code for the CNT instruction spells this out clearly:

    else if(Time mode (bit P8 == 0))
    {
    If [(P5==0) AND (Immediate Data Field == Max count)]
    OR [(P5==1) AND (Immediate Data Field >= Max count)]
    {
    Z = 1;
    Selected register = 00000;
    Immediate Data Field = 00000;
    If (Interrupt Enable == 1) HETFLG[n] = 1; /* n depends on address */
    If ([C28:C27] == 01) Generate request on request line [P25:P23];
    If ([C28:C27] == 11) Generate quiet request on request line [P25:P23];
    }
    else
    {
    Selected register = Immediate Data Field + 1;
    Immediate Data Field = Immediate Data Field + 1;
    }
    }
    
    So the range of CNT is  [0 ... max].   Therefore when decrementing from 0, you want to set the value to max not max-1.
    
    -Anthony

  • which is what the code is doing no?
    I still dont understand why is not counting backwards...
  • Miguel,

    I think it's not counting backwards because you were adding 0x59F, instead of 0x1FF FFFF.

    But try it out in the HET IDE to confirm.

    -Anthony
  • this is what I got using the app note code:

    first iteration

    second iteration:

    third iteration:

    And the index pin is not receiving data to avoid clearing the data 

    Is not counting backwards... I mean... using the signals as would be on a quadrature encoder going backwards

  • Hi Anthony
    Hope you're doing great
    I was wondering if you have any idea of what could I be doing wrong and not having the counter to backwards?? could it be something on my signals??
    or could it be a problem with the code?
  • I'm not sure about that one Miguel - I was going to find the author and ask if he's got a simulation showing it counting forward and back.
    I've definitely tested and show results of the similar task in the HAHSCPTO code, but this code is slightly different. It looks fine but it is easy enough to have a minor error cause a problem and the simulation is often the best way to spot the problem.

    I'm not really sure what to make of your postings above - I'd want to see more of a waveform view showing the counter and the PC and the A,B inputs. You know you can add memory contents to the waveform window of a HET IDE simulation, right? So you can display the counter alongs side the A,B inputs and view a trace of them evolving over time... That's what I would do next.
  • Actually I was simulatin the TI app note code to see that. The differences are the conditions. they do the same thing.
    Which code are you talikg about?? O:
    I didnt know I could do that... how do I do that?? what is it for??

    thnks!!
  • Hi Miguel,

    Whichever code isn't working for you backwards. I'm not sure if you're running the appnote code as-is or if you're running your modified version with the modulo..

    To add stuff to the trace, the HET IDE tutorial doc will take you through the steps.

    -Anthony
  • Im running the code just as it is.
    ok. I will check it =)
    thanks!
  • Hi Anthony

    I will test the code on the next days. Maybe the error is a problem with the signals I used, because nobody has complain about the code not working. But on the meantime I need to prepare the code. You told me that on the .h file was the info from the variables right??

    so.... if I want to get the data from FOR1, I should use 

    HET_FOR1_0 ??

    or pHET_FOR1_0 ??

    those are on the .h of my het codes. 

    or am I saying something that isn't right??

    thanks!!!

  • Miguel,

    You're saying it correctly. You can look at the driver code in the HAHSCPTO example to show you how to access the memory of the HET.
    The HSC driver should have a function to read the count.
  • I havent found that.... I have been looking but no...