S7G2-DK - Frequency, Event Counter

Hi,

I have an application which needs to determine the frequency of a signal using a S7G2-DK and SSP1.1.3. This can be done with an interrupt keeping track of pulses for a given period of time. It looks like the AGT module has a mode where it can count external events. I added g_timer Timer Driver on r_agt to the HAL/Common thread. When configuring the timer Mode, there are only options for one-shot and periodic. Then I checked the Pins/Peripherals and in Operation Mode there is an Event Counter.

My questions: Would using the AGT be a way to determine the frequency of a signal? Any advice on setting it up?

  • The frequency is 0 - 10kHz

    Thank you,
    Draper
  • In reply to dpalu:

    Hi,

    Consider using a GPT timer. These are 32-bit timers so will give you greater frequency range and resolution.

    By using the input capture feature the GPT hardware will automatically measure your input waveform.

    The frequency is the GPT timer frequency (PCLKA) divided by the Input Capture timer value.

     

    By default the Input Capture module only does pulse width measurement, whereas you require pulse period measurement.

    However, it is possible to reconfigure the GPT Input Capture module.  

    Please see my attached project that uses "direct register" access to reconfigure the GPT registers.

    I wrote this for a SK-S7G2, and use GPT7 as GTIOCA on Port 3.4 was easily accessible.

    You can port this to whichever GPT channel you wish by changing the code to the appropriate registers etc.

    Hope this helps.

     

    SK_S7_FREQ_COUNT_SSP113.zip

  • In reply to Richard:

    Thank you, this will work for my application.
  • Hi sir, can anyone help me about gpt timer and agt timer ? which is the better one to use it? for timers
  • In reply to Richard:

    Richard, you seem to be the one answering all timer-related questions, so I'd like to ask you one too.

    I am trying to count events that don't come in on any regular basis (specifically, photons hitting a detector). Hooking up a simple interrupt (where I just increment a counter every time I get a pulse) tops out at about 300 khz (and even then it tends to miss a few). I need to get to 10 Mhz. I was thinking I could use the AGT to sort of store up a bunch of events and then alert me every so often as to how many it's collected. But I am starting to think this not how that hardware works. Could you see a way for it to do that? Or any other suggestion to go about this using the S7's hardware? (I have the starter kit board.)

    Our current solution uses off-board electronics to count up pulses and only send a signal after 256 photons, but I was hoping the S7 could replicate this by itself. Maybe I'm expecting too much :)
  • In reply to MCP:

    S7G2_SK_PhotonCount.zip

     

    Hello MCP

    Please find attached a E2Studio (6.2.1) SSP1.5.3 project for the S7G2_SK. 

    It configures GPT0 for event counter mode, meaning that an edge on the GTIOCA pin will increment the GPT Counter.  It is configured to count rising edges, but it can be configured to count falling edges, or both.

    I have configured GPT1 to generate a 1s interrupt.  This interrupt triggers the DTC (Data transfer Controller) to read and store the value of the GPT0 Counter in an array. GPT1 will also generate another interrupt ( at 1s + 500ms ) that does a simple subtraction of the 2 count readings so that you get a counts per second value.  This is stored in the variable g_1s_photon_count.

    GPT0 will also generate an interrupt when 256 edges have been detected.  This value of 256 is set by a #define in the code so can be easily modified if required.   This interrupt sets a software flag which is detected by the main processing loop and the state of LED1 on the S7G2_SK is toggled.

     

    For testing, I have configured GPT11 to generate a 300kHz output.  You can connect P5.0 (GPT11 output) to P5.12 (GPT0 input). The push buttons S4 and S5 will increase / decrease the GPT11 period / frequency. 

    You can set a real time watch on the variable g_1s_photon_count and see that this does vary with the frequency of GPT11.

    Hope this helps and points you in the correct direction for your application

    Regards,

    Richard

  • In reply to Richard:

    Thank you very much for the incredibly detailed answer. I attached my signal generator and after fighting with Eclipse for a while got everything running. I can see it capturing 10,000,000 hits per second which is great!

    I do have some questions, some technical and some philosophical.

    Why are you using a DTC to get the data counts? What I will be doing is starting a measurement period, waiting several hundred milliseconds, and then seeing how many hits I got. Can I enable the counter, wait, disable the counter, and then just look at gpt0_reg->GTCNT to get the value? (And then clear that register for the next run, thus obviating the need to worry about overflows).

    Why is there so much configuration in the source code? Is it not possible to create this configuration from the Configuration panel, or do you prefer using source code for a reason?

    Finally, I am not sure how to change which pin is associated with the input. I can't use P5.12 because that conflicts with the touch screen driver. I couldn't figure out in your code where this association is set. Could you point me in the right direction?

    Thanks again,
    MCP
  • In reply to MCP:

    OK, I went poking around the timers and realized gpt9 hooks to pin 411, which wasn't being used in my set-up (I just today figured out that the green checkmark next to the pin in the Configuration/PIn tab means that pin is being used). I adapted your code and figured out how to stop and clear the counter. Now I have a GUIX timer event collecting the counts and I am happy to say it's quite consistent.

    I'm still interested in why so much configuration happens at the source code level. In particular isn't GTUPSR the sort of thing that would be set by the Configurator?

    I am also guessing that you used DTC just because you thought it was a good idea to invisibly keep a counter up to date in the background. Which it is, but isn't really what I need it for (though the example might come in handy later).

    This is a good outcome as it will impress my management that the S7 can do stuff we used to have to make custom electronics for!

    Thanks again!
  • In reply to MCP:

    Good to hear that you've ported the code to your application. Unfortunately, as the system complexity increases there is always a finite amount of time required to map peripheral usage to available pins. Synergy tries to help, as you have seen with the pin configuration tab, but that is only helpful if you realize the significance of the green ticks and red crosses when you set the pins.
    The learning curve for using Synergy can be steep, but once over that curve and you have the basics then hopefully you can see the advantages that it offers.

    Regarding your questions:
    Why so much configuration code? Good point! The GPT is probably the most "powerful" / "least supported via the SSP" peripheral that exists on Synergy. The issue is that because it is so configurable, how does Renesas develop a SSP driver to cover all options? The driver would have to be huge. But also, and probably more important, all of the SSP drivers are extensively tested. Writing test code would be even more complex than developing the driver. Therefore, the GPT SSP driver offers the most basic functionality and it is left to the individual engineers such as yourself to create the functionality you require.
    Regarding why I used the DTC; I did this for 2 reasons. 1, it is a simple data transfer task from A to B. Why "burn" CPU cycles doing a simple data transfer when we other peripherals (DMAC & DTC) that can do this? It free's up the CPU for processing activity. 2, for accuracy of reading the data values. In the example I provided I wanted to measure the number of pulses in 1 second. If I was relying on the CPU to read the data values in an GPT ISR, then due to the time of interrupt latency, the fact that a higher priority ISR may be being processed etc, the timing could drift very slightly. Yes, we could be talking ns, but I do not know how accurate you need to be? By using the DTC, which is triggered by the GPT directly, a more deterministic response can be achieved. NOTE - this may not be the case if you have used the DTC for many other data transfer uses, as the DTC may have to complete an existing transfer before the GPT transfer is taken. In this case, then a dedicated DMAC channel (there are 8 on the S7G2) could be used.

    Finally, if you are able to send me an example of the ISRs crashing your system I would be interested in looking into it.
    Regards,
    Richard
  • In reply to Richard:

    Thank you for your explanations! They are very helpful.

    You've brought to light a particular philosophical problem, which is to say, why I hate wizards, configurators, and other automated tools. They never do _everything_. And then you're left trying to fill in the cracks - but you don't know what that looks like because most of the work was done behind the scenes. A really well-written example can explain all of the ins and outs in such a way that you can extrapolate to your own ends. But good documentation is actually harder to write than an automated interface, and for 90% of the time the automated one is "good enough," so we're all stuck with it. :(

    For my project, counting the photons over a several hundred millisecond period is the only really important task, so I think I can set the GUIX timer to priority 1 and that should be good enough. If no other ISRs are set to that priority, can you still see a need to use your method to avoid drift?

    This does lead to another question: how do the GUIX timers interact with the GPTs? Do I dedicate a GPT every time I declare a GUIX timer, or does GUIX leverage all of their timers off of just one GPT (and if so, which one)?

    I was unable to recreate my original ISR problem. I had simply added an ISR to the GUIApp project from an-r12an0021eu0117-synergy-sk-s7g2-pk-s5d9-guix-hello-world and the compiler generated conflicts. I briefly tried it again and did not get a compiler conflict, though I haven't run it (Eclipse makes switching between different verisions of a project incredibly tedious). However, in my current app (which is derived from the Hello World app but with the include files cleaned up), I notice that there is no hal_thread_create; when I move an ISR to the Hal/Common thread and try to enable the ISR in hal_entry, it never gets called and main.c does not call hal_thread_create. The only way I can get it to work is to create a new thread and put my ISRs in there; then the new_thread_create function gets created and called. Any ideas on why the HAL thread is different (and apparently immutable)?
  • In reply to Richard:

    So, good news: management has signed off on my recommendation and now we are developing on the Synergy platform. I have a PE-HMI kit to start laying out the user interface on.

    My new question is - how do I connect to a timer on the PE-HMI board? I think the answer is through one of the PMOD connectors but I'm still struggling to link the available outputs with their associated pins. Any hints?
  • In reply to MCP:

    OK, I found it - the HE-PMI User's Guide was the key. I tried configuring P400 as GPT6 but it told me I had a "dangling connection" as that pin was already used for SCI7. I disabled SCI7 but it didn't work the first time; after I re-enabled SCI7 and manually set the SCI7 SCK line to "not used" suddenly the conflict went away (almost as if merely disabling it hadn't cleared all of the pin assignments).
  • In reply to MCP:

    OK, I found it - the HE-PMI User's Guide was the key. I tried configuring P400 as GPT6 but it told me I had a "dangling connection" as that pin was already used for SCI7. I disabled SCI7 but it didn't work the first time; after I re-enabled SCI7 and manually set the SCI7 SCK line to "not used" suddenly the conflict went away (almost as if merely disabling it hadn't cleared all of the pin assignments).