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_INTERP, Enable/disable assertions in the interpolation module, type=bool, default=0, group=hardware_interp
15 #ifndef PARAM_ASSERTIONS_ENABLED_INTERP
16 #define PARAM_ASSERTIONS_ENABLED_INTERP 0
17 #endif
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
41 #define interp0 interp0_hw
42 #define interp1 interp1_hw
43 
53 typedef struct {
54  uint32_t ctrl;
56 
57 static inline uint interp_index(interp_hw_t *interp) {
58  valid_params_if(INTERP, interp == interp0 || interp == interp1);
59  return interp == interp1 ? 1 : 0;
60 }
61 
72 void interp_claim_lane(interp_hw_t *interp, uint lane);
73 // The above really should be called this for consistency
74 #define interp_lane_claim interp_claim_lane
75 
82 void interp_claim_lane_mask(interp_hw_t *interp, uint lane_mask);
83 
90 void interp_unclaim_lane(interp_hw_t *interp, uint lane);
91 // The above really should be called this for consistency
92 #define interp_lane_unclaim interp_unclaim_lane
93 
103 bool interp_lane_is_claimed(interp_hw_t *interp, uint lane);
104 
111 void interp_unclaim_lane_mask(interp_hw_t *interp, uint lane_mask);
112 
121 static inline void interp_config_set_shift(interp_config *c, uint shift) {
122  valid_params_if(INTERP, shift < 32);
123  c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_SHIFT_BITS) |
124  ((shift << SIO_INTERP0_CTRL_LANE0_SHIFT_LSB) & SIO_INTERP0_CTRL_LANE0_SHIFT_BITS);
125 }
126 
136 static inline void interp_config_set_mask(interp_config *c, uint mask_lsb, uint mask_msb) {
137  valid_params_if(INTERP, mask_msb < 32);
138  valid_params_if(INTERP, mask_lsb <= mask_msb);
139  c->ctrl = (c->ctrl & ~(SIO_INTERP0_CTRL_LANE0_MASK_LSB_BITS | SIO_INTERP0_CTRL_LANE0_MASK_MSB_BITS)) |
140  ((mask_lsb << SIO_INTERP0_CTRL_LANE0_MASK_LSB_LSB) & SIO_INTERP0_CTRL_LANE0_MASK_LSB_BITS) |
141  ((mask_msb << SIO_INTERP0_CTRL_LANE0_MASK_MSB_LSB) & SIO_INTERP0_CTRL_LANE0_MASK_MSB_BITS);
142 }
143 
154 static inline void interp_config_set_cross_input(interp_config *c, bool cross_input) {
155  c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_CROSS_INPUT_BITS) |
156  (cross_input ? SIO_INTERP0_CTRL_LANE0_CROSS_INPUT_BITS : 0);
157 }
158 
167 static inline void interp_config_set_cross_result(interp_config *c, bool cross_result) {
168  c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_CROSS_RESULT_BITS) |
169  (cross_result ? SIO_INTERP0_CTRL_LANE0_CROSS_RESULT_BITS : 0);
170 }
171 
181 static inline void interp_config_set_signed(interp_config *c, bool _signed) {
182  c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_SIGNED_BITS) |
183  (_signed ? SIO_INTERP0_CTRL_LANE0_SIGNED_BITS : 0);
184 }
185 
194 static inline void interp_config_set_add_raw(interp_config *c, bool add_raw) {
195  c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_ADD_RAW_BITS) |
196  (add_raw ? SIO_INTERP0_CTRL_LANE0_ADD_RAW_BITS : 0);
197 }
198 
214 static inline void interp_config_set_blend(interp_config *c, bool blend) {
215  c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_BLEND_BITS) |
216  (blend ? SIO_INTERP0_CTRL_LANE0_BLEND_BITS : 0);
217 }
218 
229 static inline void interp_config_set_clamp(interp_config *c, bool clamp) {
230  c->ctrl = (c->ctrl & ~SIO_INTERP1_CTRL_LANE0_CLAMP_BITS) |
231  (clamp ? SIO_INTERP1_CTRL_LANE0_CLAMP_BITS : 0);
232 }
233 
245 static inline void interp_config_set_force_bits(interp_config *c, uint bits) {
246  invalid_params_if(INTERP, bits > 3);
247  // note cannot use hw_set_bits on SIO
248  c->ctrl = (c->ctrl & ~SIO_INTERP0_CTRL_LANE0_FORCE_MSB_BITS) |
249  (bits << SIO_INTERP0_CTRL_LANE0_FORCE_MSB_LSB);
250 }
251 
258  interp_config c = {0};
259  // Just pass through everything
260  interp_config_set_mask(&c, 0, 31);
261  return c;
262 }
263 
275 static inline void interp_set_config(interp_hw_t *interp, uint lane, interp_config *config) {
276  invalid_params_if(INTERP, lane > 1);
277  invalid_params_if(INTERP, config->ctrl & SIO_INTERP1_CTRL_LANE0_CLAMP_BITS &&
278  (!interp_index(interp) || lane)); // only interp1 lane 0 has clamp bit
279  invalid_params_if(INTERP, config->ctrl & SIO_INTERP0_CTRL_LANE0_BLEND_BITS &&
280  (interp_index(interp) || lane)); // only interp0 lane 0 has blend bit
281  interp->ctrl[lane] = config->ctrl;
282 }
283 
297 static inline void interp_set_force_bits(interp_hw_t *interp, uint lane, uint bits) {
298  // note cannot use hw_set_bits on SIO
299  interp->ctrl[lane] = interp->ctrl[lane] | (bits << SIO_INTERP0_CTRL_LANE0_FORCE_MSB_LSB);
300 }
301 
302 typedef struct {
303  uint32_t accum[2];
304  uint32_t base[3];
305  uint32_t ctrl[2];
307 
317 void interp_save(interp_hw_t *interp, interp_hw_save_t *saver);
318 
325 void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver);
326 
334 static inline void interp_set_base(interp_hw_t *interp, uint lane, uint32_t val) {
335  interp->base[lane] = val;
336 }
337 
345 static inline uint32_t interp_get_base(interp_hw_t *interp, uint lane) {
346  return interp->base[lane];
347 }
348 
358 static inline void interp_set_base_both(interp_hw_t *interp, uint32_t val) {
359  interp->base01 = val;
360 }
361 
362 
370 static inline void interp_set_accumulator(interp_hw_t *interp, uint lane, uint32_t val) {
371  interp->accum[lane] = val;
372 }
373 
381 static inline uint32_t interp_get_accumulator(interp_hw_t *interp, uint lane) {
382  return interp->accum[lane];
383 }
384 
392 static inline uint32_t interp_pop_lane_result(interp_hw_t *interp, uint lane) {
393  return interp->pop[lane];
394 }
395 
403 static inline uint32_t interp_peek_lane_result(interp_hw_t *interp, uint lane) {
404  return interp->peek[lane];
405 }
406 
413 static inline uint32_t interp_pop_full_result(interp_hw_t *interp) {
414  return interp->pop[2];
415 }
416 
423 static inline uint32_t interp_peek_full_result(interp_hw_t *interp) {
424  return interp->peek[2];
425 }
426 
437 static inline void interp_add_accumulater(interp_hw_t *interp, uint lane, uint32_t val) {
438  interp->add_raw[lane] = val;
439 }
440 
450 static inline uint32_t interp_get_raw(interp_hw_t *interp, uint lane) {
451  return interp->add_raw[lane];
452 }
453 
454 #ifdef __cplusplus
455 }
456 #endif
457 
458 #endif
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:413
interp_default_config
static interp_config interp_default_config(void)
Get a default configuration.
Definition: interp.h:257
interp_unclaim_lane_mask
void interp_unclaim_lane_mask(interp_hw_t *interp, uint lane_mask)
Release previously claimed interpolator lanes.
Definition: interp.c:44
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:358
interp_config_set_blend
static void interp_config_set_blend(interp_config *c, bool blend)
Set blend mode.
Definition: interp.h:214
interp_config_set_shift
static void interp_config_set_shift(interp_config *c, uint shift)
Set the interpolator shift value.
Definition: interp.h:121
interp_hw_save_t
Definition: interp.h:302
interp_claim_lane
void interp_claim_lane(interp_hw_t *interp, uint lane)
Claim the interpolator lane specified.
Definition: interp.c:23
interp_hw_t
Definition: interp.h:23
interp_get_raw
static uint32_t interp_get_raw(interp_hw_t *interp, uint lane)
Get raw lane value.
Definition: interp.h:450
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:39
interp_add_accumulater
static void interp_add_accumulater(interp_hw_t *interp, uint lane, uint32_t val)
Add to accumulator.
Definition: interp.h:437
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:275
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:297
interp_peek_lane_result
static uint32_t interp_peek_lane_result(interp_hw_t *interp, uint lane)
Read lane result.
Definition: interp.h:403
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:370
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:194
interp_restore
void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver)
Restore an interpolator state.
Definition: interp.c:60
interp_save
void interp_save(interp_hw_t *interp, interp_hw_save_t *saver)
Save the specified interpolator state.
Definition: interp.c:50
interp_peek_full_result
static uint32_t interp_peek_full_result(interp_hw_t *interp)
Read lane result.
Definition: interp.h:423
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:392
pico.h
interp_config_set_cross_result
static void interp_config_set_cross_result(interp_config *c, bool cross_result)
Enable cross results.
Definition: interp.h:167
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:136
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:334
interp_config
Definition: interp.h:53
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:345
interp_unclaim_lane
void interp_unclaim_lane(interp_hw_t *interp, uint lane)
Release a previously claimed interpolator lane.
Definition: interp.c:34
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:28
interp_config_set_force_bits
static void interp_config_set_force_bits(interp_config *c, uint bits)
Set interpolator Force bits.
Definition: interp.h:245
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:229
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:381
interp_config_set_cross_input
static void interp_config_set_cross_input(interp_config *c, bool cross_input)
Enable cross input.
Definition: interp.h:154
interp_config_set_signed
static void interp_config_set_signed(interp_config *c, bool _signed)
Set sign extension.
Definition: interp.h:181