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.

TMS570LS3137: Distinguishing between rising and falling in edge detection

Expert 1995 points

Part Number: TMS570LS3137
Other Parts Discussed in Thread: HALCOGEN

Hello,

In case both edges are set by Halcogen to be detected at the HET port, would it be possible once the edge occurs to distinguish if it was a rising or a falling and then programming the respective operations to do in the edgeNotification function?

Thanks.

Regards.

  • Hello, 

    If the event that triggers the counter is BOTH edges, it is impossible to distinguish the edge (rising or falling).

  • Not impossible, there is a way to achieve this.

    Enable HR share and use two separate instructions for the even and odd channels to generate interrupt on separate edges. That way you can get separate interrupts for rising and falling edges.

  • yes, this is a smart way.

  • Hello,

    Thanks for the answer.

    @Sunil: Could you please add some additional detail on how to achieve that? Is it feasible with Halcogen?

  • Yes, HALCoGen seems to enable HR share by default for the input capture functions. This is done via the "Pin 0-7" and other "Pin *" tabs from within the HET1 group. Let's take channels 0 and 1 as example. Assume you have the signal input to N2HET1[0] (channel 0). Since HR share is enabled for channels 0 and 1, the high-resolution structures for channels 0 and 1 can be used to measure the signal on channel 0.

    You can now configure the edge to be detected on the "Edge 0-7" tab. Choose to detect rising edge on channel 0 and falling edge on channel 1.

    Finally configure interrupts to be generated using the "Edge Interrupts".

    Regards, Sunil

  • Thanks for the hint. I will implement it and come back to you.

    Two questions:

    1) in this way I can save physical pins but I need to "program" 2 edges per pin and then only 4 pins can work with this (hr share) logic. My application requires 3 x falling/rising (6 edges) + 3 rising; then 9 edges in total. I think that if I want to keep the features of the HET I have necessarily to use the second HET. Correct?

    2) the function edgeNotification runs when a "programmed" edge is detected; nevertheless, when this function runs I need to implement an IF-ELSE statement inside it in order to distinguish if it was a rising edge or a falling edge (e.g. edge0 or edge1) before executing the assigned routine. I guess this distinction can take 1 additional clock cycle. Is there a way to make it more efficient by writing directly the code into an "edge0Notification" or "edge1Notification" ?

    Regards.

  • 1) in this way I can save physical pins but I need to "program" 2 edges per pin and then only 4 pins can work with this (hr share) logic. My application requires 3 x falling/rising (6 edges) + 3 rising; then 9 edges in total. I think that if I want to keep the features of the HET I have necessarily to use the second HET. Correct?

    >> The HR share logic works with all pairs of even/odd numbered channels. HET1 supports up to 32 channels, so you can have HR share enabled for up to 16 pairs. The input signal must only be driven on the even-numbered channel. The odd-numbered channel is available for general-purpose I/O still.

    2) the function edgeNotification runs when a "programmed" edge is detected; nevertheless, when this function runs I need to implement an IF-ELSE statement inside it in order to distinguish if it was a rising edge or a falling edge (e.g. edge0 or edge1) before executing the assigned routine. I guess this distinction can take 1 additional clock cycle. Is there a way to make it more efficient by writing directly the code into an "edge0Notification" or "edge1Notification"?

    >> There is a way to optimize this. HET generates two interrupt requests to the VIM, connected to two separate channels in VIM. HET1 level 0 interrupt is mapped to VIM channel 10, and HET1 level 1 interrupt is mapped to VIM channel 24. If you implement the scheme I suggested using HR share, rising / falling edge interrupts will be generated off separate instructions in the HET program. You can use the HETPRY (HET interrupt priority) register to configure all rising-edge interrupts to be mapped to level 1 and all falling-edge interrupts to be mapped to level 0.

  • Sunil Oak said:

    >> The HR share logic works with all pairs of even/odd numbered channels. HET1 supports up to 32 channels, so you can have HR share enabled for up to 16 pairs. The input signal must only be driven on the even-numbered channel. The odd-numbered channel is available for general-purpose I/O still.

    Ok, but from what I see from Halcogen at the HET1 tab (and the same inside the respective het.c file, there are only 8 edge objects (from edge0 to edge7) to set as rising or falling.

    Sunil Oak said:

    >> There is a way to optimize this. HET generates two interrupt requests to the VIM, connected to two separate channels in VIM. HET1 level 0 interrupt is mapped to VIM channel 10, and HET1 level 1 interrupt is mapped to VIM channel 24. If you implement the scheme I suggested using HR share, rising / falling edge interrupts will be generated off separate instructions in the HET program. You can use the HETPRY (HET interrupt priority) register to configure all rising-edge interrupts to be mapped to level 1 and all falling-edge interrupts to be mapped to level 0.

    Sorry, I do not follow the last part: actually I have the interrupt map HET-VIM you mentioned; but I cannot understand how can I use HETPRY to create interrupt routine linked only to one edge.

  • The limitation about only 8 edge-detect interrupts is an artificial one imposed by HALCoGen. You can choose to use all available channels for edge detection if required by the application. HALCoGen uses a template HET program to allow users to get started quickly with the HET. It serves this purpose for basic timing functions such as generating some PWMs and measuring some inputs. Any functionality beyond these basics requires you to create your own HET program. The HET IDE is very useful in this regard. We also have several HET code examples that can be used as references. See this application note for more information: 

    For the interrupt configuration:

    An HET program can be configured with up to 32 interrupt conditions. These interrupt conditions are mapped to the instruction number in the HET program. See section 20.2.7 in spnu499c.

    Each bit in HETPRY refers to one set of interrupt conditions in the above table. Bit 0 configures interrupts generated from instructions at address offsets 0, 32, 64, .... Bit 1 configures interrupts generated from instructions at address offsets 1, 33, 65, ... and so on.

    Let's say your edge detection instruction for the rising edge is instruction number 4 (counting from 0) in your program and the one for falling edge detection is number 5.

    You can configure the interrupt from the rising-edge-detect instruction to the level 1 interrupt by setting bit 4 of HETPRY. Clear bit 5 of HETPRY so that the falling-edge-detect instruction generates level 0 interrupt.

    Hope this helps.

  • Sunil Oak said:

    Each bit in HETPRY refers to one set of interrupt conditions in the above table. Bit 0 configures interrupts generated from instructions at address offsets 0, 32, 64, .... Bit 1 configures interrupts generated from instructions at address offsets 1, 33, 65, ... and so on.

    Let's say your edge detection instruction for the rising edge is instruction number 4 (counting from 0) in your program and the one for falling edge detection is number 5.

    You can configure the interrupt from the rising-edge-detect instruction to the level 1 interrupt by setting bit 4 of HETPRY. Clear bit 5 of HETPRY so that the falling-edge-detect instruction generates level 0 interrupt.

    I am getting that I can modify the bits in HETPRY to make the application reacts on a particular input edge (rising or falling), but it is not yet clear from my side where to write the corresponding code for edge 4 and edge 5. Please, consider that I have to do different operations depending where (which pin) the rising or falling edge occurs (the reason of the 1st question about extending the number of edges).

    For example I am used to write inside the function edgeNotification() and I would like to build up a similar interrupt service routine with your method.

  • Once you have separate interrupts for rising and falling edges, you still need a decode for which pin generated that interrupt. Each HET program instruction can only generate an interrupt for either a rising or falling edge on a single input channel. So it is possible to have non-overlapping interrupt offsets corresponding to each rising/falling edge.

    The interrupt management functions generated by HALCoGen are "template" functions, which may not work for your specific use case. For example, HALCoGen generates a single edgeNotification() function that is called for any edge-detection interrupt condition. You need to modify the main HET1 interrupt handler functions: het1HighLevelInterrupt (for rising edges) and het1LowLevelInterrupt (for falling edges), and write them to call the correct "edge detection" routines based on the channel number.

  • Aren't the LL interrupts having the priority 24 in the VIM?

    However, if I give a look to het1HighLevelInterrupt()

    #pragma CODE_STATE(het1HighLevelInterrupt, 32)
    #pragma INTERRUPT(het1HighLevelInterrupt, IRQ)
    
    void het1HighLevelInterrupt(void)
    {
        uint32 vec = hetREG1->OFF1;
    
        if (vec < 18U)
        {
            if ((vec & 1U) != 0U)
            {
                pwmNotification(hetREG1,(vec >> 1U) - 1U, pwmEND_OF_PERIOD);
            }
            else
            {
                pwmNotification(hetREG1,(vec >> 1U) - 1U, pwmEND_OF_DUTY);
            }
        }
        else
        {
            edgeNotification(hetREG1,vec - 18U);
        }
    }

    Based on it, I can create a function het1HighLevelInterruptEdge0 as follows:

    #pragma CODE_STATE(het1HighLevelInterruptEdge0, 32)
    #pragma INTERRUPT(het1HighLevelInterruptEdge0, IRQ)
    
    void het1HighLevelInterruptEdge0(void)
    {
        uint32 vec = hetREG1->OFF1;
    
        Edge0_Notification(hetREG1,0);
       
    }
    
    

    ...and then I will create Edge0_Notification which should run with no other edge(1-7) but only at edge0.

    void Edge0_Notification(hetBASE_t * hetREG,uint32 edge)
    {
    
    
    /*Operations Assigned only to Edge0*/
    
    
    }
    

    Could you please review my approach above and tell me in case where I am getting wrong? Thanks!

  • Hi,

    I suppose your interrupt structure would look something like the below:

    #pragma CODE_STATE(het1HighLevelInterruptEdge0, 32)
    #pragma INTERRUPT(het1HighLevelInterruptEdge0, IRQ)
    
    void het1HighLevelInterruptEdge0(void)
    {
        uint32 vec = hetREG1->OFF1;
    
        Edge1_Notification(hetREG1,vec);
       
    }

    The above assumes that het1HighLevelInterrupt is only generated whenever a rising edge is detected. The Edge1_Notification gets the index value of the instruction that caused the interrupt. The application code knows which input pin corresponds to which instruction number in the HET program.

    This way you can write a case statement within the Edge1_Notification to perform the required interrupt handling for all instructions that generate an interrupt on detecting a rising edge.

  • Thank you very much, Sunil. Now I think that I have got it.

    Two last question to understand the other possible options in edge detection:

    - instead of using the HR share, is it recommendable creating two edges (e.g. edge0 and edge1) in Halcogen with the same HET's pin? I see that Halcogen allows selecting the same pin in the edge detection tab.  

    - if I used GIOs for edge detection, but I have the same source for rising and falling, I should connect the same source to two different GIOs, correct?

    Regards.

  • - instead of using the HR share, is it recommendable creating two edges (e.g. edge0 and edge1) in Halcogen with the same HET's pin? I see that Halcogen allows selecting the same pin in the edge detection tab.  

    >> Each HET channel has a single timing logic that can only be used for one timing function. Using multiple instructions to process the same input is not feasible. This is partly the reason for enabling the HR-share feature, so that the high-resolution timing logic for two channels can be shared to process a single input.

    - if I used GIOs for edge detection, but I have the same source for rising and falling, I should connect the same source to two different GIOs, correct?

    >> GIOs can generate an interrupt on both rising and falling edges on a pin. This configuration is not supported by HALCoGen though. You need to set the corresponding bit in the GIO_INTDET register to enable this feature. Once an interrupt is generated, the interrupt handler can query the pin status to identify the edge that triggered the interrupt. This requires the pin to not switch faster than the application can process each edge. You can also implement some debounce mechanism in software to account for glitches.

  • Sunil Oak said:
    You need to set the corresponding bit in the GIO_INTDET register to enable this feature. Once an interrupt is generated, the interrupt handler can query the pin status to identify the edge that triggered the interrupt. This requires the pin to not switch faster than the application can process each edge.

    Sorry to re-open this discussion, but before this post is archived I need one additional detail: what is the maximum frequency you meant for the switching rising/falling input pin to be detected and processed without problems? The TRM concerning the GIOs focuses only on the registers and the section dedicated to the GIOs in the datasheet exposes instead directly the features of HET(???) including timing.

    Thanks ahead for a reply.

    Regards.

  • There is a min constraint on the period and duty-cycle of the input signal. This is included in the datasheet for the HET: refer to section 7.4.3 on pages 128 to 130 in SPNU162c.

    As for a GIO input, this is more dependent on factors like CPU interrupt latency, etc. This is what I meant by "input must not switch faster than the time it takes for your application to process an edge".

  • Sunil Oak said:
    There is a min constraint on the period and duty-cycle of the input signal. This is included in the datasheet for the HET: refer to section 7.4.3 on pages 128 to 130 in SPNU162c.

    So, the GIOs have the same features of the HET in terms of time to detect the edge?

    I cannot find that document, can you please give me the link? Thanks a lot!

    Regards.

  • I am sorry I don't understand the question. The GIO module can detect either a rising edge or falling edge or both edges on any GIOA/B terminal and generate an interrupt to the CPU via the interrupt manager (VIM).

    The timing constraint for how soon the next edge can be detected depends on several factors:

    • number of interrupts in the system
    • interrupt prioritization
    • interrupt latency
    • user code for the ISR
    • ...
  • Maybe the question was not well formulated, sorry for that: while for example the HET has a dedicated section in the TRM explaining the time constrains in edge detection (section 20.2.5.8 Edge Detection Input Timing), I cannot find the same level of details in the TRM or in the datasheet for the GIOs.

  • In that case, I answered the right question. As I stated in my previous post, the minimum time between successive edges on a GIOx pin tat can be processed correctly depends on several factors that are variable. This is the reason that this parameter is not specified in the datasheet.