Microchip® Advanced Software Framework

Quick Start Guide for EVENTS - Interrupt Hooks

In this use case, the EVENT module is configured for:

  • Synchronous event path with rising edge detection
  • TC4 as event generator on the allocated event channel (TC0 is used for SAM L22)
  • One event channel user attached
  • An event interrupt hook is used to execute some code when an event is detected

In this use case TC is used as event generator, generating events on overflow. One user attached, counting events on the channel. To be able to execute some code when an event is detected, an interrupt hook is used. The interrupt hook will also count the number of events detected and toggle a LED on the board each time an event is detected.

Note
Because this example is showing how to set up an interrupt hook there is no user attached to the user.

Setup

Prerequisites

There are no special setup requirements for this use case.

Code

Add to the main application source file, before any functions, according to the kit used:

Workflow

  1. Create an event channel configuration structure instance which will contain the configuration for the event.
    struct events_config config;
  2. Initialize the event channel configuration struct with safe default values.
    Note
    This shall always be performed before using the configuration struct to ensure that all members are initialized to known default values.
  3. Adjust the configuration structure:
    • Use EXAMPLE_EVENT_GENRATOR as event generator
    • Detect events on rising edge
    • Use the synchronous event path
    • Use GCLK Generator 0 as event channel clock source
    config.generator = CONF_EVENT_GENERATOR;
    config.edge_detect = EVENTS_EDGE_DETECT_RISING;
    config.path = EVENTS_PATH_SYNCHRONOUS;
    config.clock_source = GCLK_GENERATOR_0;
  4. Allocate and configure the channel using the configuration structure.

    events_allocate(resource, &config);
  5. Make sure there is no user attached. To attach a user, change the value of EXAMPLE_EVENT_USER to the correct peripheral ID.
    events_attach_user(resource, CONF_EVENT_USER);
  6. Create config_tc and config_events configuration structure instances.
    struct tc_config config_tc;
    struct tc_events config_events;
  7. Initialize the TC module configuration structure with safe default values.
    Note
    This function shall always be called on new configuration structure instances to make sure that all structure members are initialized.
  8. Adjust the config_tc structure:
    • Set counter size to 8-bit
    • Set wave generation mode to normal frequency generation
    • Use GCLK generator 1 to as TC module clock source
    • Prescale the input clock with 64
    config_tc.counter_size = TC_COUNTER_SIZE_8BIT;
    config_tc.wave_generation = TC_WAVE_GENERATION_NORMAL_FREQ;
    config_tc.clock_source = GCLK_GENERATOR_1;
    config_tc.clock_prescaler = TC_CLOCK_PRESCALER_DIV64;
  9. Initialize, configure, and assosiate the tc_instance handle with the TC hardware pointed to by TC_MODULE.
    tc_init(tc_instance, CONF_TC_MODULE, &config_tc);
  10. Adjust the config_events structure to enable event generation on overflow in the timer and then enable the event configuration.
    config_events.generate_event_on_overflow = true;
    tc_enable_events(tc_instance, &config_events);
  11. Enable the timer/counter module.
    tc_enable(tc_instance);
  12. Create a new interrupt hook and use the function event_counter as hook code.
    events_create_hook(hook, event_counter);
  13. Add the newly created hook to the interrupt hook queue and enable the event detected interrupt.
  14. Example interrupt hook code. If the hook was triggered by an event detected interrupt on the event channel this code will toggle the LED on the Xplained PRO board and increase the value of the event_count variable. The interrupt is then acknowledged.
void event_counter(struct events_resource *resource)
{
event_count++;
}
}

Use Case

Code

Copy-paste the following code to your user application:

while (events_is_busy(&example_event)) {
/* Wait for channel */
};
tc_start_counter(&tc_instance);
while (true) {
/* Nothing to do */
}

Workflow

  1. Wait for the event channel to become ready.
    while (events_is_busy(&example_event)) {
    /* Wait for channel */
    };
  2. Start the timer/counter.
    tc_start_counter(&tc_instance);