v2.0.0
interp.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_INTERP_H
8#define _HARDWARE_INTERP_H
9
10#include "pico.h"
11#include "hardware/structs/interp.h"
12#include "hardware/regs/sio.h"
13
14// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_INTERP, Enable/disable assertions in the hardware_interp module, type=bool, default=0, group=hardware_interp
15#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_INTERP
16#ifdef PARAM_ASSERTIONS_ENABLED_INTERP // backwards compatibility with SDK < 2.0.0
17#define PARAM_ASSERTIONS_ENABLED_HARDWARE_INTERP PARAM_ASSERTIONS_ENABLED_INTERP
18#else
19#define PARAM_ASSERTIONS_ENABLED_HARDWARE_INTERP 0
20#endif
21#endif
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
46#define interp0 interp0_hw
47#define interp1 interp1_hw
48
58 typedef struct {
59 uint32_t ctrl;
60} interp_config;
61
62static inline uint interp_index(interp_hw_t *interp) {
63 valid_params_if(HARDWARE_INTERP, interp == interp0 || interp == interp1);
64 return interp == interp1 ? 1 : 0;
65}
66
77void interp_claim_lane(interp_hw_t *interp, uint lane);
78// The above really should be called this for consistency
79#define interp_lane_claim interp_claim_lane
80
87void interp_claim_lane_mask(interp_hw_t *interp, uint lane_mask);
88
95void interp_unclaim_lane(interp_hw_t *interp, uint lane);
96// The above really should be called this for consistency
97#define interp_lane_unclaim interp_unclaim_lane
98
108bool interp_lane_is_claimed(interp_hw_t *interp, uint lane);
109
116void interp_unclaim_lane_mask(interp_hw_t *interp, uint lane_mask);
117
126 static inline void interp_config_set_shift(interp_config *c, uint shift) {
127 valid_params_if(HARDWARE_INTERP, shift < 32);
128 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_SHIFT_BITS) |
129 ((shift << SIO_INTERP0_CTRL_LANE0_SHIFT_LSB) & SIO_INTERP0_CTRL_LANE0_SHIFT_BITS);
130}
131
141 static inline void interp_config_set_mask(interp_config *c, uint mask_lsb, uint mask_msb) {
142 valid_params_if(HARDWARE_INTERP, mask_msb < 32);
143 valid_params_if(HARDWARE_INTERP, mask_lsb <= mask_msb);
144 c->ctrl = (c->ctrl & ~(SIO_INTERP0_CTRL_LANE0_MASK_LSB_BITS | SIO_INTERP0_CTRL_LANE0_MASK_MSB_BITS)) |
145 ((mask_lsb << SIO_INTERP0_CTRL_LANE0_MASK_LSB_LSB) & SIO_INTERP0_CTRL_LANE0_MASK_LSB_BITS) |
146 ((mask_msb << SIO_INTERP0_CTRL_LANE0_MASK_MSB_LSB) & SIO_INTERP0_CTRL_LANE0_MASK_MSB_BITS);
147}
148
159 static inline void interp_config_set_cross_input(interp_config *c, bool cross_input) {
160 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_CROSS_INPUT_BITS) |
161 (cross_input ? SIO_INTERP0_CTRL_LANE0_CROSS_INPUT_BITS : 0);
162}
163
172 static inline void interp_config_set_cross_result(interp_config *c, bool cross_result) {
173 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_CROSS_RESULT_BITS) |
174 (cross_result ? SIO_INTERP0_CTRL_LANE0_CROSS_RESULT_BITS : 0);
175}
176
186 static inline void interp_config_set_signed(interp_config *c, bool _signed) {
187 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_SIGNED_BITS) |
188 (_signed ? SIO_INTERP0_CTRL_LANE0_SIGNED_BITS : 0);
189}
190
199 static inline void interp_config_set_add_raw(interp_config *c, bool add_raw) {
200 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_ADD_RAW_BITS) |
201 (add_raw ? SIO_INTERP0_CTRL_LANE0_ADD_RAW_BITS : 0);
202}
203
219 static inline void interp_config_set_blend(interp_config *c, bool blend) {
220 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_BLEND_BITS) |
221 (blend ? SIO_INTERP0_CTRL_LANE0_BLEND_BITS : 0);
222}
223
234 static inline void interp_config_set_clamp(interp_config *c, bool clamp) {
235 c->ctrl = (c->ctrl & ~SIO_INTERP1_CTRL_LANE0_CLAMP_BITS) |
236 (clamp ? SIO_INTERP1_CTRL_LANE0_CLAMP_BITS : 0);
237}
238
250 static inline void interp_config_set_force_bits(interp_config *c, uint bits) {
251 invalid_params_if(HARDWARE_INTERP, bits > 3);
252 // note cannot use hw_set_bits on SIO
253 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_FORCE_MSB_BITS) |
254 (bits << SIO_INTERP0_CTRL_LANE0_FORCE_MSB_LSB);
255}
256
262 static inline interp_config interp_default_config(void) {
263 interp_config c = {0};
264 // Just pass through everything
265 interp_config_set_mask(&c, 0, 31);
266 return c;
267}
268
280 static inline void interp_set_config(interp_hw_t *interp, uint lane, interp_config *config) {
281 invalid_params_if(HARDWARE_INTERP, lane > 1);
282 invalid_params_if(HARDWARE_INTERP, config->ctrl & SIO_INTERP1_CTRL_LANE0_CLAMP_BITS &&
283 (!interp_index(interp) || lane)); // only interp1 lane 0 has clamp bit
284 invalid_params_if(HARDWARE_INTERP, config->ctrl & SIO_INTERP0_CTRL_LANE0_BLEND_BITS &&
285 (interp_index(interp) || lane)); // only interp0 lane 0 has blend bit
286 interp->ctrl[lane] = config->ctrl;
287}
288
302 static inline void interp_set_force_bits(interp_hw_t *interp, uint lane, uint bits) {
303 // note cannot use hw_set_bits on SIO
304 interp->ctrl[lane] = interp->ctrl[lane] | (bits << SIO_INTERP0_CTRL_LANE0_FORCE_MSB_LSB);
305}
306
307 typedef struct {
308 uint32_t accum[2];
309 uint32_t base[3];
310 uint32_t ctrl[2];
311} interp_hw_save_t;
312
322void interp_save(interp_hw_t *interp, interp_hw_save_t *saver);
323
330void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver);
331
339 static inline void interp_set_base(interp_hw_t *interp, uint lane, uint32_t val) {
340 interp->base[lane] = val;
341}
342
350 static inline uint32_t interp_get_base(interp_hw_t *interp, uint lane) {
351 return interp->base[lane];
352}
353
363 static inline void interp_set_base_both(interp_hw_t *interp, uint32_t val) {
364 interp->base01 = val;
365}
366
367
375 static inline void interp_set_accumulator(interp_hw_t *interp, uint lane, uint32_t val) {
376 interp->accum[lane] = val;
377}
378
386 static inline uint32_t interp_get_accumulator(interp_hw_t *interp, uint lane) {
387 return interp->accum[lane];
388}
389
397 static inline uint32_t interp_pop_lane_result(interp_hw_t *interp, uint lane) {
398 return interp->pop[lane];
399}
400
408 static inline uint32_t interp_peek_lane_result(interp_hw_t *interp, uint lane) {
409 return interp->peek[lane];
410}
411
418 static inline uint32_t interp_pop_full_result(interp_hw_t *interp) {
419 return interp->pop[2];
420}
421
428 static inline uint32_t interp_peek_full_result(interp_hw_t *interp) {
429 return interp->peek[2];
430}
431
441 static inline void interp_add_accumulater(interp_hw_t *interp, uint lane, uint32_t val) {
442 interp->add_raw[lane] = val;
443}
444
454 static inline uint32_t interp_get_raw(interp_hw_t *interp, uint lane) {
455 return interp->add_raw[lane];
456}
457
458#ifdef __cplusplus
459}
460#endif
461
462#endif
interp_get_base
static uint32_t interp_get_base(interp_hw_t *interp, uint lane)
Gets the content of interpolator base register by lane.
Definition: interp.h:350
interp_get_raw
static uint32_t interp_get_raw(interp_hw_t *interp, uint lane)
Get raw lane value.
Definition: interp.h:454
interp_set_base_both
static void interp_set_base_both(interp_hw_t *interp, uint32_t val)
Sets the interpolator base registers simultaneously.
Definition: interp.h:363
interp_restore
void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver)
Restore an interpolator state.
Definition: interp.c:58
interp_unclaim_lane
void interp_unclaim_lane(interp_hw_t *interp, uint lane)
Release a previously claimed interpolator lane.
Definition: interp.c:32
interp_claim_lane
void interp_claim_lane(interp_hw_t *interp, uint lane)
Claim the interpolator lane specified.
Definition: interp.c:21
interp_claim_lane_mask
void interp_claim_lane_mask(interp_hw_t *interp, uint lane_mask)
Claim the interpolator lanes specified in the mask.
Definition: interp.c:26
interp_set_force_bits
static void interp_set_force_bits(interp_hw_t *interp, uint lane, uint bits)
Directly set the force bits on a specified lane.
Definition: interp.h:302
interp_save
void interp_save(interp_hw_t *interp, interp_hw_save_t *saver)
Save the specified interpolator state.
Definition: interp.c:48
interp_unclaim_lane_mask
void interp_unclaim_lane_mask(interp_hw_t *interp, uint lane_mask)
Release previously claimed interpolator lanes.
Definition: interp.c:42
interp_set_base
static void interp_set_base(interp_hw_t *interp, uint lane, uint32_t val)
Sets the interpolator base register by lane.
Definition: interp.h:339
interp_peek_full_result
static uint32_t interp_peek_full_result(interp_hw_t *interp)
Read lane result.
Definition: interp.h:428
interp_get_accumulator
static uint32_t interp_get_accumulator(interp_hw_t *interp, uint lane)
Gets the content of the interpolator accumulator register by lane.
Definition: interp.h:386
interp_pop_full_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.
Definition: interp.h:418
interp_set_accumulator
static void interp_set_accumulator(interp_hw_t *interp, uint lane, uint32_t val)
Sets the interpolator accumulator register by lane.
Definition: interp.h:375
interp_add_accumulater
static void interp_add_accumulater(interp_hw_t *interp, uint lane, uint32_t val)
Add to accumulator.
Definition: interp.h:441
interp_lane_is_claimed
bool interp_lane_is_claimed(interp_hw_t *interp, uint lane)
Determine if an interpolator lane is claimed.
Definition: interp.c:37
interp_pop_lane_result
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.
Definition: interp.h:397
interp_peek_lane_result
static uint32_t interp_peek_lane_result(interp_hw_t *interp, uint lane)
Read lane result.
Definition: interp.h:408
interp_config_set_clamp
static void interp_config_set_clamp(interp_config *c, bool clamp)
Set interpolator clamp mode (Interpolator 1 only)
Definition: interp.h:234
interp_default_config
static interp_config interp_default_config(void)
Get a default configuration.
Definition: interp.h:262
interp_config_set_force_bits
static void interp_config_set_force_bits(interp_config *c, uint bits)
Set interpolator Force bits.
Definition: interp.h:250
interp_config_set_shift
static void interp_config_set_shift(interp_config *c, uint shift)
Set the interpolator shift value.
Definition: interp.h:126
interp_config_set_mask
static void interp_config_set_mask(interp_config *c, uint mask_lsb, uint mask_msb)
Set the interpolator mask range.
Definition: interp.h:141
interp_config_set_blend
static void interp_config_set_blend(interp_config *c, bool blend)
Set blend mode.
Definition: interp.h:219
interp_config_set_add_raw
static void interp_config_set_add_raw(interp_config *c, bool add_raw)
Set raw add option.
Definition: interp.h:199
interp_config_set_signed
static void interp_config_set_signed(interp_config *c, bool _signed)
Set sign extension.
Definition: interp.h:186
interp_set_config
static void interp_set_config(interp_hw_t *interp, uint lane, interp_config *config)
Send configuration to a lane.
Definition: interp.h:280
interp_config_set_cross_result
static void interp_config_set_cross_result(interp_config *c, bool cross_result)
Enable cross results.
Definition: interp.h:172
interp_config_set_cross_input
static void interp_config_set_cross_input(interp_config *c, bool cross_input)
Enable cross input.
Definition: interp.h:159
pico.h
interp_config
Definition: interp.h:58
interp_hw_save_t
Definition: interp.h:307
interp_hw_t
Definition: interp.h:26