Lesson 002: Blinky with Timers

Today I’ll be updating the project from Lesson 001 and replace the for loop with a timer with a 1Hz flash rate.

We will start with a new project. After creating the project, we will need to configure the timer component.

In the Synergy Configuration tab, select Components.

There are two timers that are available for use, the Asynchronous General Purpose Timer (r_agt) and General Purpose Timer (r_gpt). I haven’t dug in too deeply, but I do know the r_agt timer is a 16 bit timer while the r_gpt is 32-bit. Based on this difference, I’ll be using the r_gpt.

Check the r_gpt box.

TRAP FOR NEW PLAYERS

Just adding a component does not configure the component and won’t allow you to use it in code. You also have to add an instance of the component to the Threads tab

END TRAP

Click on the Threads tab, select the HAL/Common thread (should be the only one listed). On the HAL/Common Modules, click on New > Driver > Timers > Timer Driver on r_gpt.

Day3-AddDriver

On the properties tab, there are a bunch of options to choose from. From the Name property, we can see where the g_ioport variable name comes from. Our new timer instance is called g_timer. If you don’t like the variable name, you can change it here.

We want our timer to be Periodic (instead of a one-shot or PWM). We also want the timeout to be at least one second (since we are going to be flashing at 1Hz). Now, 1Hz is 1000ms. Since we want to turn the LED on AND off at a rate of 1Hz, the one time will be 500ms and the off time will be 500ms.

Remember where I said I wanted a 32-bit timer instead of a 16-bit? Here’s why:

Timer timer counter uses the Peripheral Clock D as it’s source. When creating the project, the D clock is configured as a 1:2 clock. Since the core frequency is 240MHz, the clock tick frequency is 120MHz.

1/120MHz = 8.333ns / tick.

At a 8.333ns tick rate, and having 32-bits, the longest our clock can run without overflow is 35.79139413 seconds (2^32-1)*8.333ns.

If we used a 16-bit timer, the longest would be (2^16-1)*8.333ns which is only 546.125us.

We could use this 16-bit timer, but we’d have check it very often and store the overflows in a separate variable, then sum the variables, etc, etc. Basically, we’d take the 16-bit timer, keep track of a specific timespan (IE: 500us), wait until we’d hit the number number of timespans (IE: 4 timespans = 4*500us = 2ms).

Much easier to just use the 32-bit timer!

Since we are interested in a maximum of 500ms on our timer, we do need a bit of overhead (since we aren’t using interrupts yet). Let’s set our period to 1000ms. This gives us an additional 500ms of extra time to ‘service’ the timer without overflowing.

Make sure the Period Unit is Milliseconds and the Period Value is 1000.

Click on Generate Project in the upper right of the Synergy Configuration tab.

Opening up our hal_entry.c file, we can start coding!

/* HAL-only entry function */
#include "hal_data.h"

// Define the number of counts per millisecond (1 count per clock tick, clock rate is 120MHz)
// So there are 120E6 ticks per second.
// Divide by 1000 to get ticks / millisecond
#define COUNTS_PER_MILLISECOND  (120E6 / 1000)

void hal_entry(void)
{
    // Boolean to hold LED state
    bool isOn = true;

    // Variable to hold counts
    timer_size_t counts = 0;

    // Open the timer using the configured options from the configurator
    g_timer.p_api->open (g_timer.p_ctrl, g_timer.p_cfg);

    // Main Loop
    while(1)
    {
        // Turn LED
        g_ioport.p_api->pinWrite(IOPORT_PORT_08_PIN_07, isOn);

        // Toggle LED State
        isOn = !isOn;

        // Wait for timer loop
        while (1)
        {
            // Get current counts
            g_timer.p_api->counterGet(g_timer.p_ctrl, &counts);

            // Check if 500ms has elapsed => This should be a helper function at some point
            // Need to look if the PBCLK settings are stored in a define somewhere...
            if (counts > (500*COUNTS_PER_MILLISECOND))
            {
                // Reset the timer to 0
                g_timer.p_api->reset(g_timer.p_ctrl);
                break;
            }
        }
    }
}

