v2.0.0
Functions
hardware_divider
Hardware APIs

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

## Functions
static divmod_result_t | hw_divider_divmod_s32 (int32_t a, int32_t b)
| Do a signed HW divide and wait for result. More...
static divmod_result_t | hw_divider_divmod_u32 (uint32_t a, uint32_t b)
| Do an unsigned HW divide and wait for result. More...
static void | hw_divider_divmod_s32_start (int32_t a, int32_t b)
| Start a signed asynchronous divide. More...
static void | hw_divider_divmod_u32_start (uint32_t a, uint32_t b)
| Start an unsigned asynchronous divide. More...
static void | hw_divider_wait_ready (void)
| Wait for a divide to complete. More...
static divmod_result_t | hw_divider_result_nowait (void)
| Return result of HW divide, nowait. More...
static divmod_result_t | hw_divider_result_wait (void)
| Return result of last asynchronous HW divide. More...
static uint32_t | to_quotient_u32 (divmod_result_t r)
| Efficient extraction of unsigned quotient from 32p32 fixed point. More...
static int32_t | to_quotient_s32 (divmod_result_t r)
| Efficient extraction of signed quotient from 32p32 fixed point. More...
static uint32_t | to_remainder_u32 (divmod_result_t r)
| Efficient extraction of unsigned remainder from 32p32 fixed point. More...
static int32_t | to_remainder_s32 (divmod_result_t r)
| Efficient extraction of signed remainder from 32p32 fixed point. More...
static uint32_t | hw_divider_u32_quotient_wait (void)
| Return result of last asynchronous HW divide, unsigned quotient only. More...
static int32_t | hw_divider_s32_quotient_wait (void)
| Return result of last asynchronous HW divide, signed quotient only. More...
static uint32_t | hw_divider_u32_remainder_wait (void)
| Return result of last asynchronous HW divide, unsigned remainder only. More...
static int32_t | hw_divider_s32_remainder_wait (void)
| Return result of last asynchronous HW divide, signed remainder only. More...
static uint32_t | hw_divider_u32_quotient (uint32_t a, uint32_t b)
| Do an unsigned HW divide, wait for result, return quotient. More...
static uint32_t | hw_divider_u32_remainder (uint32_t a, uint32_t b)
| Do an unsigned HW divide, wait for result, return remainder. More...
static int32_t | hw_divider_quotient_s32 (int32_t a, int32_t b)
| Do a signed HW divide, wait for result, return quotient. More...
static int32_t | hw_divider_remainder_s32 (int32_t a, int32_t b)
| Do a signed HW divide, wait for result, return remainder. More...
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. More...
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. More...
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. More...
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. More...
static void | hw_divider_save_state (hw_divider_state_t *dest)
| Save the calling cores hardware divider state. More...
static void | hw_divider_restore_state (hw_divider_state_t *src)
| Load a saved hardware divider state into the current core's hardware divider. More...

## Detailed Description

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

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
  pico_divider

## Example

#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;
}
to_quotient_u32
static uint32_t to_quotient_u32(divmod_result_t r)
Efficient extraction of unsigned quotient from 32p32 fixed point.
Definition: divider.h:198
hw_divider_s32_quotient_inlined
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.
Definition: divider.h:440
hw_divider_divmod_s32_start
static void hw_divider_divmod_s32_start(int32_t a, int32_t b)
Start a signed asynchronous divide.
Definition: divider.h:107
to_quotient_s32
static int32_t to_quotient_s32(divmod_result_t r)
Efficient extraction of signed quotient from 32p32 fixed point.
Definition: divider.h:208
to_remainder_s32
static int32_t to_remainder_s32(divmod_result_t r)
Efficient extraction of signed remainder from 32p32 fixed point.
Definition: divider.h:232
hw_divider_divmod_s32
static divmod_result_t hw_divider_divmod_s32(int32_t a, int32_t b)
Do a signed HW divide and wait for result.
Definition: divider.h:74
hw_divider_restore_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.
Definition: divider.h:506
hw_divider_s32_quotient_wait
static int32_t hw_divider_s32_quotient_wait(void)
Return result of last asynchronous HW divide, signed quotient only.
Definition: divider.h:260
hw_divider_save_state
static void hw_divider_save_state(hw_divider_state_t *dest)
Save the calling cores hardware divider state.
Definition: divider.h:491
hw_divider_result_wait
static divmod_result_t hw_divider_result_wait(void)
Return result of last asynchronous HW divide.
Definition: divider.h:187
hw_divider_divmod_u32
static divmod_result_t hw_divider_divmod_u32(uint32_t a, uint32_t b)
Do an unsigned HW divide and wait for result.
Definition: divider.h:92
to_remainder_u32
static uint32_t to_remainder_u32(divmod_result_t r)
Efficient extraction of unsigned remainder from 32p32 fixed point.
Definition: divider.h:220
stdio_init_all
bool stdio_init_all(void)
Initialize all of the present standard stdio types that are linked into the binary.
Definition: stdio.c:200
divider.h
stdio.h
stdlib.h

## Function Documentation

## ◆ hw_divider_divmod_s32()

static divmod_result_t hw_divider_divmod_s32 | ( | int32_t | a,
|  | int32_t | b
| ) |  |
| inlinestatic

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
| ) |  |
| inlinestatic

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
| ) |  |
| inlinestatic

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
| ) |  |
| inlinestatic

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_quotient_s32()

static int32_t hw_divider_quotient_s32 | ( | int32_t | a,
|  | int32_t | b
| ) |  |
| inlinestatic

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
| ) |  |
| inlinestatic

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 | ) |
| inlinestatic

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 |  | ) |
| inlinestatic

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 |  | ) |
| inlinestatic

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
| ) |  |
| inlinestatic

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 |  | ) |
| inlinestatic

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
| ) |  |
| inlinestatic

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 |  | ) |
| inlinestatic

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 | ) |
| inlinestatic

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
| ) |  |
| inlinestatic

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
| ) |  |
| inlinestatic

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 |  | ) |
| inlinestatic

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
| ) |  |
| inlinestatic

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
| ) |  |
| inlinestatic

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 |  | ) |
| inlinestatic

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 |  | ) |
| inlinestatic

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 | ) |
| inlinestatic

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 | ) |
| inlinestatic

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 | ) |
| inlinestatic

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 | ) |
| inlinestatic

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