Loading...
Searching...
No Matches
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
45
46#define interp0 interp0_hw
47#define interp1 interp1_hw
48
57
65typedef struct {
66 uint32_t ctrl;
68
69static inline uint interp_index(interp_hw_t *interp) {
70 valid_params_if(HARDWARE_INTERP, interp == interp0 || interp == interp1);
71 return interp == interp1 ? 1 : 0;
72}
73
84void interp_claim_lane(interp_hw_t *interp, uint lane);
85// The above really should be called this for consistency
86#define interp_lane_claim interp_claim_lane
87
94void interp_claim_lane_mask(interp_hw_t *interp, uint lane_mask);
95
102void interp_unclaim_lane(interp_hw_t *interp, uint lane);
103// The above really should be called this for consistency
104#define interp_lane_unclaim interp_unclaim_lane
105
115bool interp_lane_is_claimed(interp_hw_t *interp, uint lane);
116
123void interp_unclaim_lane_mask(interp_hw_t *interp, uint lane_mask);
124
133static inline void interp_config_set_shift(interp_config *c, uint shift) {
134 valid_params_if(HARDWARE_INTERP, shift < 32);
135 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_SHIFT_BITS) |
136 ((shift << SIO_INTERP0_CTRL_LANE0_SHIFT_LSB) & SIO_INTERP0_CTRL_LANE0_SHIFT_BITS);
137}
138
148static inline void interp_config_set_mask(interp_config *c, uint mask_lsb, uint mask_msb) {
149 valid_params_if(HARDWARE_INTERP, mask_msb < 32);
150 valid_params_if(HARDWARE_INTERP, mask_lsb <= mask_msb);
151 c->ctrl = (c->ctrl & ~(SIO_INTERP0_CTRL_LANE0_MASK_LSB_BITS | SIO_INTERP0_CTRL_LANE0_MASK_MSB_BITS)) |
152 ((mask_lsb << SIO_INTERP0_CTRL_LANE0_MASK_LSB_LSB) & SIO_INTERP0_CTRL_LANE0_MASK_LSB_BITS) |
153 ((mask_msb << SIO_INTERP0_CTRL_LANE0_MASK_MSB_LSB) & SIO_INTERP0_CTRL_LANE0_MASK_MSB_BITS);
154}
155
166static inline void interp_config_set_cross_input(interp_config *c, bool cross_input) {
167 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_CROSS_INPUT_BITS) |
168 (cross_input ? SIO_INTERP0_CTRL_LANE0_CROSS_INPUT_BITS : 0);
169}
170
179static inline void interp_config_set_cross_result(interp_config *c, bool cross_result) {
180 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_CROSS_RESULT_BITS) |
181 (cross_result ? SIO_INTERP0_CTRL_LANE0_CROSS_RESULT_BITS : 0);
182}
183
193static inline void interp_config_set_signed(interp_config *c, bool _signed) {
194 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_SIGNED_BITS) |
195 (_signed ? SIO_INTERP0_CTRL_LANE0_SIGNED_BITS : 0);
196}
197
206static inline void interp_config_set_add_raw(interp_config *c, bool add_raw) {
207 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_ADD_RAW_BITS) |
208 (add_raw ? SIO_INTERP0_CTRL_LANE0_ADD_RAW_BITS : 0);
209}
210
226static inline void interp_config_set_blend(interp_config *c, bool blend) {
227 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_BLEND_BITS) |
228 (blend ? SIO_INTERP0_CTRL_LANE0_BLEND_BITS : 0);
229}
230
241static inline void interp_config_set_clamp(interp_config *c, bool clamp) {
242 c->ctrl = (c->ctrl & ~SIO_INTERP1_CTRL_LANE0_CLAMP_BITS) |
243 (clamp ? SIO_INTERP1_CTRL_LANE0_CLAMP_BITS : 0);
244}
245
257static inline void interp_config_set_force_bits(interp_config *c, uint bits) {
258 invalid_params_if(HARDWARE_INTERP, bits > 3);
259 // note cannot use hw_set_bits on SIO
260 c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_FORCE_MSB_BITS) |
261 (bits << SIO_INTERP0_CTRL_LANE0_FORCE_MSB_LSB);
262}
263
270 interp_config c = {0};
271 // Just pass through everything
272 interp_config_set_mask(&c, 0, 31);
273 return c;
274}
275
286
287static inline void interp_set_config(interp_hw_t *interp, uint lane, interp_config *config) {
288 invalid_params_if(HARDWARE_INTERP, lane > 1);
289 invalid_params_if(HARDWARE_INTERP, config->ctrl & SIO_INTERP1_CTRL_LANE0_CLAMP_BITS &&
290 (!interp_index(interp) || lane)); // only interp1 lane 0 has clamp bit
291 invalid_params_if(HARDWARE_INTERP, config->ctrl & SIO_INTERP0_CTRL_LANE0_BLEND_BITS &&
292 (interp_index(interp) || lane)); // only interp0 lane 0 has blend bit
293 interp->ctrl[lane] = config->ctrl;
294}
295
309static inline void interp_set_force_bits(interp_hw_t *interp, uint lane, uint bits) {
310 // note cannot use hw_set_bits on SIO
311 interp->ctrl[lane] = interp->ctrl[lane] | (bits << SIO_INTERP0_CTRL_LANE0_FORCE_MSB_LSB);
312}
313
321typedef struct {
322 uint32_t accum[2];
323 uint32_t base[3];
324 uint32_t ctrl[2];
326
336void interp_save(interp_hw_t *interp, interp_hw_save_t *saver);
337
344void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver);
345
353static inline void interp_set_base(interp_hw_t *interp, uint index, uint32_t val) {
354 interp->base[index] = val;
355}
356
364static inline uint32_t interp_get_base(interp_hw_t *interp, uint index) {
365 return interp->base[index];
366}
367
377static inline void interp_set_base_both(interp_hw_t *interp, uint32_t val) {
378 interp->base01 = val;
379}
380
381
389static inline void interp_set_accumulator(interp_hw_t *interp, uint lane, uint32_t val) {
390 interp->accum[lane] = val;
391}
392
400static inline uint32_t interp_get_accumulator(interp_hw_t *interp, uint lane) {
401 return interp->accum[lane];
402}
403
411static inline uint32_t interp_pop_lane_result(interp_hw_t *interp, uint lane) {
412 return interp->pop[lane];
413}
414
422static inline uint32_t interp_peek_lane_result(interp_hw_t *interp, uint lane) {
423 return interp->peek[lane];
424}
425
432static inline uint32_t interp_pop_full_result(interp_hw_t *interp) {
433 return interp->pop[2];
434}
435
442static inline uint32_t interp_peek_full_result(interp_hw_t *interp) {
443 return interp->peek[2];
444}
445
455static inline void interp_add_accumulator(interp_hw_t *interp, uint lane, uint32_t val) {
456 interp->add_raw[lane] = val;
457}
458// backwards incompatibility with old incorrect spelling
459#define interp_add_accumulater(interp, lane, val) interp_add_accumulator(interp, lane, val)
460
470static inline uint32_t interp_get_raw(interp_hw_t *interp, uint lane) {
471 return interp->add_raw[lane];
472}
473
474#ifdef __cplusplus
475}
476#endif
477
478#endif
static uint32_t interp_get_raw(interp_hw_t *interp, uint lane)
Get raw lane value.
Definition interp.h:470
static void interp_set_base_both(interp_hw_t *interp, uint32_t val)
Sets the interpolator base registers simultaneously.
Definition interp.h:377
void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver)
Restore an interpolator state.
Definition interp.c:58
static uint32_t interp_get_base(interp_hw_t *interp, uint index)
Gets the content of interpolator base register by index.
Definition interp.h:364
void interp_unclaim_lane(interp_hw_t *interp, uint lane)
Release a previously claimed interpolator lane.
Definition interp.c:32
static void interp_add_accumulator(interp_hw_t *interp, uint lane, uint32_t val)
Add to accumulator.
Definition interp.h:455
void interp_claim_lane(interp_hw_t *interp, uint lane)
Claim the interpolator lane specified.
Definition interp.c:21
void interp_claim_lane_mask(interp_hw_t *interp, uint lane_mask)
Claim the interpolator lanes specified in the mask.
Definition interp.c:26
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:309
void interp_save(interp_hw_t *interp, interp_hw_save_t *saver)
Save the specified interpolator state.
Definition interp.c:48
void interp_unclaim_lane_mask(interp_hw_t *interp, uint lane_mask)
Release previously claimed interpolator lanes, see interp_claim_lane_mask.
Definition interp.c:42
static void interp_set_base(interp_hw_t *interp, uint index, uint32_t val)
Sets the interpolator base register by index.
Definition interp.h:353
static uint32_t interp_peek_full_result(interp_hw_t *interp)
Read lane result.
Definition interp.h:442
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:400
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:432
static void interp_set_accumulator(interp_hw_t *interp, uint lane, uint32_t val)
Sets the interpolator accumulator register by lane.
Definition interp.h:389
bool interp_lane_is_claimed(interp_hw_t *interp, uint lane)
Determine if an interpolator lane is claimed.
Definition interp.c:37
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:411
static uint32_t interp_peek_lane_result(interp_hw_t *interp, uint lane)
Read lane result.
Definition interp.h:422
static void interp_config_set_clamp(interp_config *c, bool clamp)
Set interpolator clamp mode (Interpolator 1 only).
Definition interp.h:241
static interp_config interp_default_config(void)
Get a default configuration.
Definition interp.h:269
static void interp_config_set_force_bits(interp_config *c, uint bits)
Set interpolator Force bits.
Definition interp.h:257
static void interp_config_set_shift(interp_config *c, uint shift)
Set the interpolator shift value.
Definition interp.h:133
static void interp_config_set_mask(interp_config *c, uint mask_lsb, uint mask_msb)
Set the interpolator mask range.
Definition interp.h:148
static void interp_config_set_blend(interp_config *c, bool blend)
Set blend mode.
Definition interp.h:226
static void interp_config_set_add_raw(interp_config *c, bool add_raw)
Set raw add option.
Definition interp.h:206
static void interp_config_set_signed(interp_config *c, bool _signed)
Set sign extension.
Definition interp.h:193
static void interp_set_config(interp_hw_t *interp, uint lane, interp_config *config)
Send configuration to a lane.
Definition interp.h:287
static void interp_config_set_cross_result(interp_config *c, bool cross_result)
Enable cross results.
Definition interp.h:179
static void interp_config_set_cross_input(interp_config *c, bool cross_input)
Enable cross input.
Definition interp.h:166
Holds the configuration for an interpolator lane.
Definition interp.h:65
uint32_t ctrl
Packed control register value for the interpolator lane.
Definition interp.h:66
Saved interpolator hardware state.
Definition interp.h:321
uint32_t accum[2]
Saved accumulator values for lanes 0 and 1.
Definition interp.h:322
uint32_t base[3]
Saved base register values.
Definition interp.h:323
uint32_t ctrl[2]
Saved control register values for lanes 0 and 1.
Definition interp.h:324
Definition interp.h:26