Skip to content

Group sstep_math

Modules > sstep_math

Types and operations that hide whether the library computes in fixed point or in float. More...

Classes

Type Name
struct sstep_gain
Gain of any magnitude: value = mant / 2^15 * 2^exp.
struct sstep_sincos
Sine and cosine of one angle, see sstep_sin_cos() .

Public Types

Type Name
typedef int32_t sstep_acc_t
Per-unit accumulator (Q15 in 32 bits), used by integrators and filters.
typedef uint32_t sstep_angle_t
Electrical angle: one full electrical turn (4 full steps) = 2^32.
typedef int32_t sstep_integ_t
Integrator: Q27 in 32 bits (range +/-16 pu, resolution 7.5e-9 pu).
typedef int16_t sstep_real_t
Per-unit signal (Q15).

Public Functions

Type Name
int sstep_gain_from_ratio (int32_t num, int32_t den, struct sstep_gain * gain)
Create a gain equal to num / den.
int sstep_gain_from_ratio64 (int64_t num, int64_t den, struct sstep_gain * gain)
Create a gain equal to num / den with 64-bit operands, for gains computed from several engineering values (for example L * wc * I_base / V_base).
int sstep_real_from_ratio (int32_t num, int32_t den, sstep_real_t * out)
Convert num / den to a per-unit signal, rounded and saturated.
int32_t sstep_real_to_units (sstep_acc_t x, int32_t base)
Convert a per-unit value back to engineering units: round(x * base).
struct sstep_sincos sstep_sin_cos (sstep_angle_t angle)
Sine and cosine of an electrical angle from a quarter-wave table ( SSTEP_CFG_SINE_TABLE_BITS ) with linear interpolation.

Public Static Functions