This concludes our Day Three tutorial!

Advertisements

6 thoughts on “Lesson 002: Blinky with Timers

  1. // New BSP , the syntax is different

    /* HAL-only entry function */
    #include “hal_data.h”

    // Define the number of counts per millisecond (1 count per clock tick, clock rate is 120MHz)
    // So there are 120E6 ticks per second.
    // Divide by 1000 to get ticks / millisecond
    #define COUNTS_PER_MILLISECOND (120E6 / 1000)

    void hal_entry(void)
    {
    // Boolean to hold LED state
    bool isOn = true;

    // Variable to hold counts
    timer_size_t counts = 0;

    // Open the timer using the configured options from the configurator
    g_timer0.p_api->open (g_timer0.p_ctrl, g_timer0.p_cfg);

    // Main Loop
    while(1)
    {
    // Turn LED
    // IOPORT_PORT_06_PIN_00 depend on different board
    g_ioport.p_api->pinWrite(IOPORT_PORT_06_PIN_00, isOn);

    // Toggle LED State
    isOn = !isOn;

    // Wait for timer loop
    while (1)
    {
    // Get current counts
    g_timer0.p_api->counterGet(g_timer0.p_ctrl, &counts);

    // Check if 500ms has elapsed => This should be a helper function at some point
    // Need to look if the PBCLK settings are stored in a define somewhere…
    if (counts > (500*COUNTS_PER_MILLISECOND))
    {
    // Reset the timer to 0
    g_timer0.p_api->reset(g_timer0.p_ctrl);
    break;
    }
    }
    }
    }

    Like

  2. Hi erik ,

    Hello ,

    I am using external timer using SK_S7G2 starter kit .output At p400 but it always gives me half of desired frequency in this code it gives me 0.5 Hz reather than 1 Hz. I checked on multi meter and oscilloscope even at 10khz if i change settings it gives me 5khz or if i set 20khz gives me 10khz .Do you have any information what is the problem?? I cannot post screen shots of my snergy configration settings you can see them from here . Thanks

    http://renesasrulz.com/synergy/f/206/p/6745/21210.aspx#21210

    /* HAL-only entry function */

    #define COUNTS_PER_MILLISECOND (120E6/1000 )
    #include “hal_data.h”
    void hal_entry(void)
    {
    g_timer0.p_api->open(g_timer0.p_ctrl,g_timer0.p_cfg);
    g_timer0.p_api->start( g_timer0.p_ctrl);

    timer_size_t counts = 0;
    while (1)
    {
    // Get current counts
    g_timer0.p_api->counterGet(g_timer0.p_ctrl, &counts);

    // Check if 500ms has elapsed => This should be a helper function at some point
    // Need to look if the PBCLK settings are stored in a define somewhere…
    if (counts > 500*COUNTS_PER_MILLISECOND)
    {

    // Reset the timer to 0
    g_timer0.p_api->reset(g_timer0.p_ctrl);
    break;
    }
    }

    }

    Like

  3. Khawar,

    I would look at the Clocks tab on your Synergy Configuration and look at ICLK Div/1. All your clocks are derived from this clock. The timer module is 1/2 your primary clock. On the S7G2, the primary clock is 240MHz. Divide that by two and you get the 120MHz (120E6). My guess is that your primary clock is running at 120MHz, so your timer clock is running at 60MHz. If that’s the case, replace the define #define COUNTS_PER_MILLISECOND (120E6/1000 ) with #define COUNTS_PER_MILLISECOND (60E6/1000) and your timers should run at the right frequency.

    Please let me know if this is the case. If it’s not, I can try to dig further (you can also zip up your current project and throw it up on Dropbox or Google Drive and I can download it. PM me with a link.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s