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.

NHET examples

Hi,

I need some simple "standard" function for the NHET on RM48HDK:

- demultiplication of an external frequency (in:ext freq -> out: demultiplied freq DMA events)

- measure of an external frequency

there'are somewhere some example of such standard function?

Thank you

  • Matteo,

    matteo lucarelli said:
    - demultiplication of an external frequency (in:ext freq -> out: demultiplied freq DMA events)

    I'm not sure what demultiplication is - whether it's dividing down the external input or multiplying it up.
    To some extent we can do either (the multiplication would assume a reasonably constant frequency, since the period measurement of the prior period is used as a predictor of the current input period and used to subdivide the input by "N".  something like a 'PLL' action but not really a loop... For this purpose I'd look at the RCNT instruction.

    If demultiplication is more just every 'nth' input edge create some output edge and maybe a DMA request then a combination of a BR (with pin condition of rise or fall) and if the edge is detected, follow this by a DJZ.  When you reach zero,  reset the count of the DJZ with a MOV32 and also generate your DMA request.

    matteo lucarelli said:
    - measure of an external frequency

    The PCNT instruction with a type 'RISETORISE' or 'FALLTOFALL' will give you a period measurement on a particular pin.

    There are some examples that come with the HET IDE under 'Algorithm Library' on the Tools menu.  I'd definitely sketch out what you want in the HET IDE first.

  • Antony,

    yes, what I need for demultiplication is simply "every 'nth' input edge create a DMA request".

    I'm waiting for your sketches.

    Thank you

  • Matteo,

    This is a rough sketch of one way to tackle the problem.  It's set for every edge but you could change to just rise or fall.  You could also replace the BR with a PCNT if you wanted to measure time and count edges simultaneously.

    There's also a WCAPE instruction that you could look at that takes timestamps (absolute) of a counter and also counts edges at the same time.

    So don't think of this as the only option... but a starting point to experiment. 

    Disclaimer - I put this together in about 10 min and simulated quickly so there might be issues for you to resolve.   So again consider it a starting point...

    http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/312/7711.tt2.7z

  • Hi Antony,

    thank you for the sketch. Can you please have a look to my comments to dispel some doubts?

    =================================================================
    input_pin    .equ    0

    input_count    .equ    10

    ; don't I have to set pin=input_pin here?
    START   BR { next=DONE,cond_addr=EDGE_DET,event=BOTH };

    ; ok, this decrement input_count and execute the next instruction
    ; only on count==0. So what the reg=A is meant for?
    EDGE_DET   DJZ { next=DONE,cond_addr=RESET,reg=A,data=input_count};


    ; this one i don't understand: do the instruction simply reset reg A to input_count?
    ; so why
    remote=EDGE_DET and reg=NONE
    RESET   MOV32 { remote=EDGE_DET,type=IMTOREG&REM,reg=NONE,data=input_count,hr_data=0};


    ; to generate a DMA request shouldn't be reqnum=4?
    SIGNAL   BR { next=DONE,reqnum=0,request=GENREQ,cond_addr=DONE,event=NOCOND,irq=ON};

    ; ok: that's a restart
    DONE   BR { next=START,cond_addr=START,event=NOCOND};

    =================================================================

    Another question: how can I  change the input_count value from inside the C program?

    thank you,

    Matteo

  • Matteo

    matteo lucarelli said:

    ; don't I have to set pin=input_pin here?
    START   BR { next=DONE,cond_addr=EDGE_DET,event=BOTH };

    Yes.  In this case I missed it but it worked anyway because pin={pin Number} is an optional component of the "BR" instruction and if not specified it defaults to pin 0.  but obviously that was dumb luck and you are right.

    matteo lucarelli said:
    ; ok, this decrement input_count and execute the next instruction
    ; only on count==0. So what the reg=A is meant for?
    EDGE_DET   DJZ { next=DONE,cond_addr=RESET,reg=A,data=input_count};

    Nothing.  Feel free to change it to reg=NONE if you wish.

    matteo lucarelli said:
    ; this one i don't understand: do the instruction simply reset reg A to input_count?
    ; so why
    remote=EDGE_DET and reg=NONE
    RESET   MOV32 { remote=EDGE_DET,type=IMTOREG&REM,reg=NONE,data=input_count,hr_data=0};

    Its in the 'fine print' of the instruction behavior in the TRM...  DJZ operates on the *immediate data field*;  not  the register.  So the input to DJZ has to be written to the data field of the instruction.    The register that is specified in DJZ is optional, and the DJZ can write the same value to the register as it does to it's immediate data field.  But this isn't used for the DJZ itself, it's useful to save a step in case you need to use the same count value in subsequent instructions.  By writing to the register in the DJZ it saves the step later of reading the value from the remote address of the DJZ and storing in a register.     This is a simple example of that concept we've been discussing of how HET instructions do many operations simultaneously and part of what you do is squeeze as much as you can into a single instruction;  because instruction memory and cycles available are both expensive.

    matteo lucarelli said:
    ; to generate a DMA request shouldn't be reqnum=4?
    SIGNAL   BR { next=DONE,reqnum=0,request=GENREQ,cond_addr=DONE,event=NOCOND,irq=ON};

    Yes - if you are using the central DMA rather than the HTU.    I honestly didn't pay much attention to this as it's not something you simulate in the HET IDE but good catch.

    You are becoming a HET GURU.


    matteo lucarelli said:

    Another question: how can I  change the input_count value from inside the C program?

    Take a look at the .h and .c files that are output from the HET assembler.  There will be a data structure there that you can use to reference the fields of each individual instruction, and you can use this structure in a C program to say write to the data field of the RESET instruction.   By doing that instead of writing directly to the DJZ, your update can be buffered or synchronized to the *next* count period without affecting the current count period.

  • Fast and precise. Many thanks (also for calling me "guru" ;-)