Type Name
sstep_real_t sstep_abs (sstep_real_t a)
Saturating |a|.
sstep_acc_t sstep_acc_abs (sstep_acc_t a)
Saturating |a| of an accumulator.
sstep_acc_t sstep_acc_add (sstep_acc_t a, sstep_acc_t b)
Saturating accumulator a + b.
sstep_acc_t sstep_acc_clamp (sstep_acc_t x, sstep_acc_t lo, sstep_acc_t hi)
Accumulator limited to lo .
sstep_acc_t sstep_acc_from_real (sstep_real_t a)
Convert a signal to an accumulator (exact).
sstep_acc_t sstep_acc_halve (sstep_acc_t a)
a / 2 (rounds toward minus infinity).
sstep_acc_t sstep_acc_in (sstep_acc_t x)
Limit an accumulator to +/- SSTEP_ACC_IN_MAX .
sstep_acc_t sstep_acc_scale (sstep_acc_t x, sstep_real_t k)
x * k for |x| < 2 pu (saturated first), rounded.
sstep_real_t sstep_acc_to_real (sstep_acc_t a)
Convert an accumulator to a signal, saturating.
uint16_t sstep_acc_to_ticks (sstep_acc_t duty, uint16_t period)
Duty cycle (0 .
sstep_real_t sstep_add (sstep_real_t a, sstep_real_t b)
Saturating a + b.
int32_t sstep_asr (int32_t x, uint32_t n)
Arithmetic shift right (rounds toward minus infinity), written with unsigned shifts only (MISRA C:2012 Rule 10.1); compilers emit one ASR instruction.
sstep_real_t sstep_clamp (sstep_real_t x, sstep_real_t lo, sstep_real_t hi)
x limited to lo .
sstep_real_t sstep_div_unit (sstep_acc_t num, sstep_acc_t den)
num / den for 0 <= num <= den, den > 0, as a signal in 0 .
sstep_acc_t sstep_gain_mul (const struct sstep_gain * g, sstep_real_t x)
Gain times signal: g * x, rounded to nearest.
sstep_acc_t sstep_gain_mul_acc (const struct sstep_gain * g, sstep_acc_t x)
Gain times accumulator: g * x for |x| < 4 pu (saturated first).
sstep_acc_t sstep_gain_mul_int (const struct sstep_gain * g, int32_t n)
Gain times integer: g * n as a per-unit accumulator, saturating.
sstep_integ_t sstep_integ_add (sstep_integ_t integ, const struct sstep_gain * g, sstep_real_t x)
Integrator + g * x (x a signal), saturating.
sstep_integ_t sstep_integ_add_acc (sstep_integ_t integ, const struct sstep_gain * g, sstep_acc_t x)
Integrator + g * x (x an accumulator, |x| < 4 pu), saturating.
sstep_acc_t sstep_integ_to_acc (sstep_integ_t integ)
Integrator value as an accumulator (rounded).
sstep_real_t sstep_mul (sstep_real_t a, sstep_real_t b)
a * b, rounded to nearest; (-1.0) * (-1.0) saturates to +0.99997.
sstep_real_t sstep_neg (sstep_real_t a)
Saturating -a (-(-1.0) gives +0.99997).
sstep_real_t sstep_sat (int32_t x)
Saturate a 32-bit value to sstep_real_t .
int32_t sstep_shift_round (int32_t p, int32_t sh)
Shift with rounding: sh > 0 divides by 2^sh (round half up), sh < 0 multiplies by 2^-sh with saturation.
sstep_real_t sstep_sub (sstep_real_t a, sstep_real_t b)
Saturating a - b.

Macros

Type Name
define SSTEP_ACC_C (x) (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))((x) \* 32768.0))
Accumulator constant from a floating literal (initializers only).
define SSTEP_ACC_HALF (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))16384)
0.5 as an accumulator.
define SSTEP_ACC_IN_MAX (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))131071)
Largest magnitude accepted by sstep_gain_mul_acc() and the integrator updates from accumulators (4 pu - 2^-15); larger inputs are saturated.
define SSTEP_ACC_MAX (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))INT32\_MAX)
Largest sstep_acc_t (+65536 - 2^-15).
define SSTEP_ACC_MIN (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))INT32\_MIN)
Smallest sstep_acc_t (-65536).
define SSTEP_ACC_ONE (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))32768)
1.0 as an accumulator.
define SSTEP_ACC_SCALE_MAX (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))65535)
Largest magnitude accepted by sstep_acc_scale() (2 pu - 2^-15).
define SSTEP_ACC_ZERO (([**sstep\_acc\_t**](group__sstep__math.md#typedef-sstep_acc_t))0)
Zero as an accumulator.
define SSTEP_GAIN_EXP_MAX 15
Largest gain exponent (gains up to 32767).
define SSTEP_GAIN_EXP_MIN (-16)
Smallest gain exponent.
define SSTEP_INTEG_FRAC_BITS 27
Fractional bits of sstep_integ_t .
define SSTEP_REAL_C (x) /* multi line expression */
Constant from a floating literal, saturated to -1.0 .
define SSTEP_REAL_FRAC_BITS 15
Number of fractional bits of sstep_real_t andsstep_acc_t .
define SSTEP_REAL_MAX (([**sstep\_real\_t**](group__sstep__math.md#typedef-sstep_real_t))INT16\_MAX)
Largest sstep_real_t (+0.99997).
define SSTEP_REAL_MIN (([**sstep\_real\_t**](group__sstep__math.md#typedef-sstep_real_t))INT16\_MIN)
Smallest sstep_real_t (-1.0).
define SSTEP_REAL_ZERO (([**sstep\_real\_t**](group__sstep__math.md#typedef-sstep_real_t))0)
Zero as a signal.

Detailed Description

The control code is written once against these types and operations; the backend is selected at build time with SSTEP_CFG_MATH_BACKEND.

Per-unit signals. Inside the control loops every electrical signal is normalised to a base value computed by sstep_init(): * current: 1.0 = power stage current full scale (i_full_scale_ma), * voltage: 1.0 = nominal bus voltage (vbus_nominal_mv), * duty cycle: 1.0 = 100 %.

Both backends therefore see values in about -1..+1, which makes Q15 exact enough and lets the two backends be compared sample by sample in the tests.

Type Fixed point backend Float backend
sstep_real_t int16_t, Q15 (1.0 = 32768, range -1 .. +0.99997) float, same range
sstep_acc_t int32_t, Q15 with 16 integer bits (range +/-65536) float, same range
sstep_angle_t uint32_t, one electrical turn = 2^32 same
struct sstep_gain Q15 mantissa and binary exponent float

Same behaviour in both backends. Every operation saturates to the ranges in the table instead of overflowing, in both backends, so that a test can compare them. Angles wrap by design.

Speed. The per-sample operations are static inline and branch-light; the fixed point backend uses only 32-bit multiplications (no 64-bit arithmetic), so it suits Cortex-M0. Functions that convert engineering units (*_from_ratio, sstep_real_to_units()) use 64-bit integers and division: call them at initialisation or from the slow loop, not from the fast loop.

Public Types Documentation

typedef sstep_acc_t

Per-unit accumulator (Q15 in 32 bits), used by integrators and filters.

typedef int32_t sstep_acc_t;


typedef sstep_angle_t

Electrical angle: one full electrical turn (4 full steps) = 2^32.

typedef uint32_t sstep_angle_t;


typedef sstep_integ_t

Integrator: Q27 in 32 bits (range +/-16 pu, resolution 7.5e-9 pu).

typedef int32_t sstep_integ_t;

The extra 12 fractional bits keep small increments (Ki * Ts * e is often below one Q15 LSB) instead of rounding them away.


typedef sstep_real_t

Per-unit signal (Q15).

typedef int16_t sstep_real_t;


Public Functions Documentation

function sstep_gain_from_ratio

Create a gain equal to num / den.

int sstep_gain_from_ratio (
    int32_t num,
    int32_t den,
    struct sstep_gain * gain
) 

Initialisation only (64-bit division).

Parameters:

  • num Numerator.
  • den Denominator, not 0.
  • gain Result.

Return value:

Note:

Every non-zero int32 ratio is at least 2^-31 and is representable; ratios below 2^-16 lose resolution (the mantissa is no longer normalised).


function sstep_gain_from_ratio64

Create a gain equal to num / den with 64-bit operands, for gains computed from several engineering values (for example L * wc * I_base / V_base).

int sstep_gain_from_ratio64 (
    int64_t num,
    int64_t den,
    struct sstep_gain * gain
) 

Initialisation and slow loop only: at most three 64-bit divisions.

Parameters:

  • num Numerator, |num| < 2^62.
  • den Denominator, 0 < |den| < 2^62.
  • gain Result.

Return value:

  • SSTEP_OK (gain NULL, den 0, an operand out of range, or |num / den| rounds above 32767). Ratios below 2^-31 give 0 (fixed point).

function sstep_real_from_ratio

Convert num / den to a per-unit signal, rounded and saturated.

int sstep_real_from_ratio (
    int32_t num,
    int32_t den,
    sstep_real_t * out
) 

Initialisation and slow loop only (64-bit division).

Parameters:

  • num Numerator, for example 1500 mA.
  • den Denominator, the base, for example 4000 mA; not 0.
  • out Result.

Return value:


function sstep_real_to_units

Convert a per-unit value back to engineering units: round(x * base).

int32_t sstep_real_to_units (
    sstep_acc_t x,
    int32_t base
) 

Slow loop and status only.

Parameters:

  • x Per-unit accumulator.
  • base Base in engineering units, for example 4000 mA.

Returns:

x * base, rounded to nearest and saturated to int32_t.


function sstep_sin_cos

Sine and cosine of an electrical angle from a quarter-wave table ( SSTEP_CFG_SINE_TABLE_BITS ) with linear interpolation.

struct sstep_sincos sstep_sin_cos (
    sstep_angle_t angle
) 

Fast loop safe. Quadrant symmetric: sin(a + 90 deg) is bit-exactly cos(a).

Parameters:

  • angle Angle, 2^32 = one turn.

Returns:

Sine and cosine.


Public Static Functions Documentation

function sstep_abs

Saturating |a|.

static inline sstep_real_t sstep_abs (
    sstep_real_t a
) 


function sstep_acc_abs

Saturating |a| of an accumulator.

static inline sstep_acc_t sstep_acc_abs (
    sstep_acc_t a
) 


function sstep_acc_add

Saturating accumulator a + b.

static inline sstep_acc_t sstep_acc_add (
    sstep_acc_t a,
    sstep_acc_t b
) 


function sstep_acc_clamp

Accumulator limited to lo .

static inline sstep_acc_t sstep_acc_clamp (
    sstep_acc_t x,
    sstep_acc_t lo,
    sstep_acc_t hi
) 

. hi (requires lo <= hi).


function sstep_acc_from_real

Convert a signal to an accumulator (exact).

static inline sstep_acc_t sstep_acc_from_real (
    sstep_real_t a
) 


function sstep_acc_halve

a / 2 (rounds toward minus infinity).

static inline sstep_acc_t sstep_acc_halve (
    sstep_acc_t a
) 


function sstep_acc_in

Limit an accumulator to +/- SSTEP_ACC_IN_MAX .

static inline sstep_acc_t sstep_acc_in (
    sstep_acc_t x
) 


function sstep_acc_scale

x * k for |x| < 2 pu (saturated first), rounded.

static inline sstep_acc_t sstep_acc_scale (
    sstep_acc_t x,
    sstep_real_t k
) 


function sstep_acc_to_real

Convert an accumulator to a signal, saturating.

static inline sstep_real_t sstep_acc_to_real (
    sstep_acc_t a
) 


function sstep_acc_to_ticks

Duty cycle (0 .

static inline uint16_t sstep_acc_to_ticks (
    sstep_acc_t duty,
    uint16_t period
) 

. 1, clamped) to PWM compare ticks, rounded.


function sstep_add

Saturating a + b.

static inline sstep_real_t sstep_add (
    sstep_real_t a,
    sstep_real_t b
) 


function sstep_asr

Arithmetic shift right (rounds toward minus infinity), written with unsigned shifts only (MISRA C:2012 Rule 10.1); compilers emit one ASR instruction.

static inline int32_t sstep_asr (
    int32_t x,
    uint32_t n
) 

Parameters:

  • x Value.
  • n Shift, 0..31.

Returns:

floor(x / 2^n).


function sstep_clamp

x limited to lo .

static inline sstep_real_t sstep_clamp (
    sstep_real_t x,
    sstep_real_t lo,
    sstep_real_t hi
) 

. hi (requires lo <= hi).


function sstep_div_unit

num / den for 0 <= num <= den, den > 0, as a signal in 0 .

static inline sstep_real_t sstep_div_unit (
    sstep_acc_t num,
    sstep_acc_t den
) 

. +0.99997 (rounded, 1.0 saturates). One 32-bit division.


function sstep_gain_mul

Gain times signal: g * x, rounded to nearest.

static inline sstep_acc_t sstep_gain_mul (
    const struct sstep_gain * g,
    sstep_real_t x
) 

Parameters:

Returns:

Product as an accumulator (cannot overflow: |g * x| < 32768).


function sstep_gain_mul_acc

Gain times accumulator: g * x for |x| < 4 pu (saturated first).

static inline sstep_acc_t sstep_gain_mul_acc (
    const struct sstep_gain * g,
    sstep_acc_t x
) 

The two least significant bits of x are dropped (resolution 1.2e-4 pu).


function sstep_gain_mul_int

Gain times integer: g * n as a per-unit accumulator, saturating.

static inline sstep_acc_t sstep_gain_mul_int (
    const struct sstep_gain * g,
    int32_t n
) 

Used for ADC counts: with g = 1 / (counts per unit), the result is the signal in pu.

Parameters:

Returns:

g * n in Q15, saturated to the accumulator range.


function sstep_integ_add

Integrator + g * x (x a signal), saturating.

static inline sstep_integ_t sstep_integ_add (
    sstep_integ_t integ,
    const struct sstep_gain * g,
    sstep_real_t x
) 


function sstep_integ_add_acc

Integrator + g * x (x an accumulator, |x| < 4 pu), saturating.

static inline sstep_integ_t sstep_integ_add_acc (
    sstep_integ_t integ,
    const struct sstep_gain * g,
    sstep_acc_t x
) 


function sstep_integ_to_acc

Integrator value as an accumulator (rounded).

static inline sstep_acc_t sstep_integ_to_acc (
    sstep_integ_t integ
) 


function sstep_mul

a * b, rounded to nearest; (-1.0) * (-1.0) saturates to +0.99997.

static inline sstep_real_t sstep_mul (
    sstep_real_t a,
    sstep_real_t b
) 


function sstep_neg

Saturating -a (-(-1.0) gives +0.99997).

static inline sstep_real_t sstep_neg (
    sstep_real_t a
) 


function sstep_sat

Saturate a 32-bit value to sstep_real_t .

static inline sstep_real_t sstep_sat (
    int32_t x
) 

Parameters:

  • x Value in Q15.

Returns:

x limited to SSTEP_REAL_MIN .. SSTEP_REAL_MAX.


function sstep_shift_round

Shift with rounding: sh > 0 divides by 2^sh (round half up), sh < 0 multiplies by 2^-sh with saturation.

static inline int32_t sstep_shift_round (
    int32_t p,
    int32_t sh
) 

Parameters:

  • p Value.
  • sh Shift, -31 .. 31.

Returns:

Shifted value.


function sstep_sub

Saturating a - b.

static inline sstep_real_t sstep_sub (
    sstep_real_t a,
    sstep_real_t b
) 


Macro Definition Documentation

define SSTEP_ACC_C

Accumulator constant from a floating literal (initializers only).

#define SSTEP_ACC_C (
    x
) `(( sstep_acc_t )((x) * 32768.0))`


define SSTEP_ACC_HALF

0.5 as an accumulator.

#define SSTEP_ACC_HALF `(( sstep_acc_t )16384)`


define SSTEP_ACC_IN_MAX

Largest magnitude accepted by sstep_gain_mul_acc() and the integrator updates from accumulators (4 pu - 2^-15); larger inputs are saturated.

#define SSTEP_ACC_IN_MAX `(( sstep_acc_t )131071)`


define SSTEP_ACC_MAX

Largest sstep_acc_t (+65536 - 2^-15).

#define SSTEP_ACC_MAX `(( sstep_acc_t )INT32_MAX)`


define SSTEP_ACC_MIN

Smallest sstep_acc_t (-65536).

#define SSTEP_ACC_MIN `(( sstep_acc_t )INT32_MIN)`


define SSTEP_ACC_ONE

1.0 as an accumulator.

#define SSTEP_ACC_ONE `(( sstep_acc_t )32768)`


define SSTEP_ACC_SCALE_MAX

Largest magnitude accepted by sstep_acc_scale() (2 pu - 2^-15).

#define SSTEP_ACC_SCALE_MAX `(( sstep_acc_t )65535)`


define SSTEP_ACC_ZERO

Zero as an accumulator.

#define SSTEP_ACC_ZERO `(( sstep_acc_t )0)`


define SSTEP_GAIN_EXP_MAX

Largest gain exponent (gains up to 32767).

#define SSTEP_GAIN_EXP_MAX `15`


define SSTEP_GAIN_EXP_MIN

Smallest gain exponent.

#define SSTEP_GAIN_EXP_MIN `(-16)`


define SSTEP_INTEG_FRAC_BITS

Fractional bits of sstep_integ_t .

#define SSTEP_INTEG_FRAC_BITS `27`


define SSTEP_REAL_C

Constant from a floating literal, saturated to -1.0 .

#define SSTEP_REAL_C (
    x
) `/* multi line expression */`

. +0.99997. An arithmetic constant expression: use it in initializers of static or const objects, where the compiler evaluates it and no floating point code is generated. It is not an integer constant expression (C11 6.6), so it cannot be used in #if, case or static_assert.


define SSTEP_REAL_FRAC_BITS

Number of fractional bits of sstep_real_t andsstep_acc_t .

#define SSTEP_REAL_FRAC_BITS `15`


define SSTEP_REAL_MAX

Largest sstep_real_t (+0.99997).

#define SSTEP_REAL_MAX `(( sstep_real_t )INT16_MAX)`


define SSTEP_REAL_MIN

Smallest sstep_real_t (-1.0).

#define SSTEP_REAL_MIN `(( sstep_real_t )INT16_MIN)`


define SSTEP_REAL_ZERO

Zero as a signal.

#define SSTEP_REAL_ZERO `(( sstep_real_t )0)`