Quadrature Decoder HAL Results

group group_hal_quaddec

High level interface for interacting with the Quadrature Decoder hardware resource.

The quadrature decoder block is commonly used to measure the time of occurrence of an event, to measure the time difference between two events or perform an action after a specified period of time.

The Quadrature Decoder block provides the ability to count transitions on a pair of digital signals. The signals are typically provided by a speed/position feedback system mounted on a motor or trackball. The driver allows the user to invoke a callback function when a particular event occurs. The signals, typically called A and B, are positioned 90° out-of-phase, which results in a Gray code output (a sequence where only one bit changes on each count). It also allows detection of direction and relative position. A third optional signal, named index, is used as a reference to establish an absolute position once per rotation.

The Quadrature Decoder operates in one of three resolution modes. (see cyhal_quaddec_resolution_t) The mode dictates the number of events that are counted.

../../../_images/quadrature_mode.png

An index event causes the counter to be set to the midpoint. For example, if the hardware has 16-bit resolution, the midpoint would be 0x8000. For 32-bit resolution: 0x80000000.

../../../_images/quadrature_index.png

For more details about this functionality, see the “Quadrature Decoder Mode” section of the Technical Reference Manual.

Some use case scenarios of the Quadrature Decoder:

  • Decode the output of a quadrature encoder (e.g., mouse, trackball, robotic axles, etc.).

  • Precision measurement of speed, acceleration, and position of a motor’s rotor and with rotary knobs to determine user input.

Features

Quick Start

cyhal_quaddec_init can be used for quadrature decoder initialization by providing the quaddec object - cyhal_quaddec_t, input pins, and shared clock source - clk (optional).

See Snippet 1: Initialization and direction detection.

Code Snippets

Snippet 1: Initialization and direction detection

The following snippet initializes a quadrature decoder and measures the counter to determine direction. The clk may be left NULL, in which case a clock resource is automatically assigned.

    cy_rslt_t       rslt;
    cyhal_quaddec_t quaddec_obj;
    uint32_t        count = 0x8000, prev_count = 0x8000;

    // Initialize the quadrature decoder object. Does not use index ('pin' is NC) and does not use a
    // pre-configured clock source ('clk' is NULL).
    rslt = cyhal_quaddec_init(&quaddec_obj, P0_0, P0_1, NC, CYHAL_QUADDEC_RESOLUTION_1X, NULL,
                              1000000);
    CY_ASSERT(CY_RSLT_SUCCESS == rslt);

    // Start the quadrature decoder
    rslt = cyhal_quaddec_start(&quaddec_obj);
    CY_ASSERT(CY_RSLT_SUCCESS == rslt);

    for (;;)
    {
        count = cyhal_quaddec_read_counter(&quaddec_obj);

        // Check for direction of change
        if (count > prev_count)
        {
            // Clockwise rotation
        }
        else if (count < prev_count)
        {
            // Counter Clockwise rotation
        }
        else
        {
            // No change
        }

        prev_count = count;
    }

Snippet 2: Handling an event in a callback function

The following snippet initializes a quadrature decoder and triggers an event as changes happen. The clk need not be provided (NULL), in which case a clock resource is assigned.

bool quaddec_interrupt_flag = false;

// quadrature decoder object used
cyhal_quaddec_t quaddec_obj;

static void quaddec_event_handler(void* callback_arg, cyhal_quaddec_event_t event)
{
    (void)callback_arg;

    if ((event & CYHAL_QUADDEC_IRQ_TERMINAL_COUNT) == CYHAL_QUADDEC_IRQ_TERMINAL_COUNT)
    {
        // A terminal count event was triggered, insert code to handle event
    }
    if ((event & CYHAL_QUADDEC_IRQ_CAPTURE) == CYHAL_QUADDEC_IRQ_CAPTURE)
    {
        // A capture event was triggered, insert code to handle event
    }

    // Set the interrupt flag and process it from the application
    quaddec_interrupt_flag = true;
}


void snippet_cyhal_quaddec_event_interrupt()
{
    cy_rslt_t rslt;

    // Initialize the quadrature decoder object. Does not use index ('pin' is NC) and does not use a
    // pre-configured clock source ('clk' is NULL).
    rslt = cyhal_quaddec_init(&quaddec_obj, P0_0, P0_1, NC, CYHAL_QUADDEC_RESOLUTION_4X, NULL,
                              1000000);
    CY_ASSERT(CY_RSLT_SUCCESS == rslt);

    // Assign the ISR to execute on timer interrupt
    cyhal_quaddec_register_callback(&quaddec_obj, quaddec_event_handler, NULL);

    // Set the event on which timer interrupt occurs and enable it
    cyhal_quaddec_enable_event(&quaddec_obj, CYHAL_QUADDEC_IRQ_TERMINAL_COUNT, 3, true);

    // Start the timer with the configured settings
    rslt = cyhal_quaddec_start(&quaddec_obj);
}

Typedefs

typedef void (*cyhal_quaddec_event_callback_t)(void *callback_arg, cyhal_quaddec_event_t event)

Handler for quadrature decoder events.

Enums

enum cyhal_quaddec_resolution_t

cyhal_quaddec_resolution_t: Operating resolutions for the quadrature decoder.

Values:

enumerator CYHAL_QUADDEC_RESOLUTION_1X

1x resolution

enumerator CYHAL_QUADDEC_RESOLUTION_2X

2x resolution

enumerator CYHAL_QUADDEC_RESOLUTION_4X

4x resolution

enum cyhal_quaddec_input_t

cyhal_quaddec_input_t: Quadrature decoder input signal.

Values:

enumerator CYHAL_QUADDEC_INPUT_PHI_A

The “A” input of the quadrature decoder.

enumerator CYHAL_QUADDEC_INPUT_PHI_B

The “B” input of the quadrature decoder.

enumerator CYHAL_QUADDEC_INPUT_STOP

Stops the counter from counting when activated.

enumerator CYHAL_QUADDEC_INPUT_INDEX

A reference signal that resets the counter when activated.

enum cyhal_quaddec_output_t

cyhal_quaddec_output_t: Quadrature decoder output signal.

Values:

enumerator CYHAL_QUADDEC_OUTPUT_COMPARE_MATCH

Compare Match signal.

enum cyhal_quaddec_event_t

cyhal_quaddec_event_t: Interrupt triggers for the quadrature decoder.

Values:

enumerator CYHAL_QUADDEC_IRQ_NONE

No interrupt handled.

enumerator CYHAL_QUADDEC_IRQ_TERMINAL_COUNT

Interrupt when terminal count is reached.

enumerator CYHAL_QUADDEC_IRQ_CAPTURE

Interrupt when capture value is reached.

enumerator CYHAL_QUADDEC_IRQ_ALL

Interrupt on any event.

Functions

cy_rslt_t cyhal_quaddec_init(cyhal_quaddec_t *obj, cyhal_gpio_t phi_a, cyhal_gpio_t phi_b, cyhal_gpio_t index, cyhal_quaddec_resolution_t resolution, const cyhal_clock_t *clk, uint32_t frequency)

Initialize the quadrature decoder peripheral and configure the pin.

See

Snippet 1: Initialization and direction detection.

Return

The status of the init request

Parameters
  • [out] obj: Pointer to a quadrature decoder object. The caller must allocate the memory for this object but the init function will initialize its contents.

  • [in] phi_a: - The “A” input of the quadrature decoder.

  • [in] phi_b: - The “B” input of the quadrature decoder.

  • [in] index: - Optional, resets the counter when active to act as a reference position for the quadrature decoder.

  • [in] resolution: - The resolution that the quadrature decoder runs at

  • [in] clk: - Optional, the shared clock to use, if not provided a new clock will be allocated and the quadrature decoder frequency will be set to the value passed in with the frequency parameter.

  • [in] frequency: - This is the frequency, in hertz, to use with the clock allocated by this function. This parameter is only used if the clk parameter is set to NULL. When the clk parameter is not NULL, this must be set to zero. When the clk paramether is NULL, this must be set to something other than zero.

void cyhal_quaddec_free(cyhal_quaddec_t *obj)

Deinitialize the quadrature decoder object.

Parameters
  • [inout] obj: The quadrature decoder object

cy_rslt_t cyhal_quaddec_start(cyhal_quaddec_t *obj)

Starts the quadrature decoder.

This function also acts as a reset, in that it will trigger reload/index the QuadDec. When this function is called, the count value gets stored in the capture register and the count value is returned to the mid point. For example, if the hardware has 16-bit resolution, the midpoint would be 0x8000. For 32-bit resolution: 0x80000000. See Snippet 1: Initialization and direction detection.

Return

The status of the start request

Parameters
  • [in] obj: The quadrature decoder object

cy_rslt_t cyhal_quaddec_stop(cyhal_quaddec_t *obj)

Stops the quadrature decoder.

Does not reset counter value.

Return

The status of the stop request

Parameters
  • [in] obj: The quadrature decoder object

int32_t cyhal_quaddec_get_delta(cyhal_quaddec_t *obj)

Gets the change in the quadrature decoder counter, either positive or negative, since the last time that this function was called.

note

This function is not intended for applications requiring high speed or high accuracy such as getting motor positions. It is intended for applications involving devices like radial dials.

Return

The amount that the counter has changed

Parameters
  • [in] obj: The quadrature decoder object

uint32_t cyhal_quaddec_read_counter(const cyhal_quaddec_t *obj)

Reads the current value from the quadrature decoder

The read operation works even if the counter is stopped.

See Snippet 1: Initialization and direction detection.

Return

The current value of the quadrature decoder counter register

Parameters
  • [in] obj: The quadrature decoder object

uint32_t cyhal_quaddec_read_capture(const cyhal_quaddec_t *obj)

Reads the value from the quadrature decoder’s capture register

This function does not clear the counter value.

The capture register is updated whenever there is an index event.

Return

The current value of the quadrature decoder capture register

Parameters
  • [in] obj: The quadrature decoder object

void cyhal_quaddec_register_callback(cyhal_quaddec_t *obj, cyhal_quaddec_event_callback_t callback, void *callback_arg)

Register a quadrature decoder callback handler

This function does not clear the counter value.

This function will be called when one of the events enabled by cyhal_quaddec_enable_event occurs.

See Snippet 2: Handling an event in a callback function.

Parameters
  • [in] obj: The quadrature decoder object

  • [in] callback: The callback handler which will be invoked when the event occurs

  • [in] callback_arg: Generic argument that will be provided to the callback when called

void cyhal_quaddec_enable_event(cyhal_quaddec_t *obj, cyhal_quaddec_event_t event, uint8_t intr_priority, bool enable)

Configure quadrature decoder event enable

When an enabled event occurs, the function specified by cyhal_quaddec_register_callback will be called.

See Snippet 2: Handling an event in a callback function.

Parameters
  • [in] obj: The quadrature decoder object

  • [in] event: The quadrature decoder event type

  • [in] intr_priority: The priority for NVIC interrupt events

  • [in] enable: True to turn on interrupts, False to turn off

cy_rslt_t cyhal_quaddec_connect_digital(cyhal_quaddec_t *obj, cyhal_source_t source, cyhal_quaddec_input_t signal)

Connects a source signal and configures and enables a quadrature decoder event to be triggered from that signal.

These quadrature decoder events can be configured independently and connect to the same or different source signals.

Return

The status of the connection

Parameters
  • [in] obj: Quadrature decoder obj

  • [in] source: Source signal obtained from another driver’s cyhal_<PERIPH>_enable_output

  • [in] signal: The quadrature decoder input signal

cy_rslt_t cyhal_quaddec_disconnect_digital(cyhal_quaddec_t *obj, cyhal_source_t source, cyhal_quaddec_input_t signal)

Disconnects a source signal and disables the quadrature decoder event.

Return

The status of the disconnection

Parameters
  • [in] obj: Quadrature decoder obj

  • [in] source: Source signal from cyhal_<PERIPH>_enable_output to disable

  • [in] signal: The quadrature decoder input signal

cy_rslt_t cyhal_quaddec_enable_output(cyhal_quaddec_t *obj, cyhal_quaddec_output_t signal, cyhal_source_t *source)

Enables the specified output signal from a quadrature decoder that will be triggered when the corresponding event occurs.

Multiple output signals can be configured simultaneously.

Return

The status of the output enable

Parameters
  • [in] obj: Quadrature decoder obj

  • [in] signal: The quadrature decoder output signal

  • [out] source: Pointer to user-allocated source signal object which will be initialized by enable_output. source should be passed to (dis)connect_digital functions to (dis)connect the associated endpoints.

cy_rslt_t cyhal_quaddec_disable_output(cyhal_quaddec_t *obj, cyhal_quaddec_output_t signal)

Disables the specified output signal from a quadrature decoder.

Return

The status of the output disable

Parameters
  • [in] obj: Quadrature decoder obj

  • [in] signal: The quadrature decoder output signal