We use some essential cookies to make our website work.

We use optional cookies, as detailed in our cookie policy, to remember your settings and understand how you use our website.

Hardware APIs

This group of libraries provides a thin and efficient C API / abstractions to access the RP-series microcontroller hardware without having to read and write hardware registers directly.

hardware_adc

Analog to Digital Converter (ADC) API.

hardware_base

Low-level types and (atomic) accessors for memory-mapped hardware registers.

hardware_claim

Lightweight hardware resource management API.

hardware_clocks

Clock Management API.

hardware_divider

RP2040 Low Low-level hardware-divider API. Non-RP2040 platforms provide software versions of all the functions.

hardware_dcp

Assembly macros for the Double Coprocessor. RP2350

hardware_dma

DMA Controller API.

    channel_config

DMA channel configuration .

hardware_exception

Methods for setting processor exception handlers.

hardware_flash

Low level flash programming and erase API.

hardware_gpio

General Purpose Input/Output (GPIO) API.

hardware_hazard3

Accessors for Hazard3-specific RISC-V CSRs, and intrinsics for Hazard3 custom instructions. RP2350

hardware_i2c

I2C Controller API.

hardware_interp

Hardware Interpolator API.

    interp_config

Interpolator configuration .

hardware_irq

Hardware interrupt handling API.

hardware_pio

Programmable I/O (PIO) API.

    sm_config

PIO state machine configuration .

    pio_instructions

PIO instruction encoding .

hardware_pll

Phase Locked Loop control APIs.

hardware_powman

Power Management API. RP2350

hardware_pwm

Hardware Pulse Width Modulation (PWM) API.

hardware_resets

Hardware Reset API.

hardware_riscv

Accessors for standard RISC-V hardware (mainly CSRs) RP2350

hardware_riscv_platform_timer

Accessors for standard RISC-V platform timer (mtime/mtimecmp), available on Raspberry Pi microcontrollers with RISC-V processors. RP2350

hardware_rtc

Hardware Real Time Clock API. RP2040

hardware_rcp

Inline functions and assembly macros for the Redundancy Coprocessor. RP2350

hardware_spi

Hardware SPI API.

hardware_sha256

Hardware SHA-256 Accelerator API. RP2350

hardware_sync

Low level hardware spin locks, barrier and processor event APIs.

hardware_ticks

Hardware Tick API.

hardware_timer

Low-level hardware timer API.

hardware_uart

Hardware UART API.

hardware_vreg

Voltage Regulation API.

hardware_watchdog

Hardware Watchdog Timer API.

hardware_xip_cache

Low-level cache maintenance operations for the XIP cache.

hardware_xosc

Crystal Oscillator (XOSC) API.

hardware_adc

Analog to Digital Converter (ADC) API.

Detailed Description

RP-series microcontrollers have an internal analogue-digital converter (ADC) with the following features:

  • SAR ADC

  • 500 kS/s (Using an independent 48MHz clock)

  • 12 bit (RP2040 8.7 ENOB, RP2350 9.2 ENOB)

  • RP2040 5 input mux:

    • 4 inputs that are available on package pins shared with GPIO[29:26]

    • 1 input is dedicated to the internal temperature sensor

    • 4 element receive sample FIFO

  • RP2350 5 or 9 input mux:

    • 4 inputs available on QFN-60 package pins shared with GPIO[29:26]

    • 8 inputs available on QFN-80 package pins shared with GPIO[47:40]

    • 8 element receive sample FIFO

  • One input dedicated to the internal temperature sensor (see Section 12.4.6)

  • Interrupt generation

  • DMA interface

Although there is only one ADC you can specify the input to it using the adc_select_input() function. In round robin mode (adc_set_round_robin()), the ADC will use that input and move to the next one after a read.

RP2040, RP2350 QFN-60: User ADC inputs are on 0-3 (GPIO 26-29), the temperature sensor is on input 4. RP2350 QFN-80 : User ADC inputs are on 0-7 (GPIO 40-47), the temperature sensor is on input 8.

Temperature sensor values can be approximated in centigrade as:

T = 27 - (ADC_Voltage - 0.706)/0.001721

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"

int main() {
    stdio_init_all();
    printf("ADC Example, measuring GPIO26\n");

    adc_init();

    // Make sure GPIO is high-impedance, no pullups etc
    adc_gpio_init(26);
    // Select ADC input 0 (GPIO26)
    adc_select_input(0);

    while (1) {
        // 12-bit conversion, assume max value == ADC_VREF == 3.3 V
        const float conversion_factor = 3.3f / (1 << 12);
        uint16_t result = adc_read();
        printf("Raw value: 0x%03x, voltage: %f V\n", result, result * conversion_factor);
        sleep_ms(500);
    }
}

Functions

void adc_init (void)

Initialise the ADC HW.

static void adc_gpio_init (uint gpio)

Initialise the gpio for use as an ADC pin.

static void adc_select_input (uint input)

ADC input select.

static uint adc_get_selected_input (void)

Get the currently selected ADC input channel.

static void adc_set_round_robin (uint input_mask)

Round Robin sampling selector.

static void adc_set_temp_sensor_enabled (bool enable)

Enable the onboard temperature sensor.

static uint16_t adc_read (void)

Perform a single conversion.

static void adc_run (bool run)

Enable or disable free-running sampling mode.

static void adc_set_clkdiv (float clkdiv)

Set the ADC Clock divisor.

static void adc_fifo_setup (bool en, bool dreq_en, uint16_t dreq_thresh, bool err_in_fifo, bool byte_shift)

Setup the ADC FIFO.

static bool adc_fifo_is_empty (void)

Check FIFO empty state.

static uint8_t adc_fifo_get_level (void)

Get number of entries in the ADC FIFO.

static uint16_t adc_fifo_get (void)

Get ADC result from FIFO.

static uint16_t adc_fifo_get_blocking (void)

Wait for the ADC FIFO to have data.

static void adc_fifo_drain (void)

Drain the ADC FIFO.

static void adc_irq_set_enabled (bool enabled)

Enable/Disable ADC interrupts.

Function Documentation

adc_fifo_drain

static void adc_fifo_drain (void) [inline], [static]

Drain the ADC FIFO.

Will wait for any conversion to complete then drain the FIFO, discarding any results.

adc_fifo_get

static uint16_t adc_fifo_get (void) [inline], [static]

Get ADC result from FIFO.

Pops the latest result from the ADC FIFO.

adc_fifo_get_blocking

static uint16_t adc_fifo_get_blocking (void) [inline], [static]

Wait for the ADC FIFO to have data.

Blocks until data is present in the FIFO

adc_fifo_get_level

static uint8_t adc_fifo_get_level (void) [inline], [static]

Get number of entries in the ADC FIFO.

On RP2040 the FIFO is 4 samples long. On RP2350 the FIFO is 8 samples long.

This function will return how many samples are currently present.

adc_fifo_is_empty

static bool adc_fifo_is_empty (void) [inline], [static]

Check FIFO empty state.

Returns

Returns true if the FIFO is empty

adc_fifo_setup

static void adc_fifo_setup (bool en, bool dreq_en, uint16_t dreq_thresh, bool err_in_fifo, bool byte_shift) [inline], [static]

Setup the ADC FIFO.

On RP2040 the FIFO is 4 samples long.

On RP2350 the FIFO is 8 samples long.

If a conversion is completed and the FIFO is full, the result is dropped.

Parameters

en

Enables write each conversion result to the FIFO

dreq_en

Enable DMA requests when FIFO contains data

dreq_thresh

Threshold for DMA requests/FIFO IRQ if enabled.

err_in_fifo

If enabled, bit 15 of the FIFO contains error flag for each sample

byte_shift

Shift FIFO contents to be one byte in size (for byte DMA) - enables DMA to byte buffers.

adc_get_selected_input

static uint adc_get_selected_input (void) [inline], [static]

Get the currently selected ADC input channel.

Returns

The currently selected input channel.

On RP2040 0…​3 are GPIOs 26…​29 respectively. Input 4 is the onboard temperature sensor.

On RP2350A 0…​3 are GPIOs 26…​29 respectively. Input 4 is the onboard temperature sensor. On RP2350B 0…​7 are GPIOs 40…​47 respectively. Input 8 is the onboard temperature sensor.

adc_gpio_init

static void adc_gpio_init (uint gpio) [inline], [static]

Initialise the gpio for use as an ADC pin.

Prepare a GPIO for use with ADC by disabling all digital functions.

Parameters

gpio

The GPIO number to use. Allowable GPIO numbers are 26 to 29 inclusive on RP2040 or RP2350A, 40-48 inclusive on RP2350B

adc_init

void adc_init (void)

Initialise the ADC HW.

adc_irq_set_enabled

static void adc_irq_set_enabled (bool enabled) [inline], [static]

Enable/Disable ADC interrupts.

Parameters

enabled

Set to true to enable the ADC interrupts, false to disable

adc_read

static uint16_t adc_read (void) [inline], [static]

Perform a single conversion.

Performs an ADC conversion, waits for the result, and then returns it.

Returns

Result of the conversion.

adc_run

static void adc_run (bool run) [inline], [static]

Enable or disable free-running sampling mode.

Parameters

run

false to disable, true to enable free running conversion mode.

adc_select_input

static void adc_select_input (uint input) [inline], [static]

ADC input select.

Select an ADC input On RP2040 0…​3 are GPIOs 26…​29 respectively. Input 4 is the onboard temperature sensor. On RP2350A 0…​3 are GPIOs 26…​29 respectively. Input 4 is the onboard temperature sensor. On RP2350B 0…​7 are GPIOs 40…​47 respectively. Input 8 is the onboard temperature sensor.

Parameters

input

Input to select.

adc_set_clkdiv

static void adc_set_clkdiv (float clkdiv) [inline], [static]

Set the ADC Clock divisor.

Period of samples will be (1 + div) cycles on average. Note it takes 96 cycles to perform a conversion, so any period less than that will be clamped to 96.

Parameters

clkdiv

If non-zero, conversion will be started at intervals rather than back to back.

adc_set_round_robin

static void adc_set_round_robin (uint input_mask) [inline], [static]

Round Robin sampling selector.

This function sets which inputs are to be run through in round robin mode. RP2040, RP2350 QFN-60: Value between 0 and 0x1f (bit 0 to bit 4 for GPIO 26 to 29 and temperature sensor input respectively) RP2350 QFN-80: Value between 0 and 0xff (bit 0 to bit 7 for GPIO 40 to 47 and temperature sensor input respectively)

Parameters

input_mask

A bit pattern indicating which of the 5/8 inputs are to be sampled. Write a value of 0 to disable round robin sampling.

adc_set_temp_sensor_enabled

static void adc_set_temp_sensor_enabled (bool enable) [inline], [static]

Enable the onboard temperature sensor.

Parameters

enable

Set true to power on the onboard temperature sensor, false to power off.

hardware_base

Low-level types and (atomic) accessors for memory-mapped hardware registers.

Detailed Description

hardware_base defines the low level types and access functions for memory mapped hardware registers. It is included by default by all other hardware libraries.

The following register access typedefs codify the access type (read/write) and the bus size (8/16/32) of the hardware register. The register type names are formed by concatenating one from each of the 3 parts A, B, C

A B C Meaning

io_

A Memory mapped IO register

 

ro_

read-only access

 

rw_

read-write access

 

wo_

write-only access (can’t actually be enforced via C API)

 

8

8-bit wide access

 

16

16-bit wide access

 

32

32-bit wide access

When dealing with these types, you will always use a pointer, i.e. io_rw_32 *some_reg is a pointer to a read/write 32 bit register that you can write with *some_reg = value, or read with value = *some_reg.

RP-series hardware is also aliased to provide atomic setting, clear or flipping of a subset of the bits within a hardware register so that concurrent access by two cores is always consistent with one atomic operation being performed first, followed by the second.

See hw_set_bits(), hw_clear_bits() and hw_xor_bits() provide for atomic access via a pointer to a 32 bit register

Additionally given a pointer to a structure representing a piece of hardware (e.g. dma_hw_t *dma_hw for the DMA controller), you can get an alias to the entire structure such that writing any member (register) within the structure is equivalent to an atomic operation via hw_set_alias(), hw_clear_alias() or hw_xor_alias()…​

For example hw_set_alias(dma_hw)->inte1 = 0x80; will set bit 7 of the INTE1 register of the DMA controller, leaving the other bits unchanged.

Functions

static __force_inline void hw_set_bits (io_rw_32 *addr, uint32_t mask)

Atomically set the specified bits to 1 in a HW register.

static __force_inline void hw_clear_bits (io_rw_32 *addr, uint32_t mask)

Atomically clear the specified bits to 0 in a HW register.

static __force_inline void hw_xor_bits (io_rw_32 *addr, uint32_t mask)

Atomically flip the specified bits in a HW register.

static __force_inline void hw_write_masked (io_rw_32 *addr, uint32_t values, uint32_t write_mask)

Set new values for a sub-set of the bits in a HW register.

Function Documentation

hw_clear_bits

static __force_inline void hw_clear_bits (io_rw_32 * addr, uint32_t mask) [static]

Atomically clear the specified bits to 0 in a HW register.

Parameters

addr

Address of writable register

mask

Bit-mask specifying bits to clear

hw_set_bits

static __force_inline void hw_set_bits (io_rw_32 * addr, uint32_t mask) [static]

Atomically set the specified bits to 1 in a HW register.

Parameters

addr

Address of writable register

mask

Bit-mask specifying bits to set

hw_write_masked

static __force_inline void hw_write_masked (io_rw_32 * addr, uint32_t values, uint32_t write_mask) [static]

Set new values for a sub-set of the bits in a HW register.

Sets destination bits to values specified in values, if and only if corresponding bit in write_mask is set

Note: this method allows safe concurrent modification of different bits of a register, but multiple concurrent access to the same bits is still unsafe.

Parameters

addr

Address of writable register

values

Bits values

write_mask

Mask of bits to change

hw_xor_bits

static __force_inline void hw_xor_bits (io_rw_32 * addr, uint32_t mask) [static]

Atomically flip the specified bits in a HW register.

Parameters

addr

Address of writable register

mask

Bit-mask specifying bits to invert

hardware_claim

Lightweight hardware resource management API.

Detailed Description

hardware_claim provides a simple API for management of hardware resources at runtime.

This API is usually called by other hardware specific claiming APIs and provides simple multi-core safe methods to manipulate compact bit-sets representing hardware resources.

This API allows any other library to cooperatively participate in a scheme by which both compile time and runtime allocation of resources can co-exist, and conflicts can be avoided or detected (depending on the use case) without the libraries having any other knowledge of each other.

Facilities are providing for:

  1. Claiming resources (and asserting if they are already claimed)

  2. Freeing (unclaiming) resources

  3. Finding unused resources

Functions

void hw_claim_or_assert (uint8_t *bits, uint bit_index, const char *message)

Atomically claim a resource, panicking if it is already in use.

int hw_claim_unused_from_range (uint8_t *bits, bool required, uint bit_lsb, uint bit_msb, const char *message)

Atomically claim one resource out of a range of resources, optionally asserting if none are free.

bool hw_is_claimed (const uint8_t *bits, uint bit_index)

Determine if a resource is claimed at the time of the call.

void hw_claim_clear (uint8_t *bits, uint bit_index)

Atomically unclaim a resource.

uint32_t hw_claim_lock (void)

Acquire the runtime mutual exclusion lock provided by the hardware_claim library.

void hw_claim_unlock (uint32_t token)

Release the runtime mutual exclusion lock provided by the hardware_claim library.

Function Documentation

hw_claim_clear

void hw_claim_clear (uint8_t * bits, uint bit_index)

Atomically unclaim a resource.

The resource ownership is indicated by the bit_index bit in an array of bits.

Parameters

bits

pointer to an array of bits (8 bits per byte)

bit_index

resource to unclaim (bit index into array of bits)

hw_claim_lock

uint32_t hw_claim_lock (void)

Acquire the runtime mutual exclusion lock provided by the hardware_claim library.

This method is called automatically by the other hw_claim_ methods, however it is provided as a convenience to code that might want to protect other hardware initialization code from concurrent use.

Note

hw_claim_lock() uses a spin lock internally, so disables interrupts on the calling core, and will deadlock if the calling core already owns the lock.

Returns

a token to pass to hw_claim_unlock()

hw_claim_or_assert

void hw_claim_or_assert (uint8_t * bits, uint bit_index, const char * message)

Atomically claim a resource, panicking if it is already in use.

The resource ownership is indicated by the bit_index bit in an array of bits.

Parameters

bits

pointer to an array of bits (8 bits per byte)

bit_index

resource to claim (bit index into array of bits)

message

string to display if the bit cannot be claimed; note this may have a single printf format "%d" for the bit

hw_claim_unlock

void hw_claim_unlock (uint32_t token)

Release the runtime mutual exclusion lock provided by the hardware_claim library.

Note

This method MUST be called from the same core that call hw_claim_lock()

Parameters

token

the token returned by the corresponding call to hw_claim_lock()

hw_claim_unused_from_range

int hw_claim_unused_from_range (uint8_t * bits, bool required, uint bit_lsb, uint bit_msb, const char * message)

Atomically claim one resource out of a range of resources, optionally asserting if none are free.

Parameters

bits

pointer to an array of bits (8 bits per byte)

required

true if this method should panic if the resource is not free

bit_lsb

the lower bound (inclusive) of the resource range to claim from

bit_msb

the upper bound (inclusive) of the resource range to claim from

message

string to display if the bit cannot be claimed

Returns

the bit index representing the claimed or -1 if none are available in the range, and required = false

hw_is_claimed

bool hw_is_claimed (const uint8_t * bits, uint bit_index) [inline]

Determine if a resource is claimed at the time of the call.

The resource ownership is indicated by the bit_index bit in an array of bits.

Parameters

bits

pointer to an array of bits (8 bits per byte)

bit_index

resource to check (bit index into array of bits)

Returns

true if the resource is claimed

hardware_clocks

Clock Management API.

Detailed Description

This API provides a high level interface to the clock functions.

The clocks block provides independent clocks to on-chip and external components. It takes inputs from a variety of clock sources allowing the user to trade off performance against cost, board area and power consumption. From these sources it uses multiple clock generators to provide the required clocks. This architecture allows the user flexibility to start and stop clocks independently and to vary some clock frequencies whilst maintaining others at their optimum frequencies

Please refer to the appropriate datasheet for more details on the RP-series clocks.

The clock source depends on which clock you are attempting to configure. The first table below shows main clock sources. If you are not setting the Reference clock or the System clock, or you are specifying that one of those two will be using an auxiliary clock source, then you will need to use one of the entries from the subsequent tables.

  • On RP2040 the clock sources are:

Main Clock Sources

Source Reference Clock System Clock

ROSC

CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH

Auxiliary

CLOCKS_CLK_REF_CTRL_SRC_VALUE_CLKSRC_CLK_REF_AUX

CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX

XOSC

CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC

Reference

CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF

Auxiliary Clock Sources

The auxiliary clock sources available for use in the configure function depend on which clock is being configured. The following table describes the available values that can be used. Note that for clk_gpout[x], x can be 0-3.

Aux Source clk_gpout[x] clk_ref clk_sys

System PLL

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

GPIO in 0

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

GPIO in 1

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

USB PLL

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

ROSC

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_ROSC_CLKSRC

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC

XOSC

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

System clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_SYS

USB Clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_USB

ADC clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_ADC

RTC Clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_RTC

Ref clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_REF

Aux Source clk_peri clk_usb clk_adc

System PLL

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

GPIO in 0

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

GPIO in 1

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

USB PLL

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

ROSC

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH

XOSC

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

System clock

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS

Aux Source clk_rtc

System PLL

CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

GPIO in 0

CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

GPIO in 1

CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

USB PLL

CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

ROSC

CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH

XOSC

CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

On RP2350 the clock sources are:

  • Main Clock Sources

Source Reference Clock System Clock

ROSC

CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH

Auxiliary

CLOCKS_CLK_REF_CTRL_SRC_VALUE_CLKSRC_CLK_REF_AUX

CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX

XOSC

CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC

LPOSC

CLOCKS_CLK_REF_CTRL_SRC_VALUE_LPOSC_CLKSRC

Reference

CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF

Auxiliary Clock Sources

The auxiliary clock sources available for use in the configure function depend on which clock is being configured. The following table describes the available values that can be used. Note that for clk_gpout[x], x can be 0-3.

Aux Source clk_gpout[x] clk_ref clk_sys

System PLL

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

GPIO in 0

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

GPIO in 1

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

USB PLL

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

ROSC

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_ROSC_CLKSRC

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC

XOSC

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

LPOSC

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_LPOSC_CLKSRC

System clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_SYS

USB Clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_USB

ADC clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_ADC

REF clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_REF

PERI clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_PERI

HSTX clock

CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_PERI

Aux Source clk_peri clk_hstx clk_usb clk_adc

System PLL

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS

GPIO in 0

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0

GPIO in 1

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1

USB PLL

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB

ROSC

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH

XOSC

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC

System clock

CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS

CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLK_SYS

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pll.h"
#include "hardware/clocks.h"
#include "hardware/structs/pll.h"
#include "hardware/structs/clocks.h"

void measure_freqs(void) {
    uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);
    uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);
    uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);
    uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
    uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);
    uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);
    uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);
#ifdef CLOCKS_FC0_SRC_VALUE_CLK_RTC
    uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);
#endif

    printf("pll_sys  = %dkHz\n", f_pll_sys);
    printf("pll_usb  = %dkHz\n", f_pll_usb);
    printf("rosc     = %dkHz\n", f_rosc);
    printf("clk_sys  = %dkHz\n", f_clk_sys);
    printf("clk_peri = %dkHz\n", f_clk_peri);
    printf("clk_usb  = %dkHz\n", f_clk_usb);
    printf("clk_adc  = %dkHz\n", f_clk_adc);
#ifdef CLOCKS_FC0_SRC_VALUE_CLK_RTC
    printf("clk_rtc  = %dkHz\n", f_clk_rtc);
#endif

    // Can't measure clk_ref / xosc as it is the ref
}

int main() {
    stdio_init_all();

    printf("Hello, world!\n");

    measure_freqs();

    // Change clk_sys to be 48MHz. The simplest way is to take this from PLL_USB
    // which has a source frequency of 48MHz
    clock_configure(clk_sys,
                    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
                    CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
                    48 * MHZ,
                    48 * MHZ);

    // Turn off PLL sys for good measure
    pll_deinit(pll_sys);

    // CLK peri is clocked from clk_sys so need to change clk_peri's freq
    clock_configure(clk_peri,
                    0,
                    CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
                    48 * MHZ,
                    48 * MHZ);

    // Re init uart now that clk_peri has changed
    stdio_init_all();

    measure_freqs();
    printf("Hello, 48MHz");

    return 0;
}

Typedefs

typedef enum clock_num_rp2040 clock_num_t RP2040

Clock numbers on RP2040 (used as typedef clock_num_t)

typedef enum clock_dest_num_rp2040 clock_dest_num_t RP2040

Clock destination numbers on RP2040 (used as typedef clock_dest_num_t)

typedef enum clock_num_rp2350 clock_num_t RP2350

Clock numbers on RP2350 (used as typedef clock_num_t)

typedef enum clock_dest_num_rp2350 clock_dest_num_t RP2350

Clock destination numbers on RP2350 (used as typedef clock_dest_num_t)

typedef void(* resus_callback_t)(void)

Resus callback function type.

Enumerations

enum clock_num_rp2040 { clk_gpout0 = 0, clk_gpout1 = 1, clk_gpout2 = 2, clk_gpout3 = 3, clk_ref = 4, clk_sys = 5, clk_peri = 6, clk_usb = 7, clk_adc = 8, clk_rtc = 9, CLK_COUNT } RP2040

Clock numbers on RP2040 (used as typedef clock_num_t)

enum clock_dest_num_rp2040 { CLK_DEST_SYS_CLOCKS = 0, CLK_DEST_ADC_ADC = 1, CLK_DEST_SYS_ADC = 2, CLK_DEST_SYS_BUSCTRL = 3, CLK_DEST_SYS_BUSFABRIC = 4, CLK_DEST_SYS_DMA = 5, CLK_DEST_SYS_I2C0 = 6, CLK_DEST_SYS_I2C1 = 7, CLK_DEST_SYS_IO = 8, CLK_DEST_SYS_JTAG = 9, CLK_DEST_SYS_VREG_AND_CHIP_RESET = 10, CLK_DEST_SYS_PADS = 11, CLK_DEST_SYS_PIO0 = 12, CLK_DEST_SYS_PIO1 = 13, CLK_DEST_SYS_PLL_SYS = 14, CLK_DEST_SYS_PLL_USB = 15, CLK_DEST_SYS_PSM = 16, CLK_DEST_SYS_PWM = 17, CLK_DEST_SYS_RESETS = 18, CLK_DEST_SYS_ROM = 19, CLK_DEST_SYS_ROSC = 20, CLK_DEST_RTC_RTC = 21, CLK_DEST_SYS_RTC = 22, CLK_DEST_SYS_SIO = 23, CLK_DEST_PERI_SPI0 = 24, CLK_DEST_SYS_SPI0 = 25, CLK_DEST_PERI_SPI1 = 26, CLK_DEST_SYS_SPI1 = 27, CLK_DEST_SYS_SRAM0 = 28, CLK_DEST_SYS_SRAM1 = 29, CLK_DEST_SYS_SRAM2 = 30, CLK_DEST_SYS_SRAM3 = 31, CLK_DEST_SYS_SRAM4 = 32, CLK_DEST_SYS_SRAM5 = 33, CLK_DEST_SYS_SYSCFG = 34, CLK_DEST_SYS_SYSINFO = 35, CLK_DEST_SYS_TBMAN = 36, CLK_DEST_SYS_TIMER = 37, CLK_DEST_PERI_UART0 = 38, CLK_DEST_SYS_UART0 = 39, CLK_DEST_PERI_UART1 = 40, CLK_DEST_SYS_UART1 = 41, CLK_DEST_SYS_USBCTRL = 42, CLK_DEST_USB_USBCTRL = 43, CLK_DEST_SYS_WATCHDOG = 44, CLK_DEST_SYS_XIP = 45, CLK_DEST_SYS_XOSC = 46, NUM_CLOCK_DESTINATIONS } RP2040

Clock destination numbers on RP2040 (used as typedef clock_dest_num_t)

enum clock_num_rp2350 { clk_gpout0 = 0, clk_gpout1 = 1, clk_gpout2 = 2, clk_gpout3 = 3, clk_ref = 4, clk_sys = 5, clk_peri = 6, clk_hstx = 7, clk_usb = 8, clk_adc = 9, CLK_COUNT } RP2350

Clock numbers on RP2350 (used as typedef clock_num_t)

enum clock_dest_num_rp2350 { CLK_DEST_SYS_CLOCKS = 0, CLK_DEST_SYS_ACCESSCTRL = 1, CLK_DEST_ADC = 2, CLK_DEST_SYS_ADC = 3, CLK_DEST_SYS_BOOTRAM = 4, CLK_DEST_SYS_BUSCTRL = 5, CLK_DEST_SYS_BUSFABRIC = 6, CLK_DEST_SYS_DMA = 7, CLK_DEST_SYS_GLITCH_DETECTOR = 8, CLK_DEST_HSTX = 9, CLK_DEST_SYS_HSTX = 10, CLK_DEST_SYS_I2C0 = 11, CLK_DEST_SYS_I2C1 = 12, CLK_DEST_SYS_IO = 13, CLK_DEST_SYS_JTAG = 14, CLK_DEST_REF_OTP = 15, CLK_DEST_SYS_OTP = 16, CLK_DEST_SYS_PADS = 17, CLK_DEST_SYS_PIO0 = 18, CLK_DEST_SYS_PIO1 = 19, CLK_DEST_SYS_PIO2 = 20, CLK_DEST_SYS_PLL_SYS = 21, CLK_DEST_SYS_PLL_USB = 22, CLK_DEST_REF_POWMAN = 23, CLK_DEST_SYS_POWMAN = 24, CLK_DEST_SYS_PWM = 25, CLK_DEST_SYS_RESETS = 26, CLK_DEST_SYS_ROM = 27, CLK_DEST_SYS_ROSC = 28, CLK_DEST_SYS_PSM = 29, CLK_DEST_SYS_SHA256 = 30, CLK_DEST_SYS_SIO = 31, CLK_DEST_PERI_SPI0 = 32, CLK_DEST_SYS_SPI0 = 33, CLK_DEST_PERI_SPI1 = 34, CLK_DEST_SYS_SPI1 = 35, CLK_DEST_SYS_SRAM0 = 36, CLK_DEST_SYS_SRAM1 = 37, CLK_DEST_SYS_SRAM2 = 38, CLK_DEST_SYS_SRAM3 = 39, CLK_DEST_SYS_SRAM4 = 40, CLK_DEST_SYS_SRAM5 = 41, CLK_DEST_SYS_SRAM6 = 42, CLK_DEST_SYS_SRAM7 = 43, CLK_DEST_SYS_SRAM8 = 44, CLK_DEST_SYS_SRAM9 = 45, CLK_DEST_SYS_SYSCFG = 46, CLK_DEST_SYS_SYSINFO = 47, CLK_DEST_SYS_TBMAN = 48, CLK_DEST_REF_TICKS = 49, CLK_DEST_SYS_TICKS = 50, CLK_DEST_SYS_TIMER0 = 51, CLK_DEST_SYS_TIMER1 = 52, CLK_DEST_SYS_TRNG = 53, CLK_DEST_PERI_UART0 = 54, CLK_DEST_SYS_UART0 = 55, CLK_DEST_PERI_UART1 = 56, CLK_DEST_SYS_UART1 = 57, CLK_DEST_SYS_USBCTRL = 58, CLK_DEST_USB = 59, CLK_DEST_SYS_WATCHDOG = 60, CLK_DEST_SYS_XIP = 61, CLK_DEST_SYS_XOSC = 62, NUM_CLOCK_DESTINATIONS } RP2350

Clock destination numbers on RP2350 (used as typedef clock_dest_num_t)

Functions

bool clock_configure (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq)

Configure the specified clock with automatic clock divisor setup.

void clock_configure_undivided (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq)

Configure the specified clock to use the undivided input source.

void clock_configure_int_divider (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t int_divider)

Configure the specified clock to use the undivided input source.

void clock_stop (clock_handle_t clock)

Stop the specified clock.

uint32_t clock_get_hz (clock_handle_t clock)

Get the current frequency of the specified clock.

uint32_t frequency_count_khz (uint src)

Measure a clocks frequency using the Frequency counter.

void clock_set_reported_hz (clock_handle_t clock, uint hz)

Set the "current frequency" of the clock as reported by clock_get_hz without actually changing the clock.

void clocks_enable_resus (resus_callback_t resus_callback)

Enable the resus function. Restarts clk_sys if it is accidentally stopped.

void clock_gpio_init_int_frac16 (uint gpio, uint src, uint32_t div_int, uint16_t div_frac16)

Output an optionally divided clock to the specified gpio pin.

static void clock_gpio_init_int_frac8 (uint gpio, uint src, uint32_t div_int, uint8_t div_frac8)

Output an optionally divided clock to the specified gpio pin.

static void clock_gpio_init (uint gpio, uint src, float div)

Output an optionally divided clock to the specified gpio pin.

bool clock_configure_gpin (clock_handle_t clock, uint gpio, uint32_t src_freq, uint32_t freq)

Configure a clock to come from a gpio input.

void set_sys_clock_48mhz (void)

Initialise the system clock to 48MHz.

void set_sys_clock_pll (uint32_t vco_freq, uint post_div1, uint post_div2)

Initialise the system clock.

bool check_sys_clock_hz (uint32_t freq_hz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out)

Check if a given system clock frequency is valid/attainable.

bool check_sys_clock_khz (uint32_t freq_khz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out)

Check if a given system clock frequency is valid/attainable.

static bool set_sys_clock_hz (uint32_t freq_hz, bool required)

Attempt to set a system clock frequency in hz.

static bool set_sys_clock_khz (uint32_t freq_khz, bool required)

Attempt to set a system clock frequency in khz.

Typedef Documentation

clock_num_t RP2040

typedef enum clock_num_rp2040 clock_num_t

Clock numbers on RP2040 (used as typedef clock_num_t)

clock_dest_num_t RP2040

typedef enum clock_dest_num_rp2040 clock_dest_num_t

Clock destination numbers on RP2040 (used as typedef clock_dest_num_t)

clock_num_t RP2350

typedef enum clock_num_rp2350 clock_num_t

Clock numbers on RP2350 (used as typedef clock_num_t)

clock_dest_num_t RP2350

typedef enum clock_dest_num_rp2350 clock_dest_num_t

Clock destination numbers on RP2350 (used as typedef clock_dest_num_t)

resus_callback_t

typedef void(* resus_callback_t) (void)

Resus callback function type.

User provided callback for a resus event (when clk_sys is stopped by the programmer and is restarted for them).

Enumeration Type Documentation

clock_num_rp2040 RP2040

enum clock_num_rp2040

Clock numbers on RP2040 (used as typedef clock_num_t)

Table 1. Enumerator

clk_gpout0

Select CLK_GPOUT0 as clock source.

clk_gpout1

Select CLK_GPOUT1 as clock source.

clk_gpout2

Select CLK_GPOUT2 as clock source.

clk_gpout3

Select CLK_GPOUT3 as clock source.

clk_ref

Select CLK_REF as clock source.

clk_sys

Select CLK_SYS as clock source.

clk_peri

Select CLK_PERI as clock source.

clk_usb

Select CLK_USB as clock source.

clk_adc

Select CLK_ADC as clock source.

clk_rtc

Select CLK_RTC as clock source.

clock_dest_num_rp2040 RP2040

enum clock_dest_num_rp2040

Clock destination numbers on RP2040 (used as typedef clock_dest_num_t)

Table 2. Enumerator

CLK_DEST_SYS_CLOCKS

Select SYS_CLOCKS as clock destination.

CLK_DEST_ADC_ADC

Select ADC_ADC as clock destination.

CLK_DEST_SYS_ADC

Select SYS_ADC as clock destination.

CLK_DEST_SYS_BUSCTRL

Select SYS_BUSCTRL as clock destination.

CLK_DEST_SYS_BUSFABRIC

Select SYS_BUSFABRIC as clock destination.

CLK_DEST_SYS_DMA

Select SYS_DMA as clock destination.

CLK_DEST_SYS_I2C0

Select SYS_I2C0 as clock destination.

CLK_DEST_SYS_I2C1

Select SYS_I2C1 as clock destination.

CLK_DEST_SYS_IO

Select SYS_IO as clock destination.

CLK_DEST_SYS_JTAG

Select SYS_JTAG as clock destination.

CLK_DEST_SYS_VREG_AND_CHIP_RESET

Select SYS_VREG_AND_CHIP_RESET as clock destination.

CLK_DEST_SYS_PADS

Select SYS_PADS as clock destination.

CLK_DEST_SYS_PIO0

Select SYS_PIO0 as clock destination.

CLK_DEST_SYS_PIO1

Select SYS_PIO1 as clock destination.

CLK_DEST_SYS_PLL_SYS

Select SYS_PLL_SYS as clock destination.

CLK_DEST_SYS_PLL_USB

Select SYS_PLL_USB as clock destination.

CLK_DEST_SYS_PSM

Select SYS_PSM as clock destination.

CLK_DEST_SYS_PWM

Select SYS_PWM as clock destination.

CLK_DEST_SYS_RESETS

Select SYS_RESETS as clock destination.

CLK_DEST_SYS_ROM

Select SYS_ROM as clock destination.

CLK_DEST_SYS_ROSC

Select SYS_ROSC as clock destination.

CLK_DEST_RTC_RTC

Select RTC_RTC as clock destination.

CLK_DEST_SYS_RTC

Select SYS_RTC as clock destination.

CLK_DEST_SYS_SIO

Select SYS_SIO as clock destination.

CLK_DEST_PERI_SPI0

Select PERI_SPI0 as clock destination.

CLK_DEST_SYS_SPI0

Select SYS_SPI0 as clock destination.

CLK_DEST_PERI_SPI1

Select PERI_SPI1 as clock destination.

CLK_DEST_SYS_SPI1

Select SYS_SPI1 as clock destination.

CLK_DEST_SYS_SRAM0

Select SYS_SRAM0 as clock destination.

CLK_DEST_SYS_SRAM1

Select SYS_SRAM1 as clock destination.

CLK_DEST_SYS_SRAM2

Select SYS_SRAM2 as clock destination.

CLK_DEST_SYS_SRAM3

Select SYS_SRAM3 as clock destination.

CLK_DEST_SYS_SRAM4

Select SYS_SRAM4 as clock destination.

CLK_DEST_SYS_SRAM5

Select SYS_SRAM5 as clock destination.

CLK_DEST_SYS_SYSCFG

Select SYS_SYSCFG as clock destination.

CLK_DEST_SYS_SYSINFO

Select SYS_SYSINFO as clock destination.

CLK_DEST_SYS_TBMAN

Select SYS_TBMAN as clock destination.

CLK_DEST_SYS_TIMER

Select SYS_TIMER as clock destination.

CLK_DEST_PERI_UART0

Select PERI_UART0 as clock destination.

CLK_DEST_SYS_UART0

Select SYS_UART0 as clock destination.

CLK_DEST_PERI_UART1

Select PERI_UART1 as clock destination.

CLK_DEST_SYS_UART1

Select SYS_UART1 as clock destination.

CLK_DEST_SYS_USBCTRL

Select SYS_USBCTRL as clock destination.

CLK_DEST_USB_USBCTRL

Select USB_USBCTRL as clock destination.

CLK_DEST_SYS_WATCHDOG

Select SYS_WATCHDOG as clock destination.

CLK_DEST_SYS_XIP

Select SYS_XIP as clock destination.

CLK_DEST_SYS_XOSC

Select SYS_XOSC as clock destination.

clock_num_rp2350 RP2350

enum clock_num_rp2350

Clock numbers on RP2350 (used as typedef clock_num_t)

Table 3. Enumerator

clk_gpout0

Select CLK_GPOUT0 as clock source.

clk_gpout1

Select CLK_GPOUT1 as clock source.

clk_gpout2

Select CLK_GPOUT2 as clock source.

clk_gpout3

Select CLK_GPOUT3 as clock source.

clk_ref

Select CLK_REF as clock source.

clk_sys

Select CLK_SYS as clock source.

clk_peri

Select CLK_PERI as clock source.

clk_hstx

Select CLK_HSTX as clock source.

clk_usb

Select CLK_USB as clock source.

clk_adc

Select CLK_ADC as clock source.

clock_dest_num_rp2350 RP2350

enum clock_dest_num_rp2350

Clock destination numbers on RP2350 (used as typedef clock_dest_num_t)

Table 4. Enumerator

CLK_DEST_SYS_CLOCKS

Select SYS_CLOCKS as clock destination.

CLK_DEST_SYS_ACCESSCTRL

Select SYS_ACCESSCTRL as clock destination.

CLK_DEST_ADC

Select ADC as clock destination.

CLK_DEST_SYS_ADC

Select SYS_ADC as clock destination.

CLK_DEST_SYS_BOOTRAM

Select SYS_BOOTRAM as clock destination.

CLK_DEST_SYS_BUSCTRL

Select SYS_BUSCTRL as clock destination.

CLK_DEST_SYS_BUSFABRIC

Select SYS_BUSFABRIC as clock destination.

CLK_DEST_SYS_DMA

Select SYS_DMA as clock destination.

CLK_DEST_SYS_GLITCH_DETECTOR

Select SYS_GLITCH_DETECTOR as clock destination.

CLK_DEST_HSTX

Select HSTX as clock destination.

CLK_DEST_SYS_HSTX

Select SYS_HSTX as clock destination.

CLK_DEST_SYS_I2C0

Select SYS_I2C0 as clock destination.

CLK_DEST_SYS_I2C1

Select SYS_I2C1 as clock destination.

CLK_DEST_SYS_IO

Select SYS_IO as clock destination.

CLK_DEST_SYS_JTAG

Select SYS_JTAG as clock destination.

CLK_DEST_REF_OTP

Select REF_OTP as clock destination.

CLK_DEST_SYS_OTP

Select SYS_OTP as clock destination.

CLK_DEST_SYS_PADS

Select SYS_PADS as clock destination.

CLK_DEST_SYS_PIO0

Select SYS_PIO0 as clock destination.

CLK_DEST_SYS_PIO1

Select SYS_PIO1 as clock destination.

CLK_DEST_SYS_PIO2

Select SYS_PIO2 as clock destination.

CLK_DEST_SYS_PLL_SYS

Select SYS_PLL_SYS as clock destination.

CLK_DEST_SYS_PLL_USB

Select SYS_PLL_USB as clock destination.

CLK_DEST_REF_POWMAN

Select REF_POWMAN as clock destination.

CLK_DEST_SYS_POWMAN

Select SYS_POWMAN as clock destination.

CLK_DEST_SYS_PWM

Select SYS_PWM as clock destination.

CLK_DEST_SYS_RESETS

Select SYS_RESETS as clock destination.

CLK_DEST_SYS_ROM

Select SYS_ROM as clock destination.

CLK_DEST_SYS_ROSC

Select SYS_ROSC as clock destination.

CLK_DEST_SYS_PSM

Select SYS_PSM as clock destination.

CLK_DEST_SYS_SHA256

Select SYS_SHA256 as clock destination.

CLK_DEST_SYS_SIO

Select SYS_SIO as clock destination.

CLK_DEST_PERI_SPI0

Select PERI_SPI0 as clock destination.

CLK_DEST_SYS_SPI0

Select SYS_SPI0 as clock destination.

CLK_DEST_PERI_SPI1

Select PERI_SPI1 as clock destination.

CLK_DEST_SYS_SPI1

Select SYS_SPI1 as clock destination.

CLK_DEST_SYS_SRAM0

Select SYS_SRAM0 as clock destination.

CLK_DEST_SYS_SRAM1

Select SYS_SRAM1 as clock destination.

CLK_DEST_SYS_SRAM2

Select SYS_SRAM2 as clock destination.

CLK_DEST_SYS_SRAM3

Select SYS_SRAM3 as clock destination.

CLK_DEST_SYS_SRAM4

Select SYS_SRAM4 as clock destination.

CLK_DEST_SYS_SRAM5

Select SYS_SRAM5 as clock destination.

CLK_DEST_SYS_SRAM6

Select SYS_SRAM6 as clock destination.

CLK_DEST_SYS_SRAM7

Select SYS_SRAM7 as clock destination.

CLK_DEST_SYS_SRAM8

Select SYS_SRAM8 as clock destination.

CLK_DEST_SYS_SRAM9

Select SYS_SRAM9 as clock destination.

CLK_DEST_SYS_SYSCFG

Select SYS_SYSCFG as clock destination.

CLK_DEST_SYS_SYSINFO

Select SYS_SYSINFO as clock destination.

CLK_DEST_SYS_TBMAN

Select SYS_TBMAN as clock destination.

CLK_DEST_REF_TICKS

Select REF_TICKS as clock destination.

CLK_DEST_SYS_TICKS

Select SYS_TICKS as clock destination.

CLK_DEST_SYS_TIMER0

Select SYS_TIMER0 as clock destination.

CLK_DEST_SYS_TIMER1

Select SYS_TIMER1 as clock destination.

CLK_DEST_SYS_TRNG

Select SYS_TRNG as clock destination.

CLK_DEST_PERI_UART0

Select PERI_UART0 as clock destination.

CLK_DEST_SYS_UART0

Select SYS_UART0 as clock destination.

CLK_DEST_PERI_UART1

Select PERI_UART1 as clock destination.

CLK_DEST_SYS_UART1

Select SYS_UART1 as clock destination.

CLK_DEST_SYS_USBCTRL

Select SYS_USBCTRL as clock destination.

CLK_DEST_USB

Select USB as clock destination.

CLK_DEST_SYS_WATCHDOG

Select SYS_WATCHDOG as clock destination.

CLK_DEST_SYS_XIP

Select SYS_XIP as clock destination.

CLK_DEST_SYS_XOSC

Select SYS_XOSC as clock destination.

Function Documentation

check_sys_clock_hz

bool check_sys_clock_hz (uint32_t freq_hz, uint * vco_freq_out, uint * post_div1_out, uint * post_div2_out)

Check if a given system clock frequency is valid/attainable.

Parameters

freq_hz

Requested frequency

vco_freq_out

On success, the voltage controlled oscillator frequency to be used by the SYS PLL

post_div1_out

On success, The first post divider for the SYS PLL

post_div2_out

On success, The second post divider for the SYS PLL.

Returns

true if the frequency is possible and the output parameters have been written.

check_sys_clock_khz

bool check_sys_clock_khz (uint32_t freq_khz, uint * vco_freq_out, uint * post_div1_out, uint * post_div2_out)

Check if a given system clock frequency is valid/attainable.

Parameters

freq_khz

Requested frequency

vco_freq_out

On success, the voltage controlled oscillator frequency to be used by the SYS PLL

post_div1_out

On success, The first post divider for the SYS PLL

post_div2_out

On success, The second post divider for the SYS PLL.

Returns

true if the frequency is possible and the output parameters have been written.

clock_configure

bool clock_configure (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq)

Configure the specified clock with automatic clock divisor setup.

This method allows both the src_frequency of the input clock source AND the desired frequency to be specified, and will set the clock divider to achieve the exact or higher frequency achievable, with the maximum being the src_freq.

Note: The RP2350 clock hardware supports divisors from 1.0->65536.0 in steps of 1/65536

Note: The RP2040 clock hardware only supports divisors of exactly 1.0 or 2.0->16777216.0 in steps of 1/256

See the tables in the description for details on the possible values for clock sources.

Parameters

clock

The clock to configure

src

The main clock source, can be 0.

auxsrc

The auxiliary clock source, which depends on which clock is being set. Can be 0

src_freq

Frequency of the input clock source

freq

Requested frequency

Returns

true if the clock is updated, false if freq > src_freq

clock_configure_gpin

bool clock_configure_gpin (clock_handle_t clock, uint gpio, uint32_t src_freq, uint32_t freq)

Configure a clock to come from a gpio input.

Parameters

clock

The clock to configure

gpio

The GPIO pin to run the clock from. Valid GPIOs are: 20 and 22.

src_freq

Frequency of the input clock source

freq

Requested frequency

clock_configure_int_divider

void clock_configure_int_divider (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t int_divider)

Configure the specified clock to use the undivided input source.

See the tables in the description for details on the possible values for clock sources.

Parameters

clock

The clock to configure

src

The main clock source, can be 0.

auxsrc

The auxiliary clock source, which depends on which clock is being set. Can be 0

src_freq

Frequency of the input clock source

int_divider

an integer divider

clock_configure_undivided

void clock_configure_undivided (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq)

Configure the specified clock to use the undivided input source.

See the tables in the description for details on the possible values for clock sources.

Parameters

clock

The clock to configure

src

The main clock source, can be 0.

auxsrc

The auxiliary clock source, which depends on which clock is being set. Can be 0

src_freq

Frequency of the input clock source

clock_get_hz

uint32_t clock_get_hz (clock_handle_t clock)

Get the current frequency of the specified clock.

Parameters

clock

Clock

Returns

Clock frequency in Hz

clock_gpio_init

static void clock_gpio_init (uint gpio, uint src, float div) [inline], [static]

Output an optionally divided clock to the specified gpio pin.

Parameters

gpio

The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators.

src

The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator.

div

The float amount to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock.

clock_gpio_init_int_frac16

void clock_gpio_init_int_frac16 (uint gpio, uint src, uint32_t div_int, uint16_t div_frac16)

Output an optionally divided clock to the specified gpio pin.

Parameters

gpio

The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators.

src

The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator.

div_int

The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040 and 1..2^16-1 on RP2350

div_frac16

The fractional part of the value to divide the source clock by. This is in range of 0..65535 (/65536).

clock_gpio_init_int_frac8

static void clock_gpio_init_int_frac8 (uint gpio, uint src, uint32_t div_int, uint8_t div_frac8) [inline], [static]

Output an optionally divided clock to the specified gpio pin.

Parameters

gpio

The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators.

src

The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator.

div_int

The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040 and 1..2^16-1 on RP2350

div_frac8

The fractional part of the value to divide the source clock by. This is in range of 0..255 (/256).

clock_set_reported_hz

void clock_set_reported_hz (clock_handle_t clock, uint hz)

Set the "current frequency" of the clock as reported by clock_get_hz without actually changing the clock.

See also

clock_stop

void clock_stop (clock_handle_t clock)

Stop the specified clock.

Parameters

clock

The clock to stop

clocks_enable_resus

void clocks_enable_resus (resus_callback_t resus_callback)

Enable the resus function. Restarts clk_sys if it is accidentally stopped.

The resuscitate function will restart the system clock if it falls below a certain speed (or stops). This could happen if the clock source the system clock is running from stops. For example if a PLL is stopped.

Parameters

resus_callback

a function pointer provided by the user to call if a resus event happens.

frequency_count_khz

uint32_t frequency_count_khz (uint src)

Measure a clocks frequency using the Frequency counter.

Uses the inbuilt frequency counter to measure the specified clocks frequency. Currently, this function is accurate to +-1KHz. See the datasheet for more details.

set_sys_clock_48mhz

void set_sys_clock_48mhz (void)

Initialise the system clock to 48MHz.

Set the system clock to 48MHz, and set the peripheral clock to match.

set_sys_clock_hz

static bool set_sys_clock_hz (uint32_t freq_hz, bool required) [inline], [static]

Attempt to set a system clock frequency in hz.

Note that not all clock frequencies are possible; it is preferred that you use src/rp2_common/hardware_clocks/scripts/vcocalc.py to calculate the parameters for use with set_sys_clock_pll

Parameters

freq_hz

Requested frequency

required

if true then this function will assert if the frequency is not attainable.

Returns

true if the clock was configured

set_sys_clock_khz

static bool set_sys_clock_khz (uint32_t freq_khz, bool required) [inline], [static]

Attempt to set a system clock frequency in khz.

Note that not all clock frequencies are possible; it is preferred that you use src/rp2_common/hardware_clocks/scripts/vcocalc.py to calculate the parameters for use with set_sys_clock_pll

Parameters

freq_khz

Requested frequency

required

if true then this function will assert if the frequency is not attainable.

Returns

true if the clock was configured

set_sys_clock_pll

void set_sys_clock_pll (uint32_t vco_freq, uint post_div1, uint post_div2)

Initialise the system clock.

Parameters

vco_freq

The voltage controller oscillator frequency to be used by the SYS PLL

post_div1

The first post divider for the SYS PLL

post_div2

The second post divider for the SYS PLL.

See the PLL documentation in the datasheet for details of driving the PLLs.

hardware_divider

RP2040 Low Low-level hardware-divider API. Non-RP2040 platforms provide software versions of all the functions.

Detailed Description

The SIO contains an 8-cycle signed/unsigned divide/modulo circuit, per core. Calculation is started by writing a dividend and divisor to the two argument registers, DIVIDEND and DIVISOR. The divider calculates the quotient / and remainder % of this division over the next 8 cycles, and on the 9th cycle the results can be read from the two result registers DIV_QUOTIENT and DIV_REMAINDER. A 'ready' bit in register DIV_CSR can be polled to wait for the calculation to complete, or software can insert a fixed 8-cycle delay

This header provides low level macros and inline functions for accessing the hardware dividers directly, and perhaps most usefully performing asynchronous divides. These functions however do not follow the regular SDK conventions for saving/restoring the divider state, so are not generally safe to call from interrupt handlers

The pico_divider library provides a more user friendly set of APIs over the divider (and support for 64 bit divides), and of course by default regular C language integer divisions are redirected through that library, meaning you can just use C level / and % operators and gain the benefits of the fast hardware divider.

On RP2350 there is no hardware divider, and the functions are implemented in software

See also

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/divider.h"

int main() {
    stdio_init_all();
    printf("Hello, divider!\n");

    // This is the basic hardware divider function
    int32_t dividend = 123456;
    int32_t divisor = -321;
    divmod_result_t result = hw_divider_divmod_s32(dividend, divisor);

    printf("%d/%d = %d remainder %d\n", dividend, divisor, to_quotient_s32(result), to_remainder_s32(result));

    // Is it right?

    printf("Working backwards! Result %d should equal %d!\n\n",
           to_quotient_s32(result) * divisor + to_remainder_s32(result), dividend);

    // This is the recommended unsigned fast divider for general use.
    int32_t udividend = 123456;
    int32_t udivisor = 321;
    divmod_result_t uresult = hw_divider_divmod_u32(udividend, udivisor);

    printf("%d/%d = %d remainder %d\n", udividend, udivisor, to_quotient_u32(uresult), to_remainder_u32(uresult));

    // Is it right?

    printf("Working backwards! Result %d should equal %d!\n\n",
           to_quotient_u32(result) * divisor + to_remainder_u32(result), dividend);

    // You can also do divides asynchronously. Divides will be complete after 8 cycles.

    hw_divider_divmod_s32_start(dividend, divisor);

    // Do something for 8 cycles!

    // In this example, our results function will wait for completion.
    // Use hw_divider_result_nowait() if you don't want to wait, but are sure you have delayed at least 8 cycles

    result = hw_divider_result_wait();

    printf("Async result %d/%d = %d remainder %d\n", dividend, divisor, to_quotient_s32(result),
           to_remainder_s32(result));

    // For a really fast divide, you can use the inlined versions... the / involves a function call as / always does
    // when using the ARM AEABI, so if you really want the best performance use the inlined versions.
    // Note that the / operator function DOES use the hardware divider by default, although you can change
    // that behavior by calling pico_set_divider_implementation in the cmake build for your target.
    printf("%d / %d = (by operator %d) (inlined %d)\n", dividend, divisor,
           dividend / divisor, hw_divider_s32_quotient_inlined(dividend, divisor));

    // Note however you must manually save/restore the divider state if you call the inlined methods from within an IRQ
    // handler.
    hw_divider_state_t state;
    hw_divider_divmod_s32_start(dividend, divisor);
    hw_divider_save_state(&state);

    hw_divider_divmod_s32_start(123, 7);
    printf("inner %d / %d = %d\n", 123, 7, hw_divider_s32_quotient_wait());

    hw_divider_restore_state(&state);
    int32_t tmp = hw_divider_s32_quotient_wait();
    printf("outer divide %d / %d = %d\n", dividend, divisor, tmp);
    return 0;
}

Functions

static divmod_result_t hw_divider_divmod_s32 (int32_t a, int32_t b)

Do a signed HW divide and wait for result.

static divmod_result_t hw_divider_divmod_u32 (uint32_t a, uint32_t b)

Do an unsigned HW divide and wait for result.

static void hw_divider_divmod_s32_start (int32_t a, int32_t b)

Start a signed asynchronous divide.

static void hw_divider_divmod_u32_start (uint32_t a, uint32_t b)

Start an unsigned asynchronous divide.

static void hw_divider_wait_ready (void)

Wait for a divide to complete.

static divmod_result_t hw_divider_result_nowait (void)

Return result of HW divide, nowait.

static divmod_result_t hw_divider_result_wait (void)

Return result of last asynchronous HW divide.

static uint32_t to_quotient_u32 (divmod_result_t r)

Efficient extraction of unsigned quotient from 32p32 fixed point.

static int32_t to_quotient_s32 (divmod_result_t r)

Efficient extraction of signed quotient from 32p32 fixed point.

static uint32_t to_remainder_u32 (divmod_result_t r)

Efficient extraction of unsigned remainder from 32p32 fixed point.

static int32_t to_remainder_s32 (divmod_result_t r)

Efficient extraction of signed remainder from 32p32 fixed point.

static uint32_t hw_divider_u32_quotient_wait (void)

Return result of last asynchronous HW divide, unsigned quotient only.

static int32_t hw_divider_s32_quotient_wait (void)

Return result of last asynchronous HW divide, signed quotient only.

static uint32_t hw_divider_u32_remainder_wait (void)

Return result of last asynchronous HW divide, unsigned remainder only.

static int32_t hw_divider_s32_remainder_wait (void)

Return result of last asynchronous HW divide, signed remainder only.

static uint32_t hw_divider_u32_quotient (uint32_t a, uint32_t b)

Do an unsigned HW divide, wait for result, return quotient.

static uint32_t hw_divider_u32_remainder (uint32_t a, uint32_t b)

Do an unsigned HW divide, wait for result, return remainder.

static int32_t hw_divider_quotient_s32 (int32_t a, int32_t b)

Do a signed HW divide, wait for result, return quotient.

static int32_t hw_divider_remainder_s32 (int32_t a, int32_t b)

Do a signed HW divide, wait for result, return remainder.

static void hw_divider_pause (void)

Pause for exact amount of time needed for a asynchronous divide to complete.

static uint32_t hw_divider_u32_quotient_inlined (uint32_t a, uint32_t b)

Do a hardware unsigned HW divide, wait for result, return quotient.

static uint32_t hw_divider_u32_remainder_inlined (uint32_t a, uint32_t b)

Do a hardware unsigned HW divide, wait for result, return remainder.

static int32_t hw_divider_s32_quotient_inlined (int32_t a, int32_t b)

Do a hardware signed HW divide, wait for result, return quotient.

static int32_t hw_divider_s32_remainder_inlined (int32_t a, int32_t b)

Do a hardware signed HW divide, wait for result, return remainder.

static void hw_divider_save_state (hw_divider_state_t *dest)

Save the calling cores hardware divider state.

static void hw_divider_restore_state (hw_divider_state_t *src)

Load a saved hardware divider state into the current core’s hardware divider.

Function Documentation

hw_divider_divmod_s32

static divmod_result_t hw_divider_divmod_s32 (int32_t a, int32_t b) [inline], [static]

Do a signed HW divide and wait for result.

Divide a by b, wait for calculation to complete, return result as a pair of 32-bit quotient/remainder values.

Parameters

a

The dividend

b

The divisor

Returns

Results of divide as a pair of 32-bit quotient/remainder values.

hw_divider_divmod_s32_start

static void hw_divider_divmod_s32_start (int32_t a, int32_t b) [inline], [static]

Start a signed asynchronous divide.

Start a divide of the specified signed parameters. You should wait for 8 cycles (__div_pause()) or wait for the ready bit to be set (hw_divider_wait_ready()) prior to reading the results.

Parameters

a

The dividend

b

The divisor

hw_divider_divmod_u32

static divmod_result_t hw_divider_divmod_u32 (uint32_t a, uint32_t b) [inline], [static]

Do an unsigned HW divide and wait for result.

Divide a by b, wait for calculation to complete, return result as a pair of 32-bit quotient/remainder values.

Parameters

a

The dividend

b

The divisor

Returns

Results of divide as a pair of 32-bit quotient/remainder values.

hw_divider_divmod_u32_start

static void hw_divider_divmod_u32_start (uint32_t a, uint32_t b) [inline], [static]

Start an unsigned asynchronous divide.

Start a divide of the specified unsigned parameters. You should wait for 8 cycles (__div_pause()) or wait for the ready bit to be set (hw_divider_wait_ready()) prior to reading the results.

Parameters

a

The dividend

b

The divisor

hw_divider_pause

static void hw_divider_pause (void) [inline], [static]

Pause for exact amount of time needed for a asynchronous divide to complete.

hw_divider_quotient_s32

static int32_t hw_divider_quotient_s32 (int32_t a, int32_t b) [inline], [static]

Do a signed HW divide, wait for result, return quotient.

Divide a by b, wait for calculation to complete, return quotient.

Parameters

a

The dividend

b

The divisor

Returns

Quotient results of the divide

hw_divider_remainder_s32

static int32_t hw_divider_remainder_s32 (int32_t a, int32_t b) [inline], [static]

Do a signed HW divide, wait for result, return remainder.

Divide a by b, wait for calculation to complete, return remainder.

Parameters

a

The dividend

b

The divisor

Returns

Remainder results of the divide

hw_divider_restore_state

static void hw_divider_restore_state (hw_divider_state_t * src) [inline], [static]

Load a saved hardware divider state into the current core’s hardware divider.

Copy the passed hardware divider state into the hardware divider.

Parameters

src

the location to load the divider state from

hw_divider_result_nowait

static divmod_result_t hw_divider_result_nowait (void) [inline], [static]

Return result of HW divide, nowait.

Note

This is UNSAFE in that the calculation may not have been completed.

Returns

Current result. Most significant 32 bits are the remainder, lower 32 bits are the quotient.

hw_divider_result_wait

static divmod_result_t hw_divider_result_wait (void) [inline], [static]

Return result of last asynchronous HW divide.

This function waits for the result to be ready by calling hw_divider_wait_ready().

Returns

Current result. Most significant 32 bits are the remainder, lower 32 bits are the quotient.

hw_divider_s32_quotient_inlined

static int32_t hw_divider_s32_quotient_inlined (int32_t a, int32_t b) [inline], [static]

Do a hardware signed HW divide, wait for result, return quotient.

Divide a by b, wait for calculation to complete, return quotient.

Parameters

a

The dividend

b

The divisor

Returns

Quotient result of the divide

hw_divider_s32_quotient_wait

static int32_t hw_divider_s32_quotient_wait (void) [inline], [static]

Return result of last asynchronous HW divide, signed quotient only.

This function waits for the result to be ready by calling hw_divider_wait_ready().

Returns

Current signed quotient result.

hw_divider_s32_remainder_inlined

static int32_t hw_divider_s32_remainder_inlined (int32_t a, int32_t b) [inline], [static]

Do a hardware signed HW divide, wait for result, return remainder.

Divide a by b, wait for calculation to complete, return remainder.

Parameters

a

The dividend

b

The divisor

Returns

Remainder result of the divide

hw_divider_s32_remainder_wait

static int32_t hw_divider_s32_remainder_wait (void) [inline], [static]

Return result of last asynchronous HW divide, signed remainder only.

This function waits for the result to be ready by calling hw_divider_wait_ready().

Returns

Current remainder results.

hw_divider_save_state

static void hw_divider_save_state (hw_divider_state_t * dest) [inline], [static]

Save the calling cores hardware divider state.

Copy the current core’s hardware divider state into the provided structure. This method waits for the divider results to be stable, then copies them to memory. They can be restored via hw_divider_restore_state()

Parameters

dest

the location to store the divider state

hw_divider_u32_quotient

static uint32_t hw_divider_u32_quotient (uint32_t a, uint32_t b) [inline], [static]

Do an unsigned HW divide, wait for result, return quotient.

Divide a by b, wait for calculation to complete, return quotient.

Parameters

a

The dividend

b

The divisor

Returns

Quotient results of the divide

hw_divider_u32_quotient_inlined

static uint32_t hw_divider_u32_quotient_inlined (uint32_t a, uint32_t b) [inline], [static]

Do a hardware unsigned HW divide, wait for result, return quotient.

Divide a by b, wait for calculation to complete, return quotient.

Parameters

a

The dividend

b

The divisor

Returns

Quotient result of the divide

hw_divider_u32_quotient_wait

static uint32_t hw_divider_u32_quotient_wait (void) [inline], [static]

Return result of last asynchronous HW divide, unsigned quotient only.

This function waits for the result to be ready by calling hw_divider_wait_ready().

Returns

Current unsigned quotient result.

hw_divider_u32_remainder

static uint32_t hw_divider_u32_remainder (uint32_t a, uint32_t b) [inline], [static]

Do an unsigned HW divide, wait for result, return remainder.

Divide a by b, wait for calculation to complete, return remainder.

Parameters

a

The dividend

b

The divisor

Returns

Remainder results of the divide

hw_divider_u32_remainder_inlined

static uint32_t hw_divider_u32_remainder_inlined (uint32_t a, uint32_t b) [inline], [static]

Do a hardware unsigned HW divide, wait for result, return remainder.

Divide a by b, wait for calculation to complete, return remainder.

Parameters

a

The dividend

b

The divisor

Returns

Remainder result of the divide

hw_divider_u32_remainder_wait

static uint32_t hw_divider_u32_remainder_wait (void) [inline], [static]

Return result of last asynchronous HW divide, unsigned remainder only.

This function waits for the result to be ready by calling hw_divider_wait_ready().

Returns

Current unsigned remainder result.

hw_divider_wait_ready

static void hw_divider_wait_ready (void) [inline], [static]

Wait for a divide to complete.

Wait for a divide to complete

to_quotient_s32

static int32_t to_quotient_s32 (divmod_result_t r) [inline], [static]

Efficient extraction of signed quotient from 32p32 fixed point.

Parameters

r

A pair of 32-bit quotient/remainder values.

Returns

Unsigned quotient

to_quotient_u32

static uint32_t to_quotient_u32 (divmod_result_t r) [inline], [static]

Efficient extraction of unsigned quotient from 32p32 fixed point.

Parameters

r

A pair of 32-bit quotient/remainder values.

Returns

Unsigned quotient

to_remainder_s32

static int32_t to_remainder_s32 (divmod_result_t r) [inline], [static]

Efficient extraction of signed remainder from 32p32 fixed point.

Parameters

r

A pair of 32-bit quotient/remainder values.

Returns

Signed remainder

Note

On arm this is just a 32 bit register move or a nop

to_remainder_u32

static uint32_t to_remainder_u32 (divmod_result_t r) [inline], [static]

Efficient extraction of unsigned remainder from 32p32 fixed point.

Parameters

r

A pair of 32-bit quotient/remainder values.

Returns

Unsigned remainder

Note

On Arm this is just a 32 bit register move or a nop

hardware_dcp RP2350

Assembly macros for the Double Coprocessor.

hardware_dma

DMA Controller API.

Detailed Description

The RP-series microcontroller Direct Memory Access (DMA) master performs bulk data transfers on a processor’s behalf. This leaves processors free to attend to other tasks, or enter low-power sleep states. The data throughput of the DMA is also significantly higher than one of RP-series microcontroller’s processors.

The DMA can perform one read access and one write access, up to 32 bits in size, every clock cycle. There are 12 independent channels, which each supervise a sequence of bus transfers, usually in one of the following scenarios:

  • Memory to peripheral

  • Peripheral to memory

  • Memory to memory

Modules

channel_config

DMA channel configuration .

Macros

Typedefs

typedef enum dreq_num_rp2350 dreq_num_t RP2350

DREQ numbers for DMA pacing on RP2350 (used as typedef dreq_num_t)

typedef enum dreq_num_rp2040 dreq_num_t RP2040

DREQ numbers for DMA pacing on RP2040 (used as typedef dreq_num_t)

Enumerations

enum dreq_num_rp2350 { DREQ_PIO0_TX0 = 0, DREQ_PIO0_TX1 = 1, DREQ_PIO0_TX2 = 2, DREQ_PIO0_TX3 = 3, DREQ_PIO0_RX0 = 4, DREQ_PIO0_RX1 = 5, DREQ_PIO0_RX2 = 6, DREQ_PIO0_RX3 = 7, DREQ_PIO1_TX0 = 8, DREQ_PIO1_TX1 = 9, DREQ_PIO1_TX2 = 10, DREQ_PIO1_TX3 = 11, DREQ_PIO1_RX0 = 12, DREQ_PIO1_RX1 = 13, DREQ_PIO1_RX2 = 14, DREQ_PIO1_RX3 = 15, DREQ_PIO2_TX0 = 16, DREQ_PIO2_TX1 = 17, DREQ_PIO2_TX2 = 18, DREQ_PIO2_TX3 = 19, DREQ_PIO2_RX0 = 20, DREQ_PIO2_RX1 = 21, DREQ_PIO2_RX2 = 22, DREQ_PIO2_RX3 = 23, DREQ_SPI0_TX = 24, DREQ_SPI0_RX = 25, DREQ_SPI1_TX = 26, DREQ_SPI1_RX = 27, DREQ_UART0_TX = 28, DREQ_UART0_RX = 29, DREQ_UART1_TX = 30, DREQ_UART1_RX = 31, DREQ_PWM_WRAP0 = 32, DREQ_PWM_WRAP1 = 33, DREQ_PWM_WRAP2 = 34, DREQ_PWM_WRAP3 = 35, DREQ_PWM_WRAP4 = 36, DREQ_PWM_WRAP5 = 37, DREQ_PWM_WRAP6 = 38, DREQ_PWM_WRAP7 = 39, DREQ_PWM_WRAP8 = 40, DREQ_PWM_WRAP9 = 41, DREQ_PWM_WRAP10 = 42, DREQ_PWM_WRAP11 = 43, DREQ_I2C0_TX = 44, DREQ_I2C0_RX = 45, DREQ_I2C1_TX = 46, DREQ_I2C1_RX = 47, DREQ_ADC = 48, DREQ_XIP_STREAM = 49, DREQ_XIP_QMITX = 50, DREQ_XIP_QMIRX = 51, DREQ_HSTX = 52, DREQ_CORESIGHT = 53, DREQ_SHA256 = 54, DREQ_DMA_TIMER0 = 59, DREQ_DMA_TIMER1 = 60, DREQ_DMA_TIMER2 = 61, DREQ_DMA_TIMER3 = 62, DREQ_FORCE = 63, DREQ_COUNT } RP2350

DREQ numbers for DMA pacing on RP2350 (used as typedef dreq_num_t)

enum dreq_num_rp2040 { DREQ_PIO0_TX0 = 0, DREQ_PIO0_TX1 = 1, DREQ_PIO0_TX2 = 2, DREQ_PIO0_TX3 = 3, DREQ_PIO0_RX0 = 4, DREQ_PIO0_RX1 = 5, DREQ_PIO0_RX2 = 6, DREQ_PIO0_RX3 = 7, DREQ_PIO1_TX0 = 8, DREQ_PIO1_TX1 = 9, DREQ_PIO1_TX2 = 10, DREQ_PIO1_TX3 = 11, DREQ_PIO1_RX0 = 12, DREQ_PIO1_RX1 = 13, DREQ_PIO1_RX2 = 14, DREQ_PIO1_RX3 = 15, DREQ_SPI0_TX = 16, DREQ_SPI0_RX = 17, DREQ_SPI1_TX = 18, DREQ_SPI1_RX = 19, DREQ_UART0_TX = 20, DREQ_UART0_RX = 21, DREQ_UART1_TX = 22, DREQ_UART1_RX = 23, DREQ_PWM_WRAP0 = 24, DREQ_PWM_WRAP1 = 25, DREQ_PWM_WRAP2 = 26, DREQ_PWM_WRAP3 = 27, DREQ_PWM_WRAP4 = 28, DREQ_PWM_WRAP5 = 29, DREQ_PWM_WRAP6 = 30, DREQ_PWM_WRAP7 = 31, DREQ_I2C0_TX = 32, DREQ_I2C0_RX = 33, DREQ_I2C1_TX = 34, DREQ_I2C1_RX = 35, DREQ_ADC = 36, DREQ_XIP_STREAM = 37, DREQ_XIP_SSITX = 38, DREQ_XIP_SSIRX = 39, DREQ_DMA_TIMER0 = 59, DREQ_DMA_TIMER1 = 60, DREQ_DMA_TIMER2 = 61, DREQ_DMA_TIMER3 = 62, DREQ_FORCE = 63, DREQ_COUNT } RP2040

DREQ numbers for DMA pacing on RP2040 (used as typedef dreq_num_t)

enum dma_channel_transfer_size { DMA_SIZE_8 = 0, DMA_SIZE_16 = 1, DMA_SIZE_32 = 2 }

Enumeration of available DMA channel transfer sizes.

Functions

void dma_channel_claim (uint channel)

Mark a dma channel as used.

void dma_claim_mask (uint32_t channel_mask)

Mark multiple dma channels as used.

void dma_channel_unclaim (uint channel)

Mark a dma channel as no longer used.

void dma_unclaim_mask (uint32_t channel_mask)

Mark multiple dma channels as no longer used.

int dma_claim_unused_channel (bool required)

Claim a free dma channel.

bool dma_channel_is_claimed (uint channel)

Determine if a dma channel is claimed.

static void dma_channel_set_config (uint channel, const dma_channel_config *config, bool trigger)

Set a channel configuration.

static void dma_channel_set_read_addr (uint channel, const volatile void *read_addr, bool trigger)

Set the DMA initial read address.

static void dma_channel_set_write_addr (uint channel, volatile void *write_addr, bool trigger)

Set the DMA initial write address.

static void dma_channel_set_trans_count (uint channel, uint32_t trans_count, bool trigger)

Set the number of bus transfers the channel will do.

static void dma_channel_configure (uint channel, const dma_channel_config *config, volatile void *write_addr, const volatile void *read_addr, uint transfer_count, bool trigger)

Configure all DMA parameters and optionally start transfer.

static void dma_channel_transfer_from_buffer_now (uint channel, const volatile void *read_addr, uint32_t transfer_count)

Start a DMA transfer from a buffer immediately.

static void dma_channel_transfer_to_buffer_now (uint channel, volatile void *write_addr, uint32_t transfer_count)

Start a DMA transfer to a buffer immediately.

static void dma_start_channel_mask (uint32_t chan_mask)

Start one or more channels simultaneously.

static void dma_channel_start (uint channel)

Start a single DMA channel.

static void dma_channel_abort (uint channel)

Stop a DMA transfer.

static void dma_channel_set_irq0_enabled (uint channel, bool enabled)

Enable single DMA channel’s interrupt via DMA_IRQ_0.

static void dma_set_irq0_channel_mask_enabled (uint32_t channel_mask, bool enabled)

Enable multiple DMA channels' interrupts via DMA_IRQ_0.

static void dma_channel_set_irq1_enabled (uint channel, bool enabled)

Enable single DMA channel’s interrupt via DMA_IRQ_1.

static void dma_set_irq1_channel_mask_enabled (uint32_t channel_mask, bool enabled)

Enable multiple DMA channels' interrupts via DMA_IRQ_1.

static void dma_irqn_set_channel_enabled (uint irq_index, uint channel, bool enabled)

Enable single DMA channel interrupt on either DMA_IRQ_0 or DMA_IRQ_1.

static void dma_irqn_set_channel_mask_enabled (uint irq_index, uint32_t channel_mask, bool enabled)

Enable multiple DMA channels' interrupt via either DMA_IRQ_0 or DMA_IRQ_1.

static bool dma_channel_get_irq0_status (uint channel)

Determine if a particular channel is a cause of DMA_IRQ_0.

static bool dma_channel_get_irq1_status (uint channel)

Determine if a particular channel is a cause of DMA_IRQ_1.

static bool dma_irqn_get_channel_status (uint irq_index, uint channel)

Determine if a particular channel is a cause of DMA_IRQ_N.

static void dma_channel_acknowledge_irq0 (uint channel)

Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_0.

static void dma_channel_acknowledge_irq1 (uint channel)

Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_1.

static void dma_irqn_acknowledge_channel (uint irq_index, uint channel)

Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_N.

static bool dma_channel_is_busy (uint channel)

Check if DMA channel is busy.

static void dma_channel_wait_for_finish_blocking (uint channel)

Wait for a DMA channel transfer to complete.

static void dma_sniffer_enable (uint channel, uint mode, bool force_channel_enable)

Enable the DMA sniffing targeting the specified channel.

static void dma_sniffer_set_byte_swap_enabled (bool swap)

Enable the Sniffer byte swap function.

static void dma_sniffer_set_output_invert_enabled (bool invert)

Enable the Sniffer output invert function.

static void dma_sniffer_set_output_reverse_enabled (bool reverse)

Enable the Sniffer output bit reversal function.

static void dma_sniffer_disable (void)

Disable the DMA sniffer.

static void dma_sniffer_set_data_accumulator (uint32_t seed_value)

Set the sniffer’s data accumulator with initial value.

static uint32_t dma_sniffer_get_data_accumulator (void)

Get the sniffer’s data accumulator value.

void dma_timer_claim (uint timer)

Mark a dma timer as used.

void dma_timer_unclaim (uint timer)

Mark a dma timer as no longer used.

int dma_claim_unused_timer (bool required)

Claim a free dma timer.

bool dma_timer_is_claimed (uint timer)

Determine if a dma timer is claimed.

static void dma_timer_set_fraction (uint timer, uint16_t numerator, uint16_t denominator)

Set the multiplier for the given DMA timer.

static uint dma_get_timer_dreq (uint timer_num)

Return the DREQ number for a given DMA timer.

static int dma_get_irq_num (uint irq_index)

Return DMA_IRQ_<irqn>

void dma_channel_cleanup (uint channel)

Performs DMA channel cleanup after use.

Macro Definition Documentation

DMA_IRQ_NUM

#define DMA_IRQ_NUM(irq_index)

Returns the irq_num_t for the nth DMA interrupt.

Note this macro is intended to resolve at compile time, and does no parameter checking

Typedef Documentation

dreq_num_t RP2350

typedef enum dreq_num_rp2350 dreq_num_t

DREQ numbers for DMA pacing on RP2350 (used as typedef dreq_num_t)

dreq_num_t RP2040

typedef enum dreq_num_rp2040 dreq_num_t

DREQ numbers for DMA pacing on RP2040 (used as typedef dreq_num_t)

Enumeration Type Documentation

dreq_num_rp2350 RP2350

enum dreq_num_rp2350

DREQ numbers for DMA pacing on RP2350 (used as typedef dreq_num_t)

Table 5. Enumerator

DREQ_PIO0_TX0

Select PIO0’s TX FIFO 0 as DREQ.

DREQ_PIO0_TX1

Select PIO0’s TX FIFO 1 as DREQ.

DREQ_PIO0_TX2

Select PIO0’s TX FIFO 2 as DREQ.

DREQ_PIO0_TX3

Select PIO0’s TX FIFO 3 as DREQ.

DREQ_PIO0_RX0

Select PIO0’s RX FIFO 0 as DREQ.

DREQ_PIO0_RX1

Select PIO0’s RX FIFO 1 as DREQ.

DREQ_PIO0_RX2

Select PIO0’s RX FIFO 2 as DREQ.

DREQ_PIO0_RX3

Select PIO0’s RX FIFO 3 as DREQ.

DREQ_PIO1_TX0

Select PIO1’s TX FIFO 0 as DREQ.

DREQ_PIO1_TX1

Select PIO1’s TX FIFO 1 as DREQ.

DREQ_PIO1_TX2

Select PIO1’s TX FIFO 2 as DREQ.

DREQ_PIO1_TX3

Select PIO1’s TX FIFO 3 as DREQ.

DREQ_PIO1_RX0

Select PIO1’s RX FIFO 0 as DREQ.

DREQ_PIO1_RX1

Select PIO1’s RX FIFO 1 as DREQ.

DREQ_PIO1_RX2

Select PIO1’s RX FIFO 2 as DREQ.

DREQ_PIO1_RX3

Select PIO1’s RX FIFO 3 as DREQ.

DREQ_PIO2_TX0

Select PIO2’s TX FIFO 0 as DREQ.

DREQ_PIO2_TX1

Select PIO2’s TX FIFO 1 as DREQ.

DREQ_PIO2_TX2

Select PIO2’s TX FIFO 2 as DREQ.

DREQ_PIO2_TX3

Select PIO2’s TX FIFO 3 as DREQ.

DREQ_PIO2_RX0

Select PIO2’s RX FIFO 0 as DREQ.

DREQ_PIO2_RX1

Select PIO2’s RX FIFO 1 as DREQ.

DREQ_PIO2_RX2

Select PIO2’s RX FIFO 2 as DREQ.

DREQ_PIO2_RX3

Select PIO2’s RX FIFO 3 as DREQ.

DREQ_SPI0_TX

Select SPI0’s TX FIFO as DREQ.

DREQ_SPI0_RX

Select SPI0’s RX FIFO as DREQ.

DREQ_SPI1_TX

Select SPI1’s TX FIFO as DREQ.

DREQ_SPI1_RX

Select SPI1’s RX FIFO as DREQ.

DREQ_UART0_TX

Select UART0’s TX FIFO as DREQ.

DREQ_UART0_RX

Select UART0’s RX FIFO as DREQ.

DREQ_UART1_TX

Select UART1’s TX FIFO as DREQ.

DREQ_UART1_RX

Select UART1’s RX FIFO as DREQ.

DREQ_PWM_WRAP0

Select PWM Counter 0’s Wrap Value as DREQ.

DREQ_PWM_WRAP1

Select PWM Counter 1’s Wrap Value as DREQ.

DREQ_PWM_WRAP2

Select PWM Counter 2’s Wrap Value as DREQ.

DREQ_PWM_WRAP3

Select PWM Counter 3’s Wrap Value as DREQ.

DREQ_PWM_WRAP4

Select PWM Counter 4’s Wrap Value as DREQ.

DREQ_PWM_WRAP5

Select PWM Counter 5’s Wrap Value as DREQ.

DREQ_PWM_WRAP6

Select PWM Counter 6’s Wrap Value as DREQ.

DREQ_PWM_WRAP7

Select PWM Counter 7’s Wrap Value as DREQ.

DREQ_PWM_WRAP8

Select PWM Counter 8’s Wrap Value as DREQ.

DREQ_PWM_WRAP9

Select PWM Counter 9’s Wrap Value as DREQ.

DREQ_PWM_WRAP10

Select PWM Counter 0’s Wrap Value as DREQ.

DREQ_PWM_WRAP11

Select PWM Counter 1’s Wrap Value as DREQ.

DREQ_I2C0_TX

Select I2C0’s TX FIFO as DREQ.

DREQ_I2C0_RX

Select I2C0’s RX FIFO as DREQ.

DREQ_I2C1_TX

Select I2C1’s TX FIFO as DREQ.

DREQ_I2C1_RX

Select I2C1’s RX FIFO as DREQ.

DREQ_ADC

Select the ADC as DREQ.

DREQ_XIP_STREAM

Select the XIP Streaming FIFO as DREQ.

DREQ_XIP_QMITX

Select XIP_QMITX as DREQ.

DREQ_XIP_QMIRX

Select XIP_QMIRX as DREQ.

DREQ_HSTX

Select HSTX as DREQ.

DREQ_CORESIGHT

Select CORESIGHT as DREQ.

DREQ_SHA256

Select SHA256 as DREQ.

DREQ_DMA_TIMER0

Select DMA_TIMER0 as DREQ.

DREQ_DMA_TIMER1

Select DMA_TIMER0 as DREQ.

DREQ_DMA_TIMER2

Select DMA_TIMER1 as DREQ.

DREQ_DMA_TIMER3

Select DMA_TIMER3 as DREQ.

DREQ_FORCE

Select FORCE as DREQ.

dreq_num_rp2040 RP2040

enum dreq_num_rp2040

DREQ numbers for DMA pacing on RP2040 (used as typedef dreq_num_t)

Table 6. Enumerator

DREQ_PIO0_TX0

Select PIO0’s TX FIFO 0 as DREQ.

DREQ_PIO0_TX1

Select PIO0’s TX FIFO 1 as DREQ.

DREQ_PIO0_TX2

Select PIO0’s TX FIFO 2 as DREQ.

DREQ_PIO0_TX3

Select PIO0’s TX FIFO 3 as DREQ.

DREQ_PIO0_RX0

Select PIO0’s RX FIFO 0 as DREQ.

DREQ_PIO0_RX1

Select PIO0’s RX FIFO 1 as DREQ.

DREQ_PIO0_RX2

Select PIO0’s RX FIFO 2 as DREQ.

DREQ_PIO0_RX3

Select PIO0’s RX FIFO 3 as DREQ.

DREQ_PIO1_TX0

Select PIO1’s TX FIFO 0 as DREQ.

DREQ_PIO1_TX1

Select PIO1’s TX FIFO 1 as DREQ.

DREQ_PIO1_TX2

Select PIO1’s TX FIFO 2 as DREQ.

DREQ_PIO1_TX3

Select PIO1’s TX FIFO 3 as DREQ.

DREQ_PIO1_RX0

Select PIO1’s RX FIFO 0 as DREQ.

DREQ_PIO1_RX1

Select PIO1’s RX FIFO 1 as DREQ.

DREQ_PIO1_RX2

Select PIO1’s RX FIFO 2 as DREQ.

DREQ_PIO1_RX3

Select PIO1’s RX FIFO 3 as DREQ.

DREQ_SPI0_TX

Select SPI0’s TX FIFO as DREQ.

DREQ_SPI0_RX

Select SPI0’s RX FIFO as DREQ.

DREQ_SPI1_TX

Select SPI1’s TX FIFO as DREQ.

DREQ_SPI1_RX

Select SPI1’s RX FIFO as DREQ.

DREQ_UART0_TX

Select UART0’s TX FIFO as DREQ.

DREQ_UART0_RX

Select UART0’s RX FIFO as DREQ.

DREQ_UART1_TX

Select UART1’s TX FIFO as DREQ.

DREQ_UART1_RX

Select UART1’s RX FIFO as DREQ.

DREQ_PWM_WRAP0

Select PWM Counter 0’s Wrap Value as DREQ.

DREQ_PWM_WRAP1

Select PWM Counter 1’s Wrap Value as DREQ.

DREQ_PWM_WRAP2

Select PWM Counter 2’s Wrap Value as DREQ.

DREQ_PWM_WRAP3

Select PWM Counter 3’s Wrap Value as DREQ.

DREQ_PWM_WRAP4

Select PWM Counter 4’s Wrap Value as DREQ.

DREQ_PWM_WRAP5

Select PWM Counter 5’s Wrap Value as DREQ.

DREQ_PWM_WRAP6

Select PWM Counter 6’s Wrap Value as DREQ.

DREQ_PWM_WRAP7

Select PWM Counter 7’s Wrap Value as DREQ.

DREQ_I2C0_TX

Select I2C0’s TX FIFO as DREQ.

DREQ_I2C0_RX

Select I2C0’s RX FIFO as DREQ.

DREQ_I2C1_TX

Select I2C1’s TX FIFO as DREQ.

DREQ_I2C1_RX

Select I2C1’s RX FIFO as DREQ.

DREQ_ADC

Select the ADC as DREQ.

DREQ_XIP_STREAM

Select the XIP Streaming FIFO as DREQ.

DREQ_XIP_SSITX

Select the XIP SSI TX FIFO as DREQ.

DREQ_XIP_SSIRX

Select the XIP SSI RX FIFO as DREQ.

DREQ_DMA_TIMER0

Select DMA_TIMER0 as DREQ.

DREQ_DMA_TIMER1

Select DMA_TIMER0 as DREQ.

DREQ_DMA_TIMER2

Select DMA_TIMER1 as DREQ.

DREQ_DMA_TIMER3

Select DMA_TIMER3 as DREQ.

DREQ_FORCE

Select FORCE as DREQ.

dma_channel_transfer_size

enum dma_channel_transfer_size

Enumeration of available DMA channel transfer sizes.

Names indicate the number of bits.

Table 7. Enumerator

DMA_SIZE_8

Byte transfer (8 bits)

DMA_SIZE_16

Half word transfer (16 bits)

DMA_SIZE_32

Word transfer (32 bits)

Function Documentation

dma_channel_abort

static void dma_channel_abort (uint channel) [inline], [static]

Stop a DMA transfer.

Function will only return once the DMA has stopped.

RP2040 only: Note that due to errata RP2040-E13, aborting a channel which has transfers in-flight (i.e. an individual read has taken place but the corresponding write has not), the ABORT status bit will clear prematurely, and subsequently the in-flight transfers will trigger a completion interrupt once they complete.

The effect of this is that you may see a spurious completion interrupt on the channel as a result of calling this method.

The calling code should be sure to ignore a completion IRQ as a result of this method. This may not require any additional work, as aborting a channel which may be about to complete, when you have a completion IRQ handler registered, is inherently race-prone, and so code is likely needed to disambiguate the two occurrences.

If that is not the case, but you do have a channel completion IRQ handler registered, you can simply disable/re-enable the IRQ around the call to this method as shown by this code fragment (using DMA IRQ0).

1
2
3
4
5
6
7
8
// disable the channel on IRQ0
dma_channel_set_irq0_enabled(channel, false);
// abort the channel
dma_channel_abort(channel);
// clear the spurious IRQ (if there was one)
dma_channel_acknowledge_irq0(channel);
// re-enable the channel on IRQ0
dma_channel_set_irq0_enabled(channel, true);

RP2350 only: Due to errata RP2350-E5 (see the RP2350 datasheet for further detail), it is necessary to clear the enable bit of the aborted channel and any chained channels prior to the abort to prevent re-triggering.

Parameters

channel

DMA channel

dma_channel_acknowledge_irq0

static void dma_channel_acknowledge_irq0 (uint channel) [inline], [static]

Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_0.

Parameters

channel

DMA channel

dma_channel_acknowledge_irq1

static void dma_channel_acknowledge_irq1 (uint channel) [inline], [static]

Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_1.

Parameters

channel

DMA channel

dma_channel_claim

void dma_channel_claim (uint channel)

Mark a dma channel as used.

Method for cooperative claiming of hardware. Will cause a panic if the channel is already claimed. Use of this method by libraries detects accidental configurations that would fail in unpredictable ways.

Parameters

channel

the dma channel

dma_channel_cleanup

void dma_channel_cleanup (uint channel)

Performs DMA channel cleanup after use.

This can be used to cleanup dma channels when they’re no longer needed, such that they are in a clean state for reuse. IRQ’s for the channel are disabled, any in flight-transfer is aborted and any outstanding interrupts are cleared. The channel is then clear to be reused for other purposes.

1
2
3
4
5
if (dma_channel >= 0) {
    dma_channel_cleanup(dma_channel);
    dma_channel_unclaim(dma_channel);
    dma_channel = -1;
}

Parameters

channel

DMA channel

dma_channel_configure

static void dma_channel_configure (uint channel, const dma_channel_config * config, volatile void * write_addr, const volatile void * read_addr, uint transfer_count, bool trigger) [inline], [static]

Configure all DMA parameters and optionally start transfer.

Parameters

channel

DMA channel

config

Pointer to DMA config structure

write_addr

Initial write address

read_addr

Initial read address

transfer_count

Number of transfers to perform

trigger

True to start the transfer immediately

dma_channel_get_irq0_status

static bool dma_channel_get_irq0_status (uint channel) [inline], [static]

Determine if a particular channel is a cause of DMA_IRQ_0.

Parameters

channel

DMA channel

Returns

true if the channel is a cause of DMA_IRQ_0, false otherwise

dma_channel_get_irq1_status

static bool dma_channel_get_irq1_status (uint channel) [inline], [static]

Determine if a particular channel is a cause of DMA_IRQ_1.

Parameters

channel

DMA channel

Returns

true if the channel is a cause of DMA_IRQ_1, false otherwise

dma_channel_is_busy

static bool dma_channel_is_busy (uint channel) [inline], [static]

Check if DMA channel is busy.

Parameters

channel

DMA channel

Returns

true if the channel is currently busy

dma_channel_is_claimed

bool dma_channel_is_claimed (uint channel)

Determine if a dma channel is claimed.

Parameters

channel

the dma channel

Returns

true if the channel is claimed, false otherwise

See also

dma_channel_claim_mask

dma_channel_set_config

static void dma_channel_set_config (uint channel, const dma_channel_config * config, bool trigger) [inline], [static]

Set a channel configuration.

Parameters

channel

DMA channel

config

Pointer to a config structure with required configuration

trigger

True to trigger the transfer immediately

dma_channel_set_irq0_enabled

static void dma_channel_set_irq0_enabled (uint channel, bool enabled) [inline], [static]

Enable single DMA channel’s interrupt via DMA_IRQ_0.

Parameters

channel

DMA channel

enabled

true to enable interrupt 0 on specified channel, false to disable.

dma_channel_set_irq1_enabled

static void dma_channel_set_irq1_enabled (uint channel, bool enabled) [inline], [static]

Enable single DMA channel’s interrupt via DMA_IRQ_1.

Parameters

channel

DMA channel

enabled

true to enable interrupt 1 on specified channel, false to disable.

dma_channel_set_read_addr

static void dma_channel_set_read_addr (uint channel, const volatile void * read_addr, bool trigger) [inline], [static]

Set the DMA initial read address.

Parameters

channel

DMA channel

read_addr

Initial read address of transfer.

trigger

True to start the transfer immediately

dma_channel_set_trans_count

static void dma_channel_set_trans_count (uint channel, uint32_t trans_count, bool trigger) [inline], [static]

Set the number of bus transfers the channel will do.

Parameters

channel

DMA channel

trans_count

The number of transfers (not NOT bytes, see channel_config_set_transfer_data_size)

trigger

True to start the transfer immediately

dma_channel_set_write_addr

static void dma_channel_set_write_addr (uint channel, volatile void * write_addr, bool trigger) [inline], [static]

Set the DMA initial write address.

Parameters

channel

DMA channel

write_addr

Initial write address of transfer.

trigger

True to start the transfer immediately

dma_channel_start

static void dma_channel_start (uint channel) [inline], [static]

Start a single DMA channel.

Parameters

channel

DMA channel

dma_channel_transfer_from_buffer_now

static void dma_channel_transfer_from_buffer_now (uint channel, const volatile void * read_addr, uint32_t transfer_count) [inline], [static]

Start a DMA transfer from a buffer immediately.

Parameters

channel

DMA channel

read_addr

Sets the initial read address

transfer_count

Number of transfers to make. Not bytes, but the number of transfers of channel_config_set_transfer_data_size() to be sent.

dma_channel_transfer_to_buffer_now

static void dma_channel_transfer_to_buffer_now (uint channel, volatile void * write_addr, uint32_t transfer_count) [inline], [static]

Start a DMA transfer to a buffer immediately.

Parameters

channel

DMA channel

write_addr

Sets the initial write address

transfer_count

Number of transfers to make. Not bytes, but the number of transfers of channel_config_set_transfer_data_size() to be sent.

dma_channel_unclaim

void dma_channel_unclaim (uint channel)

Mark a dma channel as no longer used.

Parameters

channel

the dma channel to release

dma_channel_wait_for_finish_blocking

static void dma_channel_wait_for_finish_blocking (uint channel) [inline], [static]

Wait for a DMA channel transfer to complete.

Parameters

channel

DMA channel

dma_claim_mask

void dma_claim_mask (uint32_t channel_mask)

Mark multiple dma channels as used.

Method for cooperative claiming of hardware. Will cause a panic if any of the channels are already claimed. Use of this method by libraries detects accidental configurations that would fail in unpredictable ways.

Parameters

channel_mask

Bitfield of all required channels to claim (bit 0 == channel 0, bit 1 == channel 1 etc)

dma_claim_unused_channel

int dma_claim_unused_channel (bool required)

Claim a free dma channel.

Parameters

required

if true the function will panic if none are available

Returns

the dma channel number or -1 if required was false, and none were free

dma_claim_unused_timer

int dma_claim_unused_timer (bool required)

Claim a free dma timer.

Parameters

required

if true the function will panic if none are available

Returns

the dma timer number or -1 if required was false, and none were free

dma_get_irq_num

static int dma_get_irq_num (uint irq_index) [inline], [static]

Return DMA_IRQ_<irqn>

Parameters

irq_index

0 the DMA irq index

Returns

The irq_num_t to use for DMA

dma_get_timer_dreq

static uint dma_get_timer_dreq (uint timer_num) [inline], [static]

Return the DREQ number for a given DMA timer.

Parameters

timer_num

DMA timer number 0-3

dma_irqn_acknowledge_channel

static void dma_irqn_acknowledge_channel (uint irq_index, uint channel) [inline], [static]

Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_N.

Parameters

irq_index

the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1

channel

DMA channel

dma_irqn_get_channel_status

static bool dma_irqn_get_channel_status (uint irq_index, uint channel) [inline], [static]

Determine if a particular channel is a cause of DMA_IRQ_N.

Parameters

irq_index

the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1

channel

DMA channel

Returns

true if the channel is a cause of the DMA_IRQ_N, false otherwise

dma_irqn_set_channel_enabled

static void dma_irqn_set_channel_enabled (uint irq_index, uint channel, bool enabled) [inline], [static]

Enable single DMA channel interrupt on either DMA_IRQ_0 or DMA_IRQ_1.

Parameters

irq_index

the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1

channel

DMA channel

enabled

true to enable interrupt via irq_index for specified channel, false to disable.

dma_irqn_set_channel_mask_enabled

static void dma_irqn_set_channel_mask_enabled (uint irq_index, uint32_t channel_mask, bool enabled) [inline], [static]

Enable multiple DMA channels' interrupt via either DMA_IRQ_0 or DMA_IRQ_1.

Parameters

irq_index

the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1

channel_mask

Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.

enabled

true to enable all the interrupts specified in the mask, false to disable all the interrupts specified in the mask.

dma_set_irq0_channel_mask_enabled

static void dma_set_irq0_channel_mask_enabled (uint32_t channel_mask, bool enabled) [inline], [static]

Enable multiple DMA channels' interrupts via DMA_IRQ_0.

Parameters

channel_mask

Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.

enabled

true to enable all the interrupts specified in the mask, false to disable all the interrupts specified in the mask.

dma_set_irq1_channel_mask_enabled

static void dma_set_irq1_channel_mask_enabled (uint32_t channel_mask, bool enabled) [inline], [static]

Enable multiple DMA channels' interrupts via DMA_IRQ_1.

Parameters

channel_mask

Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.

enabled

true to enable all the interrupts specified in the mask, false to disable all the interrupts specified in the mask.

dma_sniffer_disable

static void dma_sniffer_disable (void) [inline], [static]

Disable the DMA sniffer.

dma_sniffer_enable

static void dma_sniffer_enable (uint channel, uint mode, bool force_channel_enable) [inline], [static]

Enable the DMA sniffing targeting the specified channel.

The mode can be one of the following:

Mode Function

0x0

Calculate a CRC-32 (IEEE802.3 polynomial)

0x1

Calculate a CRC-32 (IEEE802.3 polynomial) with bit reversed data

0x2

Calculate a CRC-16-CCITT

0x3

Calculate a CRC-16-CCITT with bit reversed data

0xe

XOR reduction over all data. == 1 if the total 1 population count is odd.

0xf

Calculate a simple 32-bit checksum (addition with a 32 bit accumulator)

Parameters

channel

DMA channel

mode

See description

force_channel_enable

Set true to also turn on sniffing in the channel configuration (this is usually what you want, but sometimes you might have a chain DMA with only certain segments of the chain sniffed, in which case you might pass false).

dma_sniffer_get_data_accumulator

static uint32_t dma_sniffer_get_data_accumulator (void) [inline], [static]

Get the sniffer’s data accumulator value.

Read value calculated by the hardware from sniffing the DMA stream

dma_sniffer_set_byte_swap_enabled

static void dma_sniffer_set_byte_swap_enabled (bool swap) [inline], [static]

Enable the Sniffer byte swap function.

Locally perform a byte reverse on the sniffed data, before feeding into checksum.

Note that the sniff hardware is downstream of the DMA channel byteswap performed in the read master: if channel_config_set_bswap() and dma_sniffer_set_byte_swap_enabled() are both enabled, their effects cancel from the sniffer’s point of view.

Parameters

swap

Set true to enable byte swapping

dma_sniffer_set_data_accumulator

static void dma_sniffer_set_data_accumulator (uint32_t seed_value) [inline], [static]

Set the sniffer’s data accumulator with initial value.

Generally, CRC algorithms are used with the data accumulator initially seeded with 0xFFFF or 0xFFFFFFFF (for crc16 and crc32 algorithms)

Parameters

seed_value

value to set data accumulator

dma_sniffer_set_output_invert_enabled

static void dma_sniffer_set_output_invert_enabled (bool invert) [inline], [static]

Enable the Sniffer output invert function.

If enabled, the sniff data result appears bit-inverted when read. This does not affect the way the checksum is calculated.

Parameters

invert

Set true to enable output bit inversion

dma_sniffer_set_output_reverse_enabled

static void dma_sniffer_set_output_reverse_enabled (bool reverse) [inline], [static]

Enable the Sniffer output bit reversal function.

If enabled, the sniff data result appears bit-reversed when read. This does not affect the way the checksum is calculated.

Parameters

reverse

Set true to enable output bit reversal

dma_start_channel_mask

static void dma_start_channel_mask (uint32_t chan_mask) [inline], [static]

Start one or more channels simultaneously.

Parameters

chan_mask

Bitmask of all the channels requiring starting. Channel 0 = bit 0, channel 1 = bit 1 etc.

dma_timer_claim

void dma_timer_claim (uint timer)

Mark a dma timer as used.

Method for cooperative claiming of hardware. Will cause a panic if the timer is already claimed. Use of this method by libraries detects accidental configurations that would fail in unpredictable ways.

Parameters

timer

the dma timer

dma_timer_is_claimed

bool dma_timer_is_claimed (uint timer)

Determine if a dma timer is claimed.

Parameters

timer

the dma timer

Returns

true if the timer is claimed, false otherwise

See also

dma_timer_set_fraction

static void dma_timer_set_fraction (uint timer, uint16_t numerator, uint16_t denominator) [inline], [static]

Set the multiplier for the given DMA timer.

The timer will run at the system_clock_freq * numerator / denominator, so this is the speed that data elements will be transferred at via a DMA channel using this timer as a DREQ. The multiplier must be less than or equal to one.

Parameters

timer

the dma timer

numerator

the fraction’s numerator

denominator

the fraction’s denominator

dma_timer_unclaim

void dma_timer_unclaim (uint timer)

Mark a dma timer as no longer used.

Method for cooperative claiming of hardware.

Parameters

timer

the dma timer to release

dma_unclaim_mask

void dma_unclaim_mask (uint32_t channel_mask)

Mark multiple dma channels as no longer used.

Parameters

channel_mask

Bitfield of all channels to unclaim (bit 0 == channel 0, bit 1 == channel 1 etc)

channel_config

DMA channel configuration .

Detailed Description

A DMA channel needs to be configured, these functions provide handy helpers to set up configuration structures. See dma_channel_config

Functions

static void channel_config_set_read_increment (dma_channel_config *c, bool incr)

Set DMA channel read increment in a channel configuration object.

static void channel_config_set_write_increment (dma_channel_config *c, bool incr)

Set DMA channel write increment in a channel configuration object.

static void channel_config_set_dreq (dma_channel_config *c, uint dreq)

Select a transfer request signal in a channel configuration object.

static void channel_config_set_chain_to (dma_channel_config *c, uint chain_to)

Set DMA channel chain_to channel in a channel configuration object.

static void channel_config_set_transfer_data_size (dma_channel_config *c, enum dma_channel_transfer_size size)

Set the size of each DMA bus transfer in a channel configuration object.

static void channel_config_set_ring (dma_channel_config *c, bool write, uint size_bits)

Set address wrapping parameters in a channel configuration object.

static void channel_config_set_bswap (dma_channel_config *c, bool bswap)

Set DMA byte swapping config in a channel configuration object.

static void channel_config_set_irq_quiet (dma_channel_config *c, bool irq_quiet)

Set IRQ quiet mode in a channel configuration object.

static void channel_config_set_high_priority (dma_channel_config *c, bool high_priority)

Set the channel priority in a channel configuration object.

static void channel_config_set_enable (dma_channel_config *c, bool enable)

Enable/Disable the DMA channel in a channel configuration object.

static void channel_config_set_sniff_enable (dma_channel_config *c, bool sniff_enable)

Enable access to channel by sniff hardware in a channel configuration object.

static dma_channel_config dma_channel_get_default_config (uint channel)

Get the default channel configuration for a given channel.

static dma_channel_config dma_get_channel_config (uint channel)

Get the current configuration for the specified channel.

static uint32_t channel_config_get_ctrl_value (const dma_channel_config *config)

Get the raw configuration register from a channel configuration.

Function Documentation

channel_config_get_ctrl_value

static uint32_t channel_config_get_ctrl_value (const dma_channel_config * config) [inline], [static]

Get the raw configuration register from a channel configuration.

Parameters

config

Pointer to a config structure.

Returns

Register content

channel_config_set_bswap

static void channel_config_set_bswap (dma_channel_config * c, bool bswap) [inline], [static]

Set DMA byte swapping config in a channel configuration object.

No effect for byte data, for halfword data, the two bytes of each halfword are swapped. For word data, the four bytes of each word are swapped to reverse their order.

Parameters

c

Pointer to channel configuration object

bswap

True to enable byte swapping

channel_config_set_chain_to

static void channel_config_set_chain_to (dma_channel_config * c, uint chain_to) [inline], [static]

Set DMA channel chain_to channel in a channel configuration object.

When this channel completes, it will trigger the channel indicated by chain_to. Disable by setting chain_to to itself (the same channel)

Parameters

c

Pointer to channel configuration object

chain_to

Channel to trigger when this channel completes.

channel_config_set_dreq

static void channel_config_set_dreq (dma_channel_config * c, uint dreq) [inline], [static]

Select a transfer request signal in a channel configuration object.

The channel uses the transfer request signal to pace its data transfer rate. Sources for TREQ signals are internal (TIMERS) or external (DREQ, a Data Request from the system). 0x0 to 0x3a -> select DREQ n as TREQ 0x3b -> Select Timer 0 as TREQ 0x3c -> Select Timer 1 as TREQ 0x3d -> Select Timer 2 as TREQ (Optional) 0x3e -> Select Timer 3 as TREQ (Optional) 0x3f -> Permanent request, for unpaced transfers.

Parameters

c

Pointer to channel configuration data

dreq

Source (see description)

channel_config_set_enable

static void channel_config_set_enable (dma_channel_config * c, bool enable) [inline], [static]

Enable/Disable the DMA channel in a channel configuration object.

When false, the channel will ignore triggers, stop issuing transfers, and pause the current transfer sequence (i.e. BUSY will remain high if already high)

Parameters

c

Pointer to channel configuration object

enable

True to enable the DMA channel. When enabled, the channel will respond to triggering events, and start transferring data.

channel_config_set_high_priority

static void channel_config_set_high_priority (dma_channel_config * c, bool high_priority) [inline], [static]

Set the channel priority in a channel configuration object.

When true, gives a channel preferential treatment in issue scheduling: in each scheduling round, all high priority channels are considered first, and then only a single low priority channel, before returning to the high priority channels.

This only affects the order in which the DMA schedules channels. The DMA’s bus priority is not changed. If the DMA is not saturated then a low priority channel will see no loss of throughput.

Parameters

c

Pointer to channel configuration object

high_priority

True to enable high priority

channel_config_set_irq_quiet

static void channel_config_set_irq_quiet (dma_channel_config * c, bool irq_quiet) [inline], [static]

Set IRQ quiet mode in a channel configuration object.

In QUIET mode, the channel does not generate IRQs at the end of every transfer block. Instead, an IRQ is raised when NULL is written to a trigger register, indicating the end of a control block chain.

Parameters

c

Pointer to channel configuration object

irq_quiet

True to enable quiet mode, false to disable.

channel_config_set_read_increment

static void channel_config_set_read_increment (dma_channel_config * c, bool incr) [inline], [static]

Set DMA channel read increment in a channel configuration object.

Parameters

c

Pointer to channel configuration object

incr

True to enable read address increments, if false, each read will be from the same address Usually disabled for peripheral to memory transfers

channel_config_set_ring

static void channel_config_set_ring (dma_channel_config * c, bool write, uint size_bits) [inline], [static]

Set address wrapping parameters in a channel configuration object.

Size of address wrap region. If 0, don’t wrap. For values n > 0, only the lower n bits of the address will change. This wraps the address on a (1 << n) byte boundary, facilitating access to naturally-aligned ring buffers. Ring sizes between 2 and 32768 bytes are possible (size_bits from 1 - 15)

0x0 -> No wrapping.

Parameters

c

Pointer to channel configuration object

write

True to apply to write addresses, false to apply to read addresses

size_bits

0 to disable wrapping. Otherwise the size in bits of the changing part of the address. Effectively wraps the address on a (1 << size_bits) byte boundary.

channel_config_set_sniff_enable

static void channel_config_set_sniff_enable (dma_channel_config * c, bool sniff_enable) [inline], [static]

Enable access to channel by sniff hardware in a channel configuration object.

Sniff HW must be enabled and have this channel selected.

Parameters

c

Pointer to channel configuration object

sniff_enable

True to enable the Sniff HW access to this DMA channel.

channel_config_set_transfer_data_size

static void channel_config_set_transfer_data_size (dma_channel_config * c, enum dma_channel_transfer_size size) [inline], [static]

Set the size of each DMA bus transfer in a channel configuration object.

Set the size of each bus transfer (byte/halfword/word). The read and write addresses advance by the specific amount (1/2/4 bytes) with each transfer.

Parameters

c

Pointer to channel configuration object

size

See enum for possible values.

channel_config_set_write_increment

static void channel_config_set_write_increment (dma_channel_config * c, bool incr) [inline], [static]

Set DMA channel write increment in a channel configuration object.

Parameters

c

Pointer to channel configuration object

incr

True to enable write address increments, if false, each write will be to the same address Usually disabled for memory to peripheral transfers

dma_channel_get_default_config

static dma_channel_config dma_channel_get_default_config (uint channel) [inline], [static]

Get the default channel configuration for a given channel.

Setting Default

Read Increment

true

Write Increment

false

DReq

DREQ_FORCE

Chain to

self

Data size

DMA_SIZE_32

Ring

write=false, size=0 (i.e. off)

Byte Swap

false

Quiet IRQs

false

High Priority

false

Channel Enable

true

Sniff Enable

false

Parameters

channel

DMA channel

Returns

the default configuration which can then be modified.

dma_get_channel_config

static dma_channel_config dma_get_channel_config (uint channel) [inline], [static]

Get the current configuration for the specified channel.

Parameters

channel

DMA channel

Returns

The current configuration as read from the HW register (not cached)

hardware_exception

Methods for setting processor exception handlers.

Detailed Description

Exceptions are identified by a exception_number which is a number from -15 to -1; these are the numbers relative to the index of the first IRQ vector in the vector table. (i.e. vector table index is exception_num plus 16)

There is one set of exception handlers per core, so the exception handlers for each core as set by these methods are independent.

Note

That all exception APIs affect the executing core only (i.e. the core calling the function).

Typedefs

typedef void(* exception_handler_t)(void)

Exception handler function type.

Enumerations

enum exception_number { MIN_EXCEPTION_NUM = 2, NMI_EXCEPTION = 2, HARDFAULT_EXCEPTION = 3, MEMMANAGE_EXCEPTION = 4, BUSFAULT_EXCEPTION = 5, USAGEFAULT_EXCEPTION = 6, SECUREFAULT_EXCEPTION = 7, SVCALL_EXCEPTION = 11, PENDSV_EXCEPTION = 14, SYSTICK_EXCEPTION = 15, MAX_EXCEPTION_NUM = 15 }

Exception number definitions.

Functions

exception_handler_t exception_set_exclusive_handler (enum exception_number num, exception_handler_t handler)

Set the exception handler for an exception on the executing core.

void exception_restore_handler (enum exception_number num, exception_handler_t original_handler)

Restore the original exception handler for an exception on this core.

exception_handler_t exception_get_vtable_handler (enum exception_number num)

Get the current exception handler for the specified exception from the currently installed vector table of the execution core.

bool exception_set_priority (uint num, uint8_t hardware_priority)

Set specified exception’s priority.

uint exception_get_priority (uint num)

Get specified exception’s priority.

Typedef Documentation

exception_handler_t

typedef void(* exception_handler_t) (void)

Exception handler function type.

All exception handlers should be of this type, and follow normal ARM EABI register saving conventions

Enumeration Type Documentation

exception_number

enum exception_number

Exception number definitions.

On Arm these are vector table indices:

Name Value Exception

NMI_EXCEPTION

2

Non Maskable Interrupt

HARDFAULT_EXCEPTION

3

HardFault

MEMMANAGE_EXCEPTION | 4 | MemManage BUSFAULT_EXCEPTION | 5 | BusFault USAGEFAULT_EXCEPTION | 6 | UsageFault SECUREFAULT_EXCEPTION | 7 | SecureFault SVCALL_EXCEPTION | 11 | SV Call PENDSV_EXCEPTION | 14 | Pend SV SYSTICK_EXCEPTION | 15 | System Tick

On RISC-V these are exception cause numbers:

Name Value Exception

INSTR_ALIGN_EXCEPTION

0

Instruction fetch misaligned

INSTR_FAULT_EXCEPTION

1

Instruction fetch bus fault

INSTR_ILLEGAL_EXCEPTION

2

Invalid or illegal instruction

EBREAK_EXCEPTION

3

ebreak was not caught by an ex

LOAD_ALIGN_EXCEPTION

4

Load address not naturally ali

LOAD_FAULT_EXCEPTION

5

Load bus fault

STORE_ALIGN_EXCEPTION

6

Store or AMO address not natur

STORE_FAULT_EXCEPTION

7

Store or AMO bus fault

ECALL_UMODE_EXCEPTION

8

ecall was executed in U-mode

ECALL_SMODE_EXCEPTION

9

ecall was executed in S-mode

ECALL_MMODE_EXCEPTION

11

ecall was executed in M-mode

Table 8. Enumerator

NMI_EXCEPTION

Non Maskable Interrupt.

HARDFAULT_EXCEPTION

HardFault Interrupt.

MEMMANAGE_EXCEPTION

MemManage Interrupt.

BUSFAULT_EXCEPTION

BusFault Interrupt.

USAGEFAULT_EXCEPTION

UsageFault Interrupt.

SECUREFAULT_EXCEPTION

SecureFault Interrupt.

SVCALL_EXCEPTION

SV Call Interrupt.

PENDSV_EXCEPTION

Pend SV Interrupt.

SYSTICK_EXCEPTION

System Tick Interrupt.

Function Documentation

exception_get_priority

uint exception_get_priority (uint num)

Get specified exception’s priority.

Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority).

Only the top 2 bits are significant on ARM Cortex-M0+ on RP2040.

Only the top 4 bits are significant on ARM Cortex-M33 on RP2350, and exception priorities are not supported on RISC-V

Parameters

num

Exception number exception_number

Returns

the exception priority

exception_get_vtable_handler

exception_handler_t exception_get_vtable_handler (enum exception_number num)

Get the current exception handler for the specified exception from the currently installed vector table of the execution core.

Parameters

num

Exception number

Returns

the address stored in the VTABLE for the given exception number

exception_restore_handler

void exception_restore_handler (enum exception_number num, exception_handler_t original_handler)

Restore the original exception handler for an exception on this core.

This method may be used to restore the exception handler for an exception on this core to the state prior to the call to exception_set_exclusive_handler(), so that exception_set_exclusive_handler() may be called again in the future.

Parameters

num

Exception number exception_number

original_handler

The original handler returned from exception_set_exclusive_handler

exception_set_exclusive_handler

exception_handler_t exception_set_exclusive_handler (enum exception_number num, exception_handler_t handler)

Set the exception handler for an exception on the executing core.

This method will assert if an exception handler has been set for this exception number on this core via this method, without an intervening restore via exception_restore_handler.

Note

this method may not be used to override an exception handler that was specified at link time by providing a strong replacement for the weakly defined stub exception handlers. It will assert in this case too.

Parameters

num

Exception number

handler

The handler to set

See also

exception_set_priority

bool exception_set_priority (uint num, uint8_t hardware_priority)

Set specified exception’s priority.

Parameters

num

Exception number exception_number

hardware_priority

Priority to set.

Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority).

Only the top 2 bits are significant on ARM Cortex-M0+ on RP2040.

Only the top 4 bits are significant on ARM Cortex-M33 on RP2350, and exception priorities are not supported on RISC-V

hardware_flash

Low level flash programming and erase API.

Detailed Description

Note these functions are unsafe if you are using both cores, and the other is executing from flash concurrently with the operation. In this case, you must perform your own synchronisation to make sure that no XIP accesses take place during flash programming. One option is to use the lockout functions.

Likewise they are unsafe if you have interrupt handlers or an interrupt vector table in flash, so you must disable interrupts before calling in this case.

If PICO_NO_FLASH=1 is not defined (i.e. if the program is built to run from flash) then these functions will make a static copy of the second stage bootloader in SRAM, and use this to reenter execute-in-place mode after programming or erasing flash, so that they can safely be called from flash-resident code.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h>

#include "pico/stdlib.h"
#include "hardware/flash.h"

// We're going to erase and reprogram a region 256k from the start of flash.
// Once done, we can access this at XIP_BASE + 256k.
#define FLASH_TARGET_OFFSET (256 * 1024)

const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET);

void print_buf(const uint8_t *buf, size_t len) {
    for (size_t i = 0; i < len; ++i) {
        printf("%02x", buf[i]);
        if (i % 16 == 15)
            printf("\n");
        else
            printf(" ");
    }
}

int main() {
    stdio_init_all();
    uint8_t random_data[FLASH_PAGE_SIZE];
    for (uint i = 0; i < FLASH_PAGE_SIZE; ++i)
        random_data[i] = rand() >> 16;

    printf("Generated random data:\n");
    print_buf(random_data, FLASH_PAGE_SIZE);

    // Note that a whole number of sectors must be erased at a time.
    printf("\nErasing target region...\n");
    flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);
    printf("Done. Read back target region:\n");
    print_buf(flash_target_contents, FLASH_PAGE_SIZE);

    printf("\nProgramming target region...\n");
    flash_range_program(FLASH_TARGET_OFFSET, random_data, FLASH_PAGE_SIZE);
    printf("Done. Read back target region:\n");
    print_buf(flash_target_contents, FLASH_PAGE_SIZE);

    bool mismatch = false;
    for (uint i = 0; i < FLASH_PAGE_SIZE; ++i) {
        if (random_data[i] != flash_target_contents[i])
            mismatch = true;
    }
    if (mismatch)
        printf("Programming failed!\n");
    else
        printf("Programming successful!\n");
}

Functions

void flash_range_erase (uint32_t flash_offs, size_t count)

Erase areas of flash.

void flash_range_program (uint32_t flash_offs, const uint8_t *data, size_t count)

Program flash.

void flash_get_unique_id (uint8_t *id_out)

Get flash unique 64 bit identifier.

void flash_do_cmd (const uint8_t *txbuf, uint8_t *rxbuf, size_t count)

Execute bidirectional flash command.

Function Documentation

flash_do_cmd

void flash_do_cmd (const uint8_t * txbuf, uint8_t * rxbuf, size_t count)

Execute bidirectional flash command.

Low-level function to execute a serial command on a flash device attached to the QSPI interface. Bytes are simultaneously transmitted and received from txbuf and to rxbuf. Therefore, both buffers must be the same length, count, which is the length of the overall transaction. This is useful for reading metadata from the flash chip, such as device ID or SFDP parameters.

The XIP cache is flushed following each command, in case flash state has been modified. Like other hardware_flash functions, the flash is not accessible for execute-in-place transfers whilst the command is in progress, so entering a flash-resident interrupt handler or executing flash code on the second core concurrently will be fatal. To avoid these pitfalls it is recommended that this function only be used to extract flash metadata during startup, before the main application begins to run: see the implementation of pico_get_unique_id() for an example of this.

Parameters

txbuf

Pointer to a byte buffer which will be transmitted to the flash

rxbuf

Pointer to a byte buffer where data received from the flash will be written. txbuf and rxbuf may be the same buffer.

count

Length in bytes of txbuf and of rxbuf

flash_get_unique_id

void flash_get_unique_id (uint8_t * id_out)

Get flash unique 64 bit identifier.

Use a standard 4Bh RUID instruction to retrieve the 64 bit unique identifier from a flash device attached to the QSPI interface. Since there is a 1:1 association between the MCU and this flash, this also serves as a unique identifier for the board.

Parameters

id_out

Pointer to an 8-byte buffer to which the ID will be written

flash_range_erase

void flash_range_erase (uint32_t flash_offs, size_t count)

Erase areas of flash.

Parameters

flash_offs

Offset into flash, in bytes, to start the erase. Must be aligned to a 4096-byte flash sector.

count

Number of bytes to be erased. Must be a multiple of 4096 bytes (one sector).

Note

Erasing a flash sector sets all the bits in all the pages in that sector to one. You can then "program" flash pages in the sector to turn some of the bits to zero. Once a bit is set to zero it can only be changed back to one by erasing the whole sector again.

flash_range_program

void flash_range_program (uint32_t flash_offs, const uint8_t * data, size_t count)

Program flash.

Parameters

flash_offs

Flash address of the first byte to be programmed. Must be aligned to a 256-byte flash page.

data

Pointer to the data to program into flash

count

Number of bytes to program. Must be a multiple of 256 bytes (one page).

Note

: Programming a flash page effectively changes some of the bits from one to zero. The only way to change a zero bit back to one is to "erase" the whole sector that the page resides in. So you may need to make sure you have called flash_range_erase before calling flash_range_program.

hardware_gpio

General Purpose Input/Output (GPIO) API.

Detailed Description

RP-series microcontrollers have two banks of General Purpose Input / Output (GPIO) pins, which are assigned as follows:

RP2040 has 30 user GPIO pins in bank 0, and 6 QSPI pins in the QSPI bank 1 (QSPI_SS, QSPI_SCLK and QSPI_SD0 to QSPI_SD3). The QSPI pins are used to execute code from an external flash device, leaving the User bank (GPIO0 to GPIO29) for the programmer to use.

The number of GPIO pins available depends on the package. There are 30 user GPIOs in bank 0 in the QFN-60 package (RP2350A), or 48 user GPIOs in the QFN-80 package. Bank 1 contains the 6 QSPI pins and the USB DP/DM pins.

All GPIOs support digital input and output, but a subset can also be used as inputs to the chip’s Analogue to Digital Converter (ADC). The allocation of GPIO pins to the ADC depends on the packaging.

RP2040 and RP2350 QFN-60 GPIO, ADC pins are 26-29. RP2350 QFN-80, ADC pins are 40-47.

Each GPIO can be controlled directly by software running on the processors, or by a number of other functional blocks.

The function allocated to each GPIO is selected by calling the gpio_set_function function.

Note

Not all functions are available on all pins.

Each GPIO can have one function selected at a time. Likewise, each peripheral input (e.g. UART0 RX) should only be selected on one GPIO at a time. If the same peripheral input is connected to multiple GPIOs, the peripheral sees the logical OR of these GPIO inputs. Please refer to the datasheet for more information on GPIO function select.

Function Select Table

On RP2040 the function selects are:

GPIO F1 F2 F3 F4 F5 F6 F7 F8 F9

0

SPI0 RX

UART0 TX

I2C0 SDA

PWM0 A

SIO

PIO0

PIO1

USB OVCUR DET

1

SPI0 CSn

UART0 RX

I2C0 SCL

PWM0 B

SIO

PIO0

PIO1

USB VBUS DET

2

SPI0 SCK

UART0 CTS

I2C1 SDA

PWM1 A

SIO

PIO0

PIO1

USB VBUS EN

3

SPI0 TX

UART0 RTS

I2C1 SCL

PWM1 B

SIO

PIO0

PIO1

USB OVCUR DET

4

SPI0 RX

UART1 TX

I2C0 SDA

PWM2 A

SIO

PIO0

PIO1

USB VBUS DET

5

SPI0 CSn

UART1 RX

I2C0 SCL

PWM2 B

SIO

PIO0

PIO1

USB VBUS EN

6

SPI0 SCK

UART1 CTS

I2C1 SDA

PWM3 A

SIO

PIO0

PIO1

USB OVCUR DET

7

SPI0 TX

UART1 RTS

I2C1 SCL

PWM3 B

SIO

PIO0

PIO1

USB VBUS DET

8

SPI1 RX

UART1 TX

I2C0 SDA

PWM4 A

SIO

PIO0

PIO1

USB VBUS EN

9

SPI1 CSn

UART1 RX

I2C0 SCL

PWM4 B

SIO

PIO0

PIO1

USB OVCUR DET

10

SPI1 SCK

UART1 CTS

I2C1 SDA

PWM5 A

SIO

PIO0

PIO1

USB VBUS DET

11

SPI1 TX

UART1 RTS

I2C1 SCL

PWM5 B

SIO

PIO0

PIO1

USB VBUS EN

12

SPI1 RX

UART0 TX

I2C0 SDA

PWM6 A

SIO

PIO0

PIO1

USB OVCUR DET

13

SPI1 CSn

UART0 RX

I2C0 SCL

PWM6 B

SIO

PIO0

PIO1

USB VBUS DET

14

SPI1 SCK

UART0 CTS

I2C1 SDA

PWM7 A

SIO

PIO0

PIO1

USB VBUS EN

15

SPI1 TX

UART0 RTS

I2C1 SCL

PWM7 B

SIO

PIO0

PIO1

USB OVCUR DET

16

SPI0 RX

UART0 TX

I2C0 SDA

PWM0 A

SIO

PIO0

PIO1

USB VBUS DET

17

SPI0 CSn

UART0 RX

I2C0 SCL

PWM0 B

SIO

PIO0

PIO1

USB VBUS EN

18

SPI0 SCK

UART0 CTS

I2C1 SDA

PWM1 A

SIO

PIO0

PIO1

USB OVCUR DET

19

SPI0 TX

UART0 RTS

I2C1 SCL

PWM1 B

SIO

PIO0

PIO1

USB VBUS DET

20

SPI0 RX

UART1 TX

I2C0 SDA

PWM2 A

SIO

PIO0

PIO1

CLOCK GPIN0

USB VBUS EN

21

SPI0 CSn

UART1 RX

I2C0 SCL

PWM2 B

SIO

PIO0

PIO1

CLOCK GPOUT0

USB OVCUR DET

22

SPI0 SCK

UART1 CTS

I2C1 SDA

PWM3 A

SIO

PIO0

PIO1

CLOCK GPIN1

USB VBUS DET

23

SPI0 TX

UART1 RTS

I2C1 SCL

PWM3 B

SIO

PIO0

PIO1

CLOCK GPOUT1

USB VBUS EN

24

SPI1 RX

UART1 TX

I2C0 SDA

PWM4 A

SIO

PIO0

PIO1

CLOCK GPOUT2

USB OVCUR DET

25

SPI1 CSn

UART1 RX

I2C0 SCL

PWM4 B

SIO

PIO0

PIO1

CLOCK GPOUT3

USB VBUS DET

26

SPI1 SCK

UART1 CTS

I2C1 SDA

PWM5 A

SIO

PIO0

PIO1

USB VBUS EN

27

SPI1 TX

UART1 RTS

I2C1 SCL

PWM5 B

SIO

PIO0

PIO1

USB OVCUR DET

28

SPI1 RX

UART0 TX

I2C0 SDA

PWM6 A

SIO

PIO0

PIO1

USB VBUS DET

29

SPI1 CSn

UART0 RX

I2C0 SCL

PWM6 B

SIO

PIO0

PIO1

USB VBUS EN

On RP2350 the function selects are:

GPIO F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11

0

SPI0 RX

UART0 TX

I2C0 SDA

PWM0 A

SIO

PIO0

PIO1

PIO2

XIP_CS1n

USB OVCUR DET

1

SPI0 CSn

UART0 RX

I2C0 SCL

PWM0 B

SIO

PIO0

PIO1

PIO2

TRACECLK

USB VBUS DET

2

SPI0 SCK

UART0 CTS

I2C1 SDA

PWM1 A

SIO

PIO0

PIO1

PIO2

TRACEDATA0

USB VBUS EN

UART0 TX

3

SPI0 TX

UART0 RTS

I2C1 SCL

PWM1 B

SIO

PIO0

PIO1

PIO2

TRACEDATA1

USB OVCUR DET

UART0 RX

4

SPI0 RX

UART1 TX

I2C0 SDA

PWM2 A

SIO

PIO0

PIO1

PIO2

TRACEDATA2

USB VBUS DET

5

SPI0 CSn

UART1 RX

I2C0 SCL

PWM2 B

SIO

PIO0

PIO1

PIO2

TRACEDATA3

USB VBUS EN

6

SPI0 SCK

UART1 CTS

I2C1 SDA

PWM3 A

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

UART1 TX

7

SPI0 TX

UART1 RTS

I2C1 SCL

PWM3 B

SIO

PIO0

PIO1

PIO2

USB VBUS DET

UART1 RX

8

SPI1 RX

UART1 TX

I2C0 SDA

PWM4 A

SIO

PIO0

PIO1

PIO2

XIP_CS1n

USB VBUS EN

9

SPI1 CSn

UART1 RX

I2C0 SCL

PWM4 B

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

10

SPI1 SCK

UART1 CTS

I2C1 SDA

PWM5 A

SIO

PIO0

PIO1

PIO2

USB VBUS DET

UART1 TX

11

SPI1 TX

UART1 RTS

I2C1 SCL

PWM5 B

SIO

PIO0

PIO1

PIO2

USB VBUS EN

UART1 RX

12

HSTX

SPI1 RX

UART0 TX

I2C0 SDA

PWM6 A

SIO

PIO0

PIO1

PIO2

CLOCK GPIN0

USB OVCUR DET

13

HSTX

SPI1 CSn

UART0 RX

I2C0 SCL

PWM6 B

SIO

PIO0

PIO1

PIO2

CLOCK GPOUT0

USB VBUS DET

14

HSTX

SPI1 SCK

UART0 CTS

I2C1 SDA

PWM7 A

SIO

PIO0

PIO1

PIO2

CLOCK GPIN1

USB VBUS EN

UART0 TX

15

HSTX

SPI1 TX

UART0 RTS

I2C1 SCL

PWM7 B

SIO

PIO0

PIO1

PIO2

CLOCK GPOUT1

USB OVCUR DET

UART0 RX

16

HSTX

SPI0 RX

UART0 TX

I2C0 SDA

PWM0 A

SIO

PIO0

PIO1

PIO2

USB VBUS DET

17

HSTX

SPI0 CSn

UART0 RX

I2C0 SCL

PWM0 B

SIO

PIO0

PIO1

PIO2

USB VBUS EN

18

HSTX

SPI0 SCK

UART0 CTS

I2C1 SDA

PWM1 A

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

UART0 TX

19

HSTX

SPI0 TX

UART0 RTS

I2C1 SCL

PWM1 B

SIO

PIO0

PIO1

PIO2

XIP_CS1n

USB VBUS DET

UART0 RX

20

SPI0 RX

UART1 TX

I2C0 SDA

PWM2 A

SIO

PIO0

PIO1

PIO2

CLOCK GPIN0

USB VBUS EN

21

SPI0 CSn

UART1 RX

I2C0 SCL

PWM2 B

SIO

PIO0

PIO1

PIO2

CLOCK GPOUT0

USB OVCUR DET

22

SPI0 SCK

UART1 CTS

I2C1 SDA

PWM3 A

SIO

PIO0

PIO1

PIO2

CLOCK GPIN1

USB VBUS DET

UART1 TX

23

SPI0 TX

UART1 RTS

I2C1 SCL

PWM3 B

SIO

PIO0

PIO1

PIO2

CLOCK GPOUT1

USB VBUS EN

UART1 RX

24

SPI1 RX

UART1 TX

I2C0 SDA

PWM4 A

SIO

PIO0

PIO1

PIO2

CLOCK GPOUT2

USB OVCUR DET

25

SPI1 CSn

UART1 RX

I2C0 SCL

PWM4 B

SIO

PIO0

PIO1

PIO2

CLOCK GPOUT3

USB VBUS DET

26

SPI1 SCK

UART1 CTS

I2C1 SDA

PWM5 A

SIO

PIO0

PIO1

PIO2

USB VBUS EN

UART1 TX

27

SPI1 TX

UART1 RTS

I2C1 SCL

PWM5 B

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

UART1 RX

28

SPI1 RX

UART0 TX

I2C0 SDA

PWM6 A

SIO

PIO0

PIO1

PIO2

USB VBUS DET

29

SPI1 CSn

UART0 RX

I2C0 SCL

PWM6 B

SIO

PIO0

PIO1

PIO2

USB VBUS EN

GPIOs 30 through 47 are QFN-80 only:

GPIO F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11

30

SPI1 SCK

UART0 CTS

I2C1 SDA

PWM7 A

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

UART0 TX

31

SPI1 TX

UART0 RTS

I2C1 SCL

PWM7 B

SIO

PIO0

PIO1

PIO2

USB VBUS DET

UART0 RX

32

SPI0 RX

UART0 TX

I2C0 SDA

PWM8 A

SIO

PIO0

PIO1

PIO2

USB VBUS EN

33

SPI0 CSn

UART0 RX

I2C0 SCL

PWM8 B

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

34

SPI0 SCK

UART0 CTS

I2C1 SDA

PWM9 A

SIO

PIO0

PIO1

PIO2

USB VBUS DET

UART0 TX

35

SPI0 TX

UART0 RTS

I2C1 SCL

PWM9 B

SIO

PIO0

PIO1

PIO2

USB VBUS EN

UART0 RX

36

SPI0 RX

UART1 TX

I2C0 SDA

PWM10 A

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

37

SPI0 CSn

UART1 RX

I2C0 SCL

PWM10 B

SIO

PIO0

PIO1

PIO2

USB VBUS DET

38

SPI0 SCK

UART1 CTS

I2C1 SDA

PWM11 A

SIO

PIO0

PIO1

PIO2

USB VBUS EN

UART1 TX

39

SPI0 TX

UART1 RTS

I2C1 SCL

PWM11 B

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

UART1 RX

40

SPI1 RX

UART1 TX

I2C0 SDA

PWM8 A

SIO

PIO0

PIO1

PIO2

USB VBUS DET

41

SPI1 CSn

UART1 RX

I2C0 SCL

PWM8 B

SIO

PIO0

PIO1

PIO2

USB VBUS EN

42

SPI1 SCK

UART1 CTS

I2C1 SDA

PWM9 A

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

UART1 TX

43

SPI1 TX

UART1 RTS

I2C1 SCL

PWM9 B

SIO

PIO0

PIO1

PIO2

USB VBUS DET

UART1 RX

44

SPI1 RX

UART0 TX

I2C0 SDA

PWM10 A

SIO

PIO0

PIO1

PIO2

USB VBUS EN

45

SPI1 CSn

UART0 RX

I2C0 SCL

PWM10 B

SIO

PIO0

PIO1

PIO2

USB OVCUR DET

46

SPI1 SCK

UART0 CTS

I2C1 SDA

PWM11 A

SIO

PIO0

PIO1

PIO2

USB VBUS DET

UART0 TX

47

SPI1 TX

UART0 RTS

I2C1 SCL

PWM11 B

SIO

PIO0

PIO1

PIO2

XIP_CS1n

USB VBUS EN

UART0 RX

Typedefs

typedef enum gpio_function_rp2040 gpio_function_t RP2040

GPIO pin function selectors on RP2040 (used as typedef gpio_function_t)

typedef enum gpio_function_rp2350 gpio_function_t RP2350

GPIO pin function selectors on RP2350 (used as typedef gpio_function_t)

typedef void(* gpio_irq_callback_t)(uint gpio, uint32_t event_mask)

Enumerations

enum gpio_function_rp2040 { GPIO_FUNC_XIP = 0, GPIO_FUNC_SPI = 1, GPIO_FUNC_UART = 2, GPIO_FUNC_I2C = 3, GPIO_FUNC_PWM = 4, GPIO_FUNC_SIO = 5, GPIO_FUNC_PIO0 = 6, GPIO_FUNC_PIO1 = 7, GPIO_FUNC_GPCK = 8, GPIO_FUNC_USB = 9, GPIO_FUNC_NULL = 0x1f } RP2040

GPIO pin function selectors on RP2040 (used as typedef gpio_function_t)

enum gpio_function_rp2350 { GPIO_FUNC_HSTX = 0, GPIO_FUNC_SPI = 1, GPIO_FUNC_UART = 2, GPIO_FUNC_I2C = 3, GPIO_FUNC_PWM = 4, GPIO_FUNC_SIO = 5, GPIO_FUNC_PIO0 = 6, GPIO_FUNC_PIO1 = 7, GPIO_FUNC_PIO2 = 8, GPIO_FUNC_GPCK = 9, GPIO_FUNC_XIP_CS1 = 9, GPIO_FUNC_CORESIGHT_TRACE = 9, GPIO_FUNC_USB = 10, GPIO_FUNC_UART_AUX = 11, GPIO_FUNC_NULL = 0x1f } RP2350

GPIO pin function selectors on RP2350 (used as typedef gpio_function_t)

enum gpio_irq_level { GPIO_IRQ_LEVEL_LOW = 0x1u, GPIO_IRQ_LEVEL_HIGH = 0x2u, GPIO_IRQ_EDGE_FALL = 0x4u, GPIO_IRQ_EDGE_RISE = 0x8u }

GPIO Interrupt level definitions (GPIO events)

enum gpio_slew_rate { GPIO_SLEW_RATE_SLOW = 0, GPIO_SLEW_RATE_FAST = 1 }

Slew rate limiting levels for GPIO outputs.

enum gpio_drive_strength { GPIO_DRIVE_STRENGTH_2MA = 0, GPIO_DRIVE_STRENGTH_4MA = 1, GPIO_DRIVE_STRENGTH_8MA = 2, GPIO_DRIVE_STRENGTH_12MA = 3 }

Drive strength levels for GPIO outputs.

Functions

void gpio_set_function (uint gpio, gpio_function_t fn)

Select GPIO function.

void gpio_set_function_masked (uint32_t gpio_mask, gpio_function_t fn)

Select the function for multiple GPIOs.

void gpio_set_function_masked64 (uint64_t gpio_mask, gpio_function_t fn)

Select the function for multiple GPIOs.

gpio_function_t gpio_get_function (uint gpio) RP2040

Determine current GPIO function.

void gpio_set_pulls (uint gpio, bool up, bool down)

Select up and down pulls on specific GPIO.

static void gpio_pull_up (uint gpio)

Set specified GPIO to be pulled up.

static bool gpio_is_pulled_up (uint gpio)

Determine if the specified GPIO is pulled up.

static void gpio_pull_down (uint gpio)

Set specified GPIO to be pulled down.

static bool gpio_is_pulled_down (uint gpio)

Determine if the specified GPIO is pulled down.

static void gpio_disable_pulls (uint gpio)

Disable pulls on specified GPIO.

void gpio_set_irqover (uint gpio, uint value)

Set GPIO IRQ override.

void gpio_set_outover (uint gpio, uint value)

Set GPIO output override.

void gpio_set_inover (uint gpio, uint value)

Select GPIO input override.

void gpio_set_oeover (uint gpio, uint value)

Select GPIO output enable override.

void gpio_set_input_enabled (uint gpio, bool enabled)

Enable GPIO input.

void gpio_set_input_hysteresis_enabled (uint gpio, bool enabled)

Enable/disable GPIO input hysteresis (Schmitt trigger)

bool gpio_is_input_hysteresis_enabled (uint gpio)

Determine whether input hysteresis is enabled on a specified GPIO.

void gpio_set_slew_rate (uint gpio, enum gpio_slew_rate slew)

Set slew rate for a specified GPIO.

enum gpio_slew_rate gpio_get_slew_rate (uint gpio)

Determine current slew rate for a specified GPIO.

void gpio_set_drive_strength (uint gpio, enum gpio_drive_strength drive)

Set drive strength for a specified GPIO.

enum gpio_drive_strength gpio_get_drive_strength (uint gpio)

Determine current drive strength for a specified GPIO.

void gpio_set_irq_enabled (uint gpio, uint32_t event_mask, bool enabled)

Enable or disable specific interrupt events for specified GPIO.

void gpio_set_irq_callback (gpio_irq_callback_t callback)

Set the generic callback used for GPIO IRQ events for the current core.

void gpio_set_irq_enabled_with_callback (uint gpio, uint32_t event_mask, bool enabled, gpio_irq_callback_t callback)

Convenience function which performs multiple GPIO IRQ related initializations.

void gpio_set_dormant_irq_enabled (uint gpio, uint32_t event_mask, bool enabled)

Enable dormant wake up interrupt for specified GPIO and events.

static uint32_t gpio_get_irq_event_mask (uint gpio)

Return the current interrupt status (pending events) for the given GPIO.

void gpio_acknowledge_irq (uint gpio, uint32_t event_mask)

Acknowledge a GPIO interrupt for the specified events on the calling core.

void gpio_add_raw_irq_handler_with_order_priority_masked (uint32_t gpio_mask, irq_handler_t handler, uint8_t order_priority)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

void gpio_add_raw_irq_handler_with_order_priority_masked64 (uint64_t gpio_mask, irq_handler_t handler, uint8_t order_priority)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

static void gpio_add_raw_irq_handler_with_order_priority (uint gpio, irq_handler_t handler, uint8_t order_priority)

Adds a raw GPIO IRQ handler for a specific GPIO on the current core.

void gpio_add_raw_irq_handler_masked (uint32_t gpio_mask, irq_handler_t handler)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

void gpio_add_raw_irq_handler_masked64 (uint64_t gpio_mask, irq_handler_t handler)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

static void gpio_add_raw_irq_handler (uint gpio, irq_handler_t handler)

Adds a raw GPIO IRQ handler for a specific GPIO on the current core.

void gpio_remove_raw_irq_handler_masked (uint32_t gpio_mask, irq_handler_t handler)

Removes a raw GPIO IRQ handler for the specified GPIOs on the current core.

void gpio_remove_raw_irq_handler_masked64 (uint64_t gpio_mask, irq_handler_t handler)

Removes a raw GPIO IRQ handler for the specified GPIOs on the current core.

static void gpio_remove_raw_irq_handler (uint gpio, irq_handler_t handler)

Removes a raw GPIO IRQ handler for the specified GPIO on the current core.

void gpio_init (uint gpio)

Initialise a GPIO for (enabled I/O and set func to GPIO_FUNC_SIO)

void gpio_deinit (uint gpio)

Resets a GPIO back to the NULL function, i.e. disables it.

void gpio_init_mask (uint gpio_mask)

Initialise multiple GPIOs (enabled I/O and set func to GPIO_FUNC_SIO)

static bool gpio_get (uint gpio)

Get state of a single specified GPIO.

static uint32_t gpio_get_all (void)

Get raw value of all GPIOs.

static uint64_t gpio_get_all64 (void)

Get raw value of all GPIOs.

static void gpio_set_mask (uint32_t mask)

Drive high every GPIO appearing in mask.

static void gpio_set_mask64 (uint64_t mask)

Drive high every GPIO appearing in mask.

static void gpio_set_mask_n (uint n, uint32_t mask)

Drive high every GPIO appearing in mask.

static void gpio_clr_mask (uint32_t mask)

Drive low every GPIO appearing in mask.

static void gpio_clr_mask64 (uint64_t mask)

Drive low every GPIO appearing in mask.

static void gpio_clr_mask_n (uint n, uint32_t mask)

Drive low every GPIO appearing in mask.

static void gpio_xor_mask (uint32_t mask)

Toggle every GPIO appearing in mask.

static void gpio_xor_mask64 (uint64_t mask)

Toggle every GPIO appearing in mask.

static void gpio_xor_mask_n (uint n, uint32_t mask)

Toggle every GPIO appearing in mask.

static void gpio_put_masked (uint32_t mask, uint32_t value)

Drive GPIOs high/low depending on parameters.

static void gpio_put_masked64 (uint64_t mask, uint64_t value)

Drive GPIOs high/low depending on parameters.

static void gpio_put_masked_n (uint n, uint32_t mask, uint32_t value)

Drive GPIOs high/low depending on parameters.

static void gpio_put_all (uint32_t value)

Drive all pins simultaneously.

static void gpio_put_all64 (uint64_t value)

Drive all pins simultaneously.

static void gpio_put (uint gpio, bool value)

Drive a single GPIO high/low.

static bool gpio_get_out_level (uint gpio)

Determine whether a GPIO is currently driven high or low.

static void gpio_set_dir_out_masked (uint32_t mask)

Set a number of GPIOs to output.

static void gpio_set_dir_out_masked64 (uint64_t mask)

Set a number of GPIOs to output.

static void gpio_set_dir_in_masked (uint32_t mask)

Set a number of GPIOs to input.

static void gpio_set_dir_in_masked64 (uint64_t mask)

Set a number of GPIOs to input.

static void gpio_set_dir_masked (uint32_t mask, uint32_t value)

Set multiple GPIO directions.

static void gpio_set_dir_masked64 (uint64_t mask, uint64_t value)

Set multiple GPIO directions.

static void gpio_set_dir_all_bits (uint32_t values)

Set direction of all pins simultaneously.

static void gpio_set_dir_all_bits64 (uint64_t values)

Set direction of all pins simultaneously.

static void gpio_set_dir (uint gpio, bool out)

Set a single GPIO direction.

static bool gpio_is_dir_out (uint gpio)

Check if a specific GPIO direction is OUT.

static uint gpio_get_dir (uint gpio)

Get a specific GPIO direction.

Typedef Documentation

gpio_function_t RP2040

typedef enum gpio_function_rp2040 gpio_function_t

GPIO pin function selectors on RP2040 (used as typedef gpio_function_t)

gpio_function_t RP2350

typedef enum gpio_function_rp2350 gpio_function_t

GPIO pin function selectors on RP2350 (used as typedef gpio_function_t)

gpio_irq_callback_t

typedef void(* gpio_irq_callback_t) (uint gpio, uint32_t event_mask)

Callback function type for GPIO events

Parameters

gpio

Which GPIO caused this interrupt

event_mask

Which events caused this interrupt. See gpio_irq_level for details.

Enumeration Type Documentation

gpio_function_rp2040 RP2040

enum gpio_function_rp2040

GPIO pin function selectors on RP2040 (used as typedef gpio_function_t)

Table 9. Enumerator

GPIO_FUNC_XIP

Select XIP as GPIO pin function.

GPIO_FUNC_SPI

Select SPI as GPIO pin function.

GPIO_FUNC_UART

Select UART as GPIO pin function.

GPIO_FUNC_I2C

Select I2C as GPIO pin function.

GPIO_FUNC_PWM

Select PWM as GPIO pin function.

GPIO_FUNC_SIO

Select SIO as GPIO pin function.

GPIO_FUNC_PIO0

Select PIO0 as GPIO pin function.

GPIO_FUNC_PIO1

Select PIO1 as GPIO pin function.

GPIO_FUNC_GPCK

Select GPCK as GPIO pin function.

GPIO_FUNC_USB

Select USB as GPIO pin function.

GPIO_FUNC_NULL

Select NULL as GPIO pin function.

gpio_function_rp2350 RP2350

enum gpio_function_rp2350

GPIO pin function selectors on RP2350 (used as typedef gpio_function_t)

Table 10. Enumerator

GPIO_FUNC_HSTX

Select HSTX as GPIO pin function.

GPIO_FUNC_SPI

Select SPI as GPIO pin function.

GPIO_FUNC_UART

Select UART as GPIO pin function.

GPIO_FUNC_I2C

Select I2C as GPIO pin function.

GPIO_FUNC_PWM

Select PWM as GPIO pin function.

GPIO_FUNC_SIO

Select SIO as GPIO pin function.

GPIO_FUNC_PIO0

Select PIO0 as GPIO pin function.

GPIO_FUNC_PIO1

Select PIO1 as GPIO pin function.

GPIO_FUNC_PIO2

Select PIO2 as GPIO pin function.

GPIO_FUNC_GPCK

Select GPCK as GPIO pin function.

GPIO_FUNC_XIP_CS1

Select XIP CS1 as GPIO pin function.

GPIO_FUNC_CORESIGHT_TRACE

Select CORESIGHT TRACE as GPIO pin function.

GPIO_FUNC_USB

Select USB as GPIO pin function.

GPIO_FUNC_UART_AUX

Select UART_AUX as GPIO pin function.

GPIO_FUNC_NULL

Select NULL as GPIO pin function.

gpio_irq_level

enum gpio_irq_level

GPIO Interrupt level definitions (GPIO events)

GPIO Interrupt levels

An interrupt can be generated for every GPIO pin in 4 scenarios:

  • Level High: the GPIO pin is a logical 1

  • Level Low: the GPIO pin is a logical 0

  • Edge High: the GPIO has transitioned from a logical 0 to a logical 1

  • Edge Low: the GPIO has transitioned from a logical 1 to a logical 0

The level interrupts are not latched. This means that if the pin is a logical 1 and the level high interrupt is active, it will become inactive as soon as the pin changes to a logical 0. The edge interrupts are stored in the INTR register and can be cleared by writing to the INTR register.

Table 11. Enumerator

GPIO_IRQ_LEVEL_LOW

IRQ when the GPIO pin is a logical 0.

GPIO_IRQ_LEVEL_HIGH

IRQ when the GPIO pin is a logical 1.

GPIO_IRQ_EDGE_FALL

IRQ when the GPIO has transitioned from a logical 1 to a logical 0.

GPIO_IRQ_EDGE_RISE

IRQ when the GPIO has transitioned from a logical 0 to a logical 1.

gpio_slew_rate

enum gpio_slew_rate

Slew rate limiting levels for GPIO outputs.

Slew rate limiting increases the minimum rise/fall time when a GPIO output is lightly loaded, which can help to reduce electromagnetic emissions.

Table 12. Enumerator

GPIO_SLEW_RATE_SLOW

Slew rate limiting enabled.

GPIO_SLEW_RATE_FAST

Slew rate limiting disabled.

gpio_drive_strength

enum gpio_drive_strength

Drive strength levels for GPIO outputs.

Drive strength levels for GPIO outputs.

Table 13. Enumerator

GPIO_DRIVE_STRENGTH_2MA

2 mA nominal drive strength

GPIO_DRIVE_STRENGTH_4MA

4 mA nominal drive strength

GPIO_DRIVE_STRENGTH_8MA

8 mA nominal drive strength

GPIO_DRIVE_STRENGTH_12MA

12 mA nominal drive strength

Function Documentation

gpio_acknowledge_irq

void gpio_acknowledge_irq (uint gpio, uint32_t event_mask)

Acknowledge a GPIO interrupt for the specified events on the calling core.

Note

This may be called with a mask of any of valid bits specified in gpio_irq_level, however it has no effect on level sensitive interrupts which remain pending while the GPIO is at the specified level. When handling level sensitive interrupts, you should generally disable the interrupt (see gpio_set_irq_enabled) and then set it up again later once the GPIO level has changed (or to catch the opposite level).

Parameters

gpio

GPIO number

Note

For callbacks set with gpio_set_irq_enabled_with_callback, or gpio_set_irq_callback, this function is called automatically.

Parameters

event_mask

Bitmask of events to clear. See gpio_irq_level for details.

gpio_add_raw_irq_handler

static void gpio_add_raw_irq_handler (uint gpio, irq_handler_t handler) [inline], [static]

Adds a raw GPIO IRQ handler for a specific GPIO on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default event callback.

This method adds such a callback, and disables the "default" callback for the specified GPIO.

Note

Multiple raw handlers should not be added for the same GPIO, and this method will assert if you attempt to. Internally, this function calls irq_add_shared_handler, which will assert if the maximum number of shared handlers (configurable via PICO_MAX_IRQ_SHARED_HANDLERS) would be exceeded.

A raw handler should check for whichever GPIOs and events it handles, and acknowledge them itself; it might look something like:

1
2
3
4
5
6
void my_irq_handler(void) {
    if (gpio_get_irq_event_mask(my_gpio_num) & my_gpio_event_mask) {
       gpio_acknowledge_irq(my_gpio_num, my_gpio_event_mask);
      // handle the IRQ
    }
}

Parameters

gpio

the GPIO number that will no longer be passed to the default callback for this core

handler

the handler to add to the list of GPIO IRQ handlers for this core

gpio_add_raw_irq_handler_masked

void gpio_add_raw_irq_handler_masked (uint32_t gpio_mask, irq_handler_t handler)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default event callback.

This method adds such a callback, and disables the "default" callback for the specified GPIOs.

Note

Multiple raw handlers should not be added for the same GPIOs, and this method will assert if you attempt to. Internally, this function calls irq_add_shared_handler, which will assert if the maximum number of shared handlers (configurable via PICO_MAX_IRQ_SHARED_HANDLERS) would be exceeded.

A raw handler should check for whichever GPIOs and events it handles, and acknowledge them itself; it might look something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
void my_irq_handler(void) {
    if (gpio_get_irq_event_mask(my_gpio_num) & my_gpio_event_mask) {
       gpio_acknowledge_irq(my_gpio_num, my_gpio_event_mask);
      // handle the IRQ
    }
    if (gpio_get_irq_event_mask(my_gpio_num2) & my_gpio_event_mask2) {
       gpio_acknowledge_irq(my_gpio_num2, my_gpio_event_mask2);
      // handle the IRQ
    }
}

Parameters

gpio_mask

a bit mask of the GPIO numbers that will no longer be passed to the default callback for this core

handler

the handler to add to the list of GPIO IRQ handlers for this core

gpio_add_raw_irq_handler_masked64

void gpio_add_raw_irq_handler_masked64 (uint64_t gpio_mask, irq_handler_t handler)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default event callback.

This method adds such a callback, and disables the "default" callback for the specified GPIOs.

Note

Multiple raw handlers should not be added for the same GPIOs, and this method will assert if you attempt to. Internally, this function calls irq_add_shared_handler, which will assert if the maximum number of shared handlers (configurable via PICO_MAX_IRQ_SHARED_HANDLERS) would be exceeded.

A raw handler should check for whichever GPIOs and events it handles, and acknowledge them itself; it might look something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
void my_irq_handler(void) {
    if (gpio_get_irq_event_mask(my_gpio_num) & my_gpio_event_mask) {
       gpio_acknowledge_irq(my_gpio_num, my_gpio_event_mask);
      // handle the IRQ
    }
    if (gpio_get_irq_event_mask(my_gpio_num2) & my_gpio_event_mask2) {
       gpio_acknowledge_irq(my_gpio_num2, my_gpio_event_mask2);
      // handle the IRQ
    }
}

Parameters

gpio_mask

a 64 bit mask of the GPIO numbers that will no longer be passed to the default callback for this core

handler

the handler to add to the list of GPIO IRQ handlers for this core

gpio_add_raw_irq_handler_with_order_priority

static void gpio_add_raw_irq_handler_with_order_priority (uint gpio, irq_handler_t handler, uint8_t order_priority) [inline], [static]

Adds a raw GPIO IRQ handler for a specific GPIO on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default callback. The order relative to the default callback can be controlled via the order_priority parameter(the default callback has the priority GPIO_IRQ_CALLBACK_ORDER_PRIORITY which defaults to the lowest priority with the intention of it running last).

This method adds such a callback, and disables the "default" callback for the specified GPIO.

Note

Multiple raw handlers should not be added for the same GPIO, and this method will assert if you attempt to. Internally, this function calls irq_add_shared_handler, which will assert if the maximum number of shared handlers (configurable via PICO_MAX_IRQ_SHARED_HANDLERS) would be exceeded.

A raw handler should check for whichever GPIOs and events it handles, and acknowledge them itself; it might look something like:

1
2
3
4
5
6
void my_irq_handler(void) {
    if (gpio_get_irq_event_mask(my_gpio_num) & my_gpio_event_mask) {
       gpio_acknowledge_irq(my_gpio_num, my_gpio_event_mask);
      // handle the IRQ
    }
}

Parameters

gpio

the GPIO number that will no longer be passed to the default callback for this core

handler

the handler to add to the list of GPIO IRQ handlers for this core

order_priority

the priority order to determine the relative position of the handler in the list of GPIO IRQ handlers for this core.

gpio_add_raw_irq_handler_with_order_priority_masked

void gpio_add_raw_irq_handler_with_order_priority_masked (uint32_t gpio_mask, irq_handler_t handler, uint8_t order_priority)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default callback. The order relative to the default callback can be controlled via the order_priority parameter (the default callback has the priority GPIO_IRQ_CALLBACK_ORDER_PRIORITY which defaults to the lowest priority with the intention of it running last).

This method adds such an explicit GPIO IRQ handler, and disables the "default" callback for the specified GPIOs.

Note

Multiple raw handlers should not be added for the same GPIOs, and this method will assert if you attempt to. Internally, this function calls irq_add_shared_handler, which will assert if the maximum number of shared handlers (configurable via PICO_MAX_IRQ_SHARED_HANDLERS) would be exceeded.

A raw handler should check for whichever GPIOs and events it handles, and acknowledge them itself; it might look something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
void my_irq_handler(void) {
    if (gpio_get_irq_event_mask(my_gpio_num) & my_gpio_event_mask) {
       gpio_acknowledge_irq(my_gpio_num, my_gpio_event_mask);
      // handle the IRQ
    }
    if (gpio_get_irq_event_mask(my_gpio_num2) & my_gpio_event_mask2) {
       gpio_acknowledge_irq(my_gpio_num2, my_gpio_event_mask2);
      // handle the IRQ
    }
}

Parameters

gpio_mask

a bit mask of the GPIO numbers that will no longer be passed to the default callback for this core

handler

the handler to add to the list of GPIO IRQ handlers for this core

order_priority

the priority order to determine the relative position of the handler in the list of GPIO IRQ handlers for this core.

gpio_add_raw_irq_handler_with_order_priority_masked64

void gpio_add_raw_irq_handler_with_order_priority_masked64 (uint64_t gpio_mask, irq_handler_t handler, uint8_t order_priority)

Adds a raw GPIO IRQ handler for the specified GPIOs on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default callback. The order relative to the default callback can be controlled via the order_priority parameter (the default callback has the priority GPIO_IRQ_CALLBACK_ORDER_PRIORITY which defaults to the lowest priority with the intention of it running last).

This method adds such an explicit GPIO IRQ handler, and disables the "default" callback for the specified GPIOs.

Note

Multiple raw handlers should not be added for the same GPIOs, and this method will assert if you attempt to. Internally, this function calls irq_add_shared_handler, which will assert if the maximum number of shared handlers (configurable via PICO_MAX_IRQ_SHARED_HANDLERS) would be exceeded.

A raw handler should check for whichever GPIOs and events it handles, and acknowledge them itself; it might look something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
void my_irq_handler(void) {
    if (gpio_get_irq_event_mask(my_gpio_num) & my_gpio_event_mask) {
       gpio_acknowledge_irq(my_gpio_num, my_gpio_event_mask);
      // handle the IRQ
    }
    if (gpio_get_irq_event_mask(my_gpio_num2) & my_gpio_event_mask2) {
       gpio_acknowledge_irq(my_gpio_num2, my_gpio_event_mask2);
      // handle the IRQ
    }
}

Parameters

gpio_mask

a bit mask of the GPIO numbers that will no longer be passed to the default callback for this core

handler

the handler to add to the list of GPIO IRQ handlers for this core

order_priority

the priority order to determine the relative position of the handler in the list of GPIO IRQ handlers for this core.

gpio_clr_mask

static void gpio_clr_mask (uint32_t mask) [inline], [static]

Drive low every GPIO appearing in mask.

Parameters

mask

Bitmask of GPIO values to clear

gpio_clr_mask64

static void gpio_clr_mask64 (uint64_t mask) [inline], [static]

Drive low every GPIO appearing in mask.

Parameters

mask

Bitmask of GPIO values to clear

gpio_clr_mask_n

static void gpio_clr_mask_n (uint n, uint32_t mask) [inline], [static]

Drive low every GPIO appearing in mask.

Parameters

n

the base GPIO index of the mask to update. n == 0 means 0->31, n == 1 mean 32->63 etc.

mask

Bitmask of 32 GPIO values to clear

gpio_deinit

void gpio_deinit (uint gpio)

Resets a GPIO back to the NULL function, i.e. disables it.

Parameters

gpio

GPIO number

gpio_disable_pulls

static void gpio_disable_pulls (uint gpio) [inline], [static]

Disable pulls on specified GPIO.

Parameters

gpio

GPIO number

gpio_get

static bool gpio_get (uint gpio) [inline], [static]

Get state of a single specified GPIO.

Parameters

gpio

GPIO number

Returns

Current state of the GPIO. 0 for low, non-zero for high

gpio_get_all

static uint32_t gpio_get_all (void) [inline], [static]

Get raw value of all GPIOs.

Returns

Bitmask of raw GPIO values

gpio_get_all64

static uint64_t gpio_get_all64 (void) [inline], [static]

Get raw value of all GPIOs.

Returns

Bitmask of raw GPIO values

gpio_get_dir

static uint gpio_get_dir (uint gpio) [inline], [static]

Get a specific GPIO direction.

Parameters

gpio

GPIO number

Returns

1 for out, 0 for in

gpio_get_drive_strength

enum gpio_drive_strength gpio_get_drive_strength (uint gpio)

Determine current drive strength for a specified GPIO.

Parameters

gpio

GPIO number

Returns

Current drive strength of that GPIO

gpio_get_function

gpio_function_t gpio_get_function (uint gpio)

Determine current GPIO function.

Parameters

gpio

GPIO number

Returns

Which GPIO function is currently selected from list gpio_function_t

gpio_get_irq_event_mask

static uint32_t gpio_get_irq_event_mask (uint gpio) [inline], [static]

Return the current interrupt status (pending events) for the given GPIO.

Parameters

gpio

GPIO number

Returns

Bitmask of events that are currently pending for the GPIO. See gpio_irq_level for details.

gpio_get_out_level

static bool gpio_get_out_level (uint gpio) [inline], [static]

Determine whether a GPIO is currently driven high or low.

This function returns the high/low output level most recently assigned to a GPIO via gpio_put() or similar. This is the value that is presented outward to the IO muxing, not the input level back from the pad (which can be read using gpio_get()).

To avoid races, this function must not be used for read-modify-write sequences when driving GPIOs – instead functions like gpio_put() should be used to atomically update GPIOs. This accessor is intended for debug use only.

Parameters

gpio

GPIO number

Returns

true if the GPIO output level is high, false if low.

gpio_get_slew_rate

enum gpio_slew_rate gpio_get_slew_rate (uint gpio)

Determine current slew rate for a specified GPIO.

Parameters

gpio

GPIO number

Returns

Current slew rate of that GPIO

gpio_init

void gpio_init (uint gpio)

Initialise a GPIO for (enabled I/O and set func to GPIO_FUNC_SIO)

Clear the output enable (i.e. set to input). Clear any output value.

Parameters

gpio

GPIO number

gpio_init_mask

void gpio_init_mask (uint gpio_mask)

Initialise multiple GPIOs (enabled I/O and set func to GPIO_FUNC_SIO)

Clear the output enable (i.e. set to input). Clear any output value.

Parameters

gpio_mask

Mask with 1 bit per GPIO number to initialize

gpio_is_dir_out

static bool gpio_is_dir_out (uint gpio) [inline], [static]

Check if a specific GPIO direction is OUT.

Parameters

gpio

GPIO number

Returns

true if the direction for the pin is OUT

gpio_is_input_hysteresis_enabled

bool gpio_is_input_hysteresis_enabled (uint gpio)

Determine whether input hysteresis is enabled on a specified GPIO.

Parameters

gpio

GPIO number

gpio_is_pulled_down

static bool gpio_is_pulled_down (uint gpio) [inline], [static]

Determine if the specified GPIO is pulled down.

Parameters

gpio

GPIO number

Returns

true if the GPIO is pulled down

gpio_is_pulled_up

static bool gpio_is_pulled_up (uint gpio) [inline], [static]

Determine if the specified GPIO is pulled up.

Parameters

gpio

GPIO number

Returns

true if the GPIO is pulled up

gpio_pull_down

static void gpio_pull_down (uint gpio) [inline], [static]

Set specified GPIO to be pulled down.

Parameters

gpio

GPIO number

gpio_pull_up

static void gpio_pull_up (uint gpio) [inline], [static]

Set specified GPIO to be pulled up.

Parameters

gpio

GPIO number

gpio_put

static void gpio_put (uint gpio, bool value) [inline], [static]

Drive a single GPIO high/low.

Parameters

gpio

GPIO number

value

If false clear the GPIO, otherwise set it.

gpio_put_all

static void gpio_put_all (uint32_t value) [inline], [static]

Drive all pins simultaneously.

Parameters

value

Bitmask of GPIO values to change

gpio_put_all64

static void gpio_put_all64 (uint64_t value) [inline], [static]

Drive all pins simultaneously.

Parameters

value

Bitmask of GPIO values to change

gpio_put_masked

static void gpio_put_masked (uint32_t mask, uint32_t value) [inline], [static]

Drive GPIOs high/low depending on parameters.

Parameters

mask

Bitmask of GPIO values to change

value

Value to set

For each 1 bit in mask, drive that pin to the value given by corresponding bit in value, leaving other pins unchanged. Since this uses the TOGL alias, it is concurrency-safe with e.g. an IRQ bashing different pins from the same core.

gpio_put_masked64

static void gpio_put_masked64 (uint64_t mask, uint64_t value) [inline], [static]

Drive GPIOs high/low depending on parameters.

Parameters

mask

Bitmask of GPIO values to change

value

Value to set

For each 1 bit in mask, drive that pin to the value given by corresponding bit in value, leaving other pins unchanged. Since this uses the TOGL alias, it is concurrency-safe with e.g. an IRQ bashing different pins from the same core.

gpio_put_masked_n

static void gpio_put_masked_n (uint n, uint32_t mask, uint32_t value) [inline], [static]

Drive GPIOs high/low depending on parameters.

Parameters

n

the base GPIO index of the mask to update. n == 0 means 0->31, n == 1 mean 32->63 etc.

mask

Bitmask of GPIO values to change

value

Value to set

For each 1 bit in mask, drive that pin to the value given by corresponding bit in value, leaving other pins unchanged. Since this uses the TOGL alias, it is concurrency-safe with e.g. an IRQ bashing different pins from the same core.

gpio_remove_raw_irq_handler

static void gpio_remove_raw_irq_handler (uint gpio, irq_handler_t handler) [inline], [static]

Removes a raw GPIO IRQ handler for the specified GPIO on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default event callback.

This method removes such a callback, and enables the "default" callback for the specified GPIO.

Parameters

gpio

the GPIO number that will now be passed to the default callback for this core

handler

the handler to remove from the list of GPIO IRQ handlers for this core

gpio_remove_raw_irq_handler_masked

void gpio_remove_raw_irq_handler_masked (uint32_t gpio_mask, irq_handler_t handler)

Removes a raw GPIO IRQ handler for the specified GPIOs on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default event callback.

This method removes such a callback, and enables the "default" callback for the specified GPIOs.

Parameters

gpio_mask

a bit mask of the GPIO numbers that will now be passed to the default callback for this core

handler

the handler to remove from the list of GPIO IRQ handlers for this core

gpio_remove_raw_irq_handler_masked64

void gpio_remove_raw_irq_handler_masked64 (uint64_t gpio_mask, irq_handler_t handler)

Removes a raw GPIO IRQ handler for the specified GPIOs on the current core.

In addition to the default mechanism of a single GPIO IRQ event callback per core (see gpio_set_irq_callback), it is possible to add explicit GPIO IRQ handlers which are called independent of the default event callback.

This method removes such a callback, and enables the "default" callback for the specified GPIOs.

Parameters

gpio_mask

a bit mask of the GPIO numbers that will now be passed to the default callback for this core

handler

the handler to remove from the list of GPIO IRQ handlers for this core

gpio_set_dir

static void gpio_set_dir (uint gpio, bool out) [inline], [static]

Set a single GPIO direction.

Parameters

gpio

GPIO number

out

true for out, false for in

gpio_set_dir_all_bits

static void gpio_set_dir_all_bits (uint32_t values) [inline], [static]

Set direction of all pins simultaneously.

Parameters

values

individual settings for each gpio; for GPIO N, bit N is 1 for out, 0 for in

gpio_set_dir_all_bits64

static void gpio_set_dir_all_bits64 (uint64_t values) [inline], [static]

Set direction of all pins simultaneously.

Parameters

values

individual settings for each gpio; for GPIO N, bit N is 1 for out, 0 for in

gpio_set_dir_in_masked

static void gpio_set_dir_in_masked (uint32_t mask) [inline], [static]

Set a number of GPIOs to input.

Parameters

mask

Bitmask of GPIO to set to input

gpio_set_dir_in_masked64

static void gpio_set_dir_in_masked64 (uint64_t mask) [inline], [static]

Set a number of GPIOs to input.

Parameters

mask

Bitmask of GPIO to set to input

gpio_set_dir_masked

static void gpio_set_dir_masked (uint32_t mask, uint32_t value) [inline], [static]

Set multiple GPIO directions.

Parameters

mask

Bitmask of GPIO to set to input, as bits 0-29

value

Values to set

For each 1 bit in "mask", switch that pin to the direction given by corresponding bit in "value", leaving other pins unchanged. E.g. gpio_set_dir_masked(0x3, 0x2); -> set pin 0 to input, pin 1 to output, simultaneously.

gpio_set_dir_masked64

static void gpio_set_dir_masked64 (uint64_t mask, uint64_t value) [inline], [static]

Set multiple GPIO directions.

Parameters

mask

Bitmask of GPIO to set to input, as bits 0-29

value

Values to set

For each 1 bit in "mask", switch that pin to the direction given by corresponding bit in "value", leaving other pins unchanged. E.g. gpio_set_dir_masked(0x3, 0x2); -> set pin 0 to input, pin 1 to output, simultaneously.

gpio_set_dir_out_masked

static void gpio_set_dir_out_masked (uint32_t mask) [inline], [static]

Set a number of GPIOs to output.

Switch all GPIOs in "mask" to output

Parameters

mask

Bitmask of GPIO to set to output

gpio_set_dir_out_masked64

static void gpio_set_dir_out_masked64 (uint64_t mask) [inline], [static]

Set a number of GPIOs to output.

Switch all GPIOs in "mask" to output

Parameters

mask

Bitmask of GPIO to set to output

gpio_set_dormant_irq_enabled

void gpio_set_dormant_irq_enabled (uint gpio, uint32_t event_mask, bool enabled)

Enable dormant wake up interrupt for specified GPIO and events.

This configures IRQs to restart the XOSC or ROSC when they are disabled in dormant mode

Parameters

gpio

GPIO number

event_mask

Which events will cause an interrupt. See gpio_irq_level for details.

enabled

Enable/disable flag

gpio_set_drive_strength

void gpio_set_drive_strength (uint gpio, enum gpio_drive_strength drive)

Set drive strength for a specified GPIO.

Parameters

gpio

GPIO number

drive

GPIO output drive strength

gpio_set_function

void gpio_set_function (uint gpio, gpio_function_t fn)

Select GPIO function.

Parameters

gpio

GPIO number

fn

Which GPIO function select to use from list gpio_function_t

gpio_set_function_masked

void gpio_set_function_masked (uint32_t gpio_mask, gpio_function_t fn)

Select the function for multiple GPIOs.

Parameters

gpio_mask

Mask with 1 bit per GPIO number to set the function for

fn

Which GPIO function select to use from list gpio_function_t

gpio_set_function_masked64

void gpio_set_function_masked64 (uint64_t gpio_mask, gpio_function_t fn)

Select the function for multiple GPIOs.

Parameters

gpio_mask

Mask with 1 bit per GPIO number to set the function for

fn

Which GPIO function select to use from list gpio_function_t

gpio_set_inover

void gpio_set_inover (uint gpio, uint value)

Select GPIO input override.

Parameters

gpio

GPIO number

value

See gpio_override

gpio_set_input_enabled

void gpio_set_input_enabled (uint gpio, bool enabled)

Enable GPIO input.

Parameters

gpio

GPIO number

enabled

true to enable input on specified GPIO

gpio_set_input_hysteresis_enabled

void gpio_set_input_hysteresis_enabled (uint gpio, bool enabled)

Enable/disable GPIO input hysteresis (Schmitt trigger)

Enable or disable the Schmitt trigger hysteresis on a given GPIO. This is enabled on all GPIOs by default. Disabling input hysteresis can lead to inconsistent readings when the input signal has very long rise or fall times, but slightly reduces the GPIO’s input delay.

Parameters

gpio

GPIO number

enabled

true to enable input hysteresis on specified GPIO

gpio_set_irq_callback

void gpio_set_irq_callback (gpio_irq_callback_t callback)

Set the generic callback used for GPIO IRQ events for the current core.

This function sets the callback used for all GPIO IRQs on the current core that are not explicitly hooked via gpio_add_raw_irq_handler or other gpio_add_raw_irq_handler_ functions.

This function is called with the GPIO number and event mask for each of the (not explicitly hooked) GPIOs that have events enabled and that are pending (see gpio_get_irq_event_mask).

Note

The IO IRQs are independent per-processor. This function affects the processor that calls the function.

Parameters

callback

default user function to call on GPIO irq. Note only one of these can be set per processor.

gpio_set_irq_enabled

void gpio_set_irq_enabled (uint gpio, uint32_t event_mask, bool enabled)

Enable or disable specific interrupt events for specified GPIO.

This function sets which GPIO events cause a GPIO interrupt on the calling core. See gpio_set_irq_callback, gpio_set_irq_enabled_with_callback and gpio_add_raw_irq_handler to set up a GPIO interrupt handler to handle the events.

Note

The IO IRQs are independent per-processor. This configures the interrupt events for the processor that calls the function.

Parameters

gpio

GPIO number

event_mask

Which events will cause an interrupt

enabled

Enable or disable flag

Events is a bitmask of the following gpio_irq_level values:

bit constant interrupt

0

GPIO_IRQ_LEVEL_LOW

Continuously while level is low

1

GPIO_IRQ_LEVEL_HIGH

Continuously while level is high

2

GPIO_IRQ_EDGE_FALL

On each transition from high to low

3

GPIO_IRQ_EDGE_RISE

On each transition from low to high

which are specified in gpio_irq_level

gpio_set_irq_enabled_with_callback

void gpio_set_irq_enabled_with_callback (uint gpio, uint32_t event_mask, bool enabled, gpio_irq_callback_t callback)

Convenience function which performs multiple GPIO IRQ related initializations.

This method is a slightly eclectic mix of initialization, that:

  • Updates whether the specified events for the specified GPIO causes an interrupt on the calling core based on the enable flag.

  • Sets the callback handler for the calling core to callback (or clears the handler if the callback is NULL).

  • Enables GPIO IRQs on the current core if enabled is true.

This method is commonly used to perform a one time setup, and following that any additional IRQs/events are enabled via gpio_set_irq_enabled. All GPIOs/events added in this way on the same core share the same callback; for multiple independent handlers for different GPIOs you should use gpio_add_raw_irq_handler and related functions.

This method is equivalent to:

1
2
3
gpio_set_irq_enabled(gpio, event_mask, enabled);
gpio_set_irq_callback(callback);
if (enabled) irq_set_enabled(IO_IRQ_BANK0, true);
Note

The IO IRQs are independent per-processor. This method affects only the processor that calls the function.

Parameters

gpio

GPIO number

event_mask

Which events will cause an interrupt. See gpio_irq_level for details.

enabled

Enable or disable flag

callback

user function to call on GPIO irq. if NULL, the callback is removed

gpio_set_irqover

void gpio_set_irqover (uint gpio, uint value)

Set GPIO IRQ override.

Optionally invert a GPIO IRQ signal, or drive it high or low

Parameters

gpio

GPIO number

value

See gpio_override

gpio_set_mask

static void gpio_set_mask (uint32_t mask) [inline], [static]

Drive high every GPIO appearing in mask.

Parameters

mask

Bitmask of GPIO values to set

gpio_set_mask64

static void gpio_set_mask64 (uint64_t mask) [inline], [static]

Drive high every GPIO appearing in mask.

Parameters

mask

Bitmask of GPIO values to set

gpio_set_mask_n

static void gpio_set_mask_n (uint n, uint32_t mask) [inline], [static]

Drive high every GPIO appearing in mask.

Parameters

n

the base GPIO index of the mask to update. n == 0 means 0->31, n == 1 mean 32->63 etc.

mask

Bitmask of 32 GPIO values to set

gpio_set_oeover

void gpio_set_oeover (uint gpio, uint value)

Select GPIO output enable override.

Parameters

gpio

GPIO number

value

See gpio_override

gpio_set_outover

void gpio_set_outover (uint gpio, uint value)

Set GPIO output override.

Parameters

gpio

GPIO number

value

See gpio_override

gpio_set_pulls

void gpio_set_pulls (uint gpio, bool up, bool down)

Select up and down pulls on specific GPIO.

Parameters

gpio

GPIO number

up

If true set a pull up on the GPIO

down

If true set a pull down on the GPIO

Note

On the RP2040, setting both pulls enables a "bus keep" function, i.e. a weak pull to whatever is current high/low state of GPIO.

gpio_set_slew_rate

void gpio_set_slew_rate (uint gpio, enum gpio_slew_rate slew)

Set slew rate for a specified GPIO.

Parameters

gpio

GPIO number

slew

GPIO output slew rate

gpio_xor_mask

static void gpio_xor_mask (uint32_t mask) [inline], [static]

Toggle every GPIO appearing in mask.

Parameters

mask

Bitmask of GPIO values to toggle

gpio_xor_mask64

static void gpio_xor_mask64 (uint64_t mask) [inline], [static]

Toggle every GPIO appearing in mask.

Parameters

mask

Bitmask of GPIO values to toggle

gpio_xor_mask_n

static void gpio_xor_mask_n (uint n, uint32_t mask) [inline], [static]

Toggle every GPIO appearing in mask.

Parameters

n

the base GPIO index of the mask to update. n == 0 means 0->31, n == 1 mean 32->63 etc.

mask

Bitmask of 32 GPIO values to toggle

hardware_hazard3 RP2350

Accessors for Hazard3-specific RISC-V CSRs, and intrinsics for Hazard3 custom instructions.

Detailed Description

Intrinsics and asm macros for Hazard3 custom instructions.

Sets macros for supported Hazard3 custom extensions (features) based on PICO_PLATFORM macros.

The implementation of these intrinsics depends on the feature macros defined in hardware/hazard3/features.h. When the relevant feature is not present, the intrinsics fall back on an RV32I equivalent if possible.

hardware_i2c

I2C Controller API.

Detailed Description

The I2C bus is a two-wire serial interface, consisting of a serial data line SDA and a serial clock SCL. These wires carry information between the devices connected to the bus. Each device is recognized by a unique 7-bit address and can operate as either a “transmitter” or “receiver”, depending on the function of the device. Devices can also be considered as masters or slaves when performing data transfers. A master is a device that initiates a data transfer on the bus and generates the clock signals to permit that transfer. The first byte in the data transfer always contains the 7-bit address and a read/write bit in the LSB position. This API takes care of toggling the read/write bit. After this, any device addressed is considered a slave.

This API allows the controller to be set up as a master or a slave using the i2c_set_slave_mode function.

The external pins of each controller are connected to GPIO pins as defined in the GPIO muxing table in the datasheet. The muxing options give some IO flexibility, but each controller external pin should be connected to only one GPIO.

Note that the controller does NOT support High speed mode or Ultra-fast speed mode, the fastest operation being fast mode plus at up to 1000Kb/s.

See the datasheet for more information on the I2C controller and its usage.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Sweep through all 7-bit I2C addresses, to see if any slaves are present on
// the I2C bus. Print out a table that looks like this:
//
// I2C Bus Scan
//    0 1 2 3 4 5 6 7 8 9 A B C D E F
// 00 . . . . . . . . . . . . . . . .
// 10 . . @ . . . . . . . . . . . . .
// 20 . . . . . . . . . . . . . . . .
// 30 . . . . @ . . . . . . . . . . .
// 40 . . . . . . . . . . . . . . . .
// 50 . . . . . . . . . . . . . . . .
// 60 . . . . . . . . . . . . . . . .
// 70 . . . . . . . . . . . . . . . .
// E.g. if addresses 0x12 and 0x34 were acknowledged.

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/i2c.h"

// I2C reserves some addresses for special purposes. We exclude these from the scan.
// These are any addresses of the form 000 0xxx or 111 1xxx
bool reserved_addr(uint8_t addr) {
    return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}

int main() {
    // Enable UART so we can print status output
    stdio_init_all();
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
#warning i2c/bus_scan example requires a board with I2C pins
    puts("Default I2C pins were not defined");
#else
    // This example will use I2C0 on the default SDA and SCL pins (GP4, GP5 on a Pico)
    i2c_init(i2c_default, 100 * 1000);
    gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
    gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
    gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
    // Make the I2C pins available to picotool
    bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));

    printf("\nI2C Bus Scan\n");
    printf("   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\n");

    for (int addr = 0; addr < (1 << 7); ++addr) {
        if (addr % 16 == 0) {
            printf("%02x ", addr);
        }

        // Perform a 1-byte dummy read from the probe address. If a slave
        // acknowledges this address, the function returns the number of bytes
        // transferred. If the address byte is ignored, the function returns
        // -1.

        // Skip over any reserved addresses.
        int ret;
        uint8_t rxdata;
        if (reserved_addr(addr))
            ret = PICO_ERROR_GENERIC;
        else
            ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false);

        printf(ret < 0 ? "." : "@");
        printf(addr % 16 == 15 ? "\n" : "  ");
    }
    printf("Done.\n");
    return 0;
#endif
}

Macros

Functions

uint i2c_init (i2c_inst_t *i2c, uint baudrate)

Initialise the I2C HW block.

void i2c_deinit (i2c_inst_t *i2c)

Disable the I2C HW block.

uint i2c_set_baudrate (i2c_inst_t *i2c, uint baudrate)

Set I2C baudrate.

void i2c_set_slave_mode (i2c_inst_t *i2c, bool slave, uint8_t addr)

Set I2C port to slave mode.

static uint i2c_get_index (i2c_inst_t *i2c)

Convert I2C instance to hardware instance number.

static i2c_hw_t * i2c_get_hw (i2c_inst_t *i2c)

Return pointer to structure containing i2c hardware registers.

static i2c_inst_t * i2c_get_instance (uint num)

Convert I2C hardware instance number to I2C instance.

int i2c_write_blocking_until (i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, absolute_time_t until)

Attempt to write specified number of bytes to address, blocking until the specified absolute time is reached.

int i2c_read_blocking_until (i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until)

Attempt to read specified number of bytes from address, blocking until the specified absolute time is reached.

static int i2c_write_timeout_us (i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, uint timeout_us)

Attempt to write specified number of bytes to address, with timeout.

static int i2c_read_timeout_us (i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, uint timeout_us)

Attempt to read specified number of bytes from address, with timeout.

int i2c_write_blocking (i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop)

Attempt to write specified number of bytes to address, blocking.

int i2c_write_burst_blocking (i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len)

Attempt to write specified number of bytes to address, blocking in burst mode.

int i2c_read_blocking (i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop)

Attempt to read specified number of bytes from address, blocking.

int i2c_read_burst_blocking (i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len)

Attempt to read specified number of bytes from address, blocking in burst mode.

static size_t i2c_get_write_available (i2c_inst_t *i2c)

Determine non-blocking write space available.

static size_t i2c_get_read_available (i2c_inst_t *i2c)

Determine number of bytes received.

static void i2c_write_raw_blocking (i2c_inst_t *i2c, const uint8_t *src, size_t len)

Write direct to TX FIFO.

static void i2c_read_raw_blocking (i2c_inst_t *i2c, uint8_t *dst, size_t len)

Read direct from RX FIFO.

static uint8_t i2c_read_byte_raw (i2c_inst_t *i2c)

Pop a byte from I2C Rx FIFO.

static void i2c_write_byte_raw (i2c_inst_t *i2c, uint8_t value)

Push a byte into I2C Tx FIFO.

static uint i2c_get_dreq (i2c_inst_t *i2c, bool is_tx)

Return the DREQ to use for pacing transfers to/from a particular I2C instance.

i2c0_inst

i2c_inst_t i2c0_inst

The I2C identifiers for use in I2C functions.

e.g. i2c_init(i2c0, 48000)

Macro Definition Documentation

I2C_NUM

#define I2C_NUM(i2c)

Returns the I2C number for a I2C instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

I2C_INSTANCE

#define I2C_INSTANCE(num)

Returns the I2C instance with the given I2C number.

Note this macro is intended to resolve at compile time, and does no parameter checking

I2C_DREQ_NUM

#define I2C_DREQ_NUM(i2c, is_tx)

Returns the dreq_num_t used for pacing DMA transfers to or from this I2C instance. If is_tx is true, then it is for transfers to the I2C instance else for transfers from the I2C instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

Function Documentation

i2c_deinit

void i2c_deinit (i2c_inst_t * i2c)

Disable the I2C HW block.

Parameters

i2c

Either i2c0 or i2c1

Disable the I2C again if it is no longer used. Must be reinitialised before being used again.

i2c_get_dreq

static uint i2c_get_dreq (i2c_inst_t * i2c, bool is_tx) [inline], [static]

Return the DREQ to use for pacing transfers to/from a particular I2C instance.

Parameters

i2c

Either i2c0 or i2c1

is_tx

true for sending data to the I2C instance, false for receiving data from the I2C instance

i2c_get_hw

static i2c_hw_t * i2c_get_hw (i2c_inst_t * i2c) [inline], [static]

Return pointer to structure containing i2c hardware registers.

Parameters

i2c

I2C instance

Returns

pointer to i2c_hw_t

i2c_get_index

static uint i2c_get_index (i2c_inst_t * i2c) [inline], [static]

Convert I2C instance to hardware instance number.

Parameters

i2c

I2C instance

Returns

Number of I2C, 0 or 1.

i2c_get_instance

static i2c_inst_t * i2c_get_instance (uint num) [inline], [static]

Convert I2C hardware instance number to I2C instance.

Parameters

num

Number of I2C, 0 or 1

Returns

I2C hardware instance

i2c_get_read_available

static size_t i2c_get_read_available (i2c_inst_t * i2c) [inline], [static]

Determine number of bytes received.

Parameters

i2c

Either i2c0 or i2c1

Returns

0 if no data available, if return is nonzero at least that many bytes can be read without blocking.

i2c_get_write_available

static size_t i2c_get_write_available (i2c_inst_t * i2c) [inline], [static]

Determine non-blocking write space available.

Parameters

i2c

Either i2c0 or i2c1

Returns

0 if no space is available in the I2C to write more data. If return is nonzero, at least that many bytes can be written without blocking.

i2c_init

uint i2c_init (i2c_inst_t * i2c, uint baudrate)

Initialise the I2C HW block.

Put the I2C hardware into a known state, and enable it. Must be called before other functions. By default, the I2C is configured to operate as a master.

The I2C bus frequency is set as close as possible to requested, and the actual rate set is returned

Parameters

i2c

Either i2c0 or i2c1

baudrate

Baudrate in Hz (e.g. 100kHz is 100000)

Returns

Actual set baudrate

i2c_read_blocking

int i2c_read_blocking (i2c_inst_t * i2c, uint8_t addr, uint8_t * dst, size_t len, bool nostop)

Attempt to read specified number of bytes from address, blocking.

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to read from

dst

Pointer to buffer to receive data

len

Length of data in bytes to receive

nostop

If true, master retains control of the bus at the end of the transfer (no Stop is issued), and the next transfer will begin with a Restart rather than a Start.

Returns

Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present.

i2c_read_blocking_until

int i2c_read_blocking_until (i2c_inst_t * i2c, uint8_t addr, uint8_t * dst, size_t len, bool nostop, absolute_time_t until)

Attempt to read specified number of bytes from address, blocking until the specified absolute time is reached.

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to read from

dst

Pointer to buffer to receive data

len

Length of data in bytes to receive

nostop

If true, master retains control of the bus at the end of the transfer (no Stop is issued), and the next transfer will begin with a Restart rather than a Start.

until

The absolute time that the block will wait until the entire transaction is complete.

Returns

Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged, no device present, or PICO_ERROR_TIMEOUT if a timeout occurred.

i2c_read_burst_blocking

int i2c_read_burst_blocking (i2c_inst_t * i2c, uint8_t addr, uint8_t * dst, size_t len)

Attempt to read specified number of bytes from address, blocking in burst mode.

This version of the function will not issue a stop and will not restart on the next read. This allows you to read consecutive bytes of data without having to resend a stop bit and (for example) without having to send address byte(s) repeatedly

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to read from

dst

Pointer to buffer to receive data

len

Length of data in bytes to receive

Returns

Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present.

i2c_read_byte_raw

static uint8_t i2c_read_byte_raw (i2c_inst_t * i2c) [inline], [static]

Pop a byte from I2C Rx FIFO.

This function is non-blocking and assumes the Rx FIFO isn’t empty.

Parameters

i2c

I2C instance.

Returns

uint8_t Byte value.

i2c_read_raw_blocking

static void i2c_read_raw_blocking (i2c_inst_t * i2c, uint8_t * dst, size_t len) [inline], [static]

Read direct from RX FIFO.

Parameters

i2c

Either i2c0 or i2c1

dst

Buffer to accept data

len

Number of bytes to read

Reads directly from the I2C RX FIFO which is mainly useful for slave-mode operation.

i2c_read_timeout_us

static int i2c_read_timeout_us (i2c_inst_t * i2c, uint8_t addr, uint8_t * dst, size_t len, bool nostop, uint timeout_us) [inline], [static]

Attempt to read specified number of bytes from address, with timeout.

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to read from

dst

Pointer to buffer to receive data

len

Length of data in bytes to receive

nostop

If true, master retains control of the bus at the end of the transfer (no Stop is issued), and the next transfer will begin with a Restart rather than a Start.

timeout_us

The time that the function will wait for the entire transaction to complete

Returns

Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged, no device present, or PICO_ERROR_TIMEOUT if a timeout occurred.

i2c_set_baudrate

uint i2c_set_baudrate (i2c_inst_t * i2c, uint baudrate)

Set I2C baudrate.

Set I2C bus frequency as close as possible to requested, and return actual rate set. Baudrate may not be as exactly requested due to clocking limitations.

Parameters

i2c

Either i2c0 or i2c1

baudrate

Baudrate in Hz (e.g. 100kHz is 100000)

Returns

Actual set baudrate

i2c_set_slave_mode

void i2c_set_slave_mode (i2c_inst_t * i2c, bool slave, uint8_t addr)

Set I2C port to slave mode.

Parameters

i2c

Either i2c0 or i2c1

slave

true to use slave mode, false to use master mode

addr

If slave is true, set the slave address to this value

i2c_write_blocking

int i2c_write_blocking (i2c_inst_t * i2c, uint8_t addr, const uint8_t * src, size_t len, bool nostop)

Attempt to write specified number of bytes to address, blocking.

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to write to

src

Pointer to data to send

len

Length of data in bytes to send

nostop

If true, master retains control of the bus at the end of the transfer (no Stop is issued), and the next transfer will begin with a Restart rather than a Start.

Returns

Number of bytes written, or PICO_ERROR_GENERIC if address not acknowledged, no device present.

i2c_write_blocking_until

int i2c_write_blocking_until (i2c_inst_t * i2c, uint8_t addr, const uint8_t * src, size_t len, bool nostop, absolute_time_t until)

Attempt to write specified number of bytes to address, blocking until the specified absolute time is reached.

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to write to

src

Pointer to data to send

len

Length of data in bytes to send

nostop

If true, master retains control of the bus at the end of the transfer (no Stop is issued), and the next transfer will begin with a Restart rather than a Start.

until

The absolute time that the block will wait until the entire transaction is complete. Note, an individual timeout of this value divided by the length of data is applied for each byte transfer, so if the first or subsequent bytes fails to transfer within that sub timeout, the function will return with an error.

Returns

Number of bytes written, or PICO_ERROR_GENERIC if address not acknowledged, no device present, or PICO_ERROR_TIMEOUT if a timeout occurred.

i2c_write_burst_blocking

int i2c_write_burst_blocking (i2c_inst_t * i2c, uint8_t addr, const uint8_t * src, size_t len)

Attempt to write specified number of bytes to address, blocking in burst mode.

This version of the function will not issue a stop and will not restart on the next write. This allows you to write consecutive bytes of data without having to resend a stop bit and (for example) without having to send address byte(s) repeatedly

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to read from

dst

Pointer to buffer to receive data

len

Length of data in bytes to receive

Returns

Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present.

i2c_write_byte_raw

static void i2c_write_byte_raw (i2c_inst_t * i2c, uint8_t value) [inline], [static]

Push a byte into I2C Tx FIFO.

This function is non-blocking and assumes the Tx FIFO isn’t full.

Parameters

i2c

I2C instance.

value

Byte value.

i2c_write_raw_blocking

static void i2c_write_raw_blocking (i2c_inst_t * i2c, const uint8_t * src, size_t len) [inline], [static]

Write direct to TX FIFO.

Parameters

i2c

Either i2c0 or i2c1

src

Data to send

len

Number of bytes to send

Writes directly to the I2C TX FIFO which is mainly useful for slave-mode operation.

i2c_write_timeout_us

static int i2c_write_timeout_us (i2c_inst_t * i2c, uint8_t addr, const uint8_t * src, size_t len, bool nostop, uint timeout_us) [inline], [static]

Attempt to write specified number of bytes to address, with timeout.

Parameters

i2c

Either i2c0 or i2c1

addr

7-bit address of device to write to

src

Pointer to data to send

len

Length of data in bytes to send

nostop

If true, master retains control of the bus at the end of the transfer (no Stop is issued), and the next transfer will begin with a Restart rather than a Start.

timeout_us

The time that the function will wait for the entire transaction to complete. Note, an individual timeout of this value divided by the length of data is applied for each byte transfer, so if the first or subsequent bytes fails to transfer within that sub timeout, the function will return with an error.

Returns

Number of bytes written, or PICO_ERROR_GENERIC if address not acknowledged, no device present, or PICO_ERROR_TIMEOUT if a timeout occurred.

hardware_interp

Hardware Interpolator API.

Detailed Description

Each core is equipped with two interpolators (INTERP0 and INTERP1) which can be used to accelerate tasks by combining certain pre-configured simple operations into a single processor cycle. Intended for cases where the pre-configured operation is repeated a large number of times, this results in code which uses both fewer CPU cycles and fewer CPU registers in the time critical sections of the code.

The interpolators are used heavily to accelerate audio operations within the SDK, but their flexible configuration make it possible to optimise many other tasks such as quantization and dithering, table lookup address generation, affine texture mapping, decompression and linear feedback.

Please refer to the appropriate RP-series microcontroller datasheet for more information on the HW interpolators and how they work.

Modules

interp_config

Interpolator configuration .

Functions

void interp_claim_lane (interp_hw_t *interp, uint lane)

Claim the interpolator lane specified.

void interp_claim_lane_mask (interp_hw_t *interp, uint lane_mask)

Claim the interpolator lanes specified in the mask.

void interp_unclaim_lane (interp_hw_t *interp, uint lane)

Release a previously claimed interpolator lane.

bool interp_lane_is_claimed (interp_hw_t *interp, uint lane)

Determine if an interpolator lane is claimed.

void interp_unclaim_lane_mask (interp_hw_t *interp, uint lane_mask)

Release previously claimed interpolator lanes.

static void interp_set_force_bits (interp_hw_t *interp, uint lane, uint bits)

Directly set the force bits on a specified lane.

void interp_save (interp_hw_t *interp, interp_hw_save_t *saver)

Save the specified interpolator state.

void interp_restore (interp_hw_t *interp, interp_hw_save_t *saver)

Restore an interpolator state.

static void interp_set_base (interp_hw_t *interp, uint lane, uint32_t val)

Sets the interpolator base register by lane.

static uint32_t interp_get_base (interp_hw_t *interp, uint lane)

Gets the content of interpolator base register by lane.

static void interp_set_base_both (interp_hw_t *interp, uint32_t val)

Sets the interpolator base registers simultaneously.

static void interp_set_accumulator (interp_hw_t *interp, uint lane, uint32_t val)

Sets the interpolator accumulator register by lane.

static uint32_t interp_get_accumulator (interp_hw_t *interp, uint lane)

Gets the content of the interpolator accumulator register by lane.

static uint32_t interp_pop_lane_result (interp_hw_t *interp, uint lane)

Read lane result, and write lane results to both accumulators to update the interpolator.

static uint32_t interp_peek_lane_result (interp_hw_t *interp, uint lane)

Read lane result.

static uint32_t interp_pop_full_result (interp_hw_t *interp)

Read lane result, and write lane results to both accumulators to update the interpolator.

static uint32_t interp_peek_full_result (interp_hw_t *interp)

Read lane result.

static void interp_add_accumulator (interp_hw_t *interp, uint lane, uint32_t val)

Add to accumulator.

static uint32_t interp_get_raw (interp_hw_t *interp, uint lane)

Get raw lane value.

Function Documentation

interp_add_accumulator

static void interp_add_accumulator (interp_hw_t * interp, uint lane, uint32_t val) [inline], [static]

Add to accumulator.

Atomically add the specified value to the accumulator on the specified lane

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1

val

Value to add

interp_claim_lane

void interp_claim_lane (interp_hw_t * interp, uint lane)

Claim the interpolator lane specified.

Use this function to claim exclusive access to the specified interpolator lane.

This function will panic if the lane is already claimed.

Parameters

interp

Interpolator on which to claim a lane. interp0 or interp1

lane

The lane number, 0 or 1.

interp_claim_lane_mask

void interp_claim_lane_mask (interp_hw_t * interp, uint lane_mask)

Claim the interpolator lanes specified in the mask.

Parameters

interp

Interpolator on which to claim lanes. interp0 or interp1

lane_mask

Bit pattern of lanes to claim (only bits 0 and 1 are valid)

interp_get_accumulator

static uint32_t interp_get_accumulator (interp_hw_t * interp, uint lane) [inline], [static]

Gets the content of the interpolator accumulator register by lane.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1

Returns

The current content of the register

interp_get_base

static uint32_t interp_get_base (interp_hw_t * interp, uint lane) [inline], [static]

Gets the content of interpolator base register by lane.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1 or 2

Returns

The current content of the lane base register

interp_get_raw

static uint32_t interp_get_raw (interp_hw_t * interp, uint lane) [inline], [static]

Get raw lane value.

Returns the raw shift and mask value from the specified lane, BASE0 is NOT added

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1

Returns

The raw shift/mask value

interp_lane_is_claimed

bool interp_lane_is_claimed (interp_hw_t * interp, uint lane)

Determine if an interpolator lane is claimed.

Parameters

interp

Interpolator whose lane to check

lane

The lane number, 0 or 1

Returns

true if claimed, false otherwise

interp_peek_full_result

static uint32_t interp_peek_full_result (interp_hw_t * interp) [inline], [static]

Read lane result.

Parameters

interp

Interpolator instance, interp0 or interp1.

Returns

The content of the FULL register

interp_peek_lane_result

static uint32_t interp_peek_lane_result (interp_hw_t * interp, uint lane) [inline], [static]

Read lane result.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1

Returns

The content of the lane result register

interp_pop_full_result

static uint32_t interp_pop_full_result (interp_hw_t * interp) [inline], [static]

Read lane result, and write lane results to both accumulators to update the interpolator.

Parameters

interp

Interpolator instance, interp0 or interp1.

Returns

The content of the FULL register

interp_pop_lane_result

static uint32_t interp_pop_lane_result (interp_hw_t * interp, uint lane) [inline], [static]

Read lane result, and write lane results to both accumulators to update the interpolator.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1

Returns

The content of the lane result register

interp_restore

void interp_restore (interp_hw_t * interp, interp_hw_save_t * saver)

Restore an interpolator state.

Parameters

interp

Interpolator instance, interp0 or interp1.

saver

Pointer to save structure to reapply to the specified interpolator

interp_save

void interp_save (interp_hw_t * interp, interp_hw_save_t * saver)

Save the specified interpolator state.

Can be used to save state if you need an interpolator for another purpose, state can then be recovered afterwards and continue from that point

Parameters

interp

Interpolator instance, interp0 or interp1.

saver

Pointer to the save structure to fill in

interp_set_accumulator

static void interp_set_accumulator (interp_hw_t * interp, uint lane, uint32_t val) [inline], [static]

Sets the interpolator accumulator register by lane.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1

val

The value to apply to the register

interp_set_base

static void interp_set_base (interp_hw_t * interp, uint lane, uint32_t val) [inline], [static]

Sets the interpolator base register by lane.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane number, 0 or 1 or 2

val

The value to apply to the register

interp_set_base_both

static void interp_set_base_both (interp_hw_t * interp, uint32_t val) [inline], [static]

Sets the interpolator base registers simultaneously.

The lower 16 bits go to BASE0, upper bits to BASE1 simultaneously. Each half is sign-extended to 32 bits if that lane’s SIGNED flag is set.

Parameters

interp

Interpolator instance, interp0 or interp1.

val

The value to apply to the register

interp_set_force_bits

static void interp_set_force_bits (interp_hw_t * interp, uint lane, uint bits) [inline], [static]

Directly set the force bits on a specified lane.

These bits are ORed into bits 29:28 of the lane result presented to the processor on the bus. There is no effect on the internal 32-bit datapath.

Useful for using a lane to generate sequence of pointers into flash or SRAM, saving a subsequent OR or add operation.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane to set

bits

The bits to set (bits 0 and 1, value range 0-3)

interp_unclaim_lane

void interp_unclaim_lane (interp_hw_t * interp, uint lane)

Release a previously claimed interpolator lane.

Parameters

interp

Interpolator on which to release a lane. interp0 or interp1

lane

The lane number, 0 or 1

interp_unclaim_lane_mask

void interp_unclaim_lane_mask (interp_hw_t * interp, uint lane_mask)

Release previously claimed interpolator lanes.

Parameters

interp

Interpolator on which to release lanes. interp0 or interp1

lane_mask

Bit pattern of lanes to unclaim (only bits 0 and 1 are valid)

interp_config

Interpolator configuration .

Detailed Description

Each interpolator needs to be configured, these functions provide handy helpers to set up configuration structures.

Functions

static void interp_config_set_shift (interp_config *c, uint shift)

Set the interpolator shift value.

static void interp_config_set_mask (interp_config *c, uint mask_lsb, uint mask_msb)

Set the interpolator mask range.

static void interp_config_set_cross_input (interp_config *c, bool cross_input)

Enable cross input.

static void interp_config_set_cross_result (interp_config *c, bool cross_result)

Enable cross results.

static void interp_config_set_signed (interp_config *c, bool _signed)

Set sign extension.

static void interp_config_set_add_raw (interp_config *c, bool add_raw)

Set raw add option.

static void interp_config_set_blend (interp_config *c, bool blend)

Set blend mode.

static void interp_config_set_clamp (interp_config *c, bool clamp)

Set interpolator clamp mode (Interpolator 1 only)

static void interp_config_set_force_bits (interp_config *c, uint bits)

Set interpolator Force bits.

static interp_config interp_default_config (void)

Get a default configuration.

static void interp_set_config (interp_hw_t *interp, uint lane, interp_config *config)

Send configuration to a lane.

Function Documentation

interp_config_set_add_raw

static void interp_config_set_add_raw (interp_config * c, bool add_raw) [inline], [static]

Set raw add option.

When enabled, mask + shift is bypassed for LANE0 result. This does not affect the FULL result.

Parameters

c

Pointer to interpolation config

add_raw

If true, enable raw add option.

interp_config_set_blend

static void interp_config_set_blend (interp_config * c, bool blend) [inline], [static]

Set blend mode.

If enabled, LANE1 result is a linear interpolation between BASE0 and BASE1, controlled by the 8 LSBs of lane 1 shift and mask value (a fractional number between 0 and 255/256ths)

LANE0 result does not have BASE0 added (yields only the 8 LSBs of lane 1 shift+mask value)

FULL result does not have lane 1 shift+mask value added (BASE2 + lane 0 shift+mask)

LANE1 SIGNED flag controls whether the interpolation is signed or unsig

Parameters

c

Pointer to interpolation config

blend

Set true to enable blend mode.

interp_config_set_clamp

static void interp_config_set_clamp (interp_config * c, bool clamp) [inline], [static]

Set interpolator clamp mode (Interpolator 1 only)

Only present on INTERP1 on each core. If CLAMP mode is enabled:

  • LANE0 result is a shifted and masked ACCUM0, clamped by a lower bound of BASE0 and an upper bound of BASE1.

  • Signedness of these comparisons is determined by LANE0_CTRL_SIGNED

Parameters

c

Pointer to interpolation config

clamp

Set true to enable clamp mode

interp_config_set_cross_input

static void interp_config_set_cross_input (interp_config * c, bool cross_input) [inline], [static]

Enable cross input.

Allows feeding of the accumulator content from the other lane back in to this lanes shift+mask hardware. This will take effect even if the interp_config_set_add_raw option is set as the cross input mux is before the shift+mask bypass

Parameters

c

Pointer to interpolation config

cross_input

If true, enable the cross input.

interp_config_set_cross_result

static void interp_config_set_cross_result (interp_config * c, bool cross_result) [inline], [static]

Enable cross results.

Allows feeding of the other lane’s result into this lane’s accumulator on a POP operation.

Parameters

c

Pointer to interpolation config

cross_result

If true, enables the cross result

interp_config_set_force_bits

static void interp_config_set_force_bits (interp_config * c, uint bits) [inline], [static]

Set interpolator Force bits.

ORed into bits 29:28 of the lane result presented to the processor on the bus.

No effect on the internal 32-bit datapath. Handy for using a lane to generate sequence of pointers into flash or SRAM

Parameters

c

Pointer to interpolation config

bits

Sets the force bits to that specified. Range 0-3 (two bits)

interp_config_set_mask

static void interp_config_set_mask (interp_config * c, uint mask_lsb, uint mask_msb) [inline], [static]

Set the interpolator mask range.

Sets the range of bits (least to most) that are allowed to pass through the interpolator

Parameters

c

Pointer to interpolation config

mask_lsb

The least significant bit allowed to pass

mask_msb

The most significant bit allowed to pass

interp_config_set_shift

static void interp_config_set_shift (interp_config * c, uint shift) [inline], [static]

Set the interpolator shift value.

Sets the number of bits the accumulator is shifted before masking, on each iteration.

Parameters

c

Pointer to an interpolator config

shift

Number of bits

interp_config_set_signed

static void interp_config_set_signed (interp_config * c, bool _signed) [inline], [static]

Set sign extension.

Enables signed mode, where the shifted and masked accumulator value is sign-extended to 32 bits before adding to BASE1, and LANE1 PEEK/POP results appear extended to 32 bits when read by processor.

Parameters

c

Pointer to interpolation config

_signed

If true, enables sign extension

interp_default_config

static interp_config interp_default_config (void) [inline], [static]

Get a default configuration.

Returns

A default interpolation configuration

interp_set_config

static void interp_set_config (interp_hw_t * interp, uint lane, interp_config * config) [inline], [static]

Send configuration to a lane.

If an invalid configuration is specified (ie a lane specific item is set on wrong lane), depending on setup this function can panic.

Parameters

interp

Interpolator instance, interp0 or interp1.

lane

The lane to set

config

Pointer to interpolation config

hardware_irq

Hardware interrupt handling API.

Detailed Description

The RP2040 uses the standard ARM nested vectored interrupt controller (NVIC).

Interrupts are identified by a number from 0 to 31.

On the RP2040, only the lower 26 IRQ signals are connected on the NVIC; IRQs 26 to 31 are tied to zero (never firing).

There is one NVIC per core, and each core’s NVIC has the same hardware interrupt lines routed to it, with the exception of the IO interrupts where there is one IO interrupt per bank, per core. These are completely independent, so, for example, processor 0 can be interrupted by GPIO 0 in bank 0, and processor 1 by GPIO 1 in the same bank.

Note

All IRQ APIs affect the executing core only (i.e. the core calling the function).

You should not enable the same (shared) IRQ number on both cores, as this will lead to race conditions or starvation of one of the cores. Additionally, don’t forget that disabling interrupts on one core does not disable interrupts on the other core.

There are three different ways to set handlers for an IRQ:

  • Calling irq_add_shared_handler() at runtime to add a handler for a multiplexed interrupt (e.g. GPIO bank) on the current core. Each handler, should check and clear the relevant hardware interrupt source

  • Calling irq_set_exclusive_handler() at runtime to install a single handler for the interrupt on the current core

  • Defining the interrupt handler explicitly in your application (e.g. by defining void isr_dma_0 will make that function the handler for the DMA_IRQ_0 on core 0, and you will not be able to change it using the above APIs at runtime). Using this method can cause link conflicts at runtime, and offers no runtime performance benefit (i.e, it should not generally be used).

Note

If an IRQ is enabled and fires with no handler installed, a breakpoint will be hit and the IRQ number will be in register r0.

Interrupt Numbers

A set of defines is available (intctrl.h) with these names to avoid using the numbers directly.

On RP2040 the interrupt numbers are as follows:

IRQ Interrupt Source

0

TIMER_IRQ_0

1

TIMER_IRQ_1

2

TIMER_IRQ_2

3

TIMER_IRQ_3

4

PWM_IRQ_WRAP

5

USBCTRL_IRQ

6

XIP_IRQ

7

PIO0_IRQ_0

8

PIO0_IRQ_1

9

PIO1_IRQ_0

10

PIO1_IRQ_1

11

DMA_IRQ_0

12

DMA_IRQ_1

13

IO_IRQ_BANK0

14

IO_IRQ_QSPI

15

SIO_IRQ_PROC0

16

SIO_IRQ_PROC1

17

CLOCKS_IRQ

18

SPI0_IRQ

19

SPI1_IRQ

20

UART0_IRQ

21

UART1_IRQ

22

ADC0_IRQ_FIFO

23

I2C0_IRQ

24

I2C1_IRQ

25

RTC_IRQ

On RP2350 the interrupt numbers are as follows:

IRQ Interrupt Source

0

TIMER0_IRQ_0

1

TIMER0_IRQ_1

2

TIMER0_IRQ_2

3

TIMER0_IRQ_3

4

TIMER1_IRQ_0

5

TIMER1_IRQ_1

6

TIMER1_IRQ_2

7

TIMER1_IRQ_3

8

PWM_IRQ_WRAP_0

9

PWM_IRQ_WRAP_1

10

DMA_IRQ_0

11

DMA_IRQ_1

12

DMA_IRQ_2

13

DMA_IRQ_3

14

USBCTRL_IRQ

15

PIO0_IRQ_0

16

PIO0_IRQ_1

17

PIO1_IRQ_0

18

PIO1_IRQ_1

19

PIO2_IRQ_0

20

PIO2_IRQ_1

21

IO_IRQ_BANK0

22

IO_IRQ_BANK0_NS

23

IO_IRQ_QSPI

24

IO_IRQ_QSPI_NS

25

SIO_IRQ_FIFO

26

SIO_IRQ_BELL

27

SIO_IRQ_FIFO_NS

28

SIO_IRQ_BELL_NS

29

SIO_IRQ_MTIMECMP

30

CLOCKS_IRQ

31

SPI0_IRQ

32

SPI1_IRQ

33

UART0_IRQ

34

UART1_IRQ

35

ADC_IRQ_FIFO

36

I2C0_IRQ

37

I2C1_IRQ

38

OTP_IRQ

39

TRNG_IRQ

40

PROC0_IRQ_CTI

41

PROC1_IRQ_CTI

42

PLL_SYS_IRQ

43

PLL_USB_IRQ

44

POWMAN_IRQ_POW

45

POWMAN_IRQ_TIMER

46

SPAREIRQ_IRQ_0

47

SPAREIRQ_IRQ_1

48

SPAREIRQ_IRQ_2

49

SPAREIRQ_IRQ_3

50

SPAREIRQ_IRQ_4

51

SPAREIRQ_IRQ_5

Typedefs

typedef enum irq_num_rp2350 irq_num_t RP2350

Interrupt numbers on RP2350 (used as typedef irq_num_t)

typedef enum irq_num_rp2040 irq_num_t RP2040

Interrupt numbers on RP2040 (used as typedef irq_num_t)

typedef void(* irq_handler_t)(void)

Interrupt handler function type.

Enumerations

enum irq_num_rp2350 { TIMER0_IRQ_0 = 0, TIMER0_IRQ_1 = 1, TIMER0_IRQ_2 = 2, TIMER0_IRQ_3 = 3, TIMER1_IRQ_0 = 4, TIMER1_IRQ_1 = 5, TIMER1_IRQ_2 = 6, TIMER1_IRQ_3 = 7, PWM_IRQ_WRAP_0 = 8, PWM_IRQ_WRAP_1 = 9, DMA_IRQ_0 = 10, DMA_IRQ_1 = 11, DMA_IRQ_2 = 12, DMA_IRQ_3 = 13, USBCTRL_IRQ = 14, PIO0_IRQ_0 = 15, PIO0_IRQ_1 = 16, PIO1_IRQ_0 = 17, PIO1_IRQ_1 = 18, PIO2_IRQ_0 = 19, PIO2_IRQ_1 = 20, IO_IRQ_BANK0 = 21, IO_IRQ_BANK0_NS = 22, IO_IRQ_QSPI = 23, IO_IRQ_QSPI_NS = 24, SIO_IRQ_FIFO = 25, SIO_IRQ_BELL = 26, SIO_IRQ_FIFO_NS = 27, SIO_IRQ_BELL_NS = 28, SIO_IRQ_MTIMECMP = 29, CLOCKS_IRQ = 30, SPI0_IRQ = 31, SPI1_IRQ = 32, UART0_IRQ = 33, UART1_IRQ = 34, ADC_IRQ_FIFO = 35, I2C0_IRQ = 36, I2C1_IRQ = 37, OTP_IRQ = 38, TRNG_IRQ = 39, PROC0_IRQ_CTI = 40, PROC1_IRQ_CTI = 41, PLL_SYS_IRQ = 42, PLL_USB_IRQ = 43, POWMAN_IRQ_POW = 44, POWMAN_IRQ_TIMER = 45, SPARE_IRQ_0 = 46, SPARE_IRQ_1 = 47, SPARE_IRQ_2 = 48, SPARE_IRQ_3 = 49, SPARE_IRQ_4 = 50, SPARE_IRQ_5 = 51, IRQ_COUNT } RP2350

Interrupt numbers on RP2350 (used as typedef irq_num_t)

enum irq_num_rp2040 { TIMER_IRQ_0 = 0, TIMER_IRQ_1 = 1, TIMER_IRQ_2 = 2, TIMER_IRQ_3 = 3, PWM_IRQ_WRAP = 4, USBCTRL_IRQ = 5, XIP_IRQ = 6, PIO0_IRQ_0 = 7, PIO0_IRQ_1 = 8, PIO1_IRQ_0 = 9, PIO1_IRQ_1 = 10, DMA_IRQ_0 = 11, DMA_IRQ_1 = 12, IO_IRQ_BANK0 = 13, IO_IRQ_QSPI = 14, SIO_IRQ_PROC0 = 15, SIO_IRQ_PROC1 = 16, CLOCKS_IRQ = 17, SPI0_IRQ = 18, SPI1_IRQ = 19, UART0_IRQ = 20, UART1_IRQ = 21, ADC_IRQ_FIFO = 22, I2C0_IRQ = 23, I2C1_IRQ = 24, RTC_IRQ = 25, IRQ_COUNT } RP2040

Interrupt numbers on RP2040 (used as typedef irq_num_t)

Functions

void irq_set_priority (uint num, uint8_t hardware_priority)

Set specified interrupt’s priority.

uint irq_get_priority (uint num)

Get specified interrupt’s priority.

void irq_set_enabled (uint num, bool enabled)

Enable or disable a specific interrupt on the executing core.

bool irq_is_enabled (uint num)

Determine if a specific interrupt is enabled on the executing core.

void irq_set_mask_enabled (uint32_t mask, bool enabled)

Enable/disable multiple interrupts on the executing core.

void irq_set_mask_n_enabled (uint n, uint32_t mask, bool enabled)

Enable/disable multiple interrupts on the executing core.

void irq_set_exclusive_handler (uint num, irq_handler_t handler)

Set an exclusive interrupt handler for an interrupt on the executing core.

irq_handler_t irq_get_exclusive_handler (uint num)

Get the exclusive interrupt handler for an interrupt on the executing core.

void irq_add_shared_handler (uint num, irq_handler_t handler, uint8_t order_priority)

Add a shared interrupt handler for an interrupt on the executing core.

void irq_remove_handler (uint num, irq_handler_t handler)

Remove a specific interrupt handler for the given irq number on the executing core.

bool irq_has_handler (uint num)

Determine if there is an installed IRQ handler for the given interrupt number.

bool irq_has_shared_handler (uint num)

Determine if the current IRQ andler for the given interrupt number is shared.

irq_handler_t irq_get_vtable_handler (uint num)

Get the current IRQ handler for the specified IRQ from the currently installed hardware vector table (VTOR) of the execution core.

static void irq_clear (uint int_num)

Clear a specific interrupt on the executing core.

void irq_set_pending (uint num)

Force an interrupt to be pending on the executing core.

void user_irq_claim (uint irq_num)

Claim ownership of a user IRQ on the calling core.

void user_irq_unclaim (uint irq_num)

Mark a user IRQ as no longer used on the calling core.

int user_irq_claim_unused (bool required)

Claim ownership of a free user IRQ on the calling core.

Typedef Documentation

irq_num_t RP2350

typedef enum irq_num_rp2350 irq_num_t

Interrupt numbers on RP2350 (used as typedef irq_num_t)

irq_num_t RP2040

typedef enum irq_num_rp2040 irq_num_t

Interrupt numbers on RP2040 (used as typedef irq_num_t)

irq_handler_t

typedef void(* irq_handler_t) (void)

Interrupt handler function type.

All interrupts handlers should be of this type, and follow normal ARM EABI register saving conventions

Enumeration Type Documentation

irq_num_rp2350 RP2350

enum irq_num_rp2350

Interrupt numbers on RP2350 (used as typedef irq_num_t)

Table 14. Enumerator

TIMER0_IRQ_0

Select TIMER0’s IRQ 0 output.

TIMER0_IRQ_1

Select TIMER0’s IRQ 1 output.

TIMER0_IRQ_2

Select TIMER0’s IRQ 2 output.

TIMER0_IRQ_3

Select TIMER0’s IRQ 3 output.

TIMER1_IRQ_0

Select TIMER1’s IRQ 0 output.

TIMER1_IRQ_1

Select TIMER1’s IRQ 1 output.

TIMER1_IRQ_2

Select TIMER1’s IRQ 2 output.

TIMER1_IRQ_3

Select TIMER1’s IRQ 3 output.

PWM_IRQ_WRAP_0

Select PWM’s IRQ_WRAP 0 output.

PWM_IRQ_WRAP_1

Select PWM’s IRQ_WRAP 1 output.

DMA_IRQ_0

Select DMA’s IRQ 0 output.

DMA_IRQ_1

Select DMA’s IRQ 1 output.

DMA_IRQ_2

Select DMA’s IRQ 2 output.

DMA_IRQ_3

Select DMA’s IRQ 3 output.

USBCTRL_IRQ

Select USBCTRL’s IRQ output.

PIO0_IRQ_0

Select PIO0’s IRQ 0 output.

PIO0_IRQ_1

Select PIO0’s IRQ 1 output.

PIO1_IRQ_0

Select PIO1’s IRQ 0 output.

PIO1_IRQ_1

Select PIO1’s IRQ 1 output.

PIO2_IRQ_0

Select PIO2’s IRQ 0 output.

PIO2_IRQ_1

Select PIO2’s IRQ 1 output.

IO_IRQ_BANK0

Select IO_BANK0’s IRQ output.

IO_IRQ_BANK0_NS

Select IO_BANK0_NS’s IRQ output.

IO_IRQ_QSPI

Select IO_QSPI’s IRQ output.

IO_IRQ_QSPI_NS

Select IO_QSPI_NS’s IRQ output.

SIO_IRQ_FIFO

Select SIO’s IRQ_FIFO output.

SIO_IRQ_BELL

Select SIO’s IRQ_BELL output.

SIO_IRQ_FIFO_NS

Select SIO_NS’s IRQ_FIFO output.

SIO_IRQ_BELL_NS

Select SIO_NS’s IRQ_BELL output.

SIO_IRQ_MTIMECMP

Select SIO_IRQ_MTIMECMP’s IRQ output.

CLOCKS_IRQ

Select CLOCKS’s IRQ output.

SPI0_IRQ

Select SPI0’s IRQ output.

SPI1_IRQ

Select SPI1’s IRQ output.

UART0_IRQ

Select UART0’s IRQ output.

UART1_IRQ

Select UART1’s IRQ output.

ADC_IRQ_FIFO

Select ADC’s IRQ_FIFO output.

I2C0_IRQ

Select I2C0’s IRQ output.

I2C1_IRQ

Select I2C1’s IRQ output.

OTP_IRQ

Select OTP’s IRQ output.

TRNG_IRQ

Select TRNG’s IRQ output.

PROC0_IRQ_CTI

Select PROC0’s IRQ_CTI output.

PROC1_IRQ_CTI

Select PROC1’s IRQ_CTI output.

PLL_SYS_IRQ

Select PLL_SYS’s IRQ output.

PLL_USB_IRQ

Select PLL_USB’s IRQ output.

POWMAN_IRQ_POW

Select POWMAN’s IRQ_POW output.

POWMAN_IRQ_TIMER

Select POWMAN’s IRQ_TIMER output.

SPARE_IRQ_0

Select SPARE IRQ 0.

SPARE_IRQ_1

Select SPARE IRQ 1.

SPARE_IRQ_2

Select SPARE IRQ 2.

SPARE_IRQ_3

Select SPARE IRQ 3.

SPARE_IRQ_4

Select SPARE IRQ 4.

SPARE_IRQ_5

Select SPARE IRQ 5.

irq_num_rp2040 RP2040

enum irq_num_rp2040

Interrupt numbers on RP2040 (used as typedef irq_num_t)

Table 15. Enumerator

TIMER_IRQ_0

Select TIMER’s IRQ 0 output.

TIMER_IRQ_1

Select TIMER’s IRQ 1 output.

TIMER_IRQ_2

Select TIMER’s IRQ 2 output.

TIMER_IRQ_3

Select TIMER’s IRQ 3 output.

PWM_IRQ_WRAP

Select PWM’s IRQ_WRAP output.

USBCTRL_IRQ

Select USBCTRL’s IRQ output.

XIP_IRQ

Select XIP’s IRQ output.

PIO0_IRQ_0

Select PIO0’s IRQ 0 output.

PIO0_IRQ_1

Select PIO0’s IRQ 1 output.

PIO1_IRQ_0

Select PIO1’s IRQ 0 output.

PIO1_IRQ_1

Select PIO1’s IRQ 1 output.

DMA_IRQ_0

Select DMA’s IRQ 0 output.

DMA_IRQ_1

Select DMA’s IRQ 1 output.

IO_IRQ_BANK0

Select IO_BANK0’s IRQ output.

IO_IRQ_QSPI

Select IO_QSPI’s IRQ output.

SIO_IRQ_PROC0

Select SIO_PROC0’s IRQ output.

SIO_IRQ_PROC1

Select SIO_PROC1’s IRQ output.

CLOCKS_IRQ

Select CLOCKS’s IRQ output.

SPI0_IRQ

Select SPI0’s IRQ output.

SPI1_IRQ

Select SPI1’s IRQ output.

UART0_IRQ

Select UART0’s IRQ output.

UART1_IRQ

Select UART1’s IRQ output.

ADC_IRQ_FIFO

Select ADC’s IRQ_FIFO output.

I2C0_IRQ

Select I2C0’s IRQ output.

I2C1_IRQ

Select I2C1’s IRQ output.

RTC_IRQ

Select RTC’s IRQ output.

Function Documentation

irq_add_shared_handler

void irq_add_shared_handler (uint num, irq_handler_t handler, uint8_t order_priority)

Add a shared interrupt handler for an interrupt on the executing core.

Use this method to add a handler on an irq number shared between multiple distinct hardware sources (e.g. GPIO, DMA or PIO IRQs). Handlers added by this method will all be called in sequence from highest order_priority to lowest. The irq_set_exclusive_handler() method should be used instead if you know there will or should only ever be one handler for the interrupt.

This method will assert if there is an exclusive interrupt handler set for this irq number on this core, or if the (total across all IRQs on both cores) maximum (configurable via PICO_MAX_SHARED_IRQ_HANDLERS) number of shared handlers would be exceeded.

Note
By default, the SDK uses a single shared vector table for both cores, and the currently installed IRQ handlers are effectively a linked list starting a vector table entry for a particular IRQ number. Therefore, this method (when using the same vector table for both cores) add the same interrupt handler for both cores.

On RP2040 this was never really a cause of any confusion, because it rarely made sense to enable the same interrupt number in the NVIC on both cores (see irq_set_enabled()), because the interrupt would then fire on both cores, and the interrupt handlers would race.

The problem does exist however when dealing with interrupts which are independent on the two cores.

This includes:

  • the core local "spare" IRQs

  • on RP2350 the SIO FIFO IRQ which is now the same irq number for both cores (vs RP2040 where it was two)

In the cases where you want to enable the same IRQ on both cores, and both cores are sharing the same vector table, you should install the IRQ handler once - it will be used on both cores - and check the core number (via get_core_num()) on each core.

Note
It is not thread safe to add/remove/handle IRQs for the same irq number in the same vector table from both cores concurrently.
Note
The SDK has a PICO_VTABLE_PER_CORE define indicating whether the two vector tables are separate, however as of version 2.1.1 the user cannot set this value, and expect the vector table duplication to be handled for them. This functionality will be added in a future SDK version

Parameters

num

Interrupt number Interrupt Numbers

handler

The handler to set. See irq_handler_t

order_priority

The order priority controls the order that handlers for the same IRQ number on the core are called. The shared irq handlers for an interrupt are all called when an IRQ fires, however the order of the calls is based on the order_priority (higher priorities are called first, identical priorities are called in undefined order). A good rule of thumb is to use PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY if you don’t much care, as it is in the middle of the priority range by default.

Note

The order_priority uses higher values for higher priorities which is the opposite of the CPU interrupt priorities passed to irq_set_priority() which use lower values for higher priorities.

irq_clear

static void irq_clear (uint int_num) [inline], [static]

Clear a specific interrupt on the executing core.

This method is only useful for "software" IRQs that are not connected to hardware (e.g. IRQs 26-31 on RP2040) as the the NVIC always reflects the current state of the IRQ state of the hardware for hardware IRQs, and clearing of the IRQ state of the hardware is performed via the hardware’s registers instead.

Parameters

int_num

Interrupt number Interrupt Numbers

irq_get_exclusive_handler

irq_handler_t irq_get_exclusive_handler (uint num)

Get the exclusive interrupt handler for an interrupt on the executing core.

This method will return an exclusive IRQ handler set on this core by irq_set_exclusive_handler if there is one.

Parameters

num

Interrupt number Interrupt Numbers

Returns

handler The handler if an exclusive handler is set for the IRQ, NULL if no handler is set or shared/shareable handlers are installed

irq_get_priority

uint irq_get_priority (uint num)

Get specified interrupt’s priority.

Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority). To make it easier to specify higher or lower priorities than the default, all IRQ priorities are initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup. PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80

Only the top 2 bits are significant on ARM Cortex-M0+ on RP2040.

Only the top 4 bits are significant on ARM Cortex-M33 or Hazard3 (RISC-V) on RP2350. Note that this API uses the same (inverted) ordering as ARM on RISC-V

Parameters

num

Interrupt number Interrupt Numbers

Returns

the IRQ priority

irq_get_vtable_handler

irq_handler_t irq_get_vtable_handler (uint num)

Get the current IRQ handler for the specified IRQ from the currently installed hardware vector table (VTOR) of the execution core.

Parameters

num

Interrupt number Interrupt Numbers

Returns

the address stored in the VTABLE for the given irq number

irq_has_handler

bool irq_has_handler (uint num)

Determine if there is an installed IRQ handler for the given interrupt number.

See irq_set_exclusive_handler() for discussion on the scope of handlers when using both cores.

Parameters

num

Interrupt number Interrupt Numbers

Returns

true if the specified IRQ has a handler

irq_has_shared_handler

bool irq_has_shared_handler (uint num)

Determine if the current IRQ andler for the given interrupt number is shared.

See irq_set_exclusive_handler() for discussion on the scope of handlers when using both cores.

Parameters

num

Interrupt number Interrupt Numbers

Returns

true if the specified IRQ has a shared handler

irq_is_enabled

bool irq_is_enabled (uint num)

Determine if a specific interrupt is enabled on the executing core.

Parameters

num

Interrupt number Interrupt Numbers

Returns

true if the interrupt is enabled

irq_remove_handler

void irq_remove_handler (uint num, irq_handler_t handler)

Remove a specific interrupt handler for the given irq number on the executing core.

This method may be used to remove an irq set via either irq_set_exclusive_handler() or irq_add_shared_handler(), and will assert if the handler is not currently installed for the given IRQ number

Note

This method may only be called from user (non IRQ code) or from within the handler itself (i.e. an IRQ handler may remove itself as part of handling the IRQ). Attempts to call from another IRQ will cause an assertion.

Parameters

num

Interrupt number Interrupt Numbers

handler

The handler to removed.

irq_set_enabled

void irq_set_enabled (uint num, bool enabled)

Enable or disable a specific interrupt on the executing core.

Parameters

num

Interrupt number Interrupt Numbers

enabled

true to enable the interrupt, false to disable

irq_set_exclusive_handler

void irq_set_exclusive_handler (uint num, irq_handler_t handler)

Set an exclusive interrupt handler for an interrupt on the executing core.

Use this method to set a handler for single IRQ source interrupts, or when your code, use case or performance requirements dictate that there should be no other handlers for the interrupt.

This method will assert if there is already any sort of interrupt handler installed for the specified irq number.

Note
By default, the SDK uses a single shared vector table for both cores, and the currently installed IRQ handlers are effectively a linked list starting a vector table entry for a particular IRQ number. Therefore, this method (when using the same vector table for both cores) sets the same interrupt handler for both cores.

On RP2040 this was never really a cause of any confusion, because it rarely made sense to enable the same interrupt number in the NVIC on both cores (see irq_set_enabled()), because the interrupt would then fire on both cores, and the interrupt handlers would race.

The problem does exist however when dealing with interrupts which are independent on the two cores.

This includes:

  • the core local "spare" IRQs

  • on RP2350 the SIO FIFO IRQ which is now the same irq number for both cores (vs RP2040 where it was two)

In the cases where you want to enable the same IRQ on both cores, and both cores are sharing the same vector table, you should install the IRQ handler once - it will be used on both cores - and check the core number (via get_core_num()) on each core.

Note
It is not thread safe to add/remove/handle IRQs for the same irq number in the same vector table from both cores concurrently.
Note
The SDK has a PICO_VTABLE_PER_CORE define indicating whether the two vector tables are separate, however as of version 2.1.1 the user cannot set this value, and expect the vector table duplication to be handled for them. This functionality will be added in a future SDK version

Parameters

num

Interrupt number Interrupt Numbers

handler

The handler to set. See irq_handler_t

irq_set_mask_enabled

void irq_set_mask_enabled (uint32_t mask, bool enabled)

Enable/disable multiple interrupts on the executing core.

Parameters

mask

32-bit mask with one bits set for the interrupts to enable/disable Interrupt Numbers

enabled

true to enable the interrupts, false to disable them.

irq_set_mask_n_enabled

void irq_set_mask_n_enabled (uint n, uint32_t mask, bool enabled)

Enable/disable multiple interrupts on the executing core.

Parameters

n

the index of the mask to update. n == 0 means 0->31, n == 1 mean 32->63 etc.

mask

32-bit mask with one bits set for the interrupts to enable/disable Interrupt Numbers

enabled

true to enable the interrupts, false to disable them.

irq_set_pending

void irq_set_pending (uint num)

Force an interrupt to be pending on the executing core.

This should generally not be used for IRQs connected to hardware.

Parameters

num

Interrupt number Interrupt Numbers

irq_set_priority

void irq_set_priority (uint num, uint8_t hardware_priority)

Set specified interrupt’s priority.

Parameters

num

Interrupt number Interrupt Numbers

hardware_priority

Priority to set. Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority). To make it easier to specify higher or lower priorities than the default, all IRQ priorities are initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup. PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80

Only the top 2 bits are significant on ARM Cortex-M0+ on RP2040.

Only the top 4 bits are significant on ARM Cortex-M33 or Hazard3 (RISC-V) on RP2350. Note that this API uses the same (inverted) ordering as ARM on RISC-V

user_irq_claim

void user_irq_claim (uint irq_num)

Claim ownership of a user IRQ on the calling core.

User IRQs starting from FIRST_USER_IRQ are not connected to any hardware, but can be triggered by irq_set_pending.

Note

User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly claims ownership of a user IRQ, so other code can know it is being used.

Parameters

irq_num

the user IRQ to claim

user_irq_claim_unused

int user_irq_claim_unused (bool required)

Claim ownership of a free user IRQ on the calling core.

User IRQs starting from FIRST_USER_IRQ are not connected to any hardware, but can be triggered by irq_set_pending.

Note

User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly claims ownership of an unused user IRQ if there is one, so other code can know it is being used.

Parameters

required

if true the function will panic if none are available

Returns

the user IRQ number or -1 if required was false, and none were free

user_irq_unclaim

void user_irq_unclaim (uint irq_num)

Mark a user IRQ as no longer used on the calling core.

User IRQs starting from FIRST_USER_IRQ are not connected to any hardware, but can be triggered by irq_set_pending.

Note

User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly releases ownership of a user IRQ, so other code can know it is free to use.

Note

it is customary to have disabled the irq and removed the handler prior to calling this method.

Parameters

irq_num

the irq irq_num to unclaim

hardware_pio

Programmable I/O (PIO) API.

Detailed Description

A programmable input/output block (PIO) is a versatile hardware interface which can support a number of different IO standards.

There are two PIO blocks in the RP2040.

There are three PIO blocks in the RP2350

Each PIO is programmable in the same sense as a processor: the four state machines independently execute short, sequential programs, to manipulate GPIOs and transfer data. Unlike a general purpose processor, PIO state machines are highly specialised for IO, with a focus on determinism, precise timing, and close integration with fixed-function hardware. Each state machine is equipped with:

  • Two 32-bit shift registers – either direction, any shift count

  • Two 32-bit scratch registers

  • 4×32 bit bus FIFO in each direction (TX/RX), reconfigurable as 8×32 in a single direction

  • Fractional clock divider (16 integer, 8 fractional bits)

  • Flexible GPIO mapping

  • DMA interface, sustained throughput up to 1 word per clock from system DMA

  • IRQ flag set/clear/status

Full details of the PIO can be found in the appropriate RP-series datasheet. Note that there are additional features in the RP2350 PIO implementation that mean care should be taken when writing PIO code that needs to run on both the RP2040 and the RP2350.

On RP2040, pin numbers may always be specified from 0-31

On RP2350A, pin numbers may always be specified from 0-31.

On RP2350B, there are 48 pins but each PIO instance can only address 32 pins (the PIO instance either addresses pins 0-31 or 16-47 based on pio_set_gpio_base). The pio_sm_ methods that directly affect the hardware always take real pin numbers in the full range, however:

  • If PICO_PIO_USE_GPIO_BASE != 1 then the 5th bit of the pin number is ignored. This is done so that programs compiled for boards with RP2350A do not incur the extra overhead of dealing with higher pins that don’t exist. Effectively these functions behave exactly like RP2040 in this case. Note that PICO_PIO_USE_GPIO_BASE is defaulted to 0 if PICO_RP2350A is 1

  • If PICO_PIO_USE_GPIO_BASE == 1 then the passed pin numbers are adjusted internally by subtracting the GPIO base to give a pin number in the range 0-31 from the PIO’s perspective

You can set PARAM_ASSERTIONS_ENABLED_HARDWARE_PIO = 1 to enable parameter checking to debug pin (or other) issues with hardware_pio methods.

Note that pin masks follow the same rules as individual pins; bit N of a 32-bit or 64-bit mask always refers to pin N.

Modules

sm_config

PIO state machine configuration .

pio_instructions

PIO instruction encoding .

Macros

Typedefs

typedef enum pio_interrupt_source pio_interrupt_source_t

PIO interrupt source numbers for pio related IRQs.

Enumerations

enum pio_fifo_join { PIO_FIFO_JOIN_NONE = 0, PIO_FIFO_JOIN_TX = 1, PIO_FIFO_JOIN_RX = 2 }

FIFO join states.

enum pio_mov_status_type { STATUS_TX_LESSTHAN = 0, STATUS_RX_LESSTHAN = 1 }

MOV status types.

enum pio_interrupt_source { pis_interrupt0 = PIO_INTR_SM0_LSB, pis_interrupt1 = PIO_INTR_SM1_LSB, pis_interrupt2 = PIO_INTR_SM2_LSB, pis_interrupt3 = PIO_INTR_SM3_LSB, pis_sm0_tx_fifo_not_full = PIO_INTR_SM0_TXNFULL_LSB, pis_sm1_tx_fifo_not_full = PIO_INTR_SM1_TXNFULL_LSB, pis_sm2_tx_fifo_not_full = PIO_INTR_SM2_TXNFULL_LSB, pis_sm3_tx_fifo_not_full = PIO_INTR_SM3_TXNFULL_LSB, pis_sm0_rx_fifo_not_empty = PIO_INTR_SM0_RXNEMPTY_LSB, pis_sm1_rx_fifo_not_empty = PIO_INTR_SM1_RXNEMPTY_LSB, pis_sm2_rx_fifo_not_empty = PIO_INTR_SM2_RXNEMPTY_LSB, pis_sm3_rx_fifo_not_empty = PIO_INTR_SM3_RXNEMPTY_LSB }

PIO interrupt source numbers for pio related IRQs.

Functions

static uint pio_get_gpio_base (PIO pio)

Return the base GPIO base for the PIO instance.

static int pio_sm_set_config (PIO pio, uint sm, const pio_sm_config *config)

Apply a state machine configuration to a state machine.

static uint pio_get_index (PIO pio)

Return the instance number of a PIO instance.

static uint pio_get_funcsel (PIO pio)

Return the funcsel number of a PIO instance.

static PIO pio_get_instance (uint instance)

Convert PIO instance to hardware instance.

static void pio_gpio_init (PIO pio, uint pin)

Setup the function select for a GPIO to use output from the given PIO instance.

static uint pio_get_dreq (PIO pio, uint sm, bool is_tx)

Return the DREQ to use for pacing transfers to/from a particular state machine FIFO.

int pio_set_gpio_base (PIO pio, uint gpio_base)

Set the base GPIO base for the PIO instance.

bool pio_can_add_program (PIO pio, const pio_program_t *program)

Determine whether the given program can (at the time of the call) be loaded onto the PIO instance.

bool pio_can_add_program_at_offset (PIO pio, const pio_program_t *program, uint offset)

Determine whether the given program can (at the time of the call) be loaded onto the PIO instance starting at a particular location.

int pio_add_program (PIO pio, const pio_program_t *program)

Attempt to load the program.

int pio_add_program_at_offset (PIO pio, const pio_program_t *program, uint offset)

Attempt to load the program at the specified instruction memory offset.

void pio_remove_program (PIO pio, const pio_program_t *program, uint loaded_offset)

Remove a program from a PIO instance’s instruction memory.

void pio_clear_instruction_memory (PIO pio)

Clears all of a PIO instance’s instruction memory.

static void pio_sm_set_enabled (PIO pio, uint sm, bool enabled)

Enable or disable a PIO state machine.

static void pio_set_sm_mask_enabled (PIO pio, uint32_t mask, bool enabled)

Enable or disable multiple PIO state machines.

static void pio_sm_restart (PIO pio, uint sm)

Restart a state machine with a known state.

static void pio_restart_sm_mask (PIO pio, uint32_t mask)

Restart multiple state machine with a known state.

static void pio_sm_clkdiv_restart (PIO pio, uint sm)

Restart a state machine’s clock divider from a phase of 0.

static void pio_clkdiv_restart_sm_mask (PIO pio, uint32_t mask)

Restart multiple state machines' clock dividers from a phase of 0.

static void pio_enable_sm_mask_in_sync (PIO pio, uint32_t mask)

Enable multiple PIO state machines synchronizing their clock dividers.

static void pio_set_irq0_source_enabled (PIO pio, pio_interrupt_source_t source, bool enabled)

Enable/Disable a single source on a PIO’s IRQ 0.

static void pio_set_irq1_source_enabled (PIO pio, pio_interrupt_source_t source, bool enabled)

Enable/Disable a single source on a PIO’s IRQ 1.

static void pio_set_irq0_source_mask_enabled (PIO pio, uint32_t source_mask, bool enabled)

Enable/Disable multiple sources on a PIO’s IRQ 0.

static void pio_set_irq1_source_mask_enabled (PIO pio, uint32_t source_mask, bool enabled)

Enable/Disable multiple sources on a PIO’s IRQ 1.

static void pio_set_irqn_source_enabled (PIO pio, uint irq_index, pio_interrupt_source_t source, bool enabled)

Enable/Disable a single source on a PIO’s specified (0/1) IRQ index.

static void pio_set_irqn_source_mask_enabled (PIO pio, uint irq_index, uint32_t source_mask, bool enabled)

Enable/Disable multiple sources on a PIO’s specified (0/1) IRQ index.

static bool pio_interrupt_get (PIO pio, uint pio_interrupt_num)

Determine if a particular PIO interrupt is set.

static void pio_interrupt_clear (PIO pio, uint pio_interrupt_num)

Clear a particular PIO interrupt.

static uint8_t pio_sm_get_pc (PIO pio, uint sm)

Return the current program counter for a state machine.

static void pio_sm_exec (PIO pio, uint sm, uint instr)

Immediately execute an instruction on a state machine.

static bool pio_sm_is_exec_stalled (PIO pio, uint sm)

Determine if an instruction set by pio_sm_exec() is stalled executing.

static void pio_sm_exec_wait_blocking (PIO pio, uint sm, uint instr)

Immediately execute an instruction on a state machine and wait for it to complete.

static void pio_sm_set_wrap (PIO pio, uint sm, uint wrap_target, uint wrap)

Set the current wrap configuration for a state machine.

static void pio_sm_set_out_pins (PIO pio, uint sm, uint out_base, uint out_count)

Set the current 'out' pins for a state machine.

static void pio_sm_set_set_pins (PIO pio, uint sm, uint set_base, uint set_count)

Set the current 'set' pins for a state machine.

static void pio_sm_set_in_pins (PIO pio, uint sm, uint in_base)

Set the current 'in' pins for a state machine.

static void pio_sm_set_sideset_pins (PIO pio, uint sm, uint sideset_base)

Set the current 'sideset' pins for a state machine.

static void pio_sm_set_jmp_pin (PIO pio, uint sm, uint pin)

Set the 'jmp' pin for a state machine.

static void pio_sm_put (PIO pio, uint sm, uint32_t data)

Write a word of data to a state machine’s TX FIFO.

static uint32_t pio_sm_get (PIO pio, uint sm)

Read a word of data from a state machine’s RX FIFO.

static bool pio_sm_is_rx_fifo_full (PIO pio, uint sm)

Determine if a state machine’s RX FIFO is full.

static bool pio_sm_is_rx_fifo_empty (PIO pio, uint sm)

Determine if a state machine’s RX FIFO is empty.

static uint pio_sm_get_rx_fifo_level (PIO pio, uint sm)

Return the number of elements currently in a state machine’s RX FIFO.

static bool pio_sm_is_tx_fifo_full (PIO pio, uint sm)

Determine if a state machine’s TX FIFO is full.

static bool pio_sm_is_tx_fifo_empty (PIO pio, uint sm)

Determine if a state machine’s TX FIFO is empty.

static uint pio_sm_get_tx_fifo_level (PIO pio, uint sm)

Return the number of elements currently in a state machine’s TX FIFO.

static void pio_sm_put_blocking (PIO pio, uint sm, uint32_t data)

Write a word of data to a state machine’s TX FIFO, blocking if the FIFO is full.

static uint32_t pio_sm_get_blocking (PIO pio, uint sm)

Read a word of data from a state machine’s RX FIFO, blocking if the FIFO is empty.

void pio_sm_drain_tx_fifo (PIO pio, uint sm)

Empty out a state machine’s TX FIFO.

static void pio_sm_set_clkdiv_int_frac8 (PIO pio, uint sm, uint32_t div_int, uint8_t div_frac8)

set the current clock divider for a state machine using a 16:8 fraction

static void pio_sm_set_clkdiv (PIO pio, uint sm, float div)

set the current clock divider for a state machine

static void pio_sm_clear_fifos (PIO pio, uint sm)

Clear a state machine’s TX and RX FIFOs.

void pio_sm_set_pins (PIO pio, uint sm, uint32_t pin_values)

Use a state machine to set a value on all pins for the PIO instance.

void pio_sm_set_pins64 (PIO pio, uint sm, uint64_t pin_values)

Use a state machine to set a value on all pins for the PIO instance.

void pio_sm_set_pins_with_mask (PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask)

Use a state machine to set a value on multiple pins for the PIO instance.

void pio_sm_set_pins_with_mask64 (PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask)

Use a state machine to set a value on multiple pins for the PIO instance.

void pio_sm_set_pindirs_with_mask (PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask)

Use a state machine to set the pin directions for multiple pins for the PIO instance.

void pio_sm_set_pindirs_with_mask64 (PIO pio, uint sm, uint64_t pin_dirs, uint64_t pin_mask)

Use a state machine to set the pin directions for multiple pins for the PIO instance.

int pio_sm_set_consecutive_pindirs (PIO pio, uint sm, uint pins_base, uint pin_count, bool is_out)

Use a state machine to set the same pin direction for multiple consecutive pins for the PIO instance.

void pio_sm_claim (PIO pio, uint sm)

Mark a state machine as used.

void pio_claim_sm_mask (PIO pio, uint sm_mask)

Mark multiple state machines as used.

void pio_sm_unclaim (PIO pio, uint sm)

Mark a state machine as no longer used.

int pio_claim_unused_sm (PIO pio, bool required)

Claim a free state machine on a PIO instance.

bool pio_sm_is_claimed (PIO pio, uint sm)

Determine if a PIO state machine is claimed.

bool pio_claim_free_sm_and_add_program (const pio_program_t *program, PIO *pio, uint *sm, uint *offset)

Finds a PIO and statemachine and adds a program into PIO memory.

bool pio_claim_free_sm_and_add_program_for_gpio_range (const pio_program_t *program, PIO *pio, uint *sm, uint *offset, uint gpio_base, uint gpio_count, bool set_gpio_base)

Finds a PIO and statemachine and adds a program into PIO memory.

void pio_remove_program_and_unclaim_sm (const pio_program_t *program, PIO pio, uint sm, uint offset)

Removes a program from PIO memory and unclaims the state machine.

static int pio_get_irq_num (PIO pio, uint irqn)

Return an IRQ for a PIO hardware instance.

static pio_interrupt_source_t pio_get_tx_fifo_not_full_interrupt_source (uint sm)

Return the interrupt source for a state machines TX FIFO not full interrupt.

static pio_interrupt_source_t pio_get_rx_fifo_not_empty_interrupt_source (uint sm)

Return the interrupt source for a state machines RX FIFO not empty interrupt.

Macro Definition Documentation

pio0

#define pio0 pio0_hw

Identifier for the first (PIO 0) hardware PIO instance (for use in PIO functions).

e.g. pio_gpio_init(pio0, 5)

pio1

#define pio1 pio1_hw

Identifier for the second (PIO 1) hardware PIO instance (for use in PIO functions).

e.g. pio_gpio_init(pio1, 5)

PIO_NUM

#define PIO_NUM(pio)

Returns the PIO number for a PIO instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

PIO_INSTANCE

#define PIO_INSTANCE(instance)

Returns the PIO instance with the given PIO number.

Note this macro is intended to resolve at compile time, and does no parameter checking

PIO_FUNCSEL_NUM

#define PIO_FUNCSEL_NUM(pio, gpio)

Returns gpio_function_t needed to select the PIO function for the given PIO instance on the given GPIO.

Note this macro is intended to resolve at compile time, and does no parameter checking

PIO_DREQ_NUM

#define PIO_DREQ_NUM(pio, sm, is_tx)

Returns the dreq_num_t used for pacing DMA transfers to or from a given state machine’s FIFOs on this PIO instance. If is_tx is true, then it is for transfers to the PIO state machine TX FIFO else for transfers from the PIO state machine RX FIFO.

Note this macro is intended to resolve at compile time, and does no parameter checking

PIO_IRQ_NUM

#define PIO_IRQ_NUM(pio, irqn)

Returns the irq_num_t for processor interrupts from the given PIO instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

Typedef Documentation

pio_interrupt_source_t

typedef enum pio_interrupt_source pio_interrupt_source_t

PIO interrupt source numbers for pio related IRQs.

Enumeration Type Documentation

pio_fifo_join

enum pio_fifo_join

FIFO join states.

Table 16. Enumerator

PIO_FIFO_JOIN_NONE

TX FIFO length=4 is used for transmit, RX FIFO length=4 is used for receive.

PIO_FIFO_JOIN_TX

TX FIFO length=8 is used for transmit, RX FIFO is disabled.

PIO_FIFO_JOIN_RX

RX FIFO length=8 is used for receive, TX FIFO is disabled.

pio_mov_status_type

enum pio_mov_status_type

MOV status types.

pio_interrupt_source

enum pio_interrupt_source

PIO interrupt source numbers for pio related IRQs.

Table 17. Enumerator

pis_interrupt0

PIO interrupt 0 is raised.

pis_interrupt1

PIO interrupt 1 is raised.

pis_interrupt2

PIO interrupt 2 is raised.

pis_interrupt3

PIO interrupt 3 is raised.

pis_sm0_tx_fifo_not_full

State machine 0 TX FIFO is not full.

pis_sm1_tx_fifo_not_full

State machine 1 TX FIFO is not full.

pis_sm2_tx_fifo_not_full

State machine 2 TX FIFO is not full.

pis_sm3_tx_fifo_not_full

State machine 3 TX FIFO is not full.

pis_sm0_rx_fifo_not_empty

State machine 0 RX FIFO is not empty.

pis_sm1_rx_fifo_not_empty

State machine 1 RX FIFO is not empty.

pis_sm2_rx_fifo_not_empty

State machine 2 RX FIFO is not empty.

pis_sm3_rx_fifo_not_empty

State machine 3 RX FIFO is not empty.

Function Documentation

pio_add_program

int pio_add_program (PIO pio, const pio_program_t * program)

Attempt to load the program.

See also

pio_can_add_program() if you need to check whether the program can be loaded

Parameters

pio

The PIO instance; e.g. pio0 or pio1

program

the program definition

Returns

the instruction memory offset the program is loaded at, or negative for error (for backwards compatibility with prior SDK the error value is -1 i.e. PICO_ERROR_GENERIC)

pio_add_program_at_offset

int pio_add_program_at_offset (PIO pio, const pio_program_t * program, uint offset)

Attempt to load the program at the specified instruction memory offset.

See also

pio_can_add_program_at_offset() if you need to check whether the program can be loaded

Parameters

pio

The PIO instance; e.g. pio0 or pio1

program

the program definition

offset

the instruction memory offset wanted for the start of the program

Returns

the instruction memory offset the program is loaded at, or negative for error (for backwards compatibility with prior SDK the error value is -1 i.e. PICO_ERROR_GENERIC)

pio_can_add_program

bool pio_can_add_program (PIO pio, const pio_program_t * program)

Determine whether the given program can (at the time of the call) be loaded onto the PIO instance.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

program

the program definition

Returns

true if the program can be loaded; false if not, e.g. if there is not suitable space in the instruction memory

pio_can_add_program_at_offset

bool pio_can_add_program_at_offset (PIO pio, const pio_program_t * program, uint offset)

Determine whether the given program can (at the time of the call) be loaded onto the PIO instance starting at a particular location.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

program

the program definition

offset

the instruction memory offset wanted for the start of the program

Returns

true if the program can be loaded at that location; false if not, e.g. if there is not space in the instruction memory

pio_claim_free_sm_and_add_program

bool pio_claim_free_sm_and_add_program (const pio_program_t * program, PIO * pio, uint * sm, uint * offset)

Finds a PIO and statemachine and adds a program into PIO memory.

Parameters

program

PIO program to add

pio

Returns the PIO hardware instance or NULL if no PIO is available

sm

Returns the index of the PIO state machine that was claimed

offset

Returns the instruction memory offset of the start of the program

Returns

true on success, false otherwise

See also

pio_remove_program_unclaim_sm

pio_claim_free_sm_and_add_program_for_gpio_range

bool pio_claim_free_sm_and_add_program_for_gpio_range (const pio_program_t * program, PIO * pio, uint * sm, uint * offset, uint gpio_base, uint gpio_count, bool set_gpio_base)

Finds a PIO and statemachine and adds a program into PIO memory.

This variation of pio_claim_free_sm_and_add_program is useful on RP2350 QFN80 where the "GPIO Base" must be set per PIO instance to either address the 32 GPIOs (0->31) or the 32 GPIOS (16-47). No single PIO instance can interact with both pins 0->15 or 32->47 at the same time.

This method takes additional information about the GPIO pins needed (via gpio_base and gpio_count), and optionally will set the GPIO base (

See also

pio_set_gpio_base) of an unused PIO instance if necessary

Parameters

program

PIO program to add

pio

Returns the PIO hardware instance or NULL if no PIO is available

sm

Returns the index of the PIO state machine that was claimed

offset

Returns the instruction memory offset of the start of the program

gpio_base

the lowest GPIO number required (0-47 on RP2350B, 0-31 otherwise)

gpio_count

the count of GPIOs required

set_gpio_base

if there is no free SM on a PIO instance with the right GPIO base, and there IS an unused PIO instance, then that PIO will be reconfigured so that this method can succeed

Returns

true on success, false otherwise

See also

pio_remove_program_unclaim_sm

pio_claim_sm_mask

void pio_claim_sm_mask (PIO pio, uint sm_mask)

Mark multiple state machines as used.

Method for cooperative claiming of hardware. Will cause a panic if any of the state machines are already claimed. Use of this method by libraries detects accidental configurations that would fail in unpredictable ways.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm_mask

Mask of state machine indexes

pio_claim_unused_sm

int pio_claim_unused_sm (PIO pio, bool required)

Claim a free state machine on a PIO instance.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

required

if true the function will panic if none are available

Returns

the state machine index or negative if required was false, and none were free (for backwards compatibility with prior SDK the error value is -1 i.e. PICO_ERROR_GENERIC)

pio_clear_instruction_memory

void pio_clear_instruction_memory (PIO pio)

Clears all of a PIO instance’s instruction memory.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

pio_clkdiv_restart_sm_mask

static void pio_clkdiv_restart_sm_mask (PIO pio, uint32_t mask) [inline], [static]

Restart multiple state machines' clock dividers from a phase of 0.

Each state machine’s clock divider is a free-running piece of hardware, that generates a pattern of clock enable pulses for the state machine, based only on the configured integer/fractional divisor. The pattern of running/halted cycles slows the state machine’s execution to some controlled rate.

This function simultaneously clears the integer and fractional phase accumulators of multiple state machines' clock dividers. If these state machines all have the same integer and fractional divisors configured, their clock dividers will run in precise deterministic lockstep from this point.

With their execution clocks synchronised in this way, it is then safe to e.g. have multiple state machines performing a 'wait irq' on the same flag, and all clear it on the same cycle.

Also note that this function can be called whilst state machines are running (e.g. if you have just changed the clock divisors of some state machines and wish to resynchronise them), and that disabling a state machine does not halt its clock divider: that is, if multiple state machines have their clocks synchronised, you can safely disable and re-enable one of the state machines without losing synchronisation.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

mask

bit mask of state machine indexes to modify the enabled state of

pio_enable_sm_mask_in_sync

static void pio_enable_sm_mask_in_sync (PIO pio, uint32_t mask) [inline], [static]

Enable multiple PIO state machines synchronizing their clock dividers.

This is equivalent to calling both pio_set_sm_mask_enabled() and pio_clkdiv_restart_sm_mask() on the same clock cycle. All state machines specified by 'mask' are started simultaneously and, assuming they have the same clock divisors, their divided clocks will stay precisely synchronised.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

mask

bit mask of state machine indexes to modify the enabled state of

pio_get_dreq

static uint pio_get_dreq (PIO pio, uint sm, bool is_tx) [inline], [static]

Return the DREQ to use for pacing transfers to/from a particular state machine FIFO.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

is_tx

true for sending data to the state machine, false for receiving data from the state machine

pio_get_funcsel

static uint pio_get_funcsel (PIO pio) [inline], [static]

Return the funcsel number of a PIO instance.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

Returns

the PIO instance number (0, 1, …​)

See also

gpio_function

pio_get_gpio_base

static uint pio_get_gpio_base (PIO pio) [inline], [static]

Return the base GPIO base for the PIO instance.

This method always return 0 in RP2040

Parameters

pio

The PIO instance; e.g. pio0 or pio1

Returns

the current GPIO base for the PIO instance

pio_get_index

static uint pio_get_index (PIO pio) [inline], [static]

Return the instance number of a PIO instance.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

Returns

the PIO instance number (0, 1, …​)

pio_get_instance

static PIO pio_get_instance (uint instance) [inline], [static]

Convert PIO instance to hardware instance.

Parameters

instance

Instance of PIO, 0 or 1

Returns

the PIO hardware instance

pio_get_irq_num

static int pio_get_irq_num (PIO pio, uint irqn) [inline], [static]

Return an IRQ for a PIO hardware instance.

Parameters

pio

PIO hardware instance

irqn

0 for PIOx_IRQ_0 or 1 for PIOx_IRQ_1 etc where x is the PIO number

Returns

The IRQ number to use for the PIO

pio_get_rx_fifo_not_empty_interrupt_source

static pio_interrupt_source_t pio_get_rx_fifo_not_empty_interrupt_source (uint sm) [inline], [static]

Return the interrupt source for a state machines RX FIFO not empty interrupt.

Parameters

sm

State machine index (0..3)

Returns

The interrupt source number for use in pio_set_irqn_source_enabled or similar functions

pio_get_tx_fifo_not_full_interrupt_source

static pio_interrupt_source_t pio_get_tx_fifo_not_full_interrupt_source (uint sm) [inline], [static]

Return the interrupt source for a state machines TX FIFO not full interrupt.

Parameters

sm

State machine index (0..3)

Returns

The interrupt source number for use in pio_set_irqn_source_enabled or similar functions

pio_gpio_init

static void pio_gpio_init (PIO pio, uint pin) [inline], [static]

Setup the function select for a GPIO to use output from the given PIO instance.

PIO appears as an alternate function in the GPIO muxing, just like an SPI or UART. This function configures that multiplexing to connect a given PIO instance to a GPIO. Note that this is not necessary for a state machine to be able to read the input value from a GPIO, but only for it to set the output value or output enable.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

pin

the GPIO pin whose function select to set

pio_interrupt_clear

static void pio_interrupt_clear (PIO pio, uint pio_interrupt_num) [inline], [static]

Clear a particular PIO interrupt.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

pio_interrupt_num

the PIO interrupt number 0-7

pio_interrupt_get

static bool pio_interrupt_get (PIO pio, uint pio_interrupt_num) [inline], [static]

Determine if a particular PIO interrupt is set.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

pio_interrupt_num

the PIO interrupt number 0-7

Returns

true if corresponding PIO interrupt is currently set

pio_remove_program

void pio_remove_program (PIO pio, const pio_program_t * program, uint loaded_offset)

Remove a program from a PIO instance’s instruction memory.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

program

the program definition

loaded_offset

the loaded offset returned when the program was added

pio_remove_program_and_unclaim_sm

void pio_remove_program_and_unclaim_sm (const pio_program_t * program, PIO pio, uint sm, uint offset)

Removes a program from PIO memory and unclaims the state machine.

Parameters

program

PIO program to remove from memory

pio

PIO hardware instance being used

sm

PIO state machine that was claimed

offset

offset of the program in PIO memory

pio_restart_sm_mask

static void pio_restart_sm_mask (PIO pio, uint32_t mask) [inline], [static]

Restart multiple state machine with a known state.

This method clears the ISR, shift counters, clock divider counter pin write flags, delay counter, latched EXEC instruction, and IRQ wait condition.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

mask

bit mask of state machine indexes to modify the enabled state of

pio_set_gpio_base

int pio_set_gpio_base (PIO pio, uint gpio_base)

Set the base GPIO base for the PIO instance.

Since an individual PIO accesses only 32 pins, to be able to access more pins, the PIO instance must specify a base GPIO where the instance’s "pin 0" maps. For RP2350 the valid values are 0 and 16, indicating the PIO instance has access to pins 0-31, or 16-47 respectively.

Note
This method simply changes the underlying PIO register, it does not detect or attempt to prevent any side effects this change will have on in use state machines on this PIO.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

gpio_base

the GPIO base (either 0 or 16)

Returns

PICO_OK (0) on success, error code otherwise

pio_set_irq0_source_enabled

static void pio_set_irq0_source_enabled (PIO pio, pio_interrupt_source_t source, bool enabled) [inline], [static]

Enable/Disable a single source on a PIO’s IRQ 0.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

source

the source number (see pio_interrupt_source)

enabled

true to enable IRQ 0 for the source, false to disable.

pio_set_irq0_source_mask_enabled

static void pio_set_irq0_source_mask_enabled (PIO pio, uint32_t source_mask, bool enabled) [inline], [static]

Enable/Disable multiple sources on a PIO’s IRQ 0.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

source_mask

Mask of bits, one for each source number (see pio_interrupt_source) to affect

enabled

true to enable all the sources specified in the mask on IRQ 0, false to disable all the sources specified in the mask on IRQ 0

pio_set_irq1_source_enabled

static void pio_set_irq1_source_enabled (PIO pio, pio_interrupt_source_t source, bool enabled) [inline], [static]

Enable/Disable a single source on a PIO’s IRQ 1.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

source

the source number (see pio_interrupt_source)

enabled

true to enable IRQ 0 for the source, false to disable.

pio_set_irq1_source_mask_enabled

static void pio_set_irq1_source_mask_enabled (PIO pio, uint32_t source_mask, bool enabled) [inline], [static]

Enable/Disable multiple sources on a PIO’s IRQ 1.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

source_mask

Mask of bits, one for each source number (see pio_interrupt_source) to affect

enabled

true to enable all the sources specified in the mask on IRQ 1, false to disable all the source specified in the mask on IRQ 1

pio_set_irqn_source_enabled

static void pio_set_irqn_source_enabled (PIO pio, uint irq_index, pio_interrupt_source_t source, bool enabled) [inline], [static]

Enable/Disable a single source on a PIO’s specified (0/1) IRQ index.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

irq_index

the IRQ index; either 0 or 1

source

the source number (see pio_interrupt_source)

enabled

true to enable the source on the specified IRQ, false to disable.

pio_set_irqn_source_mask_enabled

static void pio_set_irqn_source_mask_enabled (PIO pio, uint irq_index, uint32_t source_mask, bool enabled) [inline], [static]

Enable/Disable multiple sources on a PIO’s specified (0/1) IRQ index.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

irq_index

the IRQ index; either 0 or 1

source_mask

Mask of bits, one for each source number (see pio_interrupt_source) to affect

enabled

true to enable all the sources specified in the mask on the specified IRQ, false to disable all the sources specified in the mask on the specified IRQ

pio_set_sm_mask_enabled

static void pio_set_sm_mask_enabled (PIO pio, uint32_t mask, bool enabled) [inline], [static]

Enable or disable multiple PIO state machines.

Note that this method just sets the enabled state of the state machine; if now enabled they continue exactly from where they left off.

See also

pio_enable_sm_mask_in_sync() if you wish to enable multiple state machines and ensure their clock dividers are in sync.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

mask

bit mask of state machine indexes to modify the enabled state of

enabled

true to enable the state machines; false to disable

pio_sm_claim

void pio_sm_claim (PIO pio, uint sm)

Mark a state machine as used.

Method for cooperative claiming of hardware. Will cause a panic if the state machine is already claimed. Use of this method by libraries detects accidental configurations that would fail in unpredictable ways.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pio_sm_clear_fifos

static void pio_sm_clear_fifos (PIO pio, uint sm) [inline], [static]

Clear a state machine’s TX and RX FIFOs.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pio_sm_clkdiv_restart

static void pio_sm_clkdiv_restart (PIO pio, uint sm) [inline], [static]

Restart a state machine’s clock divider from a phase of 0.

Each state machine’s clock divider is a free-running piece of hardware, that generates a pattern of clock enable pulses for the state machine, based only on the configured integer/fractional divisor. The pattern of running/halted cycles slows the state machine’s execution to some controlled rate.

This function clears the divider’s integer and fractional phase accumulators so that it restarts this pattern from the beginning. It is called automatically by pio_sm_init() but can also be called at a later time, when you enable the state machine, to ensure precisely consistent timing each time you load and run a given PIO program.

More commonly this hardware mechanism is used to synchronise the execution clocks of multiple state machines – see pio_clkdiv_restart_sm_mask().

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pio_sm_drain_tx_fifo

void pio_sm_drain_tx_fifo (PIO pio, uint sm)

Empty out a state machine’s TX FIFO.

This method executes pull instructions on the state machine until the TX FIFO is empty. This disturbs the contents of the OSR, so see also pio_sm_clear_fifos() which clears both FIFOs but leaves the state machine’s internal state undisturbed.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pio_sm_exec

static void pio_sm_exec (PIO pio, uint sm, uint instr) [inline], [static]

Immediately execute an instruction on a state machine.

This instruction is executed instead of the next instruction in the normal control flow on the state machine. Subsequent calls to this method replace the previous executed instruction if it is still running.

See also

pio_sm_is_exec_stalled() to see if an executed instruction is still running (i.e. it is stalled on some condition)

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

instr

the encoded PIO instruction

pio_sm_exec_wait_blocking

static void pio_sm_exec_wait_blocking (PIO pio, uint sm, uint instr) [inline], [static]

Immediately execute an instruction on a state machine and wait for it to complete.

This instruction is executed instead of the next instruction in the normal control flow on the state machine. Subsequent calls to this method replace the previous executed instruction if it is still running.

See also

pio_sm_is_exec_stalled() to see if an executed instruction is still running (i.e. it is stalled on some condition)

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

instr

the encoded PIO instruction

pio_sm_get

static uint32_t pio_sm_get (PIO pio, uint sm) [inline], [static]

Read a word of data from a state machine’s RX FIFO.

This is a raw FIFO access that does not check for emptiness. If the FIFO is empty, the hardware ignores the attempt to read from the FIFO (the FIFO remains in an empty state following the read) and the sticky RXUNDER flag for this FIFO is set in FDEBUG to indicate that the system tried to read from this FIFO when empty. The data returned by this function is undefined when the FIFO is empty.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pio_sm_get_blocking

static uint32_t pio_sm_get_blocking (PIO pio, uint sm) [inline], [static]

Read a word of data from a state machine’s RX FIFO, blocking if the FIFO is empty.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pio_sm_get_pc

static uint8_t pio_sm_get_pc (PIO pio, uint sm) [inline], [static]

Return the current program counter for a state machine.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

the program counter

pio_sm_get_rx_fifo_level

static uint pio_sm_get_rx_fifo_level (PIO pio, uint sm) [inline], [static]

Return the number of elements currently in a state machine’s RX FIFO.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

the number of elements in the RX FIFO

pio_sm_get_tx_fifo_level

static uint pio_sm_get_tx_fifo_level (PIO pio, uint sm) [inline], [static]

Return the number of elements currently in a state machine’s TX FIFO.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

the number of elements in the TX FIFO

pio_sm_is_claimed

bool pio_sm_is_claimed (PIO pio, uint sm)

Determine if a PIO state machine is claimed.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

true if claimed, false otherwise

pio_sm_is_exec_stalled

static bool pio_sm_is_exec_stalled (PIO pio, uint sm) [inline], [static]

Determine if an instruction set by pio_sm_exec() is stalled executing.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

true if the executed instruction is still running (stalled)

pio_sm_is_rx_fifo_empty

static bool pio_sm_is_rx_fifo_empty (PIO pio, uint sm) [inline], [static]

Determine if a state machine’s RX FIFO is empty.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

true if the RX FIFO is empty

pio_sm_is_rx_fifo_full

static bool pio_sm_is_rx_fifo_full (PIO pio, uint sm) [inline], [static]

Determine if a state machine’s RX FIFO is full.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

true if the RX FIFO is full

pio_sm_is_tx_fifo_empty

static bool pio_sm_is_tx_fifo_empty (PIO pio, uint sm) [inline], [static]

Determine if a state machine’s TX FIFO is empty.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

true if the TX FIFO is empty

pio_sm_is_tx_fifo_full

static bool pio_sm_is_tx_fifo_full (PIO pio, uint sm) [inline], [static]

Determine if a state machine’s TX FIFO is full.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

Returns

true if the TX FIFO is full

pio_sm_put

static void pio_sm_put (PIO pio, uint sm, uint32_t data) [inline], [static]

Write a word of data to a state machine’s TX FIFO.

This is a raw FIFO access that does not check for fullness. If the FIFO is full, the FIFO contents and state are not affected by the write attempt. Hardware sets the TXOVER sticky flag for this FIFO in FDEBUG, to indicate that the system attempted to write to a full FIFO.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

data

the 32 bit data value

pio_sm_put_blocking

static void pio_sm_put_blocking (PIO pio, uint sm, uint32_t data) [inline], [static]

Write a word of data to a state machine’s TX FIFO, blocking if the FIFO is full.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

data

the 32 bit data value

pio_sm_restart

static void pio_sm_restart (PIO pio, uint sm) [inline], [static]

Restart a state machine with a known state.

This method clears the ISR, shift counters, clock divider counter pin write flags, delay counter, latched EXEC instruction, and IRQ wait condition.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pio_sm_set_clkdiv

static void pio_sm_set_clkdiv (PIO pio, uint sm, float div) [inline], [static]

set the current clock divider for a state machine

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

div

the floating point clock divider

pio_sm_set_clkdiv_int_frac8

static void pio_sm_set_clkdiv_int_frac8 (PIO pio, uint sm, uint32_t div_int, uint8_t div_frac8) [inline], [static]

set the current clock divider for a state machine using a 16:8 fraction

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

div_int

the integer part of the clock divider

div_frac8

the fractional part of the clock divider in 1/256s

pio_sm_set_config

static int pio_sm_set_config (PIO pio, uint sm, const pio_sm_config * config) [inline], [static]

Apply a state machine configuration to a state machine.

See sm_config_ pins for more detail on why this method might fail on RP2350B

Parameters

pio

Handle to PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

config

the configuration to apply

Returns

PICO_OK (0) on success, negative error code otherwise

pio_sm_set_consecutive_pindirs

int pio_sm_set_consecutive_pindirs (PIO pio, uint sm, uint pins_base, uint pin_count, bool is_out)

Use a state machine to set the same pin direction for multiple consecutive pins for the PIO instance.

This method repeatedly reconfigures the target state machine’s pin configuration and executes 'set' instructions to set the pin direction on consecutive pins, before restoring the state machine’s pin configuration to what it was.

This method is provided as a convenience to set initial pin directions, and should not be used against a state machine that is enabled.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3) to use

pins_base

the first pin to set a direction for. See pio_sm_ pins for more detail on pin arguments

pin_count

the count of consecutive pins to set the direction for

is_out

the direction to set; true = out, false = in

Returns

PICO_OK (0) on success, error code otherwise

pio_sm_set_enabled

static void pio_sm_set_enabled (PIO pio, uint sm, bool enabled) [inline], [static]

Enable or disable a PIO state machine.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

enabled

true to enable the state machine; false to disable

pio_sm_set_in_pins

static void pio_sm_set_in_pins (PIO pio, uint sm, uint in_base) [inline], [static]

Set the current 'in' pins for a state machine.

'in' pins can overlap with the 'out', 'set' and 'sideset' pins

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

in_base

First pin to use as input. See pio_sm_ pins for more detail on pin arguments

pio_sm_set_jmp_pin

static void pio_sm_set_jmp_pin (PIO pio, uint sm, uint pin) [inline], [static]

Set the 'jmp' pin for a state machine.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

pin

The pin number to use as the source for a jmp pin instruction. See pio_sm_ pins for more detail on pin arguments

pio_sm_set_out_pins

static void pio_sm_set_out_pins (PIO pio, uint sm, uint out_base, uint out_count) [inline], [static]

Set the current 'out' pins for a state machine.

'out' pins can overlap with the 'in', 'set' and 'sideset' pins

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

out_base

First pin to set as output. See pio_sm_ pins for more detail on pin arguments

out_count

0-32 Number of pins to set.

pio_sm_set_pindirs_with_mask

void pio_sm_set_pindirs_with_mask (PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask)

Use a state machine to set the pin directions for multiple pins for the PIO instance.

This method repeatedly reconfigures the target state machine’s pin configuration and executes 'set' instructions to set pin directions on up to 32 pins, before restoring the state machine’s pin configuration to what it was.

This method is provided as a convenience to set initial pin directions, and should not be used against a state machine that is enabled. Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pindirs_with_mask64

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3) to use

pin_dirs

the pin directions to set - 1 = out, 0 = in (if the corresponding bit in pin_mask is set)

pin_mask

a bit for each pin to indicate whether the corresponding pin_value for that pin should be applied.

pio_sm_set_pindirs_with_mask64

void pio_sm_set_pindirs_with_mask64 (PIO pio, uint sm, uint64_t pin_dirs, uint64_t pin_mask)

Use a state machine to set the pin directions for multiple pins for the PIO instance.

This method repeatedly reconfigures the target state machine’s pin configuration and executes 'set' instructions to set pin directions on up to 32 pins, before restoring the state machine’s pin configuration to what it was.

This method is provided as a convenience to set initial pin directions, and should not be used against a state machine that is enabled.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3) to use

pin_dirs

the pin directions to set - 1 = out, 0 = in (if the corresponding bit in pin_mask is set)

pin_mask

a bit for each pin to indicate whether the corresponding pin_value for that pin should be applied.

pio_sm_set_pins

void pio_sm_set_pins (PIO pio, uint sm, uint32_t pin_values)

Use a state machine to set a value on all pins for the PIO instance.

This method repeatedly reconfigures the target state machine’s pin configuration and executes 'set' instructions to set values on all 32 pins, before restoring the state machine’s pin configuration to what it was.

This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled. Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pins64

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3) to use

pin_values

the pin values to set. See pio_sm_ pins for more detail on pin arguments

pio_sm_set_pins64

void pio_sm_set_pins64 (PIO pio, uint sm, uint64_t pin_values)

Use a state machine to set a value on all pins for the PIO instance.

This method repeatedly reconfigures the target state machine’s pin configuration and executes 'set' instructions to set values on all 32 pins, before restoring the state machine’s pin configuration to what it was.

This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3) to use

pin_values

the pin values to set. See pio_sm_ pins for more detail on pin arguments

pio_sm_set_pins_with_mask

void pio_sm_set_pins_with_mask (PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask)

Use a state machine to set a value on multiple pins for the PIO instance.

This method repeatedly reconfigures the target state machine’s pin configuration and executes 'set' instructions to set values on up to 32 pins, before restoring the state machine’s pin configuration to what it was.

This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled. Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pins_with_mask64

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3) to use

pin_values

the pin values to set (if the corresponding bit in pin_mask is set)

pin_mask

a bit for each pin to indicate whether the corresponding pin_value for that pin should be applied. See pio_sm_ pins for more detail on pin arguments

pio_sm_set_pins_with_mask64

void pio_sm_set_pins_with_mask64 (PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask)

Use a state machine to set a value on multiple pins for the PIO instance.

This method repeatedly reconfigures the target state machine’s pin configuration and executes 'set' instructions to set values on up to 32 pins, before restoring the state machine’s pin configuration to what it was.

This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3) to use

pin_values

the pin values to set (if the corresponding bit in pin_mask is set)

pin_mask

a bit for each pin to indicate whether the corresponding pin_value for that pin should be applied. See pio_sm_ pins for more detail on pin arguments

pio_sm_set_set_pins

static void pio_sm_set_set_pins (PIO pio, uint sm, uint set_base, uint set_count) [inline], [static]

Set the current 'set' pins for a state machine.

'set' pins can overlap with the 'in', 'out' and 'sideset' pins

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

set_base

First pin to set as 'set'. See pio_sm_ pins for more detail on pin arguments

set_count

0-5 Number of pins to set.

pio_sm_set_sideset_pins

static void pio_sm_set_sideset_pins (PIO pio, uint sm, uint sideset_base) [inline], [static]

Set the current 'sideset' pins for a state machine.

'sideset' pins can overlap with the 'in', 'out' and 'set' pins

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

sideset_base

Base pin for 'side set'. See pio_sm_ pins for more detail on pin arguments

pio_sm_set_wrap

static void pio_sm_set_wrap (PIO pio, uint sm, uint wrap_target, uint wrap) [inline], [static]

Set the current wrap configuration for a state machine.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

wrap_target

the instruction memory address to wrap to

wrap

the instruction memory address after which to set the program counter to wrap_target if the instruction does not itself update the program_counter

pio_sm_unclaim

void pio_sm_unclaim (PIO pio, uint sm)

Mark a state machine as no longer used.

Method for cooperative claiming of hardware.

Parameters

pio

The PIO instance; e.g. pio0 or pio1

sm

State machine index (0..3)

sm_config

PIO state machine configuration .

Detailed Description

A PIO block needs to be configured, these functions provide helpers to set up configuration structures. See pio_sm_set_config

On RP2040, pin numbers may always be specified from 0-31

On RP2350A, pin numbers may always be specified from 0-31.

On RP2350B, there are 48 pins but each PIO instance can only address 32 pins (the PIO instance either addresses pins 0-31 or 16-47 based on pio_set_gpio_base). The sm_config_ state machine configuration always take real pin numbers in the full range, however:

  • If PICO_PIO_USE_GPIO_BASE != 1 then the 5th bit of the pin number is ignored. This is done so that programs compiled for boards with RP2350A do not incur the extra overhead of dealing with higher pins that don’t exist. Effectively these functions behave exactly like RP2040 in this case. Note that PICO_PIO_USE_GPIO_BASE is defaulted to 0 if PICO_RP2350A is 1

  • If PICO_PIO_USE_GPIO_BASE == 1 then the state machine configuration stores the actual pin numbers in the range 0-47. Of course in this scenario, it is possible to make an invalid configuration (one which uses pins in both the ranges 0-15 and 32-47).

    pio_sm_set_config (or pio_sm_init which calls it) attempts to apply the configuration to a particular PIO’s state machine, and will return PICO_ERROR_BAD_ALIGNMENT if the configuration cannot be applied due to the above problem, or if the PIO’s GPIO base (see pio_set_gpio_base) does not allow access to the required pins.

    To be clear, pio_sm_set_config does not change the PIO’s GPIO base for you; you must configre the PIO’s GPIO base before calling the method, however you can use pio_claim_free_sm_and_add_program_for_gpio_range to find/configure a PIO instance suitable for a partiular GPIO range.

You can set PARAM_ASSERTIONS_ENABLED_HARDWARE_PIO = 1 to enable parameter checking to debug pin (or other) issues with hardware_pio methods.

Functions

static void sm_config_set_out_pin_base (pio_sm_config *c, uint out_base)

Set the base of the 'out' pins in a state machine configuration.

static void sm_config_set_out_pin_count (pio_sm_config *c, uint out_count)

Set the number of 'out' pins in a state machine configuration.

static void sm_config_set_out_pins (pio_sm_config *c, uint out_base, uint out_count)

Set the 'out' pins in a state machine configuration.

static void sm_config_set_set_pin_base (pio_sm_config *c, uint set_base)

Set the base of the 'set' pins in a state machine configuration.

static void sm_config_set_set_pin_count (pio_sm_config *c, uint set_count)

Set the count of 'set' pins in a state machine configuration.

static void sm_config_set_set_pins (pio_sm_config *c, uint set_base, uint set_count)

Set the 'set' pins in a state machine configuration.

static void sm_config_set_in_pin_base (pio_sm_config *c, uint in_base)

Set the base of the 'in' pins in a state machine configuration.

static void sm_config_set_in_pins (pio_sm_config *c, uint in_base)

Set the base for the 'in' pins in a state machine configuration.

static void sm_config_set_in_pin_count (pio_sm_config *c, uint in_count)

Set the count of 'in' pins in a state machine configuration.

static void sm_config_set_sideset_pin_base (pio_sm_config *c, uint sideset_base)

Set the base of the 'sideset' pins in a state machine configuration.

static void sm_config_set_sideset_pins (pio_sm_config *c, uint sideset_base)

Set the 'sideset' pins in a state machine configuration.

static void sm_config_set_sideset (pio_sm_config *c, uint bit_count, bool optional, bool pindirs)

Set the 'sideset' options in a state machine configuration.

static void sm_config_set_clkdiv_int_frac8 (pio_sm_config *c, uint32_t div_int, uint8_t div_frac8)

Set the state machine clock divider (from integer and fractional parts - 16:8) in a state machine configuration.

static void sm_config_set_clkdiv (pio_sm_config *c, float div)

Set the state machine clock divider (from a floating point value) in a state machine configuration.

static void sm_config_set_wrap (pio_sm_config *c, uint wrap_target, uint wrap)

Set the wrap addresses in a state machine configuration.

static void sm_config_set_jmp_pin (pio_sm_config *c, uint pin)

Set the 'jmp' pin in a state machine configuration.

static void sm_config_set_in_shift (pio_sm_config *c, bool shift_right, bool autopush, uint push_threshold)

Setup 'in' shifting parameters in a state machine configuration.

static void sm_config_set_out_shift (pio_sm_config *c, bool shift_right, bool autopull, uint pull_threshold)

Setup 'out' shifting parameters in a state machine configuration.

static void sm_config_set_fifo_join (pio_sm_config *c, enum pio_fifo_join join)

Setup the FIFO joining in a state machine configuration.

static void sm_config_set_out_special (pio_sm_config *c, bool sticky, bool has_enable_pin, uint enable_bit_index)

Set special 'out' operations in a state machine configuration.

static void sm_config_set_mov_status (pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n)

Set source for 'mov status' in a state machine configuration.

static pio_sm_config pio_get_default_sm_config (void)

Get the default state machine configuration.

Function Documentation

pio_get_default_sm_config

static pio_sm_config pio_get_default_sm_config (void) [inline], [static]

Get the default state machine configuration.

Setting Default

Out Pins

32 starting at 0

Set Pins

0 starting at 0

In Pins

32 starting at 0

Side Set Pins (base)

0

Side Set

disabled

Wrap

wrap=31, wrap_to=0

In Shift

shift_direction=right, autopush=false, push_threshold=32

Out Shift

shift_direction=right, autopull=false, pull_threshold=32

Jmp Pin

0

Out Special

sticky=false, has_enable_pin=false, enable_pin_index=0

Mov Status

status_sel=STATUS_TX_LESSTHAN, n=0

Returns

the default state machine configuration which can then be modified.

sm_config_set_clkdiv

static void sm_config_set_clkdiv (pio_sm_config * c, float div) [inline], [static]

Set the state machine clock divider (from a floating point value) in a state machine configuration.

The clock divider slows the state machine’s execution by masking the system clock on some cycles, in a repeating pattern, so that the state machine does not advance. Effectively this produces a slower clock for the state machine to run from, which can be used to generate e.g. a particular UART baud rate. See the datasheet for further detail.

Parameters

c

Pointer to the configuration structure to modify

div

The fractional divisor to be set. 1 for full speed. An integer clock divisor of n will cause the state machine to run 1 cycle in every n. Note that for small n, the jitter introduced by a fractional divider (e.g. 2.5) may be unacceptable although it will depend on the use case.

sm_config_set_clkdiv_int_frac8

static void sm_config_set_clkdiv_int_frac8 (pio_sm_config * c, uint32_t div_int, uint8_t div_frac8) [inline], [static]

Set the state machine clock divider (from integer and fractional parts - 16:8) in a state machine configuration.

The clock divider can slow the state machine’s execution to some rate below the system clock frequency, by enabling the state machine on some cycles but not on others, in a regular pattern. This can be used to generate e.g. a given UART baud rate. See the datasheet for further detail.

Parameters

c

Pointer to the configuration structure to modify

div_int

Integer part of the divisor

div_frac8

Fractional part in 1/256ths

sm_config_set_fifo_join

static void sm_config_set_fifo_join (pio_sm_config * c, enum pio_fifo_join join) [inline], [static]

Setup the FIFO joining in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

join

Specifies the join type.

See also

sm_config_set_in_pin_base

static void sm_config_set_in_pin_base (pio_sm_config * c, uint in_base) [inline], [static]

Set the base of the 'in' pins in a state machine configuration.

'in' pins can overlap with the 'out', 'set' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

in_base

First pin to use as input. See sm_config_ pins for more detail on pin arguments

sm_config_set_in_pin_count

static void sm_config_set_in_pin_count (pio_sm_config * c, uint in_count) [inline], [static]

Set the count of 'in' pins in a state machine configuration.

When reading pins using the IN pin mapping, this many (low) bits will be read, with the rest taking the value zero.

RP2040 does not have the ability to mask unused input pins, so the in_count must be 32

Parameters

c

Pointer to the configuration structure to modify

in_count

1-32 The number of pins to include when reading via the IN pin mapping

sm_config_set_in_pins

static void sm_config_set_in_pins (pio_sm_config * c, uint in_base) [inline], [static]

Set the base for the 'in' pins in a state machine configuration.

'in' pins can overlap with the 'out', 'set' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

in_base

First pin to use as input. See sm_config_ pins for more detail on pin arguments

sm_config_set_in_shift

static void sm_config_set_in_shift (pio_sm_config * c, bool shift_right, bool autopush, uint push_threshold) [inline], [static]

Setup 'in' shifting parameters in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

shift_right

true to shift ISR to right, false to shift ISR to left

autopush

whether autopush is enabled

push_threshold

threshold in bits to shift in before auto/conditional re-pushing of the ISR

sm_config_set_jmp_pin

static void sm_config_set_jmp_pin (pio_sm_config * c, uint pin) [inline], [static]

Set the 'jmp' pin in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

pin

The raw GPIO pin number to use as the source for a jmp pin instruction. See sm_config_ pins for more detail on pin arguments

sm_config_set_mov_status

static void sm_config_set_mov_status (pio_sm_config * c, enum pio_mov_status_type status_sel, uint status_n) [inline], [static]

Set source for 'mov status' in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

status_sel

the status operation selector.

See also

Parameters

status_n

parameter for the mov status operation (currently a bit count)

sm_config_set_out_pin_base

static void sm_config_set_out_pin_base (pio_sm_config * c, uint out_base) [inline], [static]

Set the base of the 'out' pins in a state machine configuration.

'out' pins can overlap with the 'in', 'set' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

out_base

First pin to set as output. See sm_config_ pins for more detail on pin arguments

sm_config_set_out_pin_count

static void sm_config_set_out_pin_count (pio_sm_config * c, uint out_count) [inline], [static]

Set the number of 'out' pins in a state machine configuration.

'out' pins can overlap with the 'in', 'set' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

out_count

0-32 Number of pins to set.

sm_config_set_out_pins

static void sm_config_set_out_pins (pio_sm_config * c, uint out_base, uint out_count) [inline], [static]

Set the 'out' pins in a state machine configuration.

'out' pins can overlap with the 'in', 'set' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

out_base

First pin to set as output. See sm_config_ pins for more detail on pin arguments

out_count

0-32 Number of pins to set.

sm_config_set_out_shift

static void sm_config_set_out_shift (pio_sm_config * c, bool shift_right, bool autopull, uint pull_threshold) [inline], [static]

Setup 'out' shifting parameters in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

shift_right

true to shift OSR to right, false to shift OSR to left

autopull

whether autopull is enabled

pull_threshold

threshold in bits to shift out before auto/conditional re-pulling of the OSR

sm_config_set_out_special

static void sm_config_set_out_special (pio_sm_config * c, bool sticky, bool has_enable_pin, uint enable_bit_index) [inline], [static]

Set special 'out' operations in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

sticky

to enable 'sticky' output (i.e. re-asserting most recent OUT/SET pin values on subsequent cycles)

has_enable_pin

true to enable auxiliary OUT enable pin

enable_bit_index

Data bit index for auxiliary OUT enable.

sm_config_set_set_pin_base

static void sm_config_set_set_pin_base (pio_sm_config * c, uint set_base) [inline], [static]

Set the base of the 'set' pins in a state machine configuration.

'set' pins can overlap with the 'in', 'out' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

set_base

First pin to use as 'set'. See sm_config_ pins for more detail on pin arguments

sm_config_set_set_pin_count

static void sm_config_set_set_pin_count (pio_sm_config * c, uint set_count) [inline], [static]

Set the count of 'set' pins in a state machine configuration.

'set' pins can overlap with the 'in', 'out' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

set_count

0-5 Number of pins to set.

sm_config_set_set_pins

static void sm_config_set_set_pins (pio_sm_config * c, uint set_base, uint set_count) [inline], [static]

Set the 'set' pins in a state machine configuration.

'set' pins can overlap with the 'in', 'out' and 'sideset' pins

Parameters

c

Pointer to the configuration structure to modify

set_base

First pin to use as 'set'. See sm_config_ pins for more detail on pin arguments

set_count

0-5 Number of pins to set.

sm_config_set_sideset

static void sm_config_set_sideset (pio_sm_config * c, uint bit_count, bool optional, bool pindirs) [inline], [static]

Set the 'sideset' options in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

bit_count

Number of bits to steal from delay field in the instruction for use of side set (max 5)

optional

True if the topmost side set bit is used as a flag for whether to apply side set on that instruction

pindirs

True if the side set affects pin directions rather than values

sm_config_set_sideset_pin_base

static void sm_config_set_sideset_pin_base (pio_sm_config * c, uint sideset_base) [inline], [static]

Set the base of the 'sideset' pins in a state machine configuration.

'sideset' pins can overlap with the 'in', 'out' and 'set' pins

Parameters

c

Pointer to the configuration structure to modify

sideset_base

First pin to use for 'side set'. See sm_config_ pins for more detail on pin arguments

sm_config_set_sideset_pins

static void sm_config_set_sideset_pins (pio_sm_config * c, uint sideset_base) [inline], [static]

Set the 'sideset' pins in a state machine configuration.

This method is identical to sm_config_set_sideset_pin_base, and is provided for backwards compatibility

'sideset' pins can overlap with the 'in', 'out' and 'set' pins

Parameters

c

Pointer to the configuration structure to modify

sideset_base

First pin to use for 'side set'. See sm_config_ pins for more detail on pin arguments

sm_config_set_wrap

static void sm_config_set_wrap (pio_sm_config * c, uint wrap_target, uint wrap) [inline], [static]

Set the wrap addresses in a state machine configuration.

Parameters

c

Pointer to the configuration structure to modify

wrap_target

the instruction memory address to wrap to

wrap

the instruction memory address after which to set the program counter to wrap_target if the instruction does not itself update the program_counter

pio_instructions

PIO instruction encoding .

Detailed Description

Functions for generating PIO instruction encodings programmatically. In debug builds PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS can be set to 1 to enable validation of encoding function parameters.

For fuller descriptions of the instructions in question see the "RP2040 Datasheet"

Enumerations

enum pio_src_dest { pio_pins = 0u, pio_x = 1u, pio_y = 2u, pio_null = 3u | 0x20u | 0x80u, pio_pindirs = 4u | 0x08u | 0x40u | 0x80u, pio_exec_mov = 4u | 0x08u | 0x10u | 0x20u | 0x40u, pio_status = 5u | 0x08u | 0x10u | 0x20u | 0x80u, pio_pc = 5u | 0x08u | 0x20u | 0x40u, pio_isr = 6u | 0x20u, pio_osr = 7u | 0x10u | 0x20u, pio_exec_out = 7u | 0x08u | 0x20u | 0x40u | 0x80u }

Enumeration of values to pass for source/destination args for instruction encoding functions.

Functions

static uint pio_encode_delay (uint cycles)

Encode just the delay slot bits of an instruction.

static uint pio_encode_sideset (uint sideset_bit_count, uint value)

Encode just the side set bits of an instruction (in non optional side set mode)

static uint pio_encode_sideset_opt (uint sideset_bit_count, uint value)

Encode just the side set bits of an instruction (in optional -opt side set mode)

static uint pio_encode_jmp (uint addr)

Encode an unconditional JMP instruction.

static uint pio_encode_jmp_not_x (uint addr)

Encode a conditional JMP if scratch X zero instruction.

static uint pio_encode_jmp_x_dec (uint addr)

Encode a conditional JMP if scratch X non-zero (and post-decrement X) instruction.

static uint pio_encode_jmp_not_y (uint addr)

Encode a conditional JMP if scratch Y zero instruction.

static uint pio_encode_jmp_y_dec (uint addr)

Encode a conditional JMP if scratch Y non-zero (and post-decrement Y) instruction.

static uint pio_encode_jmp_x_ne_y (uint addr)

Encode a conditional JMP if scratch X not equal scratch Y instruction.

static uint pio_encode_jmp_pin (uint addr)

Encode a conditional JMP if input pin high instruction.

static uint pio_encode_jmp_not_osre (uint addr)

Encode a conditional JMP if output shift register not empty instruction.

static uint pio_encode_wait_gpio (bool polarity, uint gpio)

Encode a WAIT for GPIO pin instruction.

static uint pio_encode_wait_pin (bool polarity, uint pin)

Encode a WAIT for pin instruction.

static uint pio_encode_wait_irq (bool polarity, bool relative, uint irq)

Encode a WAIT for IRQ instruction.

static uint pio_encode_in (enum pio_src_dest src, uint count)

Encode an IN instruction.

static uint pio_encode_out (enum pio_src_dest dest, uint count)

Encode an OUT instruction.

static uint pio_encode_push (bool if_full, bool block)

Encode a PUSH instruction.

static uint pio_encode_pull (bool if_empty, bool block)

Encode a PULL instruction.

static uint pio_encode_mov (enum pio_src_dest dest, enum pio_src_dest src)

Encode a MOV instruction.

static uint pio_encode_mov_not (enum pio_src_dest dest, enum pio_src_dest src)

Encode a MOV instruction with bit invert.

static uint pio_encode_mov_reverse (enum pio_src_dest dest, enum pio_src_dest src)

Encode a MOV instruction with bit reverse.

static uint pio_encode_irq_set (bool relative, uint irq)

Encode a IRQ SET instruction.

static uint pio_encode_irq_wait (bool relative, uint irq)

Encode a IRQ WAIT instruction.

static uint pio_encode_irq_clear (bool relative, uint irq)

Encode a IRQ CLEAR instruction.

static uint pio_encode_set (enum pio_src_dest dest, uint value)

Encode a SET instruction.

static uint pio_encode_nop (void)

Encode a NOP instruction.

Enumeration Type Documentation

pio_src_dest

enum pio_src_dest

Enumeration of values to pass for source/destination args for instruction encoding functions.

Note

Not all values are suitable for all functions. Validity is only checked in debug mode when PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS is 1

Function Documentation

pio_encode_delay

static uint pio_encode_delay (uint cycles) [inline], [static]

Encode just the delay slot bits of an instruction.

Note

This function does not return a valid instruction encoding; instead it returns an encoding of the delay slot suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when combining the results of this function with the results of pio_encode_sideset and pio_encode_sideset_opt as they share the same bits within the instruction encoding.

Parameters

cycles

the number of cycles 0-31 (or less if side set is being used)

Returns

the delay slot bits to be ORed with an instruction encoding

pio_encode_in

static uint pio_encode_in (enum pio_src_dest src, uint count) [inline], [static]

Encode an IN instruction.

This is the equivalent of IN <src>, <count>

Parameters

src

The source to take data from

count

The number of bits 1-32

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_irq_clear

static uint pio_encode_irq_clear (bool relative, uint irq) [inline], [static]

Encode a IRQ CLEAR instruction.

This is the equivalent of IRQ CLEAR <irq> <relative>

Parameters

relative

true for a IRQ CLEAR <irq> REL, false for regular IRQ CLEAR <irq>

irq

the irq number 0-7

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_irq_set

static uint pio_encode_irq_set (bool relative, uint irq) [inline], [static]

Encode a IRQ SET instruction.

This is the equivalent of IRQ SET <irq> <relative>

Parameters

relative

true for a IRQ SET <irq> REL, false for regular IRQ SET <irq>

irq

the irq number 0-7

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_irq_wait

static uint pio_encode_irq_wait (bool relative, uint irq) [inline], [static]

Encode a IRQ WAIT instruction.

This is the equivalent of IRQ WAIT <irq> <relative>

Parameters

relative

true for a IRQ WAIT <irq> REL, false for regular IRQ WAIT <irq>

irq

the irq number 0-7

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp

static uint pio_encode_jmp (uint addr) [inline], [static]

Encode an unconditional JMP instruction.

This is the equivalent of JMP <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp_not_osre

static uint pio_encode_jmp_not_osre (uint addr) [inline], [static]

Encode a conditional JMP if output shift register not empty instruction.

This is the equivalent of JMP !OSRE <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp_not_x

static uint pio_encode_jmp_not_x (uint addr) [inline], [static]

Encode a conditional JMP if scratch X zero instruction.

This is the equivalent of JMP !X <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp_not_y

static uint pio_encode_jmp_not_y (uint addr) [inline], [static]

Encode a conditional JMP if scratch Y zero instruction.

This is the equivalent of JMP !Y <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp_pin

static uint pio_encode_jmp_pin (uint addr) [inline], [static]

Encode a conditional JMP if input pin high instruction.

This is the equivalent of JMP PIN <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp_x_dec

static uint pio_encode_jmp_x_dec (uint addr) [inline], [static]

Encode a conditional JMP if scratch X non-zero (and post-decrement X) instruction.

This is the equivalent of JMP X-- <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp_x_ne_y

static uint pio_encode_jmp_x_ne_y (uint addr) [inline], [static]

Encode a conditional JMP if scratch X not equal scratch Y instruction.

This is the equivalent of JMP X!=Y <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_jmp_y_dec

static uint pio_encode_jmp_y_dec (uint addr) [inline], [static]

Encode a conditional JMP if scratch Y non-zero (and post-decrement Y) instruction.

This is the equivalent of JMP Y-- <addr>

Parameters

addr

The target address 0-31 (an absolute address within the PIO instruction memory)

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_mov

static uint pio_encode_mov (enum pio_src_dest dest, enum pio_src_dest src) [inline], [static]

Encode a MOV instruction.

This is the equivalent of MOV <dest>, <src>

Parameters

dest

The destination to write data to

src

The source to take data from

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_mov_not

static uint pio_encode_mov_not (enum pio_src_dest dest, enum pio_src_dest src) [inline], [static]

Encode a MOV instruction with bit invert.

This is the equivalent of MOV <dest>, ~<src>

Parameters

dest

The destination to write inverted data to

src

The source to take data from

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_mov_reverse

static uint pio_encode_mov_reverse (enum pio_src_dest dest, enum pio_src_dest src) [inline], [static]

Encode a MOV instruction with bit reverse.

This is the equivalent of MOV <dest>, ::<src>

Parameters

dest

The destination to write bit reversed data to

src

The source to take data from

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_nop

static uint pio_encode_nop (void) [inline], [static]

Encode a NOP instruction.

This is the equivalent of NOP which is itself encoded as MOV y, y

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_out

static uint pio_encode_out (enum pio_src_dest dest, uint count) [inline], [static]

Encode an OUT instruction.

This is the equivalent of OUT <src>, <count>

Parameters

dest

The destination to write data to

count

The number of bits 1-32

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_pull

static uint pio_encode_pull (bool if_empty, bool block) [inline], [static]

Encode a PULL instruction.

This is the equivalent of PULL <if_empty>, <block>

Parameters

if_empty

true for PULL IF_EMPTY …​, false for PULL …​

block

true for PULL …​ BLOCK, false for PULL …​

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_push

static uint pio_encode_push (bool if_full, bool block) [inline], [static]

Encode a PUSH instruction.

This is the equivalent of PUSH <if_full>, <block>

Parameters

if_full

true for PUSH IF_FULL …​, false for PUSH …​

block

true for PUSH …​ BLOCK, false for PUSH …​

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_set

static uint pio_encode_set (enum pio_src_dest dest, uint value) [inline], [static]

Encode a SET instruction.

This is the equivalent of SET <dest>, <value>

Parameters

dest

The destination to apply the value to

value

The value 0-31

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_sideset

static uint pio_encode_sideset (uint sideset_bit_count, uint value) [inline], [static]

Encode just the side set bits of an instruction (in non optional side set mode)

Note

This function does not return a valid instruction encoding; instead it returns an encoding of the side set bits suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when combining the results of this function with the results of pio_encode_delay as they share the same bits within the instruction encoding.

Parameters

sideset_bit_count

number of side set bits as would be specified via .sideset in pioasm

value

the value to sideset on the pins

Returns

the side set bits to be ORed with an instruction encoding

pio_encode_sideset_opt

static uint pio_encode_sideset_opt (uint sideset_bit_count, uint value) [inline], [static]

Encode just the side set bits of an instruction (in optional -opt side set mode)

Note

This function does not return a valid instruction encoding; instead it returns an encoding of the side set bits suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when combining the results of this function with the results of pio_encode_delay as they share the same bits within the instruction encoding.

Parameters

sideset_bit_count

number of side set bits as would be specified via .sideset <n> opt in pioasm

value

the value to sideset on the pins

Returns

the side set bits to be ORed with an instruction encoding

pio_encode_wait_gpio

static uint pio_encode_wait_gpio (bool polarity, uint gpio) [inline], [static]

Encode a WAIT for GPIO pin instruction.

This is the equivalent of WAIT <polarity> GPIO <gpio>

Parameters

polarity

true for WAIT 1, false for WAIT 0

gpio

The real GPIO number 0-31

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_wait_irq

static uint pio_encode_wait_irq (bool polarity, bool relative, uint irq) [inline], [static]

Encode a WAIT for IRQ instruction.

This is the equivalent of WAIT <polarity> IRQ <irq> <relative>

Parameters

polarity

true for WAIT 1, false for WAIT 0

relative

true for a WAIT IRQ <irq> REL, false for regular WAIT IRQ <irq>

irq

the irq number 0-7

Returns

The instruction encoding with 0 delay and no side set value

pio_encode_wait_pin

static uint pio_encode_wait_pin (bool polarity, uint pin) [inline], [static]

Encode a WAIT for pin instruction.

This is the equivalent of WAIT <polarity> PIN <pin>

Parameters

polarity

true for WAIT 1, false for WAIT 0

pin

The pin number 0-31 relative to the executing SM’s input pin mapping

Returns

The instruction encoding with 0 delay and no side set value

hardware_pll

Phase Locked Loop control APIs.

Detailed Description

There are two PLLs in RP2040. They are:

  • pll_sys - Used to generate up to a 133MHz system clock

  • pll_usb - Used to generate a 48MHz USB reference clock

For details on how the PLLs are calculated, please refer to the RP2040 datasheet.

Macros

Functions

void pll_init (PLL pll, uint ref_div, uint vco_freq, uint post_div1, uint post_div2)

Initialise specified PLL.

void pll_deinit (PLL pll)

Release/uninitialise specified PLL.

Macro Definition Documentation

PLL_RESET_NUM

#define PLL_RESET_NUM(pll)

Returns the reset_num_t used to reset a given PLL instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

Function Documentation

pll_deinit

void pll_deinit (PLL pll)

Release/uninitialise specified PLL.

This will turn off the power to the specified PLL. Note this function does not currently check if the PLL is in use before powering it off so should be used with care.

Parameters

pll

pll_sys or pll_usb

pll_init

void pll_init (PLL pll, uint ref_div, uint vco_freq, uint post_div1, uint post_div2)

Initialise specified PLL.

Parameters

pll

pll_sys or pll_usb

ref_div

Input clock divider.

vco_freq

Requested output from the VCO (voltage controlled oscillator)

post_div1

Post Divider 1 - range 1-7. Must be >= post_div2

post_div2

Post Divider 2 - range 1-7

hardware_powman RP2350

Power Management API.

Enumerations

Functions

void powman_timer_set_1khz_tick_source_lposc (void)

Use the ~32KHz low power oscillator as the powman timer source.

void powman_timer_set_1khz_tick_source_lposc_with_hz (uint32_t lposc_freq_hz)

Use the low power oscillator (specifying frequency) as the powman timer source.

void powman_timer_set_1khz_tick_source_xosc (void)

Use the crystal oscillator as the powman timer source.

void powman_timer_set_1khz_tick_source_xosc_with_hz (uint32_t xosc_freq_hz)

Use the crystal oscillator as the powman timer source.

void powman_timer_set_1khz_tick_source_gpio (uint32_t gpio)

Use a 1KHz external tick as the powman timer source.

void powman_timer_enable_gpio_1hz_sync (uint32_t gpio)

Use a 1Hz external signal as the powman timer source for seconds only.

void powman_timer_disable_gpio_1hz_sync (void)

Stop using 1Hz external signal as the powman timer source for seconds.

uint64_t powman_timer_get_ms (void)

Returns current time in ms.

void powman_timer_set_ms (uint64_t time_ms)

Set current time in ms.

void powman_timer_enable_alarm_at_ms (uint64_t alarm_time_ms)

Set an alarm at an absolute time in ms.

void powman_timer_disable_alarm (void)

Disable the alarm.

static void powman_set_bits (volatile uint32_t *reg, uint32_t bits)

hw_set_bits helper function

static void powman_clear_bits (volatile uint32_t *reg, uint32_t bits)

hw_clear_bits helper function

static bool powman_timer_is_running (void)

Determine if the powman timer is running.

static void powman_timer_stop (void)

Stop the powman timer.

static void powman_timer_start (void)

Start the powman timer.

static void powman_clear_alarm (void)

Clears the powman alarm.

powman_power_state powman_get_power_state (void)

Get the current power state.

int powman_set_power_state (powman_power_state state)

Set the power state.

static powman_power_state powman_power_state_with_domain_on (powman_power_state orig, enum powman_power_domains domain)

Helper function modify a powman_power_state to turn a domain on.

static powman_power_state powman_power_state_with_domain_off (powman_power_state orig, enum powman_power_domains domain)

Helper function modify a powman_power_state to turn a domain off.

static bool powman_power_state_is_domain_on (powman_power_state state, enum powman_power_domains domain)

Helper function to check if a domain is on in a given powman_power_state.

void powman_enable_alarm_wakeup_at_ms (uint64_t alarm_time_ms)

Wake up from an alarm at a given time.

void powman_enable_gpio_wakeup (uint gpio_wakeup_num, uint32_t gpio, bool edge, bool high)

Wake up from a gpio.

void powman_disable_alarm_wakeup (void)

Disable waking up from alarm.

void powman_disable_gpio_wakeup (uint gpio_wakeup_num)

Disable wake up from a gpio.

void powman_disable_all_wakeups (void)

Disable all wakeup sources.

bool powman_configure_wakeup_state (powman_power_state sleep_state, powman_power_state wakeup_state)

Configure sleep state and wakeup state.

static void powman_set_debug_power_request_ignored (bool ignored)

Ignore wake up when the debugger is attached.

Enumeration Type Documentation

powman_power_domains

enum powman_power_domains

Power domains of powman.

Table 18. Enumerator

POWMAN_POWER_DOMAIN_SRAM_BANK1

bank1 includes the top 256K of sram plus sram 8 and 9 (scratch x and scratch y)

POWMAN_POWER_DOMAIN_SRAM_BANK0

bank0 is bottom 256K of sSRAM

POWMAN_POWER_DOMAIN_XIP_CACHE

XIP cache is 2x8K instances.

POWMAN_POWER_DOMAIN_SWITCHED_CORE

Switched core logic (processors, busfabric, peris etc)

Function Documentation

powman_clear_alarm

static void powman_clear_alarm (void) [inline], [static]

Clears the powman alarm.

Note, the alarm must be disabled (see powman_timer_disable_alarm) before clearing the alarm, as the alarm fires if the time is greater than equal to the target, so once the time has passed the alarm will always fire while enabled.

powman_clear_bits

static void powman_clear_bits (volatile uint32_t * reg, uint32_t bits) [inline], [static]

hw_clear_bits helper function

Powman needs a password for writes, to prevent accidentally writing to it. This function implements hw_clear_bits with an appropriate password.

Parameters

reg

register to clear

bits

bits of register to clear

powman_configure_wakeup_state

bool powman_configure_wakeup_state (powman_power_state sleep_state, powman_power_state wakeup_state)

Configure sleep state and wakeup state.

Parameters

sleep_state

power state powman will go to when sleeping, used to validate the wakeup state

wakeup_state

power state powman will go to when waking up. Note switched core and xip always power up. SRAM bank0 and bank1 can be left powered off

Returns

true if the state is valid, false if not

powman_disable_alarm_wakeup

void powman_disable_alarm_wakeup (void)

Disable waking up from alarm.

powman_disable_all_wakeups

void powman_disable_all_wakeups (void)

Disable all wakeup sources.

powman_disable_gpio_wakeup

void powman_disable_gpio_wakeup (uint gpio_wakeup_num)

Disable wake up from a gpio.

Parameters

gpio_wakeup_num

hardware wakeup instance to use (0-3)

powman_enable_alarm_wakeup_at_ms

void powman_enable_alarm_wakeup_at_ms (uint64_t alarm_time_ms)

Wake up from an alarm at a given time.

Parameters

alarm_time_ms

time to wake up in ms

powman_enable_gpio_wakeup

void powman_enable_gpio_wakeup (uint gpio_wakeup_num, uint32_t gpio, bool edge, bool high)

Wake up from a gpio.

Parameters

gpio_wakeup_num

hardware wakeup instance to use (0-3)

gpio

gpio to wake up from (0-47)

edge

true for edge sensitive, false for level sensitive

high

true for active high, false active low

powman_get_power_state

powman_power_state powman_get_power_state (void)

Get the current power state.

powman_power_state_is_domain_on

static bool powman_power_state_is_domain_on (powman_power_state state, enum powman_power_domains domain) [inline], [static]

Helper function to check if a domain is on in a given powman_power_state.

Parameters

state

powman_power_state

domain

domain to check is on

powman_power_state_with_domain_off

static powman_power_state powman_power_state_with_domain_off (powman_power_state orig, enum powman_power_domains domain) [inline], [static]

Helper function modify a powman_power_state to turn a domain off.

Parameters

orig

original state

domain

domain to turn off

powman_power_state_with_domain_on

static powman_power_state powman_power_state_with_domain_on (powman_power_state orig, enum powman_power_domains domain) [inline], [static]

Helper function modify a powman_power_state to turn a domain on.

Parameters

orig

original state

domain

domain to turn on

powman_set_bits

static void powman_set_bits (volatile uint32_t * reg, uint32_t bits) [inline], [static]

hw_set_bits helper function

Parameters

reg

register to set

bits

bits of register to set Powman needs a password for writes, to prevent accidentally writing to it. This function implements hw_set_bits with an appropriate password.

powman_set_debug_power_request_ignored

static void powman_set_debug_power_request_ignored (bool ignored) [inline], [static]

Ignore wake up when the debugger is attached.

Typically, when a debugger is attached it will assert the pwrupreq signal. OpenOCD does not clear this signal, even when you quit. This means once you have attached a debugger powman will never go to sleep. This function lets you ignore the debugger pwrupreq which means you can go to sleep with a debugger attached. The debugger will error out if you go to turn off the switch core with it attached, as the processors have been powered off.

Parameters

ignored

should the debugger power up request be ignored

powman_set_power_state

int powman_set_power_state (powman_power_state state)

Set the power state.

Check the desired state is valid. Powman will go to the state if it is valid and there are no pending power up requests.

Note that if you are turning off the switched core then this function will never return as the processor will have been turned off at the end.

Parameters

state

the power state to go to

Returns

PICO_OK if the state is valid. Misc PICO_ERRORs are returned if not

powman_timer_disable_alarm

void powman_timer_disable_alarm (void)

Disable the alarm.

Once an alarm has fired it must be disabled to stop firing as the alarm comparison is alarm = alarm_time >= current_time

powman_timer_disable_gpio_1hz_sync

void powman_timer_disable_gpio_1hz_sync (void)

Stop using 1Hz external signal as the powman timer source for seconds.

powman_timer_enable_alarm_at_ms

void powman_timer_enable_alarm_at_ms (uint64_t alarm_time_ms)

Set an alarm at an absolute time in ms.

Note, the timer is stopped and then restarted as part of this function. This only controls the alarm if you want to use the alarm to wake up powman then you should use powman_enable_alarm_wakeup_at_ms

Parameters

alarm_time_ms

time at which the alarm will fire

powman_timer_enable_gpio_1hz_sync

void powman_timer_enable_gpio_1hz_sync (uint32_t gpio)

Use a 1Hz external signal as the powman timer source for seconds only.

Use a 1hz sync signal, such as from a gps for the seconds component of the timer. The milliseconds will still come from another configured source such as xosc or lposc

Parameters

gpio

the gpio to use. must be 12, 14, 20, 22

powman_timer_get_ms

uint64_t powman_timer_get_ms (void)

Returns current time in ms.

powman_timer_is_running

static bool powman_timer_is_running (void) [inline], [static]

Determine if the powman timer is running.

powman_timer_set_1khz_tick_source_gpio

void powman_timer_set_1khz_tick_source_gpio (uint32_t gpio)

Use a 1KHz external tick as the powman timer source.

Parameters

gpio

the gpio to use. must be 12, 14, 20, 22

powman_timer_set_1khz_tick_source_lposc

void powman_timer_set_1khz_tick_source_lposc (void)

Use the ~32KHz low power oscillator as the powman timer source.

powman_timer_set_1khz_tick_source_lposc_with_hz

void powman_timer_set_1khz_tick_source_lposc_with_hz (uint32_t lposc_freq_hz)

Use the low power oscillator (specifying frequency) as the powman timer source.

Parameters

lposc_freq_hz

specify an exact lposc freq to trim it

powman_timer_set_1khz_tick_source_xosc

void powman_timer_set_1khz_tick_source_xosc (void)

Use the crystal oscillator as the powman timer source.

powman_timer_set_1khz_tick_source_xosc_with_hz

void powman_timer_set_1khz_tick_source_xosc_with_hz (uint32_t xosc_freq_hz)

Use the crystal oscillator as the powman timer source.

Parameters

xosc_freq_hz

specify a crystal frequency

powman_timer_set_ms

void powman_timer_set_ms (uint64_t time_ms)

Set current time in ms.

Parameters

time_ms

Current time in ms

powman_timer_start

static void powman_timer_start (void) [inline], [static]

Start the powman timer.

powman_timer_stop

static void powman_timer_stop (void) [inline], [static]

Stop the powman timer.

hardware_pwm

Hardware Pulse Width Modulation (PWM) API.

Detailed Description

The RP2040 PWM block has 8 identical slices, the RP2350 has 12. Each slice can drive two PWM output signals, or measure the frequency or duty cycle of an input signal. This gives a total of up to 16/24 controllable PWM outputs. All 30 GPIOs can be driven by the PWM block.

The PWM hardware functions by continuously comparing the input value to a free-running counter. This produces a toggling output where the amount of time spent at the high output level is proportional to the input value. The fraction of time spent at the high signal level is known as the duty cycle of the signal.

The default behaviour of a PWM slice is to count upward until the wrap value (pwm_config_set_wrap) is reached, and then immediately wrap to 0. PWM slices also offer a phase-correct mode, where the counter starts to count downward after reaching TOP, until it reaches 0 again.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Output PWM signals on pins 0 and 1

#include "pico/stdlib.h"
#include "hardware/pwm.h"

int main() {

    // Tell GPIO 0 and 1 they are allocated to the PWM
    gpio_set_function(0, GPIO_FUNC_PWM);
    gpio_set_function(1, GPIO_FUNC_PWM);

    // Find out which PWM slice is connected to GPIO 0 (it's slice 0)
    uint slice_num = pwm_gpio_to_slice_num(0);

    // Set period of 4 cycles (0 to 3 inclusive)
    pwm_set_wrap(slice_num, 3);
    // Set channel A output high for one cycle before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_A, 1);
    // Set initial B output high for three cycles before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_B, 3);
    // Set the PWM running
    pwm_set_enabled(slice_num, true);

    // Note we could also use pwm_set_gpio_level(gpio, x) which looks up the
    // correct slice and channel for a given GPIO.
}

Macros

Enumerations

enum pwm_clkdiv_mode { PWM_DIV_FREE_RUNNING = 0, PWM_DIV_B_HIGH = 1, PWM_DIV_B_RISING = 2, PWM_DIV_B_FALLING = 3 }

PWM Divider mode settings.

Functions

static uint pwm_gpio_to_slice_num (uint gpio)

Determine the PWM slice that is attached to the specified GPIO.

static uint pwm_gpio_to_channel (uint gpio)

Determine the PWM channel that is attached to the specified GPIO.

static void pwm_config_set_phase_correct (pwm_config *c, bool phase_correct)

Set phase correction in a PWM configuration.

static void pwm_config_set_clkdiv (pwm_config *c, float div)

Set PWM clock divider in a PWM configuration.

static void pwm_config_set_clkdiv_int_frac4 (pwm_config *c, uint32_t div_int, uint8_t div_frac4)

Set PWM clock divider in a PWM configuration using an 8:4 fractional value.

static void pwm_config_set_clkdiv_int (pwm_config *c, uint32_t div_int)

Set PWM clock divider in a PWM configuration.

static void pwm_config_set_clkdiv_mode (pwm_config *c, enum pwm_clkdiv_mode mode)

Set PWM counting mode in a PWM configuration.

static void pwm_config_set_output_polarity (pwm_config *c, bool a, bool b)

Set output polarity in a PWM configuration.

static void pwm_config_set_wrap (pwm_config *c, uint16_t wrap)

Set PWM counter wrap value in a PWM configuration.

static void pwm_init (uint slice_num, pwm_config *c, bool start)

Initialise a PWM with settings from a configuration object.

static pwm_config pwm_get_default_config (void)

Get a set of default values for PWM configuration.

static void pwm_set_wrap (uint slice_num, uint16_t wrap)

Set the current PWM counter wrap value.

static void pwm_set_chan_level (uint slice_num, uint chan, uint16_t level)

Set the current PWM counter compare value for one channel.

static void pwm_set_both_levels (uint slice_num, uint16_t level_a, uint16_t level_b)

Set PWM counter compare values.

static void pwm_set_gpio_level (uint gpio, uint16_t level)

Helper function to set the PWM level for the slice and channel associated with a GPIO.

static uint16_t pwm_get_counter (uint slice_num)

Get PWM counter.

static void pwm_set_counter (uint slice_num, uint16_t c)

Set PWM counter.

static void pwm_advance_count (uint slice_num)

Advance PWM count.

static void pwm_retard_count (uint slice_num)

Retard PWM count.

static void pwm_set_clkdiv_int_frac4 (uint slice_num, uint8_t div_int, uint8_t div_frac4)

Set PWM clock divider using an 8:4 fractional value.

static void pwm_set_clkdiv (uint slice_num, float divider)

Set PWM clock divider.

static void pwm_set_output_polarity (uint slice_num, bool a, bool b)

Set PWM output polarity.

static void pwm_set_clkdiv_mode (uint slice_num, enum pwm_clkdiv_mode mode)

Set PWM divider mode.

static void pwm_set_phase_correct (uint slice_num, bool phase_correct)

Set PWM phase correct on/off.

static void pwm_set_enabled (uint slice_num, bool enabled)

Enable/Disable PWM.

static void pwm_set_mask_enabled (uint32_t mask)

Enable/Disable multiple PWM slices simultaneously.

static void pwm_set_irq_enabled (uint slice_num, bool enabled)

Enable PWM instance interrupt via the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

static void pwm_set_irq0_enabled (uint slice_num, bool enabled)

Enable PWM instance interrupt via PWM_IRQ_WRAP_0.

static void pwm_irqn_set_slice_enabled (uint irq_index, uint slice_num, bool enabled)

Enable PWM instance interrupt via either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

static void pwm_set_irq_mask_enabled (uint32_t slice_mask, bool enabled)

Enable multiple PWM instance interrupts via the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

static void pwm_set_irq0_mask_enabled (uint32_t slice_mask, bool enabled)

Enable multiple PWM instance interrupts via PWM_IRQ_WRAP_0.

static void pwm_irqn_set_slice_mask_enabled (uint irq_index, uint slice_mask, bool enabled)

Enable PWM instance interrupts via either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

static void pwm_clear_irq (uint slice_num)

Clear a single PWM channel interrupt.

static uint32_t pwm_get_irq_status_mask (void)

Get PWM interrupt status, raw for the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

static uint32_t pwm_get_irq0_status_mask (void)

Get PWM interrupt status, raw for the PWM_IRQ_WRAP_0.

static uint32_t pwm_irqn_get_status_mask (uint irq_index)

Get PWM interrupt status, raw for either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

static void pwm_force_irq (uint slice_num)

Force PWM interrupt for the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

static void pwm_force_irq0 (uint slice_num)

Force PWM interrupt via PWM_IRQ_WRAP_0.

static void pwm_irqn_force (uint irq_index, uint slice_num)

Force PWM interrupt via PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

static uint pwm_get_dreq (uint slice_num)

Return the DREQ to use for pacing transfers to a particular PWM slice.

Macro Definition Documentation

PWM_DREQ_NUM

#define PWM_DREQ_NUM(slice_num)

Returns the dreq_num_t used for pacing DMA transfers for a given PWM slice.

Note this macro is intended to resolve at compile time, and does no parameter checking

PWM_GPIO_SLICE_NUM

#define PWM_GPIO_SLICE_NUM(gpio)

Returns the PWM slice number for a given GPIO number.

PWM_DEFAULT_IRQ_NUM

#define PWM_DEFAULT_IRQ_NUM()

Returns the irq_num_t for the default PWM IRQ.

On RP2040, there is only one PWM irq: PWM_IRQ_WRAP

On RP2350 this returns to PWM_IRQ_WRAP0

Note this macro is intended to resolve at compile time, and does no parameter checking

Enumeration Type Documentation

pwm_clkdiv_mode

enum pwm_clkdiv_mode

PWM Divider mode settings.

Table 19. Enumerator

PWM_DIV_FREE_RUNNING

Free-running counting at rate dictated by fractional divider.

PWM_DIV_B_HIGH

Fractional divider is gated by the PWM B pin.

PWM_DIV_B_RISING

Fractional divider advances with each rising edge of the PWM B pin.

PWM_DIV_B_FALLING

Fractional divider advances with each falling edge of the PWM B pin.

Function Documentation

pwm_advance_count

static void pwm_advance_count (uint slice_num) [inline], [static]

Advance PWM count.

Advance the phase of a running the counter by 1 count.

This function will return once the increment is complete.

Parameters

slice_num

PWM slice number

pwm_clear_irq

static void pwm_clear_irq (uint slice_num) [inline], [static]

Clear a single PWM channel interrupt.

Parameters

slice_num

PWM slice number

pwm_config_set_clkdiv

static void pwm_config_set_clkdiv (pwm_config * c, float div) [inline], [static]

Set PWM clock divider in a PWM configuration.

Parameters

c

PWM configuration struct to modify

div

Value to divide counting rate by. Must be greater than or equal to 1.

If the divide mode is free-running, the PWM counter runs at clk_sys / div. Otherwise, the divider reduces the rate of events seen on the B pin input (level or edge) before passing them on to the PWM counter.

pwm_config_set_clkdiv_int

static void pwm_config_set_clkdiv_int (pwm_config * c, uint32_t div_int) [inline], [static]

Set PWM clock divider in a PWM configuration.

Parameters

c

PWM configuration struct to modify

div_int

Integer value to reduce counting rate by. Must be greater than or equal to 1 and less than 256.

If the divide mode is free-running, the PWM counter runs at clk_sys / div. Otherwise, the divider reduces the rate of events seen on the B pin input (level or edge) before passing them on to the PWM counter.

pwm_config_set_clkdiv_int_frac4

static void pwm_config_set_clkdiv_int_frac4 (pwm_config * c, uint32_t div_int, uint8_t div_frac4) [inline], [static]

Set PWM clock divider in a PWM configuration using an 8:4 fractional value.

Parameters

c

PWM configuration struct to modify

div_int

8 bit integer part of the clock divider. Must be greater than or equal to 1.

div_frac4

4 bit fractional part of the clock divider

If the divide mode is free-running, the PWM counter runs at clk_sys / div. Otherwise, the divider reduces the rate of events seen on the B pin input (level or edge) before passing them on to the PWM counter.

pwm_config_set_clkdiv_mode

static void pwm_config_set_clkdiv_mode (pwm_config * c, enum pwm_clkdiv_mode mode) [inline], [static]

Set PWM counting mode in a PWM configuration.

Parameters

c

PWM configuration struct to modify

mode

PWM divide/count mode

Configure which event gates the operation of the fractional divider. The default is always-on (free-running PWM). Can also be configured to count on high level, rising edge or falling edge of the B pin input.

pwm_config_set_output_polarity

static void pwm_config_set_output_polarity (pwm_config * c, bool a, bool b) [inline], [static]

Set output polarity in a PWM configuration.

Parameters

c

PWM configuration struct to modify

a

true to invert output A

b

true to invert output B

pwm_config_set_phase_correct

static void pwm_config_set_phase_correct (pwm_config * c, bool phase_correct) [inline], [static]

Set phase correction in a PWM configuration.

Parameters

c

PWM configuration struct to modify

phase_correct

true to set phase correct modulation, false to set trailing edge

Setting phase control to true means that instead of wrapping back to zero when the wrap point is reached, the PWM starts counting back down. The output frequency is halved when phase-correct mode is enabled.

pwm_config_set_wrap

static void pwm_config_set_wrap (pwm_config * c, uint16_t wrap) [inline], [static]

Set PWM counter wrap value in a PWM configuration.

Set the highest value the counter will reach before returning to 0. Also known as TOP.

Parameters

c

PWM configuration struct to modify

wrap

Value to set wrap to

pwm_force_irq

static void pwm_force_irq (uint slice_num) [inline], [static]

Force PWM interrupt for the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

Parameters

slice_num

PWM slice number

pwm_force_irq0

static void pwm_force_irq0 (uint slice_num) [inline], [static]

Force PWM interrupt via PWM_IRQ_WRAP_0.

Parameters

slice_num

PWM slice number

pwm_get_counter

static uint16_t pwm_get_counter (uint slice_num) [inline], [static]

Get PWM counter.

Get current value of PWM counter

Parameters

slice_num

PWM slice number

Returns

Current value of the PWM counter

pwm_get_default_config

static pwm_config pwm_get_default_config (void) [inline], [static]

Get a set of default values for PWM configuration.

PWM config is free-running at system clock speed, no phase correction, wrapping at 0xffff, with standard polarities for channels A and B.

Returns

Set of default values.

pwm_get_dreq

static uint pwm_get_dreq (uint slice_num) [inline], [static]

Return the DREQ to use for pacing transfers to a particular PWM slice.

Parameters

slice_num

PWM slice number

pwm_get_irq0_status_mask

static uint32_t pwm_get_irq0_status_mask (void) [inline], [static]

Get PWM interrupt status, raw for the PWM_IRQ_WRAP_0.

Returns

Bitmask of all PWM interrupts currently set

pwm_get_irq_status_mask

static uint32_t pwm_get_irq_status_mask (void) [inline], [static]

Get PWM interrupt status, raw for the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

Returns

Bitmask of all PWM interrupts currently set

pwm_gpio_to_channel

static uint pwm_gpio_to_channel (uint gpio) [inline], [static]

Determine the PWM channel that is attached to the specified GPIO.

Each slice 0 to 7 has two channels, A and B.

Returns

The PWM channel that controls the specified GPIO.

pwm_gpio_to_slice_num

static uint pwm_gpio_to_slice_num (uint gpio) [inline], [static]

Determine the PWM slice that is attached to the specified GPIO.

Returns

The PWM slice number that controls the specified GPIO.

pwm_init

static void pwm_init (uint slice_num, pwm_config * c, bool start) [inline], [static]

Initialise a PWM with settings from a configuration object.

Use the pwm_get_default_config() function to initialise a config structure, make changes as needed using the pwm_config_* functions, then call this function to set up the PWM.

Parameters

slice_num

PWM slice number

c

The configuration to use

start

If true the PWM will be started running once configured. If false you will need to start manually using pwm_set_enabled() or pwm_set_mask_enabled()

pwm_irqn_force

static void pwm_irqn_force (uint irq_index, uint slice_num) [inline], [static]

Force PWM interrupt via PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

Parameters

irq_index

the IRQ index; either 0 or 1 for PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1

slice_num

PWM slice number

pwm_irqn_get_status_mask

static uint32_t pwm_irqn_get_status_mask (uint irq_index) [inline], [static]

Get PWM interrupt status, raw for either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

Parameters

irq_index

the IRQ index; either 0 or 1 for PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1

Returns

Bitmask of all PWM interrupts currently set

pwm_irqn_set_slice_enabled

static void pwm_irqn_set_slice_enabled (uint irq_index, uint slice_num, bool enabled) [inline], [static]

Enable PWM instance interrupt via either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

Used to enable a single PWM instance interrupt.

Note there is only one PWM_IRQ_WRAP on RP2040.

Parameters

irq_index

the IRQ index; either 0 or 1 for PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1

slice_num

PWM block to enable/disable

enabled

true to enable, false to disable

pwm_irqn_set_slice_mask_enabled

static void pwm_irqn_set_slice_mask_enabled (uint irq_index, uint slice_mask, bool enabled) [inline], [static]

Enable PWM instance interrupts via either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.

Used to enable a single PWM instance interrupt.

Note there is only one PWM_IRQ_WRAP on RP2040.

Parameters

irq_index

the IRQ index; either 0 or 1 for PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1

slice_mask

Bitmask of all the blocks to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.

enabled

true to enable, false to disable

pwm_retard_count

static void pwm_retard_count (uint slice_num) [inline], [static]

Retard PWM count.

Retard the phase of a running counter by 1 count

This function will return once the retardation is complete.

Parameters

slice_num

PWM slice number

pwm_set_both_levels

static void pwm_set_both_levels (uint slice_num, uint16_t level_a, uint16_t level_b) [inline], [static]

Set PWM counter compare values.

Set the value of the PWM counter compare values, A and B.

The counter compare register is double-buffered in hardware. This means that, when the PWM is running, a write to the counter compare values does not take effect until the next time the PWM slice wraps (or, in phase-correct mode, the next time the slice reaches 0). If the PWM is not running, the write is latched in immediately.

Parameters

slice_num

PWM slice number

level_a

Value to set compare A to. When the counter reaches this value the A output is deasserted

level_b

Value to set compare B to. When the counter reaches this value the B output is deasserted

pwm_set_chan_level

static void pwm_set_chan_level (uint slice_num, uint chan, uint16_t level) [inline], [static]

Set the current PWM counter compare value for one channel.

Set the value of the PWM counter compare value, for either channel A or channel B.

The counter compare register is double-buffered in hardware. This means that, when the PWM is running, a write to the counter compare values does not take effect until the next time the PWM slice wraps (or, in phase-correct mode, the next time the slice reaches 0). If the PWM is not running, the write is latched in immediately.

Parameters

slice_num

PWM slice number

chan

Which channel to update. 0 for A, 1 for B.

level

new level for the selected output

pwm_set_clkdiv

static void pwm_set_clkdiv (uint slice_num, float divider) [inline], [static]

Set PWM clock divider.

Set the clock divider. Counter increment will be on sysclock divided by this value, taking into account the gating.

Parameters

slice_num

PWM slice number

divider

Floating point clock divider, 1.f ⇐ value < 256.f

pwm_set_clkdiv_int_frac4

static void pwm_set_clkdiv_int_frac4 (uint slice_num, uint8_t div_int, uint8_t div_frac4) [inline], [static]

Set PWM clock divider using an 8:4 fractional value.

Set the clock divider. Counter increment will be on sysclock divided by this value, taking into account the gating.

Parameters

slice_num

PWM slice number

div_int

8 bit integer part of the clock divider

div_frac4

4 bit fractional part of the clock divider

pwm_set_clkdiv_mode

static void pwm_set_clkdiv_mode (uint slice_num, enum pwm_clkdiv_mode mode) [inline], [static]

Set PWM divider mode.

Parameters

slice_num

PWM slice number

mode

Required divider mode

pwm_set_counter

static void pwm_set_counter (uint slice_num, uint16_t c) [inline], [static]

Set PWM counter.

Set the value of the PWM counter

Parameters

slice_num

PWM slice number

c

Value to set the PWM counter to

pwm_set_enabled

static void pwm_set_enabled (uint slice_num, bool enabled) [inline], [static]

Enable/Disable PWM.

When a PWM is disabled, it halts its counter, and the output pins are left high or low depending on exactly when the counter is halted. When re-enabled the PWM resumes immediately from where it left off.

If the PWM’s output pins need to be low when halted:

  • The counter compare can be set to zero whilst the PWM is enabled, and then the PWM disabled once both pins are seen to be low

  • The GPIO output overrides can be used to force the actual pins low

  • The PWM can be run for one cycle (i.e. enabled then immediately disabled) with a TOP of 0, count of 0 and counter compare of 0, to force the pins low when the PWM has already been halted. The same method can be used with a counter compare value of 1 to force a pin high.

Note that, when disabled, the PWM can still be advanced one count at a time by pulsing the PH_ADV bit in its CSR. The output pins transition as though the PWM were enabled.

Parameters

slice_num

PWM slice number

enabled

true to enable the specified PWM, false to disable.

pwm_set_gpio_level

static void pwm_set_gpio_level (uint gpio, uint16_t level) [inline], [static]

Helper function to set the PWM level for the slice and channel associated with a GPIO.

Look up the correct slice (0 to 7) and channel (A or B) for a given GPIO, and update the corresponding counter compare field.

This PWM slice should already have been configured and set running. Also be careful of multiple GPIOs mapping to the same slice and channel (if GPIOs have a difference of 16).

The counter compare register is double-buffered in hardware. This means that, when the PWM is running, a write to the counter compare values does not take effect until the next time the PWM slice wraps (or, in phase-correct mode, the next time the slice reaches 0). If the PWM is not running, the write is latched in immediately.

Parameters

gpio

GPIO to set level of

level

PWM level for this GPIO

pwm_set_irq0_enabled

static void pwm_set_irq0_enabled (uint slice_num, bool enabled) [inline], [static]

Enable PWM instance interrupt via PWM_IRQ_WRAP_0.

Used to enable a single PWM instance interrupt.

Parameters

slice_num

PWM block to enable/disable

enabled

true to enable, false to disable

pwm_set_irq0_mask_enabled

static void pwm_set_irq0_mask_enabled (uint32_t slice_mask, bool enabled) [inline], [static]

Enable multiple PWM instance interrupts via PWM_IRQ_WRAP_0.

Use this to enable multiple PWM interrupts at once.

Parameters

slice_mask

Bitmask of all the blocks to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.

enabled

true to enable, false to disable

pwm_set_irq_enabled

static void pwm_set_irq_enabled (uint slice_num, bool enabled) [inline], [static]

Enable PWM instance interrupt via the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

Used to enable a single PWM instance interrupt.

Note there is only one PWM_IRQ_WRAP on RP2040.

Parameters

slice_num

PWM block to enable/disable

enabled

true to enable, false to disable

pwm_set_irq_mask_enabled

static void pwm_set_irq_mask_enabled (uint32_t slice_mask, bool enabled) [inline], [static]

Enable multiple PWM instance interrupts via the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)

Use this to enable multiple PWM interrupts at once.

Note there is only one PWM_IRQ_WRAP on RP2040.

Parameters

slice_mask

Bitmask of all the blocks to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.

enabled

true to enable, false to disable

pwm_set_mask_enabled

static void pwm_set_mask_enabled (uint32_t mask) [inline], [static]

Enable/Disable multiple PWM slices simultaneously.

Parameters

mask

Bitmap of PWMs to enable/disable. Bits 0 to 7 enable slices 0-7 respectively

pwm_set_output_polarity

static void pwm_set_output_polarity (uint slice_num, bool a, bool b) [inline], [static]

Set PWM output polarity.

Parameters

slice_num

PWM slice number

a

true to invert output A

b

true to invert output B

pwm_set_phase_correct

static void pwm_set_phase_correct (uint slice_num, bool phase_correct) [inline], [static]

Set PWM phase correct on/off.

Parameters

slice_num

PWM slice number

phase_correct

true to set phase correct modulation, false to set trailing edge

Setting phase control to true means that instead of wrapping back to zero when the wrap point is reached, the PWM starts counting back down. The output frequency is halved when phase-correct mode is enabled.

pwm_set_wrap

static void pwm_set_wrap (uint slice_num, uint16_t wrap) [inline], [static]

Set the current PWM counter wrap value.

Set the highest value the counter will reach before returning to 0. Also known as TOP.

The counter wrap value is double-buffered in hardware. This means that, when the PWM is running, a write to the counter wrap value does not take effect until after the next time the PWM slice wraps (or, in phase-correct mode, the next time the slice reaches 0). If the PWM is not running, the write is latched in immediately.

Parameters

slice_num

PWM slice number

wrap

Value to set wrap to

hardware_resets

Hardware Reset API.

Detailed Description

The reset controller allows software control of the resets to all of the peripherals that are not critical to boot the processor in the RP-series microcontroller.

reset_bitmask

Multiple blocks are referred to using a bitmask as follows:

Block to reset Bit

USB

24

UART 1

23

UART 0

22

Timer

21

TB Manager

20

SysInfo

19

System Config

18

SPI 1

17

SPI 0

16

RTC

15

PWM

14

PLL USB

13

PLL System

12

PIO 1

11

PIO 0

10

Pads - QSPI

9

Pads - bank 0

8

JTAG

7

IO Bank 1

6

IO Bank 0

5

I2C 1

4

I2C 0

3

DMA

2

Bus Control

1

ADC 0

0

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/resets.h"

int main() {
    stdio_init_all();

    printf("Hello, reset!\n");

    // Put the PWM block into reset
    reset_block_num(RESET_PWM);

    // And bring it out
    unreset_block_num_wait_blocking(RESET_PWM);

    // Put the PWM and ADC block into reset
    reset_block_mask((1u << RESET_PWM) | (1u << RESET_ADC));

    // Wait for both to come out of reset
    unreset_block_mask_wait_blocking((1u << RESET_PWM) | (1u << RESET_ADC));

    return 0;
}

Typedefs

typedef enum reset_num_rp2040 reset_num_t RP2040

Resettable component numbers on RP2040 (used as typedef reset_num_t)

typedef enum reset_num_rp2350 reset_num_t RP2350

Resettable component numbers on RP2350 (used as typedef reset_num_t)

Enumerations

enum reset_num_rp2040 { RESET_ADC = 0, RESET_BUSCTRL = 1, RESET_DMA = 2, RESET_I2C0 = 3, RESET_I2C1 = 4, RESET_IO_BANK0 = 5, RESET_IO_QSPI = 6, RESET_JTAG = 7, RESET_PADS_BANK0 = 8, RESET_PADS_QSPI = 9, RESET_PIO0 = 10, RESET_PIO1 = 11, RESET_PLL_SYS = 12, RESET_PLL_USB = 13, RESET_PWM = 14, RESET_RTC = 15, RESET_SPI0 = 16, RESET_SPI1 = 17, RESET_SYSCFG = 18, RESET_SYSINFO = 19, RESET_TBMAN = 20, RESET_TIMER = 21, RESET_UART0 = 22, RESET_UART1 = 23, RESET_USBCTRL = 24, RESET_COUNT } RP2040

Resettable component numbers on RP2040 (used as typedef reset_num_t)

enum reset_num_rp2350 { RESET_ADC = 0, RESET_BUSCTRL = 1, RESET_DMA = 2, RESET_HSTX = 3, RESET_I2C0 = 4, RESET_I2C1 = 5, RESET_IO_BANK0 = 6, RESET_IO_QSPI = 7, RESET_JTAG = 8, RESET_PADS_BANK0 = 9, RESET_PADS_QSPI = 10, RESET_PIO0 = 11, RESET_PIO1 = 12, RESET_PIO2 = 13, RESET_PLL_SYS = 14, RESET_PLL_USB = 15, RESET_PWM = 16, RESET_SHA256 = 17, RESET_SPI0 = 18, RESET_SPI1 = 19, RESET_SYSCFG = 20, RESET_SYSINFO = 21, RESET_TBMAN = 22, RESET_TIMER0 = 23, RESET_TIMER1 = 24, RESET_TRNG = 25, RESET_UART0 = 26, RESET_UART1 = 27, RESET_USBCTRL = 28, RESET_COUNT } RP2350

Resettable component numbers on RP2350 (used as typedef reset_num_t)

Functions

static __force_inline void reset_block_mask (uint32_t bits)

Reset the specified HW blocks.

static __force_inline void unreset_block_mask (uint32_t bits)

bring specified HW blocks out of reset

static __force_inline void unreset_block_mask_wait_blocking (uint32_t bits)

Bring specified HW blocks out of reset and wait for completion.

static void reset_block_num (uint32_t block_num)

Reset the specified HW block.

static void unreset_block_num (uint block_num)

bring specified HW block out of reset

static void unreset_block_num_wait_blocking (uint block_num)

Bring specified HW block out of reset and wait for completion.

static void reset_unreset_block_num_wait_blocking (uint block_num)

Reset the specified HW block, and then bring at back out of reset and wait for completion.

Typedef Documentation

reset_num_t RP2040

typedef enum reset_num_rp2040 reset_num_t

Resettable component numbers on RP2040 (used as typedef reset_num_t)

reset_num_t RP2350

typedef enum reset_num_rp2350 reset_num_t

Resettable component numbers on RP2350 (used as typedef reset_num_t)

Enumeration Type Documentation

reset_num_rp2040 RP2040

enum reset_num_rp2040

Resettable component numbers on RP2040 (used as typedef reset_num_t)

Table 20. Enumerator

RESET_ADC

Select ADC to be reset.

RESET_BUSCTRL

Select BUSCTRL to be reset.

RESET_DMA

Select DMA to be reset.

RESET_I2C0

Select I2C0 to be reset.

RESET_I2C1

Select I2C1 to be reset.

RESET_IO_BANK0

Select IO_BANK0 to be reset.

RESET_IO_QSPI

Select IO_QSPI to be reset.

RESET_JTAG

Select JTAG to be reset.

RESET_PADS_BANK0

Select PADS_BANK0 to be reset.

RESET_PADS_QSPI

Select PADS_QSPI to be reset.

RESET_PIO0

Select PIO0 to be reset.

RESET_PIO1

Select PIO1 to be reset.

RESET_PLL_SYS

Select PLL_SYS to be reset.

RESET_PLL_USB

Select PLL_USB to be reset.

RESET_PWM

Select PWM to be reset.

RESET_RTC

Select RTC to be reset.

RESET_SPI0

Select SPI0 to be reset.

RESET_SPI1

Select SPI1 to be reset.

RESET_SYSCFG

Select SYSCFG to be reset.

RESET_SYSINFO

Select SYSINFO to be reset.

RESET_TBMAN

Select TBMAN to be reset.

RESET_TIMER

Select TIMER to be reset.

RESET_UART0

Select UART0 to be reset.

RESET_UART1

Select UART1 to be reset.

RESET_USBCTRL

Select USBCTRL to be reset.

reset_num_rp2350 RP2350

enum reset_num_rp2350

Resettable component numbers on RP2350 (used as typedef reset_num_t)

Table 21. Enumerator

RESET_ADC

Select ADC to be reset.

RESET_BUSCTRL

Select BUSCTRL to be reset.

RESET_DMA

Select DMA to be reset.

RESET_HSTX

Select HSTX to be reset.

RESET_I2C0

Select I2C0 to be reset.

RESET_I2C1

Select I2C1 to be reset.

RESET_IO_BANK0

Select IO_BANK0 to be reset.

RESET_IO_QSPI

Select IO_QSPI to be reset.

RESET_JTAG

Select JTAG to be reset.

RESET_PADS_BANK0

Select PADS_BANK0 to be reset.

RESET_PADS_QSPI

Select PADS_QSPI to be reset.

RESET_PIO0

Select PIO0 to be reset.

RESET_PIO1

Select PIO1 to be reset.

RESET_PIO2

Select PIO2 to be reset.

RESET_PLL_SYS

Select PLL_SYS to be reset.

RESET_PLL_USB

Select PLL_USB to be reset.

RESET_PWM

Select PWM to be reset.

RESET_SHA256

Select SHA256 to be reset.

RESET_SPI0

Select SPI0 to be reset.

RESET_SPI1

Select SPI1 to be reset.

RESET_SYSCFG

Select SYSCFG to be reset.

RESET_SYSINFO

Select SYSINFO to be reset.

RESET_TBMAN

Select TBMAN to be reset.

RESET_TIMER0

Select TIMER0 to be reset.

RESET_TIMER1

Select TIMER1 to be reset.

RESET_TRNG

Select TRNG to be reset.

RESET_UART0

Select UART0 to be reset.

RESET_UART1

Select UART1 to be reset.

RESET_USBCTRL

Select USBCTRL to be reset.

Function Documentation

reset_block_mask

static __force_inline void reset_block_mask (uint32_t bits) [static]

Reset the specified HW blocks.

Parameters

bits

Bit pattern indicating blocks to reset. See reset_bitmask

reset_block_num

static void reset_block_num (uint32_t block_num) [inline], [static]

Reset the specified HW block.

Parameters

block_num

the block number

reset_unreset_block_num_wait_blocking

static void reset_unreset_block_num_wait_blocking (uint block_num) [inline], [static]

Reset the specified HW block, and then bring at back out of reset and wait for completion.

Parameters

block_num

the block number

unreset_block_mask

static __force_inline void unreset_block_mask (uint32_t bits) [static]

bring specified HW blocks out of reset

Parameters

bits

Bit pattern indicating blocks to unreset. See reset_bitmask

unreset_block_mask_wait_blocking

static __force_inline void unreset_block_mask_wait_blocking (uint32_t bits) [static]

Bring specified HW blocks out of reset and wait for completion.

Parameters

bits

Bit pattern indicating blocks to unreset. See reset_bitmask

unreset_block_num

static void unreset_block_num (uint block_num) [inline], [static]

bring specified HW block out of reset

Parameters

block_num

the block number

unreset_block_num_wait_blocking

static void unreset_block_num_wait_blocking (uint block_num) [inline], [static]

Bring specified HW block out of reset and wait for completion.

Parameters

block_num

the block number

hardware_riscv RP2350

Accessors for standard RISC-V hardware (mainly CSRs)

hardware_riscv_platform_timer RP2350

Accessors for standard RISC-V platform timer (mtime/mtimecmp), available on Raspberry Pi microcontrollers with RISC-V processors.

Detailed Description

Note this header can be used by Arm as well as RISC-V processors, as the timer is a memory-mapped peripheral external to the processors. The name refers to this timer being a standard RISC-V peripheral.

Functions

static void riscv_timer_set_enabled (bool enabled)

Enable or disable the RISC-V platform timer.

static void riscv_timer_set_fullspeed (bool fullspeed)

Configure the RISC-V platform timer to run at full system clock speed.

static uint64_t riscv_timer_get_mtime (void)

Read the RISC-V platform timer.

static void riscv_timer_set_mtime (uint64_t mtime)

Update the RISC-V platform timer.

static uint64_t riscv_timer_get_mtimecmp (void)

Get the current RISC-V platform timer mtimecmp value for this core.

static void riscv_timer_set_mtimecmp (uint64_t mtimecmp)

Set a new RISC-V platform timer interrupt comparison value (mtimecmp) for this core.

Function Documentation

riscv_timer_get_mtime

static uint64_t riscv_timer_get_mtime (void) [inline], [static]

Read the RISC-V platform timer.

Returns

Current 64-bit mtime value

riscv_timer_get_mtimecmp

static uint64_t riscv_timer_get_mtimecmp (void) [inline], [static]

Get the current RISC-V platform timer mtimecmp value for this core.

Get the current mtimecmp value for the calling core. This function is interrupt-safe as long as timer interrupts only increase the value of mtimecmp. Otherwise, it must be called with timer interrupts disabled.

Returns

Current value of mtimecmp

riscv_timer_set_enabled

static void riscv_timer_set_enabled (bool enabled) [inline], [static]

Enable or disable the RISC-V platform timer.

This enables and disables the counting of the RISC-V platform timer. It does not enable or disable the interrupts, which are asserted unconditionally when a given core’s mtimecmp/mtimecmph registers are greater than the current 64-bit value of the mtime/mtimeh registers.

Parameters

enabled

Pass true to enable, false to disable

riscv_timer_set_fullspeed

static void riscv_timer_set_fullspeed (bool fullspeed) [inline], [static]

Configure the RISC-V platform timer to run at full system clock speed.

Parameters

fullspeed

Pass true to increment at system clock speed, false to increment at the frequency defined by the system tick generator (the ticks block)

riscv_timer_set_mtime

static void riscv_timer_set_mtime (uint64_t mtime) [inline], [static]

Update the RISC-V platform timer.

This function should only be called when the timer is disabled via riscv_timer_set_enabled(). Note also that unlike the mtimecmp comparison values, mtime is not core-local, so updates on one core will be visible to the other core.

Parameters

mtime

New value to set the RISC-V platform timer to

riscv_timer_set_mtimecmp

static void riscv_timer_set_mtimecmp (uint64_t mtimecmp) [inline], [static]

Set a new RISC-V platform timer interrupt comparison value (mtimecmp) for this core.

This function updates the mtimecmp value for the current core. The calling core’s RISC-V platform timer interrupt is asserted whenever the 64-bit mtime value (stored in 32-bit mtime/mtimeh registers) is greater than or equal to this core’s current mtime/mtimecmph value.

Parameters

mtime

New value to set the RISC-V platform timer to

hardware_rtc RP2040

Hardware Real Time Clock API.

Detailed Description

The RTC keeps track of time in human readable format and generates events when the time is equal to a preset value. Think of a digital clock, not epoch time used by most computers. There are seven fields, one each for year (12 bit), month (4 bit), day (5 bit), day of the week (3 bit), hour (5 bit) minute (6 bit) and second (6 bit), storing the data in binary format.

See also

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
#include "hardware/rtc.h"
#include "pico/stdlib.h"
#include "pico/util/datetime.h"

int main() {
    stdio_init_all();
    printf("Hello RTC!\n");

    char datetime_buf[256];
    char *datetime_str = &datetime_buf[0];

    // Start on Friday 5th of June 2020 15:45:00
    datetime_t t = {
            .year  = 2020,
            .month = 06,
            .day   = 05,
            .dotw  = 5, // 0 is Sunday, so 5 is Friday
            .hour  = 15,
            .min   = 45,
            .sec   = 00
    };

    // Start the RTC
    rtc_init();
    rtc_set_datetime(&t);

    // clk_sys is >2000x faster than clk_rtc, so datetime is not updated immediately when rtc_get_datetime() is called.
    // The delay is up to 3 RTC clock cycles (which is 64us with the default clock settings)
    sleep_us(64);

    // Print the time
    while (true) {
        rtc_get_datetime(&t);
        datetime_to_str(datetime_str, sizeof(datetime_buf), &t);
        printf("\r%s      ", datetime_str);
        sleep_ms(100);
    }
}

Typedefs

typedef void(* rtc_callback_t)(void)

Functions

void rtc_init (void)

Initialise the RTC system.

bool rtc_set_datetime (const datetime_t *t)

Set the RTC to the specified time.

bool rtc_get_datetime (datetime_t *t)

Get the current time from the RTC.

bool rtc_running (void)

Is the RTC running?

void rtc_set_alarm (const datetime_t *t, rtc_callback_t user_callback)

Set a time in the future for the RTC to call a user provided callback.

void rtc_enable_alarm (void)

Enable the RTC alarm (if inactive)

void rtc_disable_alarm (void)

Disable the RTC alarm (if active)

Typedef Documentation

rtc_callback_t

typedef void(* rtc_callback_t) (void)

Callback function type for RTC alarms

See also

Function Documentation

rtc_disable_alarm

void rtc_disable_alarm (void)

Disable the RTC alarm (if active)

rtc_enable_alarm

void rtc_enable_alarm (void)

Enable the RTC alarm (if inactive)

rtc_get_datetime

bool rtc_get_datetime (datetime_t * t)

Get the current time from the RTC.

Parameters

t

Pointer to a datetime_t structure to receive the current RTC time

Returns

true if datetime is valid, false if the RTC is not running.

rtc_init

void rtc_init (void)

Initialise the RTC system.

rtc_running

bool rtc_running (void)

Is the RTC running?

rtc_set_alarm

void rtc_set_alarm (const datetime_t * t, rtc_callback_t user_callback)

Set a time in the future for the RTC to call a user provided callback.

Parameters

t

Pointer to a datetime_t structure containing a time in the future to fire the alarm. Any values set to -1 will not be matched on.

user_callback

pointer to a rtc_callback_t to call when the alarm fires

rtc_set_datetime

bool rtc_set_datetime (const datetime_t * t)

Set the RTC to the specified time.

Note

Note that after setting the RTC date and time, a subsequent read of the values (e.g. via rtc_get_datetime()) may not reflect the new setting until up to three cycles of the potentially-much-slower RTC clock domain have passed. This represents a period of 64 microseconds with the default RTC clock configuration.

Parameters

t

Pointer to a datetime_t structure contains time to set

Returns

true if set, false if the passed in datetime was invalid.

hardware_rcp RP2350

Inline functions and assembly macros for the Redundancy Coprocessor.

hardware_spi

Hardware SPI API.

Detailed Description

RP-series microcontrollers have 2 identical instances of the Serial Peripheral Interface (SPI) controller.

The PrimeCell SSP is a master or slave interface for synchronous serial communication with peripheral devices that have Motorola SPI, National Semiconductor Microwire, or Texas Instruments synchronous serial interfaces.

Controller can be defined as master or slave using the spi_set_slave function.

Each controller can be connected to a number of GPIO pins, see the datasheet GPIO function selection table for more information.

Macros

Enumerations

enum spi_cpha_t { SPI_CPHA_0 = 0, SPI_CPHA_1 = 1 }

Enumeration of SPI CPHA (clock phase) values.

enum spi_cpol_t { SPI_CPOL_0 = 0, SPI_CPOL_1 = 1 }

Enumeration of SPI CPOL (clock polarity) values.

enum spi_order_t { SPI_LSB_FIRST = 0, SPI_MSB_FIRST = 1 }

Enumeration of SPI bit-order values.

Functions

uint spi_init (spi_inst_t *spi, uint baudrate)

Initialise SPI instances.

void spi_deinit (spi_inst_t *spi)

Deinitialise SPI instances.

uint spi_set_baudrate (spi_inst_t *spi, uint baudrate)

Set SPI baudrate.

uint spi_get_baudrate (const spi_inst_t *spi)

Get SPI baudrate.

static uint spi_get_index (const spi_inst_t *spi)

Convert SPI instance to hardware instance number.

static void spi_set_format (spi_inst_t *spi, uint data_bits, spi_cpol_t cpol, spi_cpha_t cpha, __unused spi_order_t order)

Configure SPI.

static void spi_set_slave (spi_inst_t *spi, bool slave)

Set SPI master/slave.

static bool spi_is_writable (const spi_inst_t *spi)

Check whether a write can be done on SPI device.

static bool spi_is_readable (const spi_inst_t *spi)

Check whether a read can be done on SPI device.

static bool spi_is_busy (const spi_inst_t *spi)

Check whether SPI is busy.

int spi_write_read_blocking (spi_inst_t *spi, const uint8_t *src, uint8_t *dst, size_t len)

Write/Read to/from an SPI device.

int spi_write_blocking (spi_inst_t *spi, const uint8_t *src, size_t len)

Write to an SPI device, blocking.

int spi_read_blocking (spi_inst_t *spi, uint8_t repeated_tx_data, uint8_t *dst, size_t len)

Read from an SPI device.

int spi_write16_read16_blocking (spi_inst_t *spi, const uint16_t *src, uint16_t *dst, size_t len)

Write/Read half words to/from an SPI device.

int spi_write16_blocking (spi_inst_t *spi, const uint16_t *src, size_t len)

Write to an SPI device.

int spi_read16_blocking (spi_inst_t *spi, uint16_t repeated_tx_data, uint16_t *dst, size_t len)

Read from an SPI device.

static uint spi_get_dreq (spi_inst_t *spi, bool is_tx)

Return the DREQ to use for pacing transfers to/from a particular SPI instance.

Macro Definition Documentation

spi0

#define spi0 ((spi_inst_t *)spi0_hw)

Identifier for the first (SPI 0) hardware SPI instance (for use in SPI functions).

e.g. spi_init(spi0, 48000)

spi1

#define spi1 ((spi_inst_t *)spi1_hw)

Identifier for the second (SPI 1) hardware SPI instance (for use in SPI functions).

e.g. spi_init(spi1, 48000)

SPI_NUM

#define SPI_NUM(spi)

Returns the SPI number for a SPI instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

SPI_INSTANCE

#define SPI_INSTANCE(num)

Returns the SPI instance with the given SPI number.

Note this macro is intended to resolve at compile time, and does no parameter checking

SPI_DREQ_NUM

#define SPI_DREQ_NUM(spi, is_tx)

Returns the dreq_num_t used for pacing DMA transfers to or from this SPI instance. If is_tx is true, then it is for transfers to the SPI else for transfers from the SPI.

Note this macro is intended to resolve at compile time, and does no parameter checking

Enumeration Type Documentation

spi_cpha_t

enum spi_cpha_t

Enumeration of SPI CPHA (clock phase) values.

spi_cpol_t

enum spi_cpol_t

Enumeration of SPI CPOL (clock polarity) values.

spi_order_t

enum spi_order_t

Enumeration of SPI bit-order values.

Function Documentation

spi_deinit

void spi_deinit (spi_inst_t * spi)

Deinitialise SPI instances.

Puts the SPI into a disabled state. Init will need to be called to re-enable the device functions.

Parameters

spi

SPI instance specifier, either spi0 or spi1

spi_get_baudrate

uint spi_get_baudrate (const spi_inst_t * spi)

Get SPI baudrate.

Get SPI baudrate which was set by

See also

Parameters

spi

SPI instance specifier, either spi0 or spi1

Returns

The actual baudrate set

spi_get_dreq

static uint spi_get_dreq (spi_inst_t * spi, bool is_tx) [inline], [static]

Return the DREQ to use for pacing transfers to/from a particular SPI instance.

Parameters

spi

SPI instance specifier, either spi0 or spi1

is_tx

true for sending data to the SPI instance, false for receiving data from the SPI instance

spi_get_index

static uint spi_get_index (const spi_inst_t * spi) [inline], [static]

Convert SPI instance to hardware instance number.

Parameters

spi

SPI instance

Returns

Number of SPI, 0 or 1.

spi_init

uint spi_init (spi_inst_t * spi, uint baudrate)

Initialise SPI instances.

Puts the SPI into a known state, and enable it. Must be called before other functions.

Note

There is no guarantee that the baudrate requested can be achieved exactly; the nearest will be chosen and returned

Parameters

spi

SPI instance specifier, either spi0 or spi1

baudrate

Baudrate requested in Hz

Returns

the actual baud rate set

spi_is_busy

static bool spi_is_busy (const spi_inst_t * spi) [inline], [static]

Check whether SPI is busy.

Parameters

spi

SPI instance specifier, either spi0 or spi1

Returns

true if SPI is busy

spi_is_readable

static bool spi_is_readable (const spi_inst_t * spi) [inline], [static]

Check whether a read can be done on SPI device.

Parameters

spi

SPI instance specifier, either spi0 or spi1

Returns

true if a read is possible i.e. data is present

spi_is_writable

static bool spi_is_writable (const spi_inst_t * spi) [inline], [static]

Check whether a write can be done on SPI device.

Parameters

spi

SPI instance specifier, either spi0 or spi1

Returns

false if no space is available to write. True if a write is possible

spi_read16_blocking

int spi_read16_blocking (spi_inst_t * spi, uint16_t repeated_tx_data, uint16_t * dst, size_t len)

Read from an SPI device.

Read len halfwords from SPI to dst. Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate. repeated_tx_data is output repeatedly on TX as data is read in from RX. Generally this can be 0, but some devices require a specific value here, e.g. SD cards expect 0xff

Note

SPI should be initialised with 16 data_bits using spi_set_format first, otherwise this function will only read 8 data_bits.

Parameters

spi

SPI instance specifier, either spi0 or spi1

repeated_tx_data

Buffer of data to write

dst

Buffer for read data

len

Length of buffer dst in halfwords

Returns

Number of halfwords written/read

spi_read_blocking

int spi_read_blocking (spi_inst_t * spi, uint8_t repeated_tx_data, uint8_t * dst, size_t len)

Read from an SPI device.

Read len bytes from SPI to dst. Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate. repeated_tx_data is output repeatedly on TX as data is read in from RX. Generally this can be 0, but some devices require a specific value here, e.g. SD cards expect 0xff

Parameters

spi

SPI instance specifier, either spi0 or spi1

repeated_tx_data

Buffer of data to write

dst

Buffer for read data

len

Length of buffer dst

Returns

Number of bytes written/read

spi_set_baudrate

uint spi_set_baudrate (spi_inst_t * spi, uint baudrate)

Set SPI baudrate.

Set SPI frequency as close as possible to baudrate, and return the actual achieved rate.

Parameters

spi

SPI instance specifier, either spi0 or spi1

baudrate

Baudrate required in Hz, should be capable of a bitrate of at least 2Mbps, or higher, depending on system clock settings.

Returns

The actual baudrate set

spi_set_format

static void spi_set_format (spi_inst_t * spi, uint data_bits, spi_cpol_t cpol, spi_cpha_t cpha, __unused spi_order_t order) [inline], [static]

Configure SPI.

Configure how the SPI serialises and deserialises data on the wire

Parameters

spi

SPI instance specifier, either spi0 or spi1

data_bits

Number of data bits per transfer. Valid values 4..16.

cpol

SSPCLKOUT polarity, applicable to Motorola SPI frame format only.

cpha

SSPCLKOUT phase, applicable to Motorola SPI frame format only

order

Must be SPI_MSB_FIRST, no other values supported on the PL022

spi_set_slave

static void spi_set_slave (spi_inst_t * spi, bool slave) [inline], [static]

Set SPI master/slave.

Configure the SPI for master- or slave-mode operation. By default, spi_init() sets master-mode.

Parameters

spi

SPI instance specifier, either spi0 or spi1

slave

true to set SPI device as a slave device, false for master.

spi_write16_blocking

int spi_write16_blocking (spi_inst_t * spi, const uint16_t * src, size_t len)

Write to an SPI device.

Write len halfwords from src to SPI. Discard any data received back. Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate.

Note

SPI should be initialised with 16 data_bits using spi_set_format first, otherwise this function will only write 8 data_bits.

Parameters

spi

SPI instance specifier, either spi0 or spi1

src

Buffer of data to write

len

Length of buffers

Returns

Number of halfwords written/read

spi_write16_read16_blocking

int spi_write16_read16_blocking (spi_inst_t * spi, const uint16_t * src, uint16_t * dst, size_t len)

Write/Read half words to/from an SPI device.

Write len halfwords from src to SPI. Simultaneously read len halfwords from SPI to dst. Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate.

Note

SPI should be initialised with 16 data_bits using spi_set_format first, otherwise this function will only read/write 8 data_bits.

Parameters

spi

SPI instance specifier, either spi0 or spi1

src

Buffer of data to write

dst

Buffer for read data

len

Length of BOTH buffers in halfwords

Returns

Number of halfwords written/read

spi_write_blocking

int spi_write_blocking (spi_inst_t * spi, const uint8_t * src, size_t len)

Write to an SPI device, blocking.

Write len bytes from src to SPI, and discard any data received back Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate.

Parameters

spi

SPI instance specifier, either spi0 or spi1

src

Buffer of data to write

len

Length of src

Returns

Number of bytes written/read

spi_write_read_blocking

int spi_write_read_blocking (spi_inst_t * spi, const uint8_t * src, uint8_t * dst, size_t len)

Write/Read to/from an SPI device.

Write len bytes from src to SPI. Simultaneously read len bytes from SPI to dst. Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate.

Parameters

spi

SPI instance specifier, either spi0 or spi1

src

Buffer of data to write

dst

Buffer for read data

len

Length of BOTH buffers

Returns

Number of bytes written/read

hardware_sha256 RP2350

Hardware SHA-256 Accelerator API.

Detailed Description

RP2350 is equipped with an implementation of the SHA-256 hash algorithm. The hardware should first be configured by calling the sha256_set_dma_size and sha256_set_bswap functions. To generate a new hash the hardware should first be initialised by calling sha256_start. The hardware is ready to accept data when sha256_is_ready returns true, at which point the data to be hashed can be written to the address returned by sha256_get_write_addr. The hardware requires 64 bytes to be written in one go or else sha256_err_not_ready will indicate an error and the hashing process must be restarted. sha256_is_sum_valid will return true when there is a valid checksum result which can be retrieved by calling sha256_get_result.

Macros

Enumerations

enum sha256_endianness { SHA256_LITTLE_ENDIAN, SHA256_BIG_ENDIAN }

SHA-256 endianness definition used in the API.

Functions

static void sha256_set_dma_size (uint size_in_bytes)

Configure the correct DMA data size.

static void sha256_set_bswap (bool swap)

Enable or disable byte swapping of 32-bit values.

static void sha256_start (void)

Prepare the hardware for a new checksum.

static bool sha256_is_sum_valid (void)

Check if a valid checksum has been calculated.

static bool sha256_is_ready (void)

Check if a the hardware is ready to accept more data.

static void sha256_wait_valid_blocking (void)

Wait until the checksum is valid.

static void sha256_wait_ready_blocking (void)

Wait until the hardware is ready to accept more data.

void sha256_get_result (sha256_result_t *out, enum sha256_endianness endianness)

Get the checksum result.

static bool sha256_err_not_ready (void)

Check if data was written before the hardware was ready.

static void sha256_err_not_ready_clear (void)

Clear the "not ready" error condition.

static volatile void * sha256_get_write_addr (void)

Address to write the data to be hashed.

static void sha256_put_word (uint32_t word)

Write one 32bit word of data to the SHA-256 hardware.

static void sha256_put_byte (uint8_t b)

Write one byte of data to the SHA-256 hardware.

Macro Definition Documentation

SHA256_RESULT_BYTES

#define SHA256_RESULT_BYTES 32

Size of a sha256 result in bytes.

Enumeration Type Documentation

sha256_endianness

enum sha256_endianness

SHA-256 endianness definition used in the API.

Table 22. Enumerator

SHA256_LITTLE_ENDIAN

Little Endian.

SHA256_BIG_ENDIAN

Big Endian.

Function Documentation

sha256_err_not_ready

static bool sha256_err_not_ready (void) [inline], [static]

Check if data was written before the hardware was ready.

Indicates if an error has occurred due to data being written when the hardware is not ready.

Returns

True if data was written before the hardware was ready

sha256_err_not_ready_clear

static void sha256_err_not_ready_clear (void) [inline], [static]

Clear the "not ready" error condition.

Resets the hardware if a "not ready" error condition is indicated.

sha256_get_result

void sha256_get_result (sha256_result_t * out, enum sha256_endianness endianness)

Get the checksum result.

Read the 32 byte result calculated by the hardware. Only valid if sha256_is_sum_valid is True

Parameters

out

The checksum result

Copyright (c) 2024 Raspberry Pi (Trading) Ltd.

SPDX-License-Identifier: BSD-3-Clause

sha256_get_write_addr

static volatile void * sha256_get_write_addr (void) [inline], [static]

Address to write the data to be hashed.

Returns the hardware address where data to be hashed should be written

Returns

Address to write data to be hashed

sha256_is_ready

static bool sha256_is_ready (void) [inline], [static]

Check if a the hardware is ready to accept more data.

After writing 64 bytes of data to the hardware, it will be unable to accept more data for a time. Call this to check if the hardware is ready for more data to be written.

Returns

True if the hardware is ready to receive more data

sha256_is_sum_valid

static bool sha256_is_sum_valid (void) [inline], [static]

Check if a valid checksum has been calculated.

The checksum result will be invalid when data is first written to the hardware, and then once 64 bytes of data has been written it may take some time to complete the digest of the current block. This function can be used to determine when the checksum is valid.

Returns

True if sha256_get_result would return a valid result

sha256_put_byte

static void sha256_put_byte (uint8_t b) [inline], [static]

Write one byte of data to the SHA-256 hardware.

Parameters

b

data to write

sha256_put_word

static void sha256_put_word (uint32_t word) [inline], [static]

Write one 32bit word of data to the SHA-256 hardware.

Parameters

word

data to write

sha256_set_bswap

static void sha256_set_bswap (bool swap) [inline], [static]

Enable or disable byte swapping of 32-bit values.

The SHA256 algorithm expects bytes in big endian order, but the system bus deals with little endian data, so control is provided to convert little endian bus data to big endian internal data. This defaults to true

Parameters

swap

false to disable byte swapping

sha256_set_dma_size

static void sha256_set_dma_size (uint size_in_bytes) [inline], [static]

Configure the correct DMA data size.

This must be configured before the DMA channel is triggered and ensures the correct number of transfers is requested per block.

Parameters

size_in_bytes

Size of DMA transfers, either 1, 2 or 4 bytes only.

sha256_start

static void sha256_start (void) [inline], [static]

Prepare the hardware for a new checksum.

Called to initialise the hardware before starting the checksum calculation

sha256_wait_ready_blocking

static void sha256_wait_ready_blocking (void) [inline], [static]

Wait until the hardware is ready to accept more data.

Before writing to the hardware, it’s necessary to check it is ready to accept more data. This function waits until the hardware is ready to accept more data

sha256_wait_valid_blocking

static void sha256_wait_valid_blocking (void) [inline], [static]

Wait until the checksum is valid.

When a multiple of 64 bytes of data has been written to the hardware, the checksum will be valid once the digest of the current block is complete. This function waits until when the checksum result is valid.

hardware_sync

Low level hardware spin locks, barrier and processor event APIs.

Detailed Description

Spin Locks

The RP-series microcontrollers provide 32 hardware spin locks, which can be used to manage mutually-exclusive access to shared software and hardware resources.

Generally each spin lock itself is a shared resource, i.e. the same hardware spin lock can be used by multiple higher level primitives (as long as the spin locks are neither held for long periods, nor held concurrently with other spin locks by the same core - which could lead to deadlock). A hardware spin lock that is exclusively owned can be used individually without more flexibility and without regard to other software. Note that no hardware spin lock may be acquired re-entrantly (i.e. hardware spin locks are not on their own safe for use by both thread code and IRQs) however the default spinlock related methods here (e.g. spin_lock_blocking) always disable interrupts while the lock is held as use by IRQ handlers and user code is common/desirable, and spin locks are only expected to be held for brief periods.

RP2350 Warning. Due to erratum RP2350-E2, writes to new SIO registers above an offset of +0x180 alias the spinlocks, causing spurious lock releases. This SDK by default uses atomic memory accesses to implement the hardware_sync_spin_lock API, as a workaround on RP2350 A2.

The SDK uses the following default spin lock assignments, classifying which spin locks are reserved for exclusive/special purposes vs those suitable for more general shared use:

Number (ID) Description

0-13

Currently reserved for exclusive use by the SDK and other libraries. If you use these spin locks, you risk breaking SDK or other library functionality. Each reserved spin lock used individually has its own PICO_SPINLOCK_ID so you can search for those.

14,15

(PICO_SPINLOCK_ID_OS1 and PICO_SPINLOCK_ID_OS2). Currently reserved for exclusive use by an operating system (or other system level software) co-existing with the SDK.

16-23

(PICO_SPINLOCK_ID_STRIPED_FIRST - PICO_SPINLOCK_ID_STRIPED_LAST). Spin locks from this range are assigned in a round-robin fashion via next_striped_spin_lock_num(). These spin locks are shared, but assigning numbers from a range reduces the probability that two higher level locking primitives using striped spin locks will actually be using the same spin lock.

24-31

(PICO_SPINLOCK_ID_CLAIM_FREE_FIRST - PICO_SPINLOCK_ID_CLAIM_FREE_LAST). These are reserved for exclusive use and are allocated on a first come first served basis at runtime via spin_lock_claim_unused()

Macros

Functions

static __force_inline void __nop (void)

Insert a NOP instruction in to the code path.

static __force_inline void __sev (void)

Insert a SEV instruction in to the code path.

static __force_inline void __wfe (void)

Insert a WFE instruction in to the code path.

static __force_inline void __wfi (void)

Insert a WFI instruction in to the code path.

static __force_inline void __dmb (void)

Insert a DMB instruction in to the code path.

static __force_inline void __dsb (void)

Insert a DSB instruction in to the code path.

static __force_inline void __isb (void)

Insert a ISB instruction in to the code path.

static __force_inline void __mem_fence_acquire (void)

Acquire a memory fence.

static __force_inline void __mem_fence_release (void)

Release a memory fence.

static __force_inline uint32_t disable_interrupts (void)

Explicitly disable interrupts on the calling core.

static __force_inline uint32_t enable_interrupts (void)

Explicitly enable interrupts on the calling core.

static __force_inline uint32_t save_and_disable_interrupts (void)

Disable interrupts on the calling core, returning the previous interrupt state.

static __force_inline void restore_interrupts (uint32_t status)

Restore interrupts to a specified state on the calling core.

static __force_inline void restore_interrupts_from_disabled (uint32_t status)

Restore interrupts to a specified state on the calling core with restricted transitions.

uint next_striped_spin_lock_num (void)

Return a spin lock number from the striped range.

void spin_lock_claim (uint lock_num)

Mark a spin lock as used.

void spin_lock_claim_mask (uint32_t lock_num_mask)

Mark multiple spin locks as used.

void spin_lock_unclaim (uint lock_num)

Mark a spin lock as no longer used.

int spin_lock_claim_unused (bool required)

Claim a free spin lock.

bool spin_lock_is_claimed (uint lock_num)

Determine if a spin lock is claimed.

static __force_inline spin_lock_t * spin_lock_instance (uint lock_num)

Get HW Spinlock instance from number.

static __force_inline uint spin_lock_get_num (spin_lock_t *lock)

Get HW Spinlock number from instance.

static __force_inline void spin_lock_unsafe_blocking (spin_lock_t *lock)

Acquire a spin lock without disabling interrupts (hence unsafe)

static __force_inline void spin_unlock_unsafe (spin_lock_t *lock)

Release a spin lock without re-enabling interrupts.

static __force_inline uint32_t spin_lock_blocking (spin_lock_t *lock)

Acquire a spin lock safely.

static bool is_spin_locked (spin_lock_t *lock)

Check to see if a spinlock is currently acquired elsewhere.

static __force_inline void spin_unlock (spin_lock_t *lock, uint32_t saved_irq)

Release a spin lock safely.

spin_lock_t * spin_lock_init (uint lock_num)

Initialise a spin lock.

void spin_locks_reset (void)

Release all spin locks.

Macro Definition Documentation

SW_SPIN_LOCK_TYPE RP2350

#define SW_SPIN_LOCK_TYPE volatile uint8_t

A spin lock identifier.

Function Documentation

__dmb

static __force_inline void __dmb (void) [static]

Insert a DMB instruction in to the code path.

The DMB (data memory barrier) acts as a memory barrier, all memory accesses prior to this instruction will be observed before any explicit access after the instruction.

__dsb

static __force_inline void __dsb (void) [static]

Insert a DSB instruction in to the code path.

The DSB (data synchronization barrier) acts as a special kind of data memory barrier (DMB). The DSB operation completes when all explicit memory accesses before this instruction complete.

__isb

static __force_inline void __isb (void) [static]

Insert a ISB instruction in to the code path.

ISB acts as an instruction synchronization barrier. It flushes the pipeline of the processor, so that all instructions following the ISB are fetched from cache or memory again, after the ISB instruction has been completed.

__mem_fence_acquire

static __force_inline void __mem_fence_acquire (void) [static]

Acquire a memory fence.

__mem_fence_release

static __force_inline void __mem_fence_release (void) [static]

Release a memory fence.

__nop

static __force_inline void __nop (void) [static]

Insert a NOP instruction in to the code path.

NOP does nothing for one cycle. On RP2350 Arm binaries this is forced to be a 32-bit instruction to avoid dual-issue of NOPs.

__sev

static __force_inline void __sev (void) [static]

Insert a SEV instruction in to the code path.

The SEV (send event) instruction sends an event to both cores.

__wfe

static __force_inline void __wfe (void) [static]

Insert a WFE instruction in to the code path.

The WFE (wait for event) instruction waits until one of a number of events occurs, including events signalled by the SEV instruction on either core.

__wfi

static __force_inline void __wfi (void) [static]

Insert a WFI instruction in to the code path.

The WFI (wait for interrupt) instruction waits for a interrupt to wake up the core.

disable_interrupts

static __force_inline uint32_t disable_interrupts (void) [static]

Explicitly disable interrupts on the calling core.

enable_interrupts

static __force_inline uint32_t enable_interrupts (void) [static]

Explicitly enable interrupts on the calling core.

is_spin_locked

static bool is_spin_locked (spin_lock_t * lock) [inline], [static]

Check to see if a spinlock is currently acquired elsewhere.

Parameters

lock

Spinlock instance

next_striped_spin_lock_num

uint next_striped_spin_lock_num (void)

Return a spin lock number from the striped range.

Returns a spin lock number in the range PICO_SPINLOCK_ID_STRIPED_FIRST to PICO_SPINLOCK_ID_STRIPED_LAST in a round robin fashion. This does not grant the caller exclusive access to the spin lock, so the caller must:

  1. Abide (with other callers) by the contract of only holding this spin lock briefly (and with IRQs disabled - the default via spin_lock_blocking()), and not whilst holding other spin locks.

  2. Be OK with any contention caused by the - brief due to the above requirement - contention with other possible users of the spin lock.

Returns

lock_num a spin lock number the caller may use (non exclusively)

See also

PICO_SPINLOCK_ID_STRIPED_FIRST

PICO_SPINLOCK_ID_STRIPED_LAST

restore_interrupts

static __force_inline void restore_interrupts (uint32_t status) [static]

Restore interrupts to a specified state on the calling core.

Parameters

status

Previous interrupt status from save_and_disable_interrupts()

restore_interrupts_from_disabled

static __force_inline void restore_interrupts_from_disabled (uint32_t status) [static]

Restore interrupts to a specified state on the calling core with restricted transitions.

This method should only be used when the current interrupt state is known to be disabled, e.g. when paired with save_and_disable_interrupts()

Parameters

status

Previous interrupt status from save_and_disable_interrupts()

save_and_disable_interrupts

static __force_inline uint32_t save_and_disable_interrupts (void) [static]

Disable interrupts on the calling core, returning the previous interrupt state.

This method is commonly paired with restore_interrupts_from_disabled() to temporarily disable interrupts around a piece of code, without needing to care whether interrupts were previously enabled

Returns

The prior interrupt enable status for restoration later via restore_interrupts_from_disabled() or restore_interrupts()

spin_lock_blocking

static __force_inline uint32_t spin_lock_blocking (spin_lock_t * lock) [static]

Acquire a spin lock safely.

This function will disable interrupts prior to acquiring the spinlock

Parameters

lock

Spinlock instance

Returns

interrupt status to be used when unlocking, to restore to original state

spin_lock_claim

void spin_lock_claim (uint lock_num)

Mark a spin lock as used.

Method for cooperative claiming of hardware. Will cause a panic if the spin lock is already claimed. Use of this method by libraries detects accidental configurations that would fail in unpredictable ways.

Parameters

lock_num

the spin lock number

spin_lock_claim_mask

void spin_lock_claim_mask (uint32_t lock_num_mask)

Mark multiple spin locks as used.

Method for cooperative claiming of hardware. Will cause a panic if any of the spin locks are already claimed. Use of this method by libraries detects accidental configurations that would fail in unpredictable ways.

Parameters

lock_num_mask

Bitfield of all required spin locks to claim (bit 0 == spin lock 0, bit 1 == spin lock 1 etc)

spin_lock_claim_unused

int spin_lock_claim_unused (bool required)

Claim a free spin lock.

Parameters

required

if true the function will panic if none are available

Returns

the spin lock number or -1 if required was false, and none were free

spin_lock_get_num

static __force_inline uint spin_lock_get_num (spin_lock_t * lock) [static]

Get HW Spinlock number from instance.

Parameters

lock

The Spinlock instance

Returns

The Spinlock ID

spin_lock_init

spin_lock_t * spin_lock_init (uint lock_num)

Initialise a spin lock.

The spin lock is initially unlocked

Parameters

lock_num

The spin lock number

Returns

The spin lock instance

spin_lock_instance

static __force_inline spin_lock_t * spin_lock_instance (uint lock_num) [static]

Get HW Spinlock instance from number.

Parameters

lock_num

Spinlock ID

Returns

The spinlock instance

spin_lock_is_claimed

bool spin_lock_is_claimed (uint lock_num)

Determine if a spin lock is claimed.

Parameters

lock_num

the spin lock number

Returns

true if claimed, false otherwise

spin_lock_unclaim

void spin_lock_unclaim (uint lock_num)

Mark a spin lock as no longer used.

Method for cooperative claiming of hardware.

Parameters

lock_num

the spin lock number to release

spin_lock_unsafe_blocking

static __force_inline void spin_lock_unsafe_blocking (spin_lock_t * lock) [static]

Acquire a spin lock without disabling interrupts (hence unsafe)

Parameters

lock

Spinlock instance

spin_locks_reset

void spin_locks_reset (void)

Release all spin locks.

spin_unlock

static __force_inline void spin_unlock (spin_lock_t * lock, uint32_t saved_irq) [static]

Release a spin lock safely.

This function will re-enable interrupts according to the parameters.

Parameters

lock

Spinlock instance

saved_irq

Return value from the spin_lock_blocking() function.

spin_unlock_unsafe

static __force_inline void spin_unlock_unsafe (spin_lock_t * lock) [static]

Release a spin lock without re-enabling interrupts.

Parameters

lock

Spinlock instance

hardware_ticks

Hardware Tick API.

Detailed Description

RP2040 only has one tick generator, and it is part of the watchdog hardware.

The RP2350 has a dedicated Tick block that is used to supply ticks to TIMER0, TIMER1, RISC-V platform timer, Arm Cortex-M33 0 timer, Arm Cortex-M33 1 timer and the WATCHDOG block.

Typedefs

typedef enum tick_gen_num_rp2350 tick_gen_num_t RP2350

Tick generator numbers on RP2350 (used as typedef tick_gen_num_t)

typedef enum tick_gen_num_rp2040 tick_gen_num_t RP2040

Tick generator numbers on RP2040 (used as typedef tick_gen_num_t)

Enumerations

enum tick_gen_num_rp2350 { TICK_PROC0 = 0, TICK_PROC1 = 1, TICK_TIMER0 = 2, TICK_TIMER1 = 3, TICK_WATCHDOG = 4, TICK_RISCV = 5, TICK_COUNT } RP2350

Tick generator numbers on RP2350 (used as typedef tick_gen_num_t)

enum tick_gen_num_rp2040 { TICK_WATCHDOG = 0, TICK_COUNT } RP2040

Tick generator numbers on RP2040 (used as typedef tick_gen_num_t)

Functions

void tick_start (tick_gen_num_t tick, uint cycles)

Start a tick generator.

void tick_stop (tick_gen_num_t tick)

Stop a tick generator.

bool tick_is_running (tick_gen_num_t tick)

Check if a tick genererator is currently running.

Typedef Documentation

tick_gen_num_t RP2350

typedef enum tick_gen_num_rp2350 tick_gen_num_t

Tick generator numbers on RP2350 (used as typedef tick_gen_num_t)

tick_gen_num_t RP2040

typedef enum tick_gen_num_rp2040 tick_gen_num_t

Tick generator numbers on RP2040 (used as typedef tick_gen_num_t)

RP2040 only has one tick generator, and it is part of the watchdog hardware

Enumeration Type Documentation

tick_gen_num_rp2350 RP2350

enum tick_gen_num_rp2350

Tick generator numbers on RP2350 (used as typedef tick_gen_num_t)

tick_gen_num_rp2040 RP2040

enum tick_gen_num_rp2040

Tick generator numbers on RP2040 (used as typedef tick_gen_num_t)

RP2040 only has one tick generator, and it is part of the watchdog hardware

Function Documentation

tick_is_running

bool tick_is_running (tick_gen_num_t tick)

Check if a tick genererator is currently running.

Parameters

tick

The tick generator number

Returns

true if the specific ticker is running.

tick_start

void tick_start (tick_gen_num_t tick, uint cycles)

Start a tick generator.

Parameters

tick

The tick generator number

cycles

The number of clock cycles per tick

tick_stop

void tick_stop (tick_gen_num_t tick)

Stop a tick generator.

Parameters

tick

The tick generator number

hardware_timer

Low-level hardware timer API.

Detailed Description

This API provides medium level access to the timer HW. See also pico_time which provides higher levels functionality using the hardware timer.

The timer peripheral on RP-series microcontrollers supports the following features:

  • RP2040 single 64-bit counter, incrementing once per microsecond

  • RP2350 two 64-bit counters, ticks generated from the tick block

  • Latching two-stage read of counter, for race-free read over 32 bit bus

  • Four alarms: match on the lower 32 bits of counter, IRQ on match.

On RP2040, by default the timer uses a one microsecond reference that is generated in the Watchdog (see RP2040 Datasheet Section 4.8.2) which is derived from the clk_ref.

On RP2350, by default the timer uses a one microsecond reference that is generated by the tick block (see RP2350 Datasheet Section 8.5)

The timer has 4 alarms, and can output a separate interrupt for each alarm. The alarms match on the lower 32 bits of the 64 bit counter which means they can be fired a maximum of 2^32 microseconds into the future. This is equivalent to:

  • 2^32 ÷ 10^6: ~4295 seconds

  • 4295 ÷ 60: ~72 minutes

The timer is expected to be used for short sleeps, if you want a longer alarm see the hardware_rtc functions.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include "pico/stdlib.h"

volatile bool timer_fired = false;

int64_t alarm_callback(alarm_id_t id, __unused void *user_data) {
    printf("Timer %d fired!\n", (int) id);
    timer_fired = true;
    // Can return a value here in us to fire in the future
    return 0;
}

bool repeating_timer_callback(__unused struct repeating_timer *t) {
    printf("Repeat at %lld\n", time_us_64());
    return true;
}

int main() {
    stdio_init_all();
    printf("Hello Timer!\n");

    // Call alarm_callback in 2 seconds
    add_alarm_in_ms(2000, alarm_callback, NULL, false);

    // Wait for alarm callback to set timer_fired
    while (!timer_fired) {
        tight_loop_contents();
    }

    // Create a repeating timer that calls repeating_timer_callback.
    // If the delay is > 0 then this is the delay between the previous callback ending and the next starting.
    // If the delay is negative (see below) then the next call to the callback will be exactly 500ms after the
    // start of the call to the last callback
    struct repeating_timer timer;
    add_repeating_timer_ms(500, repeating_timer_callback, NULL, &timer);
    sleep_ms(3000);
    bool cancelled = cancel_repeating_timer(&timer);
    printf("cancelled... %d\n", cancelled);
    sleep_ms(2000);

    // Negative delay so means we will call repeating_timer_callback, and call it again
    // 500ms later regardless of how long the callback took to execute
    add_repeating_timer_ms(-500, repeating_timer_callback, NULL, &timer);
    sleep_ms(3000);
    cancelled = cancel_repeating_timer(&timer);
    printf("cancelled... %d\n", cancelled);
    sleep_ms(2000);
    printf("Done\n");
    return 0;
}

See also

Macros

Typedefs

typedef void(* hardware_alarm_callback_t)(uint alarm_num)

Functions

static uint32_t timer_time_us_32 (timer_hw_t *timer)

Return a 32 bit timestamp value in microseconds for a given timer instance.

static uint32_t time_us_32 (void)

Return a 32 bit timestamp value in microseconds for the default timer instance.

uint64_t timer_time_us_64 (timer_hw_t *timer)

Return the current 64 bit timestamp value in microseconds for a given timer instance.

uint64_t time_us_64 (void)

Return the current 64 bit timestamp value in microseconds for the default timer instance.

void timer_busy_wait_us_32 (timer_hw_t *timer, uint32_t delay_us)

Busy wait wasting cycles for the given (32 bit) number of microseconds using the given timer instance.

void busy_wait_us_32 (uint32_t delay_us)

Busy wait wasting cycles for the given (32 bit) number of microseconds using the default timer instance.

void timer_busy_wait_us (timer_hw_t *timer, uint64_t delay_us)

Busy wait wasting cycles for the given (64 bit) number of microseconds using the given timer instance.

void busy_wait_us (uint64_t delay_us)

Busy wait wasting cycles for the given (64 bit) number of microseconds using the default timer instance.

void timer_busy_wait_ms (timer_hw_t *timer, uint32_t delay_ms)

Busy wait wasting cycles for the given number of milliseconds using the given timer instance.

void busy_wait_ms (uint32_t delay_ms)

Busy wait wasting cycles for the given number of milliseconds using the default timer instance.

void timer_busy_wait_until (timer_hw_t *timer, absolute_time_t t)

Busy wait wasting cycles until after the specified timestamp using the given timer instance.

void busy_wait_until (absolute_time_t t)

Busy wait wasting cycles until after the specified timestamp using the default timer instance.

static bool timer_time_reached (timer_hw_t *timer, absolute_time_t t)

Check if the specified timestamp has been reached on the given timer instance.

static bool time_reached (absolute_time_t t)

Check if the specified timestamp has been reached on the default timer instance.

void timer_hardware_alarm_claim (timer_hw_t *timer, uint alarm_num)

cooperatively claim the use of this hardware alarm_num on the given timer instance

void hardware_alarm_claim (uint alarm_num)

cooperatively claim the use of this hardware alarm_num on the default timer instance

int timer_hardware_alarm_claim_unused (timer_hw_t *timer, bool required)

cooperatively claim the use of a hardware alarm_num on the given timer instance

int hardware_alarm_claim_unused (bool required)

cooperatively claim the use of a hardware alarm_num on the default timer instance

void timer_hardware_alarm_unclaim (timer_hw_t *timer, uint alarm_num)

cooperatively release the claim on use of this hardware alarm_num on the given timer instance

void hardware_alarm_unclaim (uint alarm_num)

cooperatively release the claim on use of this hardware alarm_num on the default timer instance

bool timer_hardware_alarm_is_claimed (timer_hw_t *timer, uint alarm_num)

Determine if a hardware alarm has been claimed on the given timer instance.

bool hardware_alarm_is_claimed (uint alarm_num)

Determine if a hardware alarm has been claimed on the default timer instance.

void timer_hardware_alarm_set_callback (timer_hw_t *timer, uint alarm_num, hardware_alarm_callback_t callback)

Enable/Disable a callback for a hardware alarm for a given timer instance on this core.

void hardware_alarm_set_callback (uint alarm_num, hardware_alarm_callback_t callback)

Enable/Disable a callback for a hardware alarm on the default timer instance on this core.

bool timer_hardware_alarm_set_target (timer_hw_t *timer, uint alarm_num, absolute_time_t t)

Set the current target for a specific hardware alarm on the given timer instance.

bool hardware_alarm_set_target (uint alarm_num, absolute_time_t t)

Set the current target for the specified hardware alarm on the default timer instance.

void timer_hardware_alarm_cancel (timer_hw_t *timer, uint alarm_num)

Cancel an existing target (if any) for a specific hardware_alarm on the given timer instance.

void hardware_alarm_cancel (uint alarm_num)

Cancel an existing target (if any) for the specified hardware_alarm on the default timer instance.

void timer_hardware_alarm_force_irq (timer_hw_t *timer, uint alarm_num)

Force and IRQ for a specific hardware alarm on the given timer instance.

void hardware_alarm_force_irq (uint alarm_num)

Force and IRQ for a specific hardware alarm on the default timer instance.

static uint timer_hardware_alarm_get_irq_num (timer_hw_t *timer, uint alarm_num)

Returns the irq_num_t for the alarm interrupt from the given alarm on the given timer instance.

static uint hardware_alarm_get_irq_num (uint alarm_num)

Returns the irq_num_t for the alarm interrupt from the given alarm on the default timer instance.

static uint timer_get_index (timer_hw_t *timer)

Returns the timer number for a timer instance.

static timer_hw_t * timer_get_instance (uint timer_num)

Returns the timer instance with the given timer number.

Macro Definition Documentation

TIMER_ALARM_IRQ_NUM

#define TIMER_ALARM_IRQ_NUM(timer, alarm_num)

Returns the irq_num_t for the alarm interrupt from the given alarm on the given timer instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

TIMER_ALARM_NUM_FROM_IRQ

#define TIMER_ALARM_NUM_FROM_IRQ(irq_num)

Returns the alarm number from an irq_num_t. See TIMER_INSTANCE_NUM_FROM_IRQ to get the timer instance number.

Note this macro is intended to resolve at compile time, and does no parameter checking

TIMER_NUM_FROM_IRQ

#define TIMER_NUM_FROM_IRQ(irq_num)

Returns the alarm number from an irq_num_t. See TIMER_INSTANCE_NUM_FROM_IRQ to get the alarm number.

Note this macro is intended to resolve at compile time, and does no parameter checking

PICO_DEFAULT_TIMER

#define PICO_DEFAULT_TIMER 0

The default timer instance number of the timer instance used for APIs that don’t take an explicit timer instance On RP2040 this must be 0 as there is only one timer instance On RP2040 this may be set to 0 or 1 .

PICO_DEFAULT_TIMER_INSTANCE

#define PICO_DEFAULT_TIMER_INSTANCE()

Returns the default timer instance on the platform based on the setting of PICO_DEFAULT_TIMER.

Note this macro is intended to resolve at compile time, and does no parameter checking

Typedef Documentation

hardware_alarm_callback_t

typedef void(* hardware_alarm_callback_t) (uint alarm_num)

Callback function type for hardware alarms

Parameters

alarm_num

the hardware alarm number

Function Documentation

busy_wait_ms

void busy_wait_ms (uint32_t delay_ms)

Busy wait wasting cycles for the given number of milliseconds using the default timer instance.

Parameters

delay_ms

delay amount in milliseconds

busy_wait_until

void busy_wait_until (absolute_time_t t)

Busy wait wasting cycles until after the specified timestamp using the default timer instance.

Parameters

t

Absolute time to wait until

busy_wait_us

void busy_wait_us (uint64_t delay_us)

Busy wait wasting cycles for the given (64 bit) number of microseconds using the default timer instance.

Parameters

delay_us

delay amount in microseconds

busy_wait_us_32

void busy_wait_us_32 (uint32_t delay_us)

Busy wait wasting cycles for the given (32 bit) number of microseconds using the default timer instance.

Parameters

delay_us

delay amount in microseconds

hardware_alarm_cancel

void hardware_alarm_cancel (uint alarm_num)

Cancel an existing target (if any) for the specified hardware_alarm on the default timer instance.

Parameters

alarm_num

the hardware alarm number

hardware_alarm_claim

void hardware_alarm_claim (uint alarm_num)

cooperatively claim the use of this hardware alarm_num on the default timer instance

This method hard asserts if the hardware alarm is currently claimed.

Parameters

alarm_num

the hardware alarm to claim

See also

hardware_claiming

hardware_alarm_claim_unused

int hardware_alarm_claim_unused (bool required)

cooperatively claim the use of a hardware alarm_num on the default timer instance

This method attempts to claim an unused hardware alarm

Parameters

required

if true the function will panic if none are available

Returns

alarm_num the hardware alarm claimed or -1 if required was false, and none are available

See also

hardware_claiming

hardware_alarm_force_irq

void hardware_alarm_force_irq (uint alarm_num)

Force and IRQ for a specific hardware alarm on the default timer instance.

This method will forcibly make sure the current alarm callback (if present) for the hardware alarm is called from an IRQ context after this call. If an actual callback is due at the same time then the callback may only be called once.

Calling this method does not otherwise interfere with regular callback operations.

Parameters

alarm_num

the hardware alarm number

hardware_alarm_get_irq_num

static uint hardware_alarm_get_irq_num (uint alarm_num) [inline], [static]

Returns the irq_num_t for the alarm interrupt from the given alarm on the default timer instance.

Parameters

alarm_num

the alarm number

hardware_alarm_is_claimed

bool hardware_alarm_is_claimed (uint alarm_num)

Determine if a hardware alarm has been claimed on the default timer instance.

Parameters

alarm_num

the hardware alarm number

Returns

true if claimed, false otherwise

hardware_alarm_set_callback

void hardware_alarm_set_callback (uint alarm_num, hardware_alarm_callback_t callback)

Enable/Disable a callback for a hardware alarm on the default timer instance on this core.

This method enables/disables the alarm IRQ for the specified hardware alarm on the calling core, and set the specified callback to be associated with that alarm.

This callback will be used for the timeout set via hardware_alarm_set_target

Note

This will install the handler on the current core if the IRQ handler isn’t already set. Therefore the user has the opportunity to call this up from the core of their choice

Parameters

alarm_num

the hardware alarm number

callback

the callback to install, or NULL to unset

hardware_alarm_set_target

bool hardware_alarm_set_target (uint alarm_num, absolute_time_t t)

Set the current target for the specified hardware alarm on the default timer instance.

This will replace any existing target

Parameters

alarm_num

the hardware alarm number

t

the target timestamp

Returns

true if the target was "missed"; i.e. it was in the past, or occurred before a future hardware timeout could be set

hardware_alarm_unclaim

void hardware_alarm_unclaim (uint alarm_num)

cooperatively release the claim on use of this hardware alarm_num on the default timer instance

Parameters

alarm_num

the hardware alarm to unclaim

See also

hardware_claiming

time_reached

static bool time_reached (absolute_time_t t) [inline], [static]

Check if the specified timestamp has been reached on the default timer instance.

Parameters

t

Absolute time to compare against current time

Returns

true if it is now after the specified timestamp

time_us_32

static uint32_t time_us_32 (void) [inline], [static]

Return a 32 bit timestamp value in microseconds for the default timer instance.

Returns the low 32 bits of the hardware timer.

Note

This value wraps roughly every 1 hour 11 minutes and 35 seconds.

Returns

the 32 bit timestamp

See also

time_us_64

uint64_t time_us_64 (void)

Return the current 64 bit timestamp value in microseconds for the default timer instance.

Returns the full 64 bits of the hardware timer. The pico_time and other functions rely on the fact that this value monotonically increases from power up. As such it is expected that this value counts upwards and never wraps (we apologize for introducing a potential year 5851444 bug).

Returns

the 64 bit timestamp

See also

timer_busy_wait_ms

void timer_busy_wait_ms (timer_hw_t * timer, uint32_t delay_ms)

Busy wait wasting cycles for the given number of milliseconds using the given timer instance.

Parameters

timer

the timer instance

delay_ms

delay amount in milliseconds

See also

timer_busy_wait_until

void timer_busy_wait_until (timer_hw_t * timer, absolute_time_t t)

Busy wait wasting cycles until after the specified timestamp using the given timer instance.

Parameters

timer

the timer instance

t

Absolute time to wait until

See also

timer_busy_wait_us

void timer_busy_wait_us (timer_hw_t * timer, uint64_t delay_us)

Busy wait wasting cycles for the given (64 bit) number of microseconds using the given timer instance.

Parameters

timer

the timer instance

delay_us

delay amount in microseconds

See also

timer_busy_wait_us_32

void timer_busy_wait_us_32 (timer_hw_t * timer, uint32_t delay_us)

Busy wait wasting cycles for the given (32 bit) number of microseconds using the given timer instance.

Parameters

timer

the timer instance

delay_us

delay amount in microseconds

See also

Busy wait wasting cycles for the given (32 bit) number of microseconds using the given timer instance.

timer_get_index

static uint timer_get_index (timer_hw_t * timer) [inline], [static]

Returns the timer number for a timer instance.

Parameters

timer

the timer instance

Returns

the timer number

See also

TIMER_NUM

timer_get_instance

static timer_hw_t * timer_get_instance (uint timer_num) [inline], [static]

Returns the timer instance with the given timer number.

Parameters

timer_num

the timer number

Returns

the timer instance

timer_hardware_alarm_cancel

void timer_hardware_alarm_cancel (timer_hw_t * timer, uint alarm_num)

Cancel an existing target (if any) for a specific hardware_alarm on the given timer instance.

Parameters

timer

the timer instance

alarm_num

the hardware alarm number

timer_hardware_alarm_claim

void timer_hardware_alarm_claim (timer_hw_t * timer, uint alarm_num)

cooperatively claim the use of this hardware alarm_num on the given timer instance

This method hard asserts if the hardware alarm is currently claimed.

Parameters

timer

the timer instance

alarm_num

the hardware alarm to claim

See also

hardware_claiming

timer_hardware_alarm_claim_unused

int timer_hardware_alarm_claim_unused (timer_hw_t * timer, bool required)

cooperatively claim the use of a hardware alarm_num on the given timer instance

This method attempts to claim an unused hardware alarm

Parameters

timer

the timer instance

required

if true the function will panic if none are available

Returns

alarm_num the hardware alarm claimed or -1 if required was false, and none are available

See also

hardware_claiming

timer_hardware_alarm_force_irq

void timer_hardware_alarm_force_irq (timer_hw_t * timer, uint alarm_num)

Force and IRQ for a specific hardware alarm on the given timer instance.

This method will forcibly make sure the current alarm callback (if present) for the hardware alarm is called from an IRQ context after this call. If an actual callback is due at the same time then the callback may only be called once.

Calling this method does not otherwise interfere with regular callback operations.

Parameters

timer

the timer instance

alarm_num

the hardware alarm number

timer_hardware_alarm_get_irq_num

static uint timer_hardware_alarm_get_irq_num (timer_hw_t * timer, uint alarm_num) [inline], [static]

Returns the irq_num_t for the alarm interrupt from the given alarm on the given timer instance.

Parameters

timer

the timer instance

alarm_num

the alarm number

timer_hardware_alarm_is_claimed

bool timer_hardware_alarm_is_claimed (timer_hw_t * timer, uint alarm_num)

Determine if a hardware alarm has been claimed on the given timer instance.

Parameters

timer

the timer instance

alarm_num

the hardware alarm number

Returns

true if claimed, false otherwise

timer_hardware_alarm_set_callback

void timer_hardware_alarm_set_callback (timer_hw_t * timer, uint alarm_num, hardware_alarm_callback_t callback)

Enable/Disable a callback for a hardware alarm for a given timer instance on this core.

This method enables/disables the alarm IRQ for the specified hardware alarm on the calling core, and set the specified callback to be associated with that alarm.

This callback will be used for the timeout set via hardware_alarm_set_target

Note

This will install the handler on the current core if the IRQ handler isn’t already set. Therefore the user has the opportunity to call this up from the core of their choice

Parameters

timer

the timer instance

alarm_num

the hardware alarm number

callback

the callback to install, or NULL to unset

timer_hardware_alarm_set_target

bool timer_hardware_alarm_set_target (timer_hw_t * timer, uint alarm_num, absolute_time_t t)

Set the current target for a specific hardware alarm on the given timer instance.

This will replace any existing target

Parameters

timer

the timer instance

alarm_num

the hardware alarm number

t

the target timestamp

Returns

true if the target was "missed"; i.e. it was in the past, or occurred before a future hardware timeout could be set

timer_hardware_alarm_unclaim

void timer_hardware_alarm_unclaim (timer_hw_t * timer, uint alarm_num)

cooperatively release the claim on use of this hardware alarm_num on the given timer instance

Parameters

timer

the timer instance

alarm_num

the hardware alarm to unclaim

See also

hardware_claiming

timer_time_reached

static bool timer_time_reached (timer_hw_t * timer, absolute_time_t t) [inline], [static]

Check if the specified timestamp has been reached on the given timer instance.

Parameters

timer

the timer instance

t

Absolute time to compare against current time

Returns

true if it is now after the specified timestamp

See also

timer_time_us_32

static uint32_t timer_time_us_32 (timer_hw_t * timer) [inline], [static]

Return a 32 bit timestamp value in microseconds for a given timer instance.

Returns the low 32 bits of the hardware timer.

Note

This value wraps roughly every 1 hour 11 minutes and 35 seconds.

Parameters

timer

the timer instance

Returns

the 32 bit timestamp

See also

timer_time_us_64

uint64_t timer_time_us_64 (timer_hw_t * timer)

Return the current 64 bit timestamp value in microseconds for a given timer instance.

Returns the full 64 bits of the hardware timer. The pico_time and other functions rely on the fact that this value monotonically increases from power up. As such it is expected that this value counts upwards and never wraps (we apologize for introducing a potential year 5851444 bug).

Parameters

timer

the timer instance

Returns

the 64 bit timestamp

See also

Return the current 64 bit timestamp value in microseconds for a given timer instance.

hardware_uart

Hardware UART API.

Detailed Description

RP-series microcontrollers have 2 identical instances of a UART peripheral, based on the ARM PL011. Each UART can be connected to a number of GPIO pins as defined in the GPIO muxing.

Only the TX, RX, RTS, and CTS signals are connected, meaning that the modem mode and IrDA mode of the PL011 are not supported.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 int main() {

    // Set the GPIO pin mux to the UART - pin 0 is TX, 1 is RX; note use of UART_FUNCSEL_NUM for the general
    // case where the func sel used for UART depends on the pin number
    // Do this before calling uart_init to avoid losing data
    gpio_set_function(0, UART_FUNCSEL_NUM(uart0, 0));
    gpio_set_function(1, UART_FUNCSEL_NUM(uart0, 1));

    // Initialise UART 0
    uart_init(uart0, 115200);

    uart_puts(uart0, "Hello world!");
}

Macros

Enumerations

enum uart_parity_t { UART_PARITY_NONE, UART_PARITY_EVEN, UART_PARITY_ODD }

UART Parity enumeration.

Functions

static uint uart_get_index (uart_inst_t *uart)

Convert UART instance to hardware instance number.

static uart_inst_t * uart_get_instance (uint num)

Get the UART instance from an instance number.

static uart_hw_t * uart_get_hw (uart_inst_t *uart)

Get the real hardware UART instance from a UART instance.

uint uart_init (uart_inst_t *uart, uint baudrate)

Initialise a UART.

void uart_deinit (uart_inst_t *uart)

DeInitialise a UART.

uint uart_set_baudrate (uart_inst_t *uart, uint baudrate)

Set UART baud rate.

static void uart_set_hw_flow (uart_inst_t *uart, bool cts, bool rts)

Set UART flow control CTS/RTS.

void uart_set_format (uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity)

Set UART data format.

static void uart_set_irqs_enabled (uart_inst_t *uart, bool rx_has_data, bool tx_needs_data)

Enable/Disable UART interrupt outputs.

static bool uart_is_enabled (uart_inst_t *uart)

Test if specific UART is enabled.

void uart_set_fifo_enabled (uart_inst_t *uart, bool enabled)

Enable/Disable the FIFOs on specified UART.

static bool uart_is_writable (uart_inst_t *uart)

Determine if space is available in the TX FIFO.

static void uart_tx_wait_blocking (uart_inst_t *uart)

Wait for the UART TX fifo to be drained.

static bool uart_is_readable (uart_inst_t *uart)

Determine whether data is waiting in the RX FIFO.

static void uart_write_blocking (uart_inst_t *uart, const uint8_t *src, size_t len)

Write to the UART for transmission.

static void uart_read_blocking (uart_inst_t *uart, uint8_t *dst, size_t len)

Read from the UART.

static void uart_putc_raw (uart_inst_t *uart, char c)

Write single character to UART for transmission.

static void uart_putc (uart_inst_t *uart, char c)

Write single character to UART for transmission, with optional CR/LF conversions.

static void uart_puts (uart_inst_t *uart, const char *s)

Write string to UART for transmission, doing any CR/LF conversions.

static char uart_getc (uart_inst_t *uart)

Read a single character from the UART.

void uart_set_break (uart_inst_t *uart, bool en)

Assert a break condition on the UART transmission.

void uart_set_translate_crlf (uart_inst_t *uart, bool translate)

Set CR/LF conversion on UART.

static void uart_default_tx_wait_blocking (void)

Wait for the default UART’s TX FIFO to be drained.

bool uart_is_readable_within_us (uart_inst_t *uart, uint32_t us)

Wait for up to a certain number of microseconds for the RX FIFO to be non empty.

static uint uart_get_dreq_num (uart_inst_t *uart, bool is_tx)

Return the dreq_num_t to use for pacing transfers to/from a particular UART instance.

static uint uart_get_reset_num (uart_inst_t *uart)

Return the reset_num_t to use to reset a particular UART instance.

uart0

#define uart0 ((uart_inst_t *)uart0_hw)

Identifier for UART instance 0.

The UART identifiers for use in UART functions.

e.g. uart_init(uart1, 48000)

uart1

#define uart1 ((uart_inst_t *)uart1_hw)

Identifier for UART instance 1.

Macro Definition Documentation

UART_NUM

#define UART_NUM(uart)

Returns the UART number for a UART instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

UART_INSTANCE

#define UART_INSTANCE(num)

Returns the UART instance with the given UART number.

Note this macro is intended to resolve at compile time, and does no parameter checking

UART_DREQ_NUM

#define UART_DREQ_NUM(uart, is_tx)

Returns the dreq_num_t used for pacing DMA transfers to or from this UART instance. If is_tx is true, then it is for transfers to the UART else for transfers from the UART.

Note this macro is intended to resolve at compile time, and does no parameter checking

UART_CLOCK_NUM

#define UART_CLOCK_NUM(uart)

Returns clock_num_t of the clock for the given UART instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

UART_FUNCSEL_NUM

#define UART_FUNCSEL_NUM(uart, gpio)

Returns gpio_function_t needed to select the UART function for the given UART instance on the given GPIO number.

Note this macro is intended to resolve at compile time, and does no parameter checking

UART_IRQ_NUM

#define UART_IRQ_NUM(uart)

Returns the irq_num_t for processor interrupts from the given UART instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

UART_RESET_NUM

#define UART_RESET_NUM(uart)

Returns the reset_num_t used to reset a given UART instance.

Note this macro is intended to resolve at compile time, and does no parameter checking

Enumeration Type Documentation

uart_parity_t

enum uart_parity_t

UART Parity enumeration.

Function Documentation

uart_default_tx_wait_blocking

static void uart_default_tx_wait_blocking (void) [inline], [static]

Wait for the default UART’s TX FIFO to be drained.

uart_deinit

void uart_deinit (uart_inst_t * uart)

DeInitialise a UART.

Disable the UART if it is no longer used. Must be reinitialised before being used again.

Parameters

uart

UART instance. uart0 or uart1

uart_get_dreq_num

static uint uart_get_dreq_num (uart_inst_t * uart, bool is_tx) [inline], [static]

Return the dreq_num_t to use for pacing transfers to/from a particular UART instance.

Parameters

uart

UART instance. uart0 or uart1

is_tx

true for sending data to the UART instance, false for receiving data from the UART instance

uart_get_hw

static uart_hw_t * uart_get_hw (uart_inst_t * uart) [inline], [static]

Get the real hardware UART instance from a UART instance.

This extra level of abstraction was added to facilitate adding PIO UARTs in the future. It currently does nothing, and costs nothing.

Parameters

uart

UART instance

Returns

The uart_hw_t pointer to the UART instance registers

uart_get_index

static uint uart_get_index (uart_inst_t * uart) [inline], [static]

Convert UART instance to hardware instance number.

Parameters

uart

UART instance

Returns

Number of UART, 0 or 1

uart_get_instance

static uart_inst_t * uart_get_instance (uint num) [inline], [static]

Get the UART instance from an instance number.

Parameters

num

Number of UART, 0 or 1

Returns

UART instance

uart_get_reset_num

static uint uart_get_reset_num (uart_inst_t * uart) [inline], [static]

Return the reset_num_t to use to reset a particular UART instance.

Parameters

uart

UART instance. uart0 or uart1

uart_getc

static char uart_getc (uart_inst_t * uart) [inline], [static]

Read a single character from the UART.

This function will block until a character has been read

Parameters

uart

UART instance. uart0 or uart1

Returns

The character read.

uart_init

uint uart_init (uart_inst_t * uart, uint baudrate)

Initialise a UART.

Put the UART into a known state, and enable it. Must be called before other functions.

This function always enables the FIFOs, and configures the UART for the following default line format:

  • 8 data bits

  • No parity bit

  • One stop bit

Note

There is no guarantee that the baudrate requested will be possible, the nearest will be chosen, and this function will return the configured baud rate.

Parameters

uart

UART instance. uart0 or uart1

baudrate

Baudrate of UART in Hz

Returns

Actual set baudrate

uart_is_enabled

static bool uart_is_enabled (uart_inst_t * uart) [inline], [static]

Test if specific UART is enabled.

Parameters

uart

UART instance. uart0 or uart1

Returns

true if the UART is enabled

uart_is_readable

static bool uart_is_readable (uart_inst_t * uart) [inline], [static]

Determine whether data is waiting in the RX FIFO.

Parameters

uart

UART instance. uart0 or uart1

Returns

true if the RX FIFO is not empty, otherwise false.

uart_is_readable_within_us

bool uart_is_readable_within_us (uart_inst_t * uart, uint32_t us)

Wait for up to a certain number of microseconds for the RX FIFO to be non empty.

Parameters

uart

UART instance. uart0 or uart1

us

the number of microseconds to wait at most (may be 0 for an instantaneous check)

Returns

true if the RX FIFO became non empty before the timeout, false otherwise

uart_is_writable

static bool uart_is_writable (uart_inst_t * uart) [inline], [static]

Determine if space is available in the TX FIFO.

Parameters

uart

UART instance. uart0 or uart1

Returns

false if no space available, true otherwise

uart_putc

static void uart_putc (uart_inst_t * uart, char c) [inline], [static]

Write single character to UART for transmission, with optional CR/LF conversions.

This function will block until the character has been sent to the UART transmit buffer

Parameters

uart

UART instance. uart0 or uart1

c

The character to send

uart_putc_raw

static void uart_putc_raw (uart_inst_t * uart, char c) [inline], [static]

Write single character to UART for transmission.

This function will block until the entire character has been sent to the UART transmit buffer

Parameters

uart

UART instance. uart0 or uart1

c

The character to send

uart_puts

static void uart_puts (uart_inst_t * uart, const char * s) [inline], [static]

Write string to UART for transmission, doing any CR/LF conversions.

This function will block until the entire string has been sent to the UART transmit buffer

Parameters

uart

UART instance. uart0 or uart1

s

The null terminated string to send

uart_read_blocking

static void uart_read_blocking (uart_inst_t * uart, uint8_t * dst, size_t len) [inline], [static]

Read from the UART.

This function blocks until len characters have been read from the UART

Parameters

uart

UART instance. uart0 or uart1

dst

Buffer to accept received bytes

len

The number of bytes to receive.

uart_set_baudrate

uint uart_set_baudrate (uart_inst_t * uart, uint baudrate)

Set UART baud rate.

Set baud rate as close as possible to requested, and return actual rate selected.

The UART is paused for around two character periods whilst the settings are changed. Data received during this time may be dropped by the UART.

Any characters still in the transmit buffer will be sent using the new updated baud rate. uart_tx_wait_blocking() can be called before this function to ensure all characters at the old baud rate have been sent before the rate is changed.

This function should not be called from an interrupt context, and the UART interrupt should be disabled before calling this function.

Parameters

uart

UART instance. uart0 or uart1

baudrate

Baudrate in Hz

Returns

Actual set baudrate

uart_set_break

void uart_set_break (uart_inst_t * uart, bool en)

Assert a break condition on the UART transmission.

Parameters

uart

UART instance. uart0 or uart1

en

Assert break condition (TX held low) if true. Clear break condition if false.

uart_set_fifo_enabled

void uart_set_fifo_enabled (uart_inst_t * uart, bool enabled)

Enable/Disable the FIFOs on specified UART.

The UART is paused for around two character periods whilst the settings are changed. Data received during this time may be dropped by the UART.

Any characters still in the transmit FIFO will be lost if the FIFO is disabled. uart_tx_wait_blocking() can be called before this function to avoid this.

This function should not be called from an interrupt context, and the UART interrupt should be disabled when calling this function.

Parameters

uart

UART instance. uart0 or uart1

enabled

true to enable FIFO (default), false to disable

uart_set_format

void uart_set_format (uart_inst_t * uart, uint data_bits, uint stop_bits, uart_parity_t parity)

Set UART data format.

Configure the data format (bits etc) for the UART.

The UART is paused for around two character periods whilst the settings are changed. Data received during this time may be dropped by the UART.

Any characters still in the transmit buffer will be sent using the new updated data format. uart_tx_wait_blocking() can be called before this function to ensure all characters needing the old format have been sent before the format is changed.

This function should not be called from an interrupt context, and the UART interrupt should be disabled before calling this function.

Parameters

uart

UART instance. uart0 or uart1

data_bits

Number of bits of data. 5..8

stop_bits

Number of stop bits 1..2

parity

Parity option.

uart_set_hw_flow

static void uart_set_hw_flow (uart_inst_t * uart, bool cts, bool rts) [inline], [static]

Set UART flow control CTS/RTS.

Parameters

uart

UART instance. uart0 or uart1

cts

If true enable flow control of TX by clear-to-send input

rts

If true enable assertion of request-to-send output by RX flow control

uart_set_irqs_enabled

static void uart_set_irqs_enabled (uart_inst_t * uart, bool rx_has_data, bool tx_needs_data) [inline], [static]

Enable/Disable UART interrupt outputs.

Enable/Disable the UART’s interrupt outputs. An interrupt handler should be installed prior to calling this function.

Parameters

uart

UART instance. uart0 or uart1

rx_has_data

If true an interrupt will be fired when the RX FIFO contains data.

tx_needs_data

If true an interrupt will be fired when the TX FIFO needs data.

uart_set_translate_crlf

void uart_set_translate_crlf (uart_inst_t * uart, bool translate)

Set CR/LF conversion on UART.

Parameters

uart

UART instance. uart0 or uart1

translate

If true, convert line feeds to carriage return on transmissions

uart_tx_wait_blocking

static void uart_tx_wait_blocking (uart_inst_t * uart) [inline], [static]

Wait for the UART TX fifo to be drained.

Parameters

uart

UART instance. uart0 or uart1

uart_write_blocking

static void uart_write_blocking (uart_inst_t * uart, const uint8_t * src, size_t len) [inline], [static]

Write to the UART for transmission.

This function will block until all the data has been sent to the UART transmit buffer hardware. Note: Serial data transmission will continue until the Tx FIFO and the transmit shift register (not programmer-accessible) are empty. To ensure the UART FIFO has been emptied, you can use uart_tx_wait_blocking()

Parameters

uart

UART instance. uart0 or uart1

src

The bytes to send

len

The number of bytes to send

hardware_vreg

Voltage Regulation API.

Functions

void vreg_set_voltage (enum vreg_voltage voltage)

Set voltage.

enum vreg_voltage vreg_get_voltage (void)

Get voltage.

void vreg_disable_voltage_limit (void)

Enable use of voltages beyond the safe range of operation.

Function Documentation

vreg_disable_voltage_limit

void vreg_disable_voltage_limit (void)

Enable use of voltages beyond the safe range of operation.

This allows voltages beyond VREG_VOLTAGE_MAX to be used, on platforms where they are available (e.g. RP2350). Attempting to set a higher voltage without first calling this function will result in a voltage of VREG_VOLTAGE_MAX.

vreg_get_voltage

enum vreg_voltage vreg_get_voltage (void)

Get voltage.

Returns

The current voltage (from enumeration vreg_voltage) of the voltage regulator

vreg_set_voltage

void vreg_set_voltage (enum vreg_voltage voltage)

Set voltage.

Parameters

voltage

The voltage (from enumeration vreg_voltage) to apply to the voltage regulator

hardware_watchdog

Hardware Watchdog Timer API.

Detailed Description

Supporting functions for the Pico hardware watchdog timer.

The RP-series microcontrollers have a built in HW watchdog Timer. This is a countdown timer that can restart parts of the chip if it reaches zero. For example, this can be used to restart the processor if the software running on it gets stuck in an infinite loop or similar. The programmer has to periodically write a value to the watchdog to stop it reaching zero.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/watchdog.h"

int main() {
    stdio_init_all();

    if (watchdog_caused_reboot()) {
        printf("Rebooted by Watchdog!\n");
        return 0;
    } else {
        printf("Clean boot\n");
    }

    // Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will reboot
    // second arg is pause on debug which means the watchdog will pause when stepping through code
    watchdog_enable(100, 1);

    for (uint i = 0; i < 5; i++) {
        printf("Updating watchdog %d\n", i);
        watchdog_update();
    }

    // Wait in an infinite loop and don't update the watchdog so it reboots us
    printf("Waiting to be rebooted by watchdog\n");
    while(1);
}

Functions

void watchdog_reboot (uint32_t pc, uint32_t sp, uint32_t delay_ms)

Define actions to perform at watchdog timeout.

void watchdog_start_tick (uint cycles)

Start the watchdog tick.

void watchdog_update (void)

Reload the watchdog counter with the amount of time set in watchdog_enable.

void watchdog_enable (uint32_t delay_ms, bool pause_on_debug)

Enable the watchdog.

void watchdog_disable (void)

Disable the watchdog.

bool watchdog_caused_reboot (void)

Did the watchdog cause the last reboot?

bool watchdog_enable_caused_reboot (void)

Did watchdog_enable cause the last reboot?

uint32_t watchdog_get_time_remaining_ms (void)

Returns the number of microseconds before the watchdog will reboot the chip.

Function Documentation

watchdog_caused_reboot

bool watchdog_caused_reboot (void)

Did the watchdog cause the last reboot?

Returns

true If the watchdog timer or a watchdog force caused the last reboot

Returns

false If there has been no watchdog reboot since the last power on reset. A power on reset is typically caused by a power cycle or the run pin (reset button) being toggled.

watchdog_disable

void watchdog_disable (void)

Disable the watchdog.

watchdog_enable

void watchdog_enable (uint32_t delay_ms, bool pause_on_debug)

Enable the watchdog.

Note

If watchdog_start_tick value does not give a 1MHz clock to the watchdog system, then the delay_ms parameter will not be in milliseconds. See the datasheet for more details.

By default the SDK assumes a 12MHz XOSC and sets the watchdog_start_tick appropriately.

This method sets a marker in the watchdog scratch register 4 that is checked by watchdog_enable_caused_reboot. If the device is subsequently reset via a call to watchdog_reboot (including for example by dragging a UF2 onto the RPI-RP2), then this value will be cleared, and so watchdog_enable_caused_reboot will return false.

Parameters

delay_ms

Number of milliseconds before watchdog will reboot without watchdog_update being called. Maximum of 8388, which is approximately 8.3 seconds

pause_on_debug

If the watchdog should be paused when the debugger is stepping through code

watchdog_enable_caused_reboot

bool watchdog_enable_caused_reboot (void)

Did watchdog_enable cause the last reboot?

Perform additional checking along with watchdog_caused_reboot to determine if a watchdog timeout initiated by watchdog_enable caused the last reboot.

This method checks for a special value in watchdog scratch register 4 placed there by watchdog_enable. This would not be present if a watchdog reset is initiated by watchdog_reboot or by the RP-series microcontroller bootrom (e.g. dragging a UF2 onto the RPI-RP2 drive).

Returns

true If the watchdog timer or a watchdog force caused (see watchdog_caused_reboot) the last reboot and the watchdog reboot happened after watchdog_enable was called

Returns

false If there has been no watchdog reboot since the last power on reset, or the watchdog reboot was not caused by a watchdog timeout after watchdog_enable was called. A power on reset is typically caused by a power cycle or the run pin (reset button) being toggled.

watchdog_get_time_remaining_ms

uint32_t watchdog_get_time_remaining_ms (void)

Returns the number of microseconds before the watchdog will reboot the chip.

Returns

The number of microseconds before the watchdog will reboot the chip.

watchdog_reboot

void watchdog_reboot (uint32_t pc, uint32_t sp, uint32_t delay_ms)

Define actions to perform at watchdog timeout.

Note

If watchdog_start_tick value does not give a 1MHz clock to the watchdog system, then the delay_ms parameter will not be in milliseconds. See the datasheet for more details.

By default the SDK assumes a 12MHz XOSC and sets the watchdog_start_tick appropriately.

Parameters

pc

If Zero, a standard boot will be performed, if non-zero this is the program counter to jump to on reset.

sp

If pc is non-zero, this will be the stack pointer used.

delay_ms

Initial load value. Maximum value 8388, approximately 8.3s.

watchdog_start_tick

void watchdog_start_tick (uint cycles)

Start the watchdog tick.

Parameters

cycles

This needs to be a divider that when applied to the XOSC input, produces a 1MHz clock. So if the XOSC is 12MHz, this will need to be 12.

watchdog_update

void watchdog_update (void)

Reload the watchdog counter with the amount of time set in watchdog_enable.

hardware_xip_cache

Low-level cache maintenance operations for the XIP cache.

Detailed Description

These functions apply some maintenance operation to either the entire cache contents, or a range of offsets within the downstream address space. Offsets start from 0 (indicating the first byte of flash), so pointers should have XIP_BASE subtracted before passing into one of these functions.

The only valid cache maintenance operation on RP2040 is "invalidate", which tells the cache to forget everything it knows about some address. This is necessary after a programming operation, because the cache does not automatically know about any serial programming operations performed on the external flash device, and could return stale data.

On RP2350, the three types of operation are:

  • Invalidate: tell the cache to forget everything it knows about some address. The next access to that address will fetch from downstream memory.

  • Clean: if the addressed cache line contains data not yet written to external memory, then write that data out now, and mark the line as "clean" (i.e. not containing uncommitted write data)

  • Pin: mark an address as always being resident in the cache. This persists until the line is invalidated, and can be used to allocate part of the cache for cache-as-SRAM use.

When using both external flash and external RAM (e.g. PSRAM), a simple way to maintain coherence over flash programming operations is to:

  1. Clean the entire cache (e.g. using xip_cache_clean_all())

  2. Erase + program the flash using serial SPI commands

  3. Invalidate ("flush") the entire cache (e.g. using xip_cache_invalidate_all())

The invalidate ensures the programming is visible to subsequent reads. The clean ensures that the invalidate does not discard any cached PSRAM write data.

Functions

void xip_cache_invalidate_all (void)

Invalidate the cache for the entire XIP address space.

void xip_cache_invalidate_range (uintptr_t start_offset, uintptr_t size_bytes)

Invalidate a range of offsets within the XIP address space.

void xip_cache_clean_all (void) RP2350

Clean the cache for the entire XIP address space.

void xip_cache_clean_range (uintptr_t start_offset, uintptr_t size_bytes) RP2350

Clean a range of offsets within the XIP address space.

void xip_cache_pin_range (uintptr_t start_offset, uintptr_t size_bytes) RP2350

Pin a range of offsets within the XIP address space.

Function Documentation

xip_cache_clean_all RP2350

void xip_cache_clean_all (void)

Clean the cache for the entire XIP address space.

This causes the cache to write out all pending write data to the downstream memory. For example, when suspending the system with state retained in external PSRAM, this ensures all data has made it out to external PSRAM before powering down.

This function is faster than calling xip_cache_clean_range() for the entire address space, because it iterates over cachelines instead of addresses.

On RP2040 this is a no-op, as the XIP cache is read-only. This is indicated by the XIP_CACHE_IS_READ_ONLY macro.

On RP2350, due to the workaround applied for RP2350-E11, this function also effectively invalidates all cache lines after cleaning them. The next access to each line will miss. Avoid this by calling xip_cache_clean_range() which does not suffer this issue.

xip_cache_clean_range RP2350

void xip_cache_clean_range (uintptr_t start_offset, uintptr_t size_bytes)

Clean a range of offsets within the XIP address space.

This causes the cache to write out pending write data at these offsets to the downstream memory.

On RP2040 this is a no-op, as the XIP cache is read-only. This is indicated by the XIP_CACHE_IS_READ_ONLY macro.

Parameters

start_offset

The first offset to be invalidated. Offset 0 means the first byte of XIP memory (e.g. flash). Pointers must have XIP_BASE subtracted before passing into this function. Must be aligned to the start of a cache line (XIP_CACHE_LINE_SIZE).

size_bytes

The number of bytes to clean. Must be a multiple of XIP_CACHE_LINE_SIZE.

xip_cache_invalidate_all

void xip_cache_invalidate_all (void)

Invalidate the cache for the entire XIP address space.

Invalidation ensures that subsequent reads will fetch data from the downstream memory, rather than using (potentially stale) cached data.

This function is faster than calling xip_cache_invalidate_range() for the entire address space, because it iterates over cachelines instead of addresses.

Note

Any pending write data held in the cache is lost: you can force the cache to commit these writes first, by calling xip_cache_clean_all()

Unlike flash_flush_cache(), this function affects only the cache line state. flash_flush_cache() calls a ROM API which can have other effects on some platforms, like cleaning up the bootrom’s QSPI GPIO setup on RP2040. Prefer this function for general cache maintenance use, and prefer flash_flush_cache in sequences of ROM flash API calls.

xip_cache_invalidate_range

void xip_cache_invalidate_range (uintptr_t start_offset, uintptr_t size_bytes)

Invalidate a range of offsets within the XIP address space.

Parameters

start_offset

The first offset to be invalidated. Offset 0 means the first byte of XIP memory (e.g. flash). Pointers must have XIP_BASE subtracted before passing into this function. Must be 4-byte-aligned on RP2040. Must be a aligned to the start of a cache line (XIP_CACHE_LINE_SIZE) on other platforms.

size_bytes

The number of bytes to invalidate. Must be a multiple of 4 bytes on RP2040. Must be a multiple of XIP_CACHE_LINE_SIZE on other platforms.

Invalidation ensures that subsequent reads will fetch data from the downstream memory, rather than using (potentially stale) cached data.

Note

Any pending write data held in the cache is lost: you can force the cache to commit these writes first, by calling xip_cache_clean_range() with the same parameters. Generally this is not necessary because invalidation is used with flash (write-behind via programming), and cleaning is used with PSRAM (writing through the cache).

xip_cache_pin_range RP2350

void xip_cache_pin_range (uintptr_t start_offset, uintptr_t size_bytes)

Pin a range of offsets within the XIP address space.

Pinning a line at an address allocates the line exclusively for use at that address. This means that all subsequent accesses to that address will hit the cache, and will not go to downstream memory. This persists until one of two things happens:

  • The line is invalidated, e.g. via xip_cache_invalidate_all()

  • The same line is pinned at a different address (note lines are selected by address modulo XIP_CACHE_SIZE)

Parameters

start_offset

The first offset to be pinnned. Offset 0 means the first byte of XIP memory (e.g. flash). Pointers must have XIP_BASE subtracted before passing into this function. Must be aligned to the start of a cache line (XIP_CACHE_LINE_SIZE).

size_bytes

The number of bytes to pin. Must be a multiple of XIP_CACHE_LINE_SIZE.

hardware_xosc

Crystal Oscillator (XOSC) API.

Functions

void xosc_init (void)

Initialise the crystal oscillator system.

void xosc_disable (void)

Disable the Crystal oscillator.

void xosc_dormant (void)

Set the crystal oscillator system to dormant.

Function Documentation

xosc_disable

void xosc_disable (void)

Disable the Crystal oscillator.

Turns off the crystal oscillator source, and waits for it to become unstable

xosc_dormant

void xosc_dormant (void)

Set the crystal oscillator system to dormant.

Turns off the crystal oscillator until it is woken by an interrupt. This will block and hence the entire system will stop, until an interrupt wakes it up. This function will continue to block until the oscillator becomes stable after its wakeup.

xosc_init

void xosc_init (void)

Initialise the crystal oscillator system.

This function will block until the crystal oscillator has stabilised.

On this page