Merge pull request #33 from adafruit/reduce-post-addr-delay
Reduce post addr delay
This commit is contained in:
commit
f80ae1e772
20 changed files with 2337 additions and 2284 deletions
|
|
@ -12,6 +12,9 @@
|
||||||
#
|
#
|
||||||
# See https://github.com/pre-commit/pre-commit
|
# See https://github.com/pre-commit/pre-commit
|
||||||
|
|
||||||
|
# Don't re-format vendored files
|
||||||
|
exclude: "^src/piolib/.*$"
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
autoupdate_commit_msg: "chore: update pre-commit hooks"
|
autoupdate_commit_msg: "chore: update pre-commit hooks"
|
||||||
autofix_commit_msg: "style: pre-commit fixes"
|
autofix_commit_msg: "style: pre-commit fixes"
|
||||||
|
|
|
||||||
20
src/CMakeLists.txt
Normal file
20
src/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
|
project(protodemo C CXX)
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
add_compile_options(-Wall -g3 -Og)
|
||||||
|
add_executable(protodemo
|
||||||
|
protodemo.cpp
|
||||||
|
piolib/piolib.c
|
||||||
|
piolib/pio_rp1.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/protomatter.pio.h
|
||||||
|
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/assemble.py ${CMAKE_CURRENT_SOURCE_DIR}/protomatter.pio ${CMAKE_CURRENT_BINARY_DIR}/protomatter.pio.h
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/assemble.py ${CMAKE_CURRENT_SOURCE_DIR}/protomatter.pio
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(protodemo PRIVATE include piolib/include)
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
protodemo: protodemo.c piolib/*.c include/piomatter/*.h include/piomatter/protomatter.pio.h Makefile
|
|
||||||
g++ -std=c++20 -O3 -ggdb -x c++ -Iinclude -Ipiolib/include -o $@ $(filter %.c, $^) -Wno-narrowing
|
|
||||||
|
|
||||||
matrixmap.h:
|
|
||||||
|
|
||||||
include/piomatter/protomatter.pio.h: protomatter.pio assemble.py
|
|
||||||
python assemble.py $< $@
|
|
||||||
|
|
@ -27,8 +27,8 @@ class _PybindEnumChoice(click.Choice):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def _validate_temporal_planes(ctx, param, value):
|
def _validate_temporal_planes(ctx, param, value):
|
||||||
if value not in (0, 2, 4):
|
if value not in (0, 1, 2, 3, 4, 5):
|
||||||
raise click.BadParameter("must be 0, 2, or 4")
|
raise click.BadParameter("must be from 0 to 5 (0 and 1 both disable temporal planes)")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def standard_options(
|
def standard_options(
|
||||||
|
|
|
||||||
|
|
@ -134,47 +134,27 @@ schedule_sequence make_temporal_dither_schedule(int n_planes,
|
||||||
if (n_temporal_planes >= n_planes) {
|
if (n_temporal_planes >= n_planes) {
|
||||||
throw std::range_error("n_temporal_planes can't exceed n_planes");
|
throw std::range_error("n_temporal_planes can't exceed n_planes");
|
||||||
}
|
}
|
||||||
if (n_temporal_planes != 2 && n_temporal_planes != 4) {
|
|
||||||
// the code can generate a schedule for 8 temporal planes, but it
|
|
||||||
// flickers intolerably
|
|
||||||
throw std::range_error("n_temporal_planes must be 0, 1, 2, or 4");
|
|
||||||
}
|
|
||||||
|
|
||||||
int n_real_planes = n_planes - n_temporal_planes;
|
int n_real_planes = n_planes - n_temporal_planes;
|
||||||
|
|
||||||
schedule base_sched;
|
|
||||||
for (int j = 0; j < n_real_planes; j++) {
|
|
||||||
base_sched.emplace_back(
|
|
||||||
9 - j, (1 << (n_temporal_planes + n_real_planes - j - 1)) /
|
|
||||||
n_temporal_planes);
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule_sequence result;
|
schedule_sequence result;
|
||||||
|
|
||||||
auto add_sched = [&result, &base_sched](int plane, int count) {
|
auto add_sched = [&result, n_real_planes,
|
||||||
auto sched = base_sched;
|
n_temporal_planes](int i, int plane, int count) {
|
||||||
|
schedule sched;
|
||||||
|
for (int j = 0; j < n_real_planes; j++) {
|
||||||
|
int k = 1 << (n_temporal_planes + n_real_planes - j - 1);
|
||||||
|
sched.emplace_back(9 - j, (k + i) / n_temporal_planes);
|
||||||
|
}
|
||||||
sched.emplace_back(9 - plane, count);
|
sched.emplace_back(9 - plane, count);
|
||||||
result.emplace_back(sched);
|
result.emplace_back(sched);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < n_temporal_planes; i++) {
|
for (int i = 0; i < n_temporal_planes; i++) {
|
||||||
add_sched(n_real_planes + i, 1 << (n_temporal_planes - i - 1));
|
add_sched(i, n_real_planes + i, 1 << (n_temporal_planes - i - 1));
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
std::vector<uint32_t> counts(10, 0);
|
|
||||||
for (auto s : result) {
|
|
||||||
for(auto t: s) {
|
|
||||||
counts[t.shift] += t.active_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto s : counts) {
|
|
||||||
printf("%d ", s);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rescale_schedule(result, pixels_across);
|
return rescale_schedule(result, pixels_across);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct matrix_geometry {
|
struct matrix_geometry {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ struct adafruit_matrix_bonnet_pinout {
|
||||||
|
|
||||||
static constexpr uint32_t post_oe_delay = 0;
|
static constexpr uint32_t post_oe_delay = 0;
|
||||||
static constexpr uint32_t post_latch_delay = 0;
|
static constexpr uint32_t post_latch_delay = 0;
|
||||||
static constexpr uint32_t post_addr_delay = 500;
|
static constexpr uint32_t post_addr_delay = 5;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct adafruit_matrix_bonnet_pinout_bgr {
|
struct adafruit_matrix_bonnet_pinout_bgr {
|
||||||
|
|
@ -37,7 +37,7 @@ struct adafruit_matrix_bonnet_pinout_bgr {
|
||||||
|
|
||||||
static constexpr uint32_t post_oe_delay = 0;
|
static constexpr uint32_t post_oe_delay = 0;
|
||||||
static constexpr uint32_t post_latch_delay = 0;
|
static constexpr uint32_t post_latch_delay = 0;
|
||||||
static constexpr uint32_t post_addr_delay = 500;
|
static constexpr uint32_t post_addr_delay = 5;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct active3_pinout {
|
struct active3_pinout {
|
||||||
|
|
@ -56,7 +56,7 @@ struct active3_pinout {
|
||||||
|
|
||||||
static constexpr uint32_t post_oe_delay = 0;
|
static constexpr uint32_t post_oe_delay = 0;
|
||||||
static constexpr uint32_t post_latch_delay = 0;
|
static constexpr uint32_t post_latch_delay = 0;
|
||||||
static constexpr uint32_t post_addr_delay = 500;
|
static constexpr uint32_t post_addr_delay = 5;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct active3_pinout_bgr {
|
struct active3_pinout_bgr {
|
||||||
|
|
@ -75,7 +75,7 @@ struct active3_pinout_bgr {
|
||||||
|
|
||||||
static constexpr uint32_t post_oe_delay = 0;
|
static constexpr uint32_t post_oe_delay = 0;
|
||||||
static constexpr uint32_t post_latch_delay = 0;
|
static constexpr uint32_t post_latch_delay = 0;
|
||||||
static constexpr uint32_t post_addr_delay = 500;
|
static constexpr uint32_t post_addr_delay = 5;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace piomatter
|
} // namespace piomatter
|
||||||
|
|
|
||||||
|
|
@ -20,20 +20,6 @@ static uint64_t monotonicns64() {
|
||||||
|
|
||||||
constexpr size_t MAX_XFER = 65532;
|
constexpr size_t MAX_XFER = 65532;
|
||||||
|
|
||||||
void pio_sm_xfer_data_large(PIO pio, int sm, int direction, size_t size,
|
|
||||||
uint32_t *databuf) {
|
|
||||||
while (size) {
|
|
||||||
size_t xfersize = std::min(size_t{MAX_XFER}, size);
|
|
||||||
int r = pio_sm_xfer_data(pio, sm, direction, xfersize, databuf);
|
|
||||||
if (r) {
|
|
||||||
throw std::runtime_error(
|
|
||||||
"pio_sm_xfer_data (reboot may be required)");
|
|
||||||
}
|
|
||||||
size -= xfersize;
|
|
||||||
databuf += xfersize / sizeof(*databuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct piomatter_base {
|
struct piomatter_base {
|
||||||
piomatter_base() {}
|
piomatter_base() {}
|
||||||
piomatter_base(const piomatter_base &) = delete;
|
piomatter_base(const piomatter_base &) = delete;
|
||||||
|
|
@ -106,7 +92,7 @@ struct piomatter : piomatter_base {
|
||||||
if (sm < 0) {
|
if (sm < 0) {
|
||||||
throw std::runtime_error("pio_claim_unused_sm");
|
throw std::runtime_error("pio_claim_unused_sm");
|
||||||
}
|
}
|
||||||
int r = pio_sm_config_xfer(pio, sm, PIO_DIR_TO_SM, MAX_XFER, 2);
|
int r = pio_sm_config_xfer(pio, sm, PIO_DIR_TO_SM, MAX_XFER, 3);
|
||||||
if (r) {
|
if (r) {
|
||||||
throw std::runtime_error("pio_sm_config_xfer");
|
throw std::runtime_error("pio_sm_config_xfer");
|
||||||
}
|
}
|
||||||
|
|
@ -188,8 +174,7 @@ struct piomatter : piomatter_base {
|
||||||
const auto &data = cur_buf[seq_idx];
|
const auto &data = cur_buf[seq_idx];
|
||||||
auto datasize = sizeof(uint32_t) * data.size();
|
auto datasize = sizeof(uint32_t) * data.size();
|
||||||
auto dataptr = const_cast<uint32_t *>(&data[0]);
|
auto dataptr = const_cast<uint32_t *>(&data[0]);
|
||||||
pio_sm_xfer_data_large(pio, sm, PIO_DIR_TO_SM, datasize,
|
pio_sm_xfer_data(pio, sm, PIO_DIR_TO_SM, datasize, dataptr);
|
||||||
dataptr);
|
|
||||||
t1 = monotonicns64();
|
t1 = monotonicns64();
|
||||||
if (t0 != t1) {
|
if (t0 != t1) {
|
||||||
fps = 1e9 / (t1 - t0);
|
fps = 1e9 / (t1 - t0);
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,8 @@ enum gpio_irq_level {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum gpio_override {
|
enum gpio_override {
|
||||||
GPIO_OVERRIDE_NORMAL =
|
GPIO_OVERRIDE_NORMAL = 0, ///< peripheral signal selected via \ref gpio_set_function
|
||||||
0, ///< peripheral signal selected via \ref gpio_set_function
|
GPIO_OVERRIDE_INVERT = 1, ///< invert peripheral signal selected via \ref gpio_set_function
|
||||||
GPIO_OVERRIDE_INVERT =
|
|
||||||
1, ///< invert peripheral signal selected via \ref gpio_set_function
|
|
||||||
GPIO_OVERRIDE_LOW = 2, ///< drive low/disable output
|
GPIO_OVERRIDE_LOW = 2, ///< drive low/disable output
|
||||||
GPIO_OVERRIDE_HIGH = 3, ///< drive high/enable output
|
GPIO_OVERRIDE_HIGH = 3, ///< drive high/enable output
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,14 @@
|
||||||
* \defgroup pio_instructions pio_instructions
|
* \defgroup pio_instructions pio_instructions
|
||||||
* \ingroup hardware_pio
|
* \ingroup hardware_pio
|
||||||
*
|
*
|
||||||
* Functions for generating PIO instruction encodings programmatically. In debug
|
* Functions for generating PIO instruction encodings programmatically. In debug builds
|
||||||
*builds `PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS` can be set to 1 to enable
|
*`PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS` can be set to 1 to enable validation of encoding function
|
||||||
*validation of encoding function parameters.
|
* parameters.
|
||||||
*
|
*
|
||||||
* For fuller descriptions of the instructions in question see the "RP2040
|
* For fuller descriptions of the instructions in question see the "RP2040 Datasheet"
|
||||||
*Datasheet"
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS, Enable/disable
|
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS, Enable/disable assertions in the PIO instructions, type=bool, default=0, group=pio_instructions
|
||||||
// assertions in the PIO instructions, type=bool, default=0,
|
|
||||||
// group=pio_instructions
|
|
||||||
#ifndef PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS
|
#ifndef PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS
|
||||||
#define PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS 0
|
#define PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -58,35 +55,31 @@ enum pio_instr_bits {
|
||||||
#define _PIO_INVALID_MOV_DEST 0u
|
#define _PIO_INVALID_MOV_DEST 0u
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \brief Enumeration of values to pass for source/destination args for
|
/*! \brief Enumeration of values to pass for source/destination args for instruction encoding functions
|
||||||
* instruction encoding functions \ingroup pio_instructions
|
* \ingroup pio_instructions
|
||||||
*
|
*
|
||||||
* \note Not all values are suitable for all functions. Validity is only checked
|
* \note Not all values are suitable for all functions. Validity is only checked in debug mode when
|
||||||
* in debug mode when `PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS` is 1
|
* `PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS` is 1
|
||||||
*/
|
*/
|
||||||
enum pio_src_dest {
|
enum pio_src_dest {
|
||||||
pio_pins = 0u,
|
pio_pins = 0u,
|
||||||
pio_x = 1u,
|
pio_x = 1u,
|
||||||
pio_y = 2u,
|
pio_y = 2u,
|
||||||
pio_null = 3u | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
pio_null = 3u | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
||||||
pio_pindirs =
|
pio_pindirs = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
||||||
4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
pio_exec_mov = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
||||||
pio_exec_mov = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST |
|
pio_status = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
||||||
_PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
pio_pc = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
||||||
pio_status = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST |
|
|
||||||
_PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
|
||||||
pio_pc =
|
|
||||||
5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
|
||||||
pio_isr = 6u | _PIO_INVALID_SET_DEST,
|
pio_isr = 6u | _PIO_INVALID_SET_DEST,
|
||||||
pio_osr = 7u | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST,
|
pio_osr = 7u | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST,
|
||||||
pio_exec_out = 7u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST |
|
pio_exec_out = 7u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
||||||
_PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint _pio_major_instr_bits(uint instr) { return instr & 0xe000u; }
|
static inline uint _pio_major_instr_bits(uint instr) {
|
||||||
|
return instr & 0xe000u;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint _pio_encode_instr_and_args(enum pio_instr_bits instr_bits,
|
static inline uint _pio_encode_instr_and_args(enum pio_instr_bits instr_bits, uint arg1, uint arg2) {
|
||||||
uint arg1, uint arg2) {
|
|
||||||
valid_params_if(PIO_INSTRUCTIONS, arg1 <= 0x7);
|
valid_params_if(PIO_INSTRUCTIONS, arg1 <= 0x7);
|
||||||
#if PARAM_ASSERTIONS_ENABLED(PIO_INSTRUCTIONS)
|
#if PARAM_ASSERTIONS_ENABLED(PIO_INSTRUCTIONS)
|
||||||
uint32_t major = _pio_major_instr_bits(instr_bits);
|
uint32_t major = _pio_major_instr_bits(instr_bits);
|
||||||
|
|
@ -99,21 +92,17 @@ static inline uint _pio_encode_instr_and_args(enum pio_instr_bits instr_bits,
|
||||||
return instr_bits | (arg1 << 5u) | (arg2 & 0x1fu);
|
return instr_bits | (arg1 << 5u) | (arg2 & 0x1fu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint
|
static inline uint _pio_encode_instr_and_src_dest(enum pio_instr_bits instr_bits, enum pio_src_dest dest, uint value) {
|
||||||
_pio_encode_instr_and_src_dest(enum pio_instr_bits instr_bits,
|
|
||||||
enum pio_src_dest dest, uint value) {
|
|
||||||
return _pio_encode_instr_and_args(instr_bits, dest & 7u, value);
|
return _pio_encode_instr_and_args(instr_bits, dest & 7u, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode just the delay slot bits of an instruction
|
/*! \brief Encode just the delay slot bits of an instruction
|
||||||
* \ingroup pio_instructions
|
* \ingroup pio_instructions
|
||||||
*
|
*
|
||||||
* \note This function does not return a valid instruction encoding; instead it
|
* \note This function does not return a valid instruction encoding; instead it returns an encoding of the delay
|
||||||
* returns an encoding of the delay slot suitable for `OR`ing with the result of
|
* slot suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when
|
||||||
* an encoding function for an actual instruction. Care should be taken when
|
* combining the results of this function with the results of \ref pio_encode_sideset and \ref pio_encode_sideset_opt
|
||||||
* combining the results of this function with the results of \ref
|
* as they share the same bits within the instruction encoding.
|
||||||
* pio_encode_sideset and \ref pio_encode_sideset_opt as they share the same
|
|
||||||
* bits within the instruction encoding.
|
|
||||||
*
|
*
|
||||||
* \param cycles the number of cycles 0-31 (or less if side set is being used)
|
* \param cycles the number of cycles 0-31 (or less if side set is being used)
|
||||||
* \return the delay slot bits to be ORed with an instruction encoding
|
* \return the delay slot bits to be ORed with an instruction encoding
|
||||||
|
|
@ -124,42 +113,38 @@ static inline uint pio_encode_delay(uint cycles) {
|
||||||
return cycles << 8u;
|
return cycles << 8u;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode just the side set bits of an instruction (in non optional side
|
/*! \brief Encode just the side set bits of an instruction (in non optional side set mode)
|
||||||
* set mode) \ingroup pio_instructions
|
* \ingroup pio_instructions
|
||||||
*
|
*
|
||||||
* \note This function does not return a valid instruction encoding; instead it
|
* \note This function does not return a valid instruction encoding; instead it returns an encoding of the side set bits
|
||||||
* returns an encoding of the side set bits suitable for `OR`ing with the result
|
* suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when
|
||||||
* of an encoding function for an actual instruction. Care should be taken when
|
* combining the results of this function with the results of \ref pio_encode_delay as they share the same bits
|
||||||
* combining the results of this function with the results of \ref
|
* within the instruction encoding.
|
||||||
* pio_encode_delay as they share the same bits within the instruction encoding.
|
|
||||||
*
|
*
|
||||||
* \param sideset_bit_count number of side set bits as would be specified via
|
* \param sideset_bit_count number of side set bits as would be specified via `.sideset` in pioasm
|
||||||
* `.sideset` in pioasm \param value the value to sideset on the pins \return
|
* \param value the value to sideset on the pins
|
||||||
* the side set bits to be ORed with an instruction encoding
|
* \return the side set bits to be ORed with an instruction encoding
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_sideset(uint sideset_bit_count, uint value) {
|
static inline uint pio_encode_sideset(uint sideset_bit_count, uint value) {
|
||||||
valid_params_if(PIO_INSTRUCTIONS,
|
valid_params_if(PIO_INSTRUCTIONS, sideset_bit_count >= 1 && sideset_bit_count <= 5);
|
||||||
sideset_bit_count >= 1 && sideset_bit_count <= 5);
|
|
||||||
valid_params_if(PIO_INSTRUCTIONS, value <= ((1u << sideset_bit_count) - 1));
|
valid_params_if(PIO_INSTRUCTIONS, value <= ((1u << sideset_bit_count) - 1));
|
||||||
return value << (13u - sideset_bit_count);
|
return value << (13u - sideset_bit_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode just the side set bits of an instruction (in optional -`opt`
|
/*! \brief Encode just the side set bits of an instruction (in optional -`opt` side set mode)
|
||||||
* side set mode) \ingroup pio_instructions
|
* \ingroup pio_instructions
|
||||||
*
|
*
|
||||||
* \note This function does not return a valid instruction encoding; instead it
|
* \note This function does not return a valid instruction encoding; instead it returns an encoding of the side set bits
|
||||||
* returns an encoding of the side set bits suitable for `OR`ing with the result
|
* suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when
|
||||||
* of an encoding function for an actual instruction. Care should be taken when
|
* combining the results of this function with the results of \ref pio_encode_delay as they share the same bits
|
||||||
* combining the results of this function with the results of \ref
|
* within the instruction encoding.
|
||||||
* pio_encode_delay as they share the same bits within the instruction encoding.
|
|
||||||
*
|
*
|
||||||
* \param sideset_bit_count number of side set bits as would be specified via
|
* \param sideset_bit_count number of side set bits as would be specified via `.sideset <n> opt` in pioasm
|
||||||
* `.sideset <n> opt` in pioasm \param value the value to sideset on the pins
|
* \param value the value to sideset on the pins
|
||||||
* \return the side set bits to be ORed with an instruction encoding
|
* \return the side set bits to be ORed with an instruction encoding
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_sideset_opt(uint sideset_bit_count, uint value) {
|
static inline uint pio_encode_sideset_opt(uint sideset_bit_count, uint value) {
|
||||||
valid_params_if(PIO_INSTRUCTIONS,
|
valid_params_if(PIO_INSTRUCTIONS, sideset_bit_count >= 1 && sideset_bit_count <= 4);
|
||||||
sideset_bit_count >= 1 && sideset_bit_count <= 4);
|
|
||||||
valid_params_if(PIO_INSTRUCTIONS, value <= ((1u << sideset_bit_count) - 1));
|
valid_params_if(PIO_INSTRUCTIONS, value <= ((1u << sideset_bit_count) - 1));
|
||||||
return 0x1000u | value << (12u - sideset_bit_count);
|
return 0x1000u | value << (12u - sideset_bit_count);
|
||||||
}
|
}
|
||||||
|
|
@ -169,9 +154,9 @@ static inline uint pio_encode_sideset_opt(uint sideset_bit_count, uint value) {
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP <addr>`
|
* This is the equivalent of `JMP <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp(uint addr) {
|
static inline uint pio_encode_jmp(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 0, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 0, addr);
|
||||||
|
|
@ -182,22 +167,22 @@ static inline uint pio_encode_jmp(uint addr) {
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP !X <addr>`
|
* This is the equivalent of `JMP !X <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp_not_x(uint addr) {
|
static inline uint pio_encode_jmp_not_x(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 1, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 1, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a conditional JMP if scratch X non-zero (and post-decrement X)
|
/*! \brief Encode a conditional JMP if scratch X non-zero (and post-decrement X) instruction
|
||||||
* instruction \ingroup pio_instructions
|
* \ingroup pio_instructions
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP X-- <addr>`
|
* This is the equivalent of `JMP X-- <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp_x_dec(uint addr) {
|
static inline uint pio_encode_jmp_x_dec(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 2, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 2, addr);
|
||||||
|
|
@ -208,22 +193,22 @@ static inline uint pio_encode_jmp_x_dec(uint addr) {
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP !Y <addr>`
|
* This is the equivalent of `JMP !Y <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp_not_y(uint addr) {
|
static inline uint pio_encode_jmp_not_y(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 3, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 3, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a conditional JMP if scratch Y non-zero (and post-decrement Y)
|
/*! \brief Encode a conditional JMP if scratch Y non-zero (and post-decrement Y) instruction
|
||||||
* instruction \ingroup pio_instructions
|
* \ingroup pio_instructions
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP Y-- <addr>`
|
* This is the equivalent of `JMP Y-- <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp_y_dec(uint addr) {
|
static inline uint pio_encode_jmp_y_dec(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 4, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 4, addr);
|
||||||
|
|
@ -234,9 +219,9 @@ static inline uint pio_encode_jmp_y_dec(uint addr) {
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP X!=Y <addr>`
|
* This is the equivalent of `JMP X!=Y <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp_x_ne_y(uint addr) {
|
static inline uint pio_encode_jmp_x_ne_y(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 5, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 5, addr);
|
||||||
|
|
@ -247,22 +232,22 @@ static inline uint pio_encode_jmp_x_ne_y(uint addr) {
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP PIN <addr>`
|
* This is the equivalent of `JMP PIN <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp_pin(uint addr) {
|
static inline uint pio_encode_jmp_pin(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 6, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 6, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a conditional JMP if output shift register not empty
|
/*! \brief Encode a conditional JMP if output shift register not empty instruction
|
||||||
* instruction \ingroup pio_instructions
|
* \ingroup pio_instructions
|
||||||
*
|
*
|
||||||
* This is the equivalent of `JMP !OSRE <addr>`
|
* This is the equivalent of `JMP !OSRE <addr>`
|
||||||
*
|
*
|
||||||
* \param addr The target address 0-31 (an absolute address within the PIO
|
* \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
|
||||||
* instruction memory) \return The instruction encoding with 0 delay and no side
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* set value \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_jmp_not_osre(uint addr) {
|
static inline uint pio_encode_jmp_not_osre(uint addr) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 7, addr);
|
return _pio_encode_instr_and_args(pio_instr_bits_jmp, 7, addr);
|
||||||
|
|
@ -284,8 +269,7 @@ static inline uint _pio_encode_irq(bool relative, uint irq) {
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_wait_gpio(bool polarity, uint gpio) {
|
static inline uint pio_encode_wait_gpio(bool polarity, uint gpio) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_wait,
|
return _pio_encode_instr_and_args(pio_instr_bits_wait, 0u | (polarity ? 4u : 0u), gpio);
|
||||||
0u | (polarity ? 4u : 0u), gpio);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a WAIT for pin instruction
|
/*! \brief Encode a WAIT for pin instruction
|
||||||
|
|
@ -294,13 +278,12 @@ static inline uint pio_encode_wait_gpio(bool polarity, uint gpio) {
|
||||||
* This is the equivalent of `WAIT <polarity> PIN <pin>`
|
* This is the equivalent of `WAIT <polarity> PIN <pin>`
|
||||||
*
|
*
|
||||||
* \param polarity true for `WAIT 1`, false for `WAIT 0`
|
* \param polarity true for `WAIT 1`, false for `WAIT 0`
|
||||||
* \param pin The pin number 0-31 relative to the executing SM's input pin
|
* \param pin The pin number 0-31 relative to the executing SM's input pin mapping
|
||||||
* mapping \return The instruction encoding with 0 delay and no side set value
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_wait_pin(bool polarity, uint pin) {
|
static inline uint pio_encode_wait_pin(bool polarity, uint pin) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_wait,
|
return _pio_encode_instr_and_args(pio_instr_bits_wait, 1u | (polarity ? 4u : 0u), pin);
|
||||||
1u | (polarity ? 4u : 0u), pin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a WAIT for IRQ instruction
|
/*! \brief Encode a WAIT for IRQ instruction
|
||||||
|
|
@ -309,16 +292,14 @@ static inline uint pio_encode_wait_pin(bool polarity, uint pin) {
|
||||||
* This is the equivalent of `WAIT <polarity> IRQ <irq> <relative>`
|
* This is the equivalent of `WAIT <polarity> IRQ <irq> <relative>`
|
||||||
*
|
*
|
||||||
* \param polarity true for `WAIT 1`, false for `WAIT 0`
|
* \param polarity true for `WAIT 1`, false for `WAIT 0`
|
||||||
* \param relative true for a `WAIT IRQ <irq> REL`, false for regular `WAIT IRQ
|
* \param relative true for a `WAIT IRQ <irq> REL`, false for regular `WAIT IRQ <irq>`
|
||||||
* <irq>` \param irq the irq number 0-7 \return The instruction encoding with 0
|
* \param irq the irq number 0-7
|
||||||
* delay and no side set value \see pio_encode_delay, pio_encode_sideset,
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_wait_irq(bool polarity, bool relative, uint irq) {
|
static inline uint pio_encode_wait_irq(bool polarity, bool relative, uint irq) {
|
||||||
valid_params_if(PIO_INSTRUCTIONS, irq <= 7);
|
valid_params_if(PIO_INSTRUCTIONS, irq <= 7);
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_wait,
|
return _pio_encode_instr_and_args(pio_instr_bits_wait, 2u | (polarity ? 4u : 0u), _pio_encode_irq(relative, irq));
|
||||||
2u | (polarity ? 4u : 0u),
|
|
||||||
_pio_encode_irq(relative, irq));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode an IN instruction
|
/*! \brief Encode an IN instruction
|
||||||
|
|
@ -362,8 +343,7 @@ static inline uint pio_encode_out(enum pio_src_dest dest, uint count) {
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_push(bool if_full, bool block) {
|
static inline uint pio_encode_push(bool if_full, bool block) {
|
||||||
return _pio_encode_instr_and_args(
|
return _pio_encode_instr_and_args(pio_instr_bits_push, (if_full ? 2u : 0u) | (block ? 1u : 0u), 0);
|
||||||
pio_instr_bits_push, (if_full ? 2u : 0u) | (block ? 1u : 0u), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a PULL instruction
|
/*! \brief Encode a PULL instruction
|
||||||
|
|
@ -377,8 +357,7 @@ static inline uint pio_encode_push(bool if_full, bool block) {
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_pull(bool if_empty, bool block) {
|
static inline uint pio_encode_pull(bool if_empty, bool block) {
|
||||||
return _pio_encode_instr_and_args(
|
return _pio_encode_instr_and_args(pio_instr_bits_pull, (if_empty ? 2u : 0u) | (block ? 1u : 0u), 0);
|
||||||
pio_instr_bits_pull, (if_empty ? 2u : 0u) | (block ? 1u : 0u), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a MOV instruction
|
/*! \brief Encode a MOV instruction
|
||||||
|
|
@ -391,8 +370,7 @@ static inline uint pio_encode_pull(bool if_empty, bool block) {
|
||||||
* \return The instruction encoding with 0 delay and no side set value
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_mov(enum pio_src_dest dest,
|
static inline uint pio_encode_mov(enum pio_src_dest dest, enum pio_src_dest src) {
|
||||||
enum pio_src_dest src) {
|
|
||||||
valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
|
valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
|
||||||
valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
|
valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
|
||||||
return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, src & 7u);
|
return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, src & 7u);
|
||||||
|
|
@ -408,12 +386,10 @@ static inline uint pio_encode_mov(enum pio_src_dest dest,
|
||||||
* \return The instruction encoding with 0 delay and no side set value
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_mov_not(enum pio_src_dest dest,
|
static inline uint pio_encode_mov_not(enum pio_src_dest dest, enum pio_src_dest src) {
|
||||||
enum pio_src_dest src) {
|
|
||||||
valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
|
valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
|
||||||
valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
|
valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
|
||||||
return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest,
|
return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, (1u << 3u) | (src & 7u));
|
||||||
(1u << 3u) | (src & 7u));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a MOV instruction with bit reverse
|
/*! \brief Encode a MOV instruction with bit reverse
|
||||||
|
|
@ -426,12 +402,10 @@ static inline uint pio_encode_mov_not(enum pio_src_dest dest,
|
||||||
* \return The instruction encoding with 0 delay and no side set value
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_mov_reverse(enum pio_src_dest dest,
|
static inline uint pio_encode_mov_reverse(enum pio_src_dest dest, enum pio_src_dest src) {
|
||||||
enum pio_src_dest src) {
|
|
||||||
valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
|
valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
|
||||||
valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
|
valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
|
||||||
return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest,
|
return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, (2u << 3u) | (src & 7u));
|
||||||
(2u << 3u) | (src & 7u));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a IRQ SET instruction
|
/*! \brief Encode a IRQ SET instruction
|
||||||
|
|
@ -439,14 +413,13 @@ static inline uint pio_encode_mov_reverse(enum pio_src_dest dest,
|
||||||
*
|
*
|
||||||
* This is the equivalent of `IRQ SET <irq> <relative>`
|
* This is the equivalent of `IRQ SET <irq> <relative>`
|
||||||
*
|
*
|
||||||
* \param relative true for a `IRQ SET <irq> REL`, false for regular `IRQ SET
|
* \param relative true for a `IRQ SET <irq> REL`, false for regular `IRQ SET <irq>`
|
||||||
* <irq>` \param irq the irq number 0-7 \return The instruction encoding with 0
|
* \param irq the irq number 0-7
|
||||||
* delay and no side set value \see pio_encode_delay, pio_encode_sideset,
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_irq_set(bool relative, uint irq) {
|
static inline uint pio_encode_irq_set(bool relative, uint irq) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_irq, 0,
|
return _pio_encode_instr_and_args(pio_instr_bits_irq, 0, _pio_encode_irq(relative, irq));
|
||||||
_pio_encode_irq(relative, irq));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a IRQ WAIT instruction
|
/*! \brief Encode a IRQ WAIT instruction
|
||||||
|
|
@ -454,14 +427,13 @@ static inline uint pio_encode_irq_set(bool relative, uint irq) {
|
||||||
*
|
*
|
||||||
* This is the equivalent of `IRQ WAIT <irq> <relative>`
|
* This is the equivalent of `IRQ WAIT <irq> <relative>`
|
||||||
*
|
*
|
||||||
* \param relative true for a `IRQ WAIT <irq> REL`, false for regular `IRQ WAIT
|
* \param relative true for a `IRQ WAIT <irq> REL`, false for regular `IRQ WAIT <irq>`
|
||||||
* <irq>` \param irq the irq number 0-7 \return The instruction encoding with 0
|
* \param irq the irq number 0-7
|
||||||
* delay and no side set value \see pio_encode_delay, pio_encode_sideset,
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_irq_wait(bool relative, uint irq) {
|
static inline uint pio_encode_irq_wait(bool relative, uint irq) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_irq, 1,
|
return _pio_encode_instr_and_args(pio_instr_bits_irq, 1, _pio_encode_irq(relative, irq));
|
||||||
_pio_encode_irq(relative, irq));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a IRQ CLEAR instruction
|
/*! \brief Encode a IRQ CLEAR instruction
|
||||||
|
|
@ -469,14 +441,13 @@ static inline uint pio_encode_irq_wait(bool relative, uint irq) {
|
||||||
*
|
*
|
||||||
* This is the equivalent of `IRQ CLEAR <irq> <relative>`
|
* This is the equivalent of `IRQ CLEAR <irq> <relative>`
|
||||||
*
|
*
|
||||||
* \param relative true for a `IRQ CLEAR <irq> REL`, false for regular `IRQ
|
* \param relative true for a `IRQ CLEAR <irq> REL`, false for regular `IRQ CLEAR <irq>`
|
||||||
* CLEAR <irq>` \param irq the irq number 0-7 \return The instruction encoding
|
* \param irq the irq number 0-7
|
||||||
* with 0 delay and no side set value \see pio_encode_delay, pio_encode_sideset,
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_irq_clear(bool relative, uint irq) {
|
static inline uint pio_encode_irq_clear(bool relative, uint irq) {
|
||||||
return _pio_encode_instr_and_args(pio_instr_bits_irq, 2,
|
return _pio_encode_instr_and_args(pio_instr_bits_irq, 2, _pio_encode_irq(relative, irq));
|
||||||
_pio_encode_irq(relative, irq));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Encode a SET instruction
|
/*! \brief Encode a SET instruction
|
||||||
|
|
@ -502,7 +473,9 @@ static inline uint pio_encode_set(enum pio_src_dest dest, uint value) {
|
||||||
* \return The instruction encoding with 0 delay and no side set value
|
* \return The instruction encoding with 0 delay and no side set value
|
||||||
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
* \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
|
||||||
*/
|
*/
|
||||||
static inline uint pio_encode_nop(void) { return pio_encode_mov(pio_y, pio_y); }
|
static inline uint pio_encode_nop(void) {
|
||||||
|
return pio_encode_mov(pio_y, pio_y);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
src/piolib/include/hardware/timer.h
Normal file
11
src/piolib/include/hardware/timer.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Raspberry Pi Ltd.
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
#ifndef _HARDWARE_TIMER_H
|
||||||
|
#define _HARDWARE_TIMER_H
|
||||||
|
|
||||||
|
#include "piolib.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -25,27 +25,17 @@
|
||||||
#define PARAM_ASSERTIONS_DISABLE_ALL 0
|
#define PARAM_ASSERTIONS_DISABLE_ALL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PARAM_ASSERTIONS_ENABLED(x) \
|
#define PARAM_ASSERTIONS_ENABLED(x) ((PARAM_ASSERTIONS_ENABLED_ ## x || PARAM_ASSERTIONS_ENABLE_ALL) && !PARAM_ASSERTIONS_DISABLE_ALL)
|
||||||
((PARAM_ASSERTIONS_ENABLED_##x || PARAM_ASSERTIONS_ENABLE_ALL) && \
|
#define invalid_params_if(x, test) ({if (PARAM_ASSERTIONS_ENABLED(x)) assert(!(test));})
|
||||||
!PARAM_ASSERTIONS_DISABLE_ALL)
|
#define valid_params_if(x, test) ({if (PARAM_ASSERTIONS_ENABLED(x)) assert(test);})
|
||||||
#define invalid_params_if(x, test) \
|
|
||||||
({ \
|
|
||||||
if (PARAM_ASSERTIONS_ENABLED(x)) \
|
|
||||||
assert(!(test)); \
|
|
||||||
})
|
|
||||||
#define valid_params_if(x, test) \
|
|
||||||
({ \
|
|
||||||
if (PARAM_ASSERTIONS_ENABLED(x)) \
|
|
||||||
assert(test); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define STATIC_ASSERT(cond) static_assert(cond, #cond)
|
#define STATIC_ASSERT(cond) static_assert(cond, #cond)
|
||||||
|
|
||||||
#define _u(x) ((uint)(x))
|
#define _u(x) ((uint)(x))
|
||||||
#define bool_to_bit(x) ((uint) !!(x))
|
#define bool_to_bit(x) ((uint)!!(x))
|
||||||
|
|
||||||
#ifndef count_of
|
#ifndef count_of
|
||||||
#define count_of(a) (sizeof(a) / sizeof((a)[0]))
|
#define count_of(a) (sizeof(a)/sizeof((a)[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
|
|
|
||||||
|
|
@ -11,17 +11,17 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "pio_platform.h"
|
||||||
#include "hardware/clocks.h"
|
#include "hardware/clocks.h"
|
||||||
#include "hardware/gpio.h"
|
#include "hardware/gpio.h"
|
||||||
#include "pio_platform.h"
|
|
||||||
|
|
||||||
#ifndef PARAM_ASSERTIONS_ENABLED_PIO
|
#ifndef PARAM_ASSERTIONS_ENABLED_PIO
|
||||||
#define PARAM_ASSERTIONS_ENABLED_PIO 0
|
#define PARAM_ASSERTIONS_ENABLED_PIO 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PIO_ERR(x) ((PIO)(uintptr_t)(x))
|
#define PIO_ERR(x)((PIO)(uintptr_t)(x))
|
||||||
#define PIO_IS_ERR(x) (((uintptr_t)(x) >= (uintptr_t)-200))
|
#define PIO_IS_ERR(x)(((uintptr_t)(x) >= (uintptr_t)-200))
|
||||||
#define PIO_ERR_VAL(x) ((int)(uintptr_t)(x))
|
#define PIO_ERR_VAL(x)((int)(uintptr_t)(x))
|
||||||
|
|
||||||
#define PIO_ORIGIN_ANY ((uint)(~0))
|
#define PIO_ORIGIN_ANY ((uint)(~0))
|
||||||
#define PIO_ORIGIN_INVALID PIO_ORIGIN_ANY
|
#define PIO_ORIGIN_INVALID PIO_ORIGIN_ANY
|
||||||
|
|
@ -34,9 +34,16 @@ enum pio_fifo_join {
|
||||||
PIO_FIFO_JOIN_RX = 2,
|
PIO_FIFO_JOIN_RX = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum pio_mov_status_type { STATUS_TX_LESSTHAN = 0, STATUS_RX_LESSTHAN = 1 };
|
enum pio_mov_status_type {
|
||||||
|
STATUS_TX_LESSTHAN = 0,
|
||||||
|
STATUS_RX_LESSTHAN = 1
|
||||||
|
};
|
||||||
|
|
||||||
enum pio_xfer_dir { PIO_DIR_TO_SM, PIO_DIR_FROM_SM, PIO_DIR_COUNT };
|
enum pio_xfer_dir {
|
||||||
|
PIO_DIR_TO_SM,
|
||||||
|
PIO_DIR_FROM_SM,
|
||||||
|
PIO_DIR_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef PIOLIB_INTERNALS
|
#ifndef PIOLIB_INTERNALS
|
||||||
|
|
||||||
|
|
@ -71,18 +78,13 @@ enum pio_src_dest {
|
||||||
pio_x = 1u,
|
pio_x = 1u,
|
||||||
pio_y = 2u,
|
pio_y = 2u,
|
||||||
pio_null = 3u | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
pio_null = 3u | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
||||||
pio_pindirs =
|
pio_pindirs = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
||||||
4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
pio_exec_mov = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
||||||
pio_exec_mov = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST |
|
pio_status = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
||||||
_PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
pio_pc = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
||||||
pio_status = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST |
|
|
||||||
_PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
|
|
||||||
pio_pc =
|
|
||||||
5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
|
|
||||||
pio_isr = 6u | _PIO_INVALID_SET_DEST,
|
pio_isr = 6u | _PIO_INVALID_SET_DEST,
|
||||||
pio_osr = 7u | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST,
|
pio_osr = 7u | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST,
|
||||||
pio_exec_out = 7u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST |
|
pio_exec_out = 7u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
||||||
_PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -113,17 +115,12 @@ struct pio_chip {
|
||||||
int (*open_instance)(PIO pio);
|
int (*open_instance)(PIO pio);
|
||||||
void (*close_instance)(PIO pio);
|
void (*close_instance)(PIO pio);
|
||||||
|
|
||||||
int (*pio_sm_config_xfer)(PIO pio, uint sm, uint dir, uint buf_size,
|
int (*pio_sm_config_xfer)(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count);
|
||||||
uint buf_count);
|
int (*pio_sm_xfer_data)(PIO pio, uint sm, uint dir, uint data_bytes, void *data);
|
||||||
int (*pio_sm_xfer_data)(PIO pio, uint sm, uint dir, uint data_bytes,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
bool (*pio_can_add_program_at_offset)(PIO pio, const pio_program_t *program,
|
bool (*pio_can_add_program_at_offset)(PIO pio, const pio_program_t *program, uint offset);
|
||||||
uint offset);
|
uint (*pio_add_program_at_offset)(PIO pio, const pio_program_t *program, uint offset);
|
||||||
uint (*pio_add_program_at_offset)(PIO pio, const pio_program_t *program,
|
bool (*pio_remove_program)(PIO pio, const pio_program_t *program, uint loaded_offset);
|
||||||
uint offset);
|
|
||||||
bool (*pio_remove_program)(PIO pio, const pio_program_t *program,
|
|
||||||
uint loaded_offset);
|
|
||||||
bool (*pio_clear_instruction_memory)(PIO pio);
|
bool (*pio_clear_instruction_memory)(PIO pio);
|
||||||
uint (*pio_encode_delay)(PIO pio, uint cycles);
|
uint (*pio_encode_delay)(PIO pio, uint cycles);
|
||||||
uint (*pio_encode_sideset)(PIO pio, uint sideset_bit_count, uint value);
|
uint (*pio_encode_sideset)(PIO pio, uint sideset_bit_count, uint value);
|
||||||
|
|
@ -138,18 +135,14 @@ struct pio_chip {
|
||||||
uint (*pio_encode_jmp_not_osre)(PIO pio, uint addr);
|
uint (*pio_encode_jmp_not_osre)(PIO pio, uint addr);
|
||||||
uint (*pio_encode_wait_gpio)(PIO pio, bool polarity, uint gpio);
|
uint (*pio_encode_wait_gpio)(PIO pio, bool polarity, uint gpio);
|
||||||
uint (*pio_encode_wait_pin)(PIO pio, bool polarity, uint pin);
|
uint (*pio_encode_wait_pin)(PIO pio, bool polarity, uint pin);
|
||||||
uint (*pio_encode_wait_irq)(PIO pio, bool polarity, bool relative,
|
uint (*pio_encode_wait_irq)(PIO pio, bool polarity, bool relative, uint irq);
|
||||||
uint irq);
|
|
||||||
uint (*pio_encode_in)(PIO pio, enum pio_src_dest src, uint count);
|
uint (*pio_encode_in)(PIO pio, enum pio_src_dest src, uint count);
|
||||||
uint (*pio_encode_out)(PIO pio, enum pio_src_dest dest, uint count);
|
uint (*pio_encode_out)(PIO pio, enum pio_src_dest dest, uint count);
|
||||||
uint (*pio_encode_push)(PIO pio, bool if_full, bool block);
|
uint (*pio_encode_push)(PIO pio, bool if_full, bool block);
|
||||||
uint (*pio_encode_pull)(PIO pio, bool if_empty, bool block);
|
uint (*pio_encode_pull)(PIO pio, bool if_empty, bool block);
|
||||||
uint (*pio_encode_mov)(PIO pio, enum pio_src_dest dest,
|
uint (*pio_encode_mov)(PIO pio, enum pio_src_dest dest, enum pio_src_dest src);
|
||||||
enum pio_src_dest src);
|
uint (*pio_encode_mov_not)(PIO pio, enum pio_src_dest dest, enum pio_src_dest src);
|
||||||
uint (*pio_encode_mov_not)(PIO pio, enum pio_src_dest dest,
|
uint (*pio_encode_mov_reverse)(PIO pio, enum pio_src_dest dest, enum pio_src_dest src);
|
||||||
enum pio_src_dest src);
|
|
||||||
uint (*pio_encode_mov_reverse)(PIO pio, enum pio_src_dest dest,
|
|
||||||
enum pio_src_dest src);
|
|
||||||
uint (*pio_encode_irq_set)(PIO pio, bool relative, uint irq);
|
uint (*pio_encode_irq_set)(PIO pio, bool relative, uint irq);
|
||||||
uint (*pio_encode_irq_wait)(PIO pio, bool relative, uint irq);
|
uint (*pio_encode_irq_wait)(PIO pio, bool relative, uint irq);
|
||||||
uint (*pio_encode_irq_clear)(PIO pio, bool relative, uint irq);
|
uint (*pio_encode_irq_clear)(PIO pio, bool relative, uint irq);
|
||||||
|
|
@ -162,21 +155,16 @@ struct pio_chip {
|
||||||
bool (*pio_sm_unclaim)(PIO pio, uint sm);
|
bool (*pio_sm_unclaim)(PIO pio, uint sm);
|
||||||
bool (*pio_sm_is_claimed)(PIO pio, uint sm);
|
bool (*pio_sm_is_claimed)(PIO pio, uint sm);
|
||||||
|
|
||||||
void (*pio_sm_init)(PIO pio, uint sm, uint initial_pc,
|
void (*pio_sm_init)(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config);
|
||||||
const pio_sm_config *config);
|
|
||||||
void (*pio_sm_set_config)(PIO pio, uint sm, const pio_sm_config *config);
|
void (*pio_sm_set_config)(PIO pio, uint sm, const pio_sm_config *config);
|
||||||
void (*pio_sm_exec)(PIO pio, uint sm, uint instr, bool blocking);
|
void (*pio_sm_exec)(PIO pio, uint sm, uint instr, bool blocking);
|
||||||
void (*pio_sm_clear_fifos)(PIO pio, uint sm);
|
void (*pio_sm_clear_fifos)(PIO pio, uint sm);
|
||||||
void (*pio_sm_set_clkdiv_int_frac)(PIO pio, uint sm, uint16_t div_int,
|
void (*pio_sm_set_clkdiv_int_frac)(PIO pio, uint sm, uint16_t div_int, uint8_t div_frac);
|
||||||
uint8_t div_frac);
|
|
||||||
void (*pio_sm_set_clkdiv)(PIO pio, uint sm, float div);
|
void (*pio_sm_set_clkdiv)(PIO pio, uint sm, float div);
|
||||||
void (*pio_sm_set_pins)(PIO pio, uint sm, uint32_t pin_values);
|
void (*pio_sm_set_pins)(PIO pio, uint sm, uint32_t pin_values);
|
||||||
void (*pio_sm_set_pins_with_mask)(PIO pio, uint sm, uint32_t pin_values,
|
void (*pio_sm_set_pins_with_mask)(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask);
|
||||||
uint32_t pin_mask);
|
void (*pio_sm_set_pindirs_with_mask)(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask);
|
||||||
void (*pio_sm_set_pindirs_with_mask)(PIO pio, uint sm, uint32_t pin_dirs,
|
void (*pio_sm_set_consecutive_pindirs)(PIO pio, uint sm, uint pin_base, uint pin_count, bool is_out);
|
||||||
uint32_t pin_mask);
|
|
||||||
void (*pio_sm_set_consecutive_pindirs)(PIO pio, uint sm, uint pin_base,
|
|
||||||
uint pin_count, bool is_out);
|
|
||||||
void (*pio_sm_set_enabled)(PIO pio, uint sm, bool enabled);
|
void (*pio_sm_set_enabled)(PIO pio, uint sm, bool enabled);
|
||||||
void (*pio_sm_set_enabled_mask)(PIO pio, uint32_t mask, bool enabled);
|
void (*pio_sm_set_enabled_mask)(PIO pio, uint32_t mask, bool enabled);
|
||||||
void (*pio_sm_restart)(PIO pio, uint sm);
|
void (*pio_sm_restart)(PIO pio, uint sm);
|
||||||
|
|
@ -196,34 +184,23 @@ struct pio_chip {
|
||||||
void (*pio_sm_drain_tx_fifo)(PIO pio, uint sm);
|
void (*pio_sm_drain_tx_fifo)(PIO pio, uint sm);
|
||||||
|
|
||||||
pio_sm_config (*pio_get_default_sm_config)(PIO pio);
|
pio_sm_config (*pio_get_default_sm_config)(PIO pio);
|
||||||
void (*smc_set_out_pins)(PIO pio, pio_sm_config *c, uint out_base,
|
void (*smc_set_out_pins)(PIO pio, pio_sm_config *c, uint out_base, uint out_count);
|
||||||
uint out_count);
|
void (*smc_set_set_pins)(PIO pio, pio_sm_config *c, uint set_base, uint set_count);
|
||||||
void (*smc_set_set_pins)(PIO pio, pio_sm_config *c, uint set_base,
|
|
||||||
uint set_count);
|
|
||||||
void (*smc_set_in_pins)(PIO pio, pio_sm_config *c, uint in_base);
|
void (*smc_set_in_pins)(PIO pio, pio_sm_config *c, uint in_base);
|
||||||
void (*smc_set_sideset_pins)(PIO pio, pio_sm_config *c, uint sideset_base);
|
void (*smc_set_sideset_pins)(PIO pio, pio_sm_config *c, uint sideset_base);
|
||||||
void (*smc_set_sideset)(PIO pio, pio_sm_config *c, uint bit_count,
|
void (*smc_set_sideset)(PIO pio, pio_sm_config *c, uint bit_count, bool optional, bool pindirs);
|
||||||
bool optional, bool pindirs);
|
void (*smc_set_clkdiv_int_frac)(PIO pio, pio_sm_config *c, uint16_t div_int, uint8_t div_frac);
|
||||||
void (*smc_set_clkdiv_int_frac)(PIO pio, pio_sm_config *c, uint16_t div_int,
|
|
||||||
uint8_t div_frac);
|
|
||||||
void (*smc_set_clkdiv)(PIO pio, pio_sm_config *c, float div);
|
void (*smc_set_clkdiv)(PIO pio, pio_sm_config *c, float div);
|
||||||
void (*smc_set_wrap)(PIO pio, pio_sm_config *c, uint wrap_target,
|
void (*smc_set_wrap)(PIO pio, pio_sm_config *c, uint wrap_target, uint wrap);
|
||||||
uint wrap);
|
|
||||||
void (*smc_set_jmp_pin)(PIO pio, pio_sm_config *c, uint pin);
|
void (*smc_set_jmp_pin)(PIO pio, pio_sm_config *c, uint pin);
|
||||||
void (*smc_set_in_shift)(PIO pio, pio_sm_config *c, bool shift_right,
|
void (*smc_set_in_shift)(PIO pio, pio_sm_config *c, bool shift_right, bool autopush, uint push_threshold);
|
||||||
bool autopush, uint push_threshold);
|
void (*smc_set_out_shift)(PIO pio, pio_sm_config *c, bool shift_right, bool autopull, uint pull_threshold);
|
||||||
void (*smc_set_out_shift)(PIO pio, pio_sm_config *c, bool shift_right,
|
void (*smc_set_fifo_join)(PIO pio, pio_sm_config *c, enum pio_fifo_join join);
|
||||||
bool autopull, uint pull_threshold);
|
void (*smc_set_out_special)(PIO pio, pio_sm_config *c, bool sticky, bool has_enable_pin, uint enable_pin_index);
|
||||||
void (*smc_set_fifo_join)(PIO pio, pio_sm_config *c,
|
void (*smc_set_mov_status)(PIO pio, pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n);
|
||||||
enum pio_fifo_join join);
|
|
||||||
void (*smc_set_out_special)(PIO pio, pio_sm_config *c, bool sticky,
|
|
||||||
bool has_enable_pin, uint enable_pin_index);
|
|
||||||
void (*smc_set_mov_status)(PIO pio, pio_sm_config *c,
|
|
||||||
enum pio_mov_status_type status_sel,
|
|
||||||
uint status_n);
|
|
||||||
|
|
||||||
uint32_t (*clock_get_hz)(PIO pio, enum clock_index clk_index);
|
uint32_t (*clock_get_hz)(PIO pio, enum clock_index clk_index);
|
||||||
void (*pio_gpio_init)(PIO pio, uint pin);
|
void (*pio_gpio_init)(PIO, uint pin);
|
||||||
void (*gpio_init)(PIO pio, uint gpio);
|
void (*gpio_init)(PIO pio, uint gpio);
|
||||||
void (*gpio_set_function)(PIO pio, uint gpio, enum gpio_function fn);
|
void (*gpio_set_function)(PIO pio, uint gpio, enum gpio_function fn);
|
||||||
void (*gpio_set_pulls)(PIO pio, uint gpio, bool up, bool down);
|
void (*gpio_set_pulls)(PIO pio, uint gpio, bool up, bool down);
|
||||||
|
|
@ -231,8 +208,7 @@ struct pio_chip {
|
||||||
void (*gpio_set_inover)(PIO pio, uint gpio, uint value);
|
void (*gpio_set_inover)(PIO pio, uint gpio, uint value);
|
||||||
void (*gpio_set_oeover)(PIO pio, uint gpio, uint value);
|
void (*gpio_set_oeover)(PIO pio, uint gpio, uint value);
|
||||||
void (*gpio_set_input_enabled)(PIO pio, uint gpio, bool enabled);
|
void (*gpio_set_input_enabled)(PIO pio, uint gpio, bool enabled);
|
||||||
void (*gpio_set_drive_strength)(PIO pio, uint gpio,
|
void (*gpio_set_drive_strength)(PIO pio, uint gpio, enum gpio_drive_strength drive);
|
||||||
enum gpio_drive_strength drive);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pio_instance {
|
struct pio_instance {
|
||||||
|
|
@ -252,58 +228,74 @@ int pio_get_index(PIO pio);
|
||||||
void pio_select(PIO pio);
|
void pio_select(PIO pio);
|
||||||
PIO pio_get_current(void);
|
PIO pio_get_current(void);
|
||||||
|
|
||||||
static inline void pio_error(PIO pio, const char *msg) {
|
static inline void pio_error(PIO pio, const char *msg)
|
||||||
|
{
|
||||||
pio->error = true;
|
pio->error = true;
|
||||||
if (pio->errors_are_fatal)
|
if (pio->errors_are_fatal)
|
||||||
pio_panic(msg);
|
pio_panic(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pio_get_error(PIO pio) { return pio->error; }
|
static inline bool pio_get_error(PIO pio)
|
||||||
|
{
|
||||||
|
return pio->error;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void pio_clear_error(PIO pio) { pio->error = false; }
|
static inline void pio_clear_error(PIO pio)
|
||||||
|
{
|
||||||
|
pio->error = false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void pio_enable_fatal_errors(PIO pio, bool enable) {
|
static inline void pio_enable_fatal_errors(PIO pio, bool enable)
|
||||||
|
{
|
||||||
pio->errors_are_fatal = enable;
|
pio->errors_are_fatal = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_get_sm_count(PIO pio) { return pio->chip->sm_count; }
|
static inline uint pio_get_sm_count(PIO pio)
|
||||||
|
{
|
||||||
|
return pio->chip->sm_count;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint pio_get_instruction_count(PIO pio) {
|
static inline uint pio_get_instruction_count(PIO pio)
|
||||||
|
{
|
||||||
return pio->chip->instr_count;
|
return pio->chip->instr_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_get_fifo_depth(PIO pio) { return pio->chip->fifo_depth; }
|
static inline uint pio_get_fifo_depth(PIO pio)
|
||||||
|
{
|
||||||
|
return pio->chip->fifo_depth;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void check_pio_param(__unused PIO pio) {
|
static inline void check_pio_param(__unused PIO pio)
|
||||||
|
{
|
||||||
valid_params_if(PIO, pio_get_index(pio) >= 0);
|
valid_params_if(PIO, pio_get_index(pio) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pio_sm_config_xfer(PIO pio, uint sm, uint dir, uint buf_size,
|
static inline int pio_sm_config_xfer(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count)
|
||||||
uint buf_count) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_config_xfer(pio, sm, dir, buf_size, buf_count);
|
return pio->chip->pio_sm_config_xfer(pio, sm, dir, buf_size, buf_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pio_sm_xfer_data(PIO pio, uint sm, uint dir, uint data_bytes,
|
static inline int pio_sm_xfer_data(PIO pio, uint sm, uint dir, uint data_bytes, void *data)
|
||||||
void *data) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_xfer_data(pio, sm, dir, data_bytes, data);
|
return pio->chip->pio_sm_xfer_data(pio, sm, dir, data_bytes, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pio_can_add_program(PIO pio, const pio_program_t *program) {
|
static inline bool pio_can_add_program(PIO pio, const pio_program_t *program)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_can_add_program_at_offset(pio, program,
|
return pio->chip->pio_can_add_program_at_offset(pio, program, PIO_ORIGIN_ANY);
|
||||||
PIO_ORIGIN_ANY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pio_can_add_program_at_offset(PIO pio,
|
static inline bool pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset)
|
||||||
const pio_program_t *program,
|
{
|
||||||
uint offset) {
|
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_can_add_program_at_offset(pio, program, offset);
|
return pio->chip->pio_can_add_program_at_offset(pio, program, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_add_program(PIO pio, const pio_program_t *program) {
|
static inline uint pio_add_program(PIO pio, const pio_program_t *program)
|
||||||
|
{
|
||||||
uint offset;
|
uint offset;
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
offset = pio->chip->pio_add_program_at_offset(pio, program, PIO_ORIGIN_ANY);
|
offset = pio->chip->pio_add_program_at_offset(pio, program, PIO_ORIGIN_ANY);
|
||||||
|
|
@ -312,492 +304,548 @@ static inline uint pio_add_program(PIO pio, const pio_program_t *program) {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void pio_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset)
|
||||||
pio_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
if (pio->chip->pio_add_program_at_offset(pio, program, offset) ==
|
if (pio->chip->pio_add_program_at_offset(pio, program, offset) == PIO_ORIGIN_INVALID)
|
||||||
PIO_ORIGIN_INVALID)
|
|
||||||
pio_error(pio, "No program space");
|
pio_error(pio, "No program space");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_remove_program(PIO pio, const pio_program_t *program,
|
static inline void pio_remove_program(PIO pio, const pio_program_t *program, uint loaded_offset)
|
||||||
uint loaded_offset) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
if (!pio->chip->pio_remove_program(pio, program, loaded_offset))
|
if (!pio->chip->pio_remove_program(pio, program, loaded_offset))
|
||||||
pio_error(pio, "Failed to remove program");
|
pio_error(pio, "Failed to remove program");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_clear_instruction_memory(PIO pio) {
|
static inline void pio_clear_instruction_memory(PIO pio)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
if (!pio->chip->pio_clear_instruction_memory(pio))
|
if (!pio->chip->pio_clear_instruction_memory(pio))
|
||||||
pio_error(pio, "Failed to clear instruction memory");
|
pio_error(pio, "Failed to clear instruction memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_delay(uint cycles) {
|
static inline uint pio_encode_delay(uint cycles)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_delay(pio, cycles);
|
return pio->chip->pio_encode_delay(pio, cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_sideset(uint sideset_bit_count, uint value) {
|
static inline uint pio_encode_sideset(uint sideset_bit_count, uint value)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_sideset(pio, sideset_bit_count, value);
|
return pio->chip->pio_encode_sideset(pio, sideset_bit_count, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_sideset_opt(uint sideset_bit_count, uint value) {
|
static inline uint pio_encode_sideset_opt(uint sideset_bit_count, uint value)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_sideset_opt(pio, sideset_bit_count, value);
|
return pio->chip->pio_encode_sideset_opt(pio, sideset_bit_count, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp(uint addr) {
|
static inline uint pio_encode_jmp(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp(pio, addr);
|
return pio->chip->pio_encode_jmp(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp_not_x(uint addr) {
|
static inline uint pio_encode_jmp_not_x(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp_not_x(pio, addr);
|
return pio->chip->pio_encode_jmp_not_x(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp_x_dec(uint addr) {
|
static inline uint pio_encode_jmp_x_dec(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp_x_dec(pio, addr);
|
return pio->chip->pio_encode_jmp_x_dec(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp_not_y(uint addr) {
|
static inline uint pio_encode_jmp_not_y(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp_not_y(pio, addr);
|
return pio->chip->pio_encode_jmp_not_y(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp_y_dec(uint addr) {
|
static inline uint pio_encode_jmp_y_dec(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp_y_dec(pio, addr);
|
return pio->chip->pio_encode_jmp_y_dec(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp_x_ne_y(uint addr) {
|
static inline uint pio_encode_jmp_x_ne_y(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp_x_ne_y(pio, addr);
|
return pio->chip->pio_encode_jmp_x_ne_y(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp_pin(uint addr) {
|
static inline uint pio_encode_jmp_pin(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp_pin(pio, addr);
|
return pio->chip->pio_encode_jmp_pin(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_jmp_not_osre(uint addr) {
|
static inline uint pio_encode_jmp_not_osre(uint addr)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_jmp_not_osre(pio, addr);
|
return pio->chip->pio_encode_jmp_not_osre(pio, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_wait_gpio(bool polarity, uint gpio) {
|
static inline uint pio_encode_wait_gpio(bool polarity, uint gpio)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_wait_gpio(pio, polarity, gpio);
|
return pio->chip->pio_encode_wait_gpio(pio, polarity, gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_wait_pin(bool polarity, uint pin) {
|
static inline uint pio_encode_wait_pin(bool polarity, uint pin)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_wait_pin(pio, polarity, pin);
|
return pio->chip->pio_encode_wait_pin(pio, polarity, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_wait_irq(bool polarity, bool relative, uint irq) {
|
static inline uint pio_encode_wait_irq(bool polarity, bool relative, uint irq)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_wait_irq(pio, polarity, relative, irq);
|
return pio->chip->pio_encode_wait_irq(pio, polarity, relative, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_in(enum pio_src_dest src, uint count) {
|
static inline uint pio_encode_in(enum pio_src_dest src, uint count)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_in(pio, src, count);
|
return pio->chip->pio_encode_in(pio, src, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_out(enum pio_src_dest dest, uint count) {
|
static inline uint pio_encode_out(enum pio_src_dest dest, uint count)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_out(pio, dest, count);
|
return pio->chip->pio_encode_out(pio, dest, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_push(bool if_full, bool block) {
|
static inline uint pio_encode_push(bool if_full, bool block)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_push(pio, if_full, block);
|
return pio->chip->pio_encode_push(pio, if_full, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_pull(bool if_empty, bool block) {
|
static inline uint pio_encode_pull(bool if_empty, bool block)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_pull(pio, if_empty, block);
|
return pio->chip->pio_encode_pull(pio, if_empty, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_mov(enum pio_src_dest dest,
|
static inline uint pio_encode_mov(enum pio_src_dest dest, enum pio_src_dest src)
|
||||||
enum pio_src_dest src) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_mov(pio, dest, src);
|
return pio->chip->pio_encode_mov(pio, dest, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_mov_not(enum pio_src_dest dest,
|
static inline uint pio_encode_mov_not(enum pio_src_dest dest, enum pio_src_dest src)
|
||||||
enum pio_src_dest src) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_mov_not(pio, dest, src);
|
return pio->chip->pio_encode_mov_not(pio, dest, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_mov_reverse(enum pio_src_dest dest,
|
static inline uint pio_encode_mov_reverse(enum pio_src_dest dest, enum pio_src_dest src)
|
||||||
enum pio_src_dest src) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_mov_reverse(pio, dest, src);
|
return pio->chip->pio_encode_mov_reverse(pio, dest, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_irq_set(bool relative, uint irq) {
|
static inline uint pio_encode_irq_set(bool relative, uint irq)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_irq_set(pio, relative, irq);
|
return pio->chip->pio_encode_irq_set(pio, relative, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_irq_wait(bool relative, uint irq) {
|
static inline uint pio_encode_irq_wait(bool relative, uint irq)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_irq_wait(pio, relative, irq);
|
return pio->chip->pio_encode_irq_wait(pio, relative, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_irq_clear(bool relative, uint irq) {
|
static inline uint pio_encode_irq_clear(bool relative, uint irq)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_irq_clear(pio, relative, irq);
|
return pio->chip->pio_encode_irq_clear(pio, relative, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_set(enum pio_src_dest dest, uint value) {
|
static inline uint pio_encode_set(enum pio_src_dest dest, uint value)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_set(pio, dest, value);
|
return pio->chip->pio_encode_set(pio, dest, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_encode_nop(void) {
|
static inline uint pio_encode_nop(void)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_encode_nop(pio);
|
return pio->chip->pio_encode_nop(pio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_claim(PIO pio, uint sm) {
|
static inline void pio_sm_claim(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
if (!pio->chip->pio_sm_claim(pio, sm))
|
if (!pio->chip->pio_sm_claim(pio, sm))
|
||||||
pio_error(pio, "Failed to claim SM");
|
pio_error(pio, "Failed to claim SM");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_claim_sm_mask(PIO pio, uint mask) {
|
static inline void pio_claim_sm_mask(PIO pio, uint mask)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
if (!pio->chip->pio_sm_claim_mask(pio, mask))
|
if (!pio->chip->pio_sm_claim_mask(pio, mask))
|
||||||
pio_error(pio, "Failed to claim masked SMs");
|
pio_error(pio, "Failed to claim masked SMs");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_unclaim(PIO pio, uint sm) {
|
static inline void pio_sm_unclaim(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_unclaim(pio, sm);
|
pio->chip->pio_sm_unclaim(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pio_claim_unused_sm(PIO pio, bool required) {
|
static inline int pio_claim_unused_sm(PIO pio, bool required)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_claim_unused(pio, required);
|
return pio->chip->pio_sm_claim_unused(pio, required);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pio_sm_is_claimed(PIO pio, uint sm) {
|
static inline bool pio_sm_is_claimed(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_is_claimed(pio, sm);
|
return pio->chip->pio_sm_is_claimed(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_init(PIO pio, uint sm, uint initial_pc,
|
static inline void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config)
|
||||||
const pio_sm_config *config) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_init(pio, sm, initial_pc, config);
|
pio->chip->pio_sm_init(pio, sm, initial_pc, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_config(PIO pio, uint sm,
|
static inline void pio_sm_set_config(PIO pio, uint sm, const pio_sm_config *config)
|
||||||
const pio_sm_config *config) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_config(pio, sm, config);
|
pio->chip->pio_sm_set_config(pio, sm, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_exec(PIO pio, uint sm, uint instr) {
|
static inline void pio_sm_exec(PIO pio, uint sm, uint instr)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_exec(pio, sm, instr, false);
|
pio->chip->pio_sm_exec(pio, sm, instr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr) {
|
static inline void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_exec(pio, sm, instr, true);
|
pio->chip->pio_sm_exec(pio, sm, instr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_clear_fifos(PIO pio, uint sm) {
|
static inline void pio_sm_clear_fifos(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_clear_fifos(pio, sm);
|
pio->chip->pio_sm_clear_fifos(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm,
|
static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int, uint8_t div_frac)
|
||||||
uint16_t div_int,
|
{
|
||||||
uint8_t div_frac) {
|
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_clkdiv_int_frac(pio, sm, div_int, div_frac);
|
pio->chip->pio_sm_set_clkdiv_int_frac(pio, sm, div_int, div_frac);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) {
|
static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_clkdiv(pio, sm, div);
|
pio->chip->pio_sm_set_clkdiv(pio, sm, div);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values) {
|
static inline void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_pins(pio, sm, pin_values);
|
pio->chip->pio_sm_set_pins(pio, sm, pin_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_pins_with_mask(PIO pio, uint sm,
|
static inline void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask)
|
||||||
uint32_t pin_values,
|
{
|
||||||
uint32_t pin_mask) {
|
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_pins_with_mask(pio, sm, pin_values, pin_mask);
|
pio->chip->pio_sm_set_pins_with_mask(pio, sm, pin_values, pin_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_pindirs_with_mask(PIO pio, uint sm,
|
static inline void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask)
|
||||||
uint32_t pin_dirs,
|
{
|
||||||
uint32_t pin_mask) {
|
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_pindirs_with_mask(pio, sm, pin_dirs, pin_mask);
|
pio->chip->pio_sm_set_pindirs_with_mask(pio, sm, pin_dirs, pin_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_consecutive_pindirs(PIO pio, uint sm,
|
static inline void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin_base, uint pin_count, bool is_out)
|
||||||
uint pin_base, uint pin_count,
|
{
|
||||||
bool is_out) {
|
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count,
|
pio->chip->pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, is_out);
|
||||||
is_out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) {
|
static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_enabled(pio, sm, enabled);
|
pio->chip->pio_sm_set_enabled(pio, sm, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask,
|
static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled)
|
||||||
bool enabled) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_enabled_mask(pio, mask, enabled);
|
pio->chip->pio_sm_set_enabled_mask(pio, mask, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_restart(PIO pio, uint sm) {
|
static inline void pio_sm_restart(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_restart(pio, sm);
|
pio->chip->pio_sm_restart(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_restart_sm_mask(PIO pio, uint32_t mask) {
|
static inline void pio_restart_sm_mask(PIO pio, uint32_t mask)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_restart_mask(pio, mask);
|
pio->chip->pio_sm_restart_mask(pio, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_clkdiv_restart(PIO pio, uint sm) {
|
static inline void pio_sm_clkdiv_restart(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_clkdiv_restart(pio, sm);
|
pio->chip->pio_sm_clkdiv_restart(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
|
static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_clkdiv_restart_mask(pio, mask);
|
pio->chip->pio_sm_clkdiv_restart_mask(pio, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_enable_sm_in_sync_mask(PIO pio, uint32_t mask) {
|
static inline void pio_enable_sm_in_sync_mask(PIO pio, uint32_t mask)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_enable_sync(pio, mask);
|
pio->chip->pio_sm_enable_sync(pio, mask);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void pio_sm_set_dmactrl(PIO pio, uint sm, bool is_tx,
|
static inline void pio_sm_set_dmactrl(PIO pio, uint sm, bool is_tx, uint32_t ctrl)
|
||||||
uint32_t ctrl) {
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_set_dmactrl(pio, sm, is_tx, ctrl);
|
pio->chip->pio_sm_set_dmactrl(pio, sm, is_tx, ctrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm) {
|
static inline bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_is_rx_fifo_empty(pio, sm);
|
return pio->chip->pio_sm_is_rx_fifo_empty(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pio_sm_is_rx_fifo_full(PIO pio, uint sm) {
|
static inline bool pio_sm_is_rx_fifo_full(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_is_rx_fifo_full(pio, sm);
|
return pio->chip->pio_sm_is_rx_fifo_full(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_sm_get_rx_fifo_level(PIO pio, uint sm) {
|
static inline uint pio_sm_get_rx_fifo_level(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_get_rx_fifo_level(pio, sm);
|
return pio->chip->pio_sm_get_rx_fifo_level(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm) {
|
static inline bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_is_tx_fifo_empty(pio, sm);
|
return pio->chip->pio_sm_is_tx_fifo_empty(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pio_sm_is_tx_fifo_full(PIO pio, uint sm) {
|
static inline bool pio_sm_is_tx_fifo_full(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_is_tx_fifo_full(pio, sm);
|
return pio->chip->pio_sm_is_tx_fifo_full(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint pio_sm_get_tx_fifo_level(PIO pio, uint sm) {
|
static inline uint pio_sm_get_tx_fifo_level(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_get_tx_fifo_level(pio, sm);
|
return pio->chip->pio_sm_get_tx_fifo_level(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_drain_tx_fifo(PIO pio, uint sm) {
|
static inline void pio_sm_drain_tx_fifo(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_drain_tx_fifo(pio, sm);
|
return pio->chip->pio_sm_drain_tx_fifo(pio, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_put(PIO pio, uint sm, uint32_t data) {
|
static inline void pio_sm_put(PIO pio, uint sm, uint32_t data)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_put(pio, sm, data, false);
|
pio->chip->pio_sm_put(pio, sm, data, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data) {
|
static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_sm_put(pio, sm, data, true);
|
pio->chip->pio_sm_put(pio, sm, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t pio_sm_get(PIO pio, uint sm) {
|
static inline uint32_t pio_sm_get(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_get(pio, sm, false);
|
return pio->chip->pio_sm_get(pio, sm, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm) {
|
static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_sm_get(pio, sm, true);
|
return pio->chip->pio_sm_get(pio, sm, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pio_sm_config pio_get_default_sm_config_for_pio(PIO pio) {
|
static inline pio_sm_config pio_get_default_sm_config_for_pio(PIO pio)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio->chip->pio_get_default_sm_config(pio);
|
return pio->chip->pio_get_default_sm_config(pio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pio_sm_config pio_get_default_sm_config(void) {
|
static inline pio_sm_config pio_get_default_sm_config(void)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->pio_get_default_sm_config(pio);
|
return pio->chip->pio_get_default_sm_config(pio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base,
|
static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint out_count)
|
||||||
uint out_count) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_out_pins(pio, c, out_base, out_count);
|
pio->chip->smc_set_out_pins(pio, c, out_base, out_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_set_pins(pio_sm_config *c, uint set_base,
|
static inline void sm_config_set_set_pins(pio_sm_config *c, uint set_base, uint set_count)
|
||||||
uint set_count) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_set_pins(pio, c, set_base, set_count);
|
pio->chip->smc_set_set_pins(pio, c, set_base, set_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_in_pins(pio_sm_config *c, uint in_base) {
|
static inline void sm_config_set_in_pins(pio_sm_config *c, uint in_base)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_in_pins(pio, c, in_base);
|
pio->chip->smc_set_in_pins(pio, c, in_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_sideset_pins(pio_sm_config *c,
|
static inline void sm_config_set_sideset_pins(pio_sm_config *c, uint sideset_base)
|
||||||
uint sideset_base) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_sideset_pins(pio, c, sideset_base);
|
pio->chip->smc_set_sideset_pins(pio, c, sideset_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count,
|
static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool optional, bool pindirs)
|
||||||
bool optional, bool pindirs) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_sideset(pio, c, bit_count, optional, pindirs);
|
pio->chip->smc_set_sideset(pio, c, bit_count, optional, pindirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c,
|
static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_int, uint8_t div_frac)
|
||||||
uint16_t div_int,
|
{
|
||||||
uint8_t div_frac) {
|
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_clkdiv_int_frac(pio, c, div_int, div_frac);
|
pio->chip->smc_set_clkdiv_int_frac(pio, c, div_int, div_frac);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_clkdiv(pio_sm_config *c, float div) {
|
static inline void sm_config_set_clkdiv(pio_sm_config *c, float div)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_clkdiv(pio, c, div);
|
pio->chip->smc_set_clkdiv(pio, c, div);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_wrap(pio_sm_config *c, uint wrap_target,
|
static inline void sm_config_set_wrap(pio_sm_config *c, uint wrap_target, uint wrap)
|
||||||
uint wrap) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_wrap(pio, c, wrap_target, wrap);
|
pio->chip->smc_set_wrap(pio, c, wrap_target, wrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_jmp_pin(pio_sm_config *c, uint pin) {
|
static inline void sm_config_set_jmp_pin(pio_sm_config *c, uint pin)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_jmp_pin(pio, c, pin);
|
pio->chip->smc_set_jmp_pin(pio, c, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_in_shift(pio_sm_config *c, bool shift_right,
|
static inline void sm_config_set_in_shift(pio_sm_config *c, bool shift_right, bool autopush, uint push_threshold)
|
||||||
bool autopush, uint push_threshold) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_in_shift(pio, c, shift_right, autopush, push_threshold);
|
pio->chip->smc_set_in_shift(pio, c, shift_right, autopush, push_threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_out_shift(pio_sm_config *c, bool shift_right,
|
static inline void sm_config_set_out_shift(pio_sm_config *c, bool shift_right, bool autopull, uint pull_threshold)
|
||||||
bool autopull, uint pull_threshold) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_out_shift(pio, c, shift_right, autopull, pull_threshold);
|
pio->chip->smc_set_out_shift(pio, c, shift_right, autopull, pull_threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_fifo_join(pio_sm_config *c,
|
static inline void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join)
|
||||||
enum pio_fifo_join join) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_fifo_join(pio, c, join);
|
pio->chip->smc_set_fifo_join(pio, c, join);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_out_special(pio_sm_config *c, bool sticky,
|
static inline void sm_config_set_out_special(pio_sm_config *c, bool sticky, bool has_enable_pin, uint enable_pin_index)
|
||||||
bool has_enable_pin,
|
{
|
||||||
uint enable_pin_index) {
|
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_out_special(pio, c, sticky, has_enable_pin,
|
pio->chip->smc_set_out_special(pio, c, sticky, has_enable_pin, enable_pin_index);
|
||||||
enable_pin_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sm_config_set_mov_status(pio_sm_config *c,
|
static inline void sm_config_set_mov_status(pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n)
|
||||||
enum pio_mov_status_type status_sel,
|
{
|
||||||
uint status_n) {
|
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->smc_set_mov_status(pio, c, status_sel, status_n);
|
pio->chip->smc_set_mov_status(pio, c, status_sel, status_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pio_gpio_init(PIO pio, uint pin) {
|
static inline void pio_gpio_init(PIO pio, uint pin)
|
||||||
|
{
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
pio->chip->pio_gpio_init(pio, pin);
|
pio->chip->pio_gpio_init(pio, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t clock_get_hz(enum clock_index clk_index) {
|
static inline uint32_t clock_get_hz(enum clock_index clk_index)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
return pio->chip->clock_get_hz(pio, clk_index);
|
return pio->chip->clock_get_hz(pio, clk_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_init(uint gpio) {
|
static inline void gpio_init(uint gpio)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_init(pio, gpio);
|
pio->chip->gpio_init(pio, gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_set_function(uint gpio, enum gpio_function fn) {
|
static inline void gpio_set_function(uint gpio, enum gpio_function fn)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_set_function(pio, gpio, fn);
|
pio->chip->gpio_set_function(pio, gpio, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_set_pulls(uint gpio, bool up, bool down) {
|
|
||||||
|
static inline void gpio_set_pulls(uint gpio, bool up, bool down)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_set_pulls(pio, gpio, up, down);
|
pio->chip->gpio_set_pulls(pio, gpio, up, down);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_set_outover(uint gpio, uint value) {
|
static inline void gpio_set_outover(uint gpio, uint value)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_set_outover(pio, gpio, value);
|
pio->chip->gpio_set_outover(pio, gpio, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_set_inover(uint gpio, uint value) {
|
static inline void gpio_set_inover(uint gpio, uint value)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_set_inover(pio, gpio, value);
|
pio->chip->gpio_set_inover(pio, gpio, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_set_oeover(uint gpio, uint value) {
|
static inline void gpio_set_oeover(uint gpio, uint value)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_set_oeover(pio, gpio, value);
|
pio->chip->gpio_set_oeover(pio, gpio, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_set_input_enabled(uint gpio, bool enabled) {
|
static inline void gpio_set_input_enabled(uint gpio, bool enabled)
|
||||||
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_set_input_enabled(pio, gpio, enabled);
|
pio->chip->gpio_set_input_enabled(pio, gpio, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gpio_set_drive_strength(uint gpio,
|
static inline void gpio_set_drive_strength(uint gpio, enum gpio_drive_strength drive)
|
||||||
enum gpio_drive_strength drive) {
|
{
|
||||||
PIO pio = pio_get_current();
|
PIO pio = pio_get_current();
|
||||||
pio->chip->gpio_set_drive_strength(pio, gpio, drive);
|
pio->chip->gpio_set_drive_strength(pio, gpio, drive);
|
||||||
}
|
}
|
||||||
|
|
@ -814,7 +862,9 @@ static inline void gpio_disable_pulls(uint gpio) {
|
||||||
gpio_set_pulls(gpio, false, false);
|
gpio_set_pulls(gpio, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void stdio_init_all(void) {}
|
static inline void stdio_init_all(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void sleep_us(uint64_t us);
|
void sleep_us(uint64_t us);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include "pio_platform.h"
|
#include "pio_platform.h"
|
||||||
|
|
||||||
#define DECLARE_PIO_CHIP(chip) \
|
#define DECLARE_PIO_CHIP(chip) \
|
||||||
const PIO_CHIP_T *__ptr_##chip __attribute__((section("piochips"))) \
|
const PIO_CHIP_T *__ptr_ ## chip __attribute__ ((section ("piochips"))) __attribute__ ((used)) = \
|
||||||
__attribute__((used)) = &chip
|
&chip
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -160,10 +160,25 @@ struct rp1_pio_sm_config_xfer_args {
|
||||||
uint16_t buf_count;
|
uint16_t buf_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rp1_pio_sm_config_xfer32_args {
|
||||||
|
uint16_t sm;
|
||||||
|
uint16_t dir;
|
||||||
|
uint32_t buf_size;
|
||||||
|
uint32_t buf_count;
|
||||||
|
};
|
||||||
|
|
||||||
struct rp1_pio_sm_xfer_data_args {
|
struct rp1_pio_sm_xfer_data_args {
|
||||||
uint16_t sm;
|
uint16_t sm;
|
||||||
uint16_t dir;
|
uint16_t dir;
|
||||||
uint16_t data_bytes;
|
uint16_t data_bytes;
|
||||||
|
uint16_t rsvd;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rp1_pio_sm_xfer_data32_args {
|
||||||
|
uint16_t sm;
|
||||||
|
uint16_t dir;
|
||||||
|
uint32_t data_bytes;
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -175,75 +190,47 @@ struct rp1_access_hw_args {
|
||||||
|
|
||||||
#define PIO_IOC_MAGIC 102
|
#define PIO_IOC_MAGIC 102
|
||||||
|
|
||||||
#define PIO_IOC_SM_CONFIG_XFER \
|
#define PIO_IOC_SM_CONFIG_XFER _IOW(PIO_IOC_MAGIC, 0, struct rp1_pio_sm_config_xfer_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 0, struct rp1_pio_sm_config_xfer_args)
|
#define PIO_IOC_SM_XFER_DATA _IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args)
|
||||||
#define PIO_IOC_SM_XFER_DATA \
|
#define PIO_IOC_SM_XFER_DATA32 _IOW(PIO_IOC_MAGIC, 2, struct rp1_pio_sm_xfer_data32_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args)
|
#define PIO_IOC_SM_CONFIG_XFER32 _IOW(PIO_IOC_MAGIC, 3, struct rp1_pio_sm_config_xfer32_args)
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
|
||||||
// XXX #define PIO_IOC_SM_XFER_DATA32 _IOW(PIO_IOC_MAGIC, 2, struct
|
|
||||||
// pio_sm_xfer_data_args)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PIO_IOC_READ_HW _IOW(PIO_IOC_MAGIC, 8, struct rp1_access_hw_args)
|
#define PIO_IOC_READ_HW _IOW(PIO_IOC_MAGIC, 8, struct rp1_access_hw_args)
|
||||||
#define PIO_IOC_WRITE_HW _IOW(PIO_IOC_MAGIC, 9, struct rp1_access_hw_args)
|
#define PIO_IOC_WRITE_HW _IOW(PIO_IOC_MAGIC, 9, struct rp1_access_hw_args)
|
||||||
|
|
||||||
#define PIO_IOC_CAN_ADD_PROGRAM \
|
#define PIO_IOC_CAN_ADD_PROGRAM _IOW(PIO_IOC_MAGIC, 10, struct rp1_pio_add_program_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 10, struct rp1_pio_add_program_args)
|
#define PIO_IOC_ADD_PROGRAM _IOW(PIO_IOC_MAGIC, 11, struct rp1_pio_add_program_args)
|
||||||
#define PIO_IOC_ADD_PROGRAM \
|
#define PIO_IOC_REMOVE_PROGRAM _IOW(PIO_IOC_MAGIC, 12, struct rp1_pio_remove_program_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 11, struct rp1_pio_add_program_args)
|
|
||||||
#define PIO_IOC_REMOVE_PROGRAM \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 12, struct rp1_pio_remove_program_args)
|
|
||||||
#define PIO_IOC_CLEAR_INSTR_MEM _IO(PIO_IOC_MAGIC, 13)
|
#define PIO_IOC_CLEAR_INSTR_MEM _IO(PIO_IOC_MAGIC, 13)
|
||||||
|
|
||||||
#define PIO_IOC_SM_CLAIM _IOW(PIO_IOC_MAGIC, 20, struct rp1_pio_sm_claim_args)
|
#define PIO_IOC_SM_CLAIM _IOW(PIO_IOC_MAGIC, 20, struct rp1_pio_sm_claim_args)
|
||||||
#define PIO_IOC_SM_UNCLAIM _IOW(PIO_IOC_MAGIC, 21, struct rp1_pio_sm_claim_args)
|
#define PIO_IOC_SM_UNCLAIM _IOW(PIO_IOC_MAGIC, 21, struct rp1_pio_sm_claim_args)
|
||||||
#define PIO_IOC_SM_IS_CLAIMED \
|
#define PIO_IOC_SM_IS_CLAIMED _IOW(PIO_IOC_MAGIC, 22, struct rp1_pio_sm_claim_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 22, struct rp1_pio_sm_claim_args)
|
|
||||||
|
|
||||||
#define PIO_IOC_SM_INIT _IOW(PIO_IOC_MAGIC, 30, struct rp1_pio_sm_init_args)
|
#define PIO_IOC_SM_INIT _IOW(PIO_IOC_MAGIC, 30, struct rp1_pio_sm_init_args)
|
||||||
#define PIO_IOC_SM_SET_CONFIG \
|
#define PIO_IOC_SM_SET_CONFIG _IOW(PIO_IOC_MAGIC, 31, struct rp1_pio_sm_set_config_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 31, struct rp1_pio_sm_set_config_args)
|
|
||||||
#define PIO_IOC_SM_EXEC _IOW(PIO_IOC_MAGIC, 32, struct rp1_pio_sm_exec_args)
|
#define PIO_IOC_SM_EXEC _IOW(PIO_IOC_MAGIC, 32, struct rp1_pio_sm_exec_args)
|
||||||
#define PIO_IOC_SM_CLEAR_FIFOS \
|
#define PIO_IOC_SM_CLEAR_FIFOS _IOW(PIO_IOC_MAGIC, 33, struct rp1_pio_sm_clear_fifos_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 33, struct rp1_pio_sm_clear_fifos_args)
|
#define PIO_IOC_SM_SET_CLKDIV _IOW(PIO_IOC_MAGIC, 34, struct rp1_pio_sm_set_clkdiv_args)
|
||||||
#define PIO_IOC_SM_SET_CLKDIV \
|
#define PIO_IOC_SM_SET_PINS _IOW(PIO_IOC_MAGIC, 35, struct rp1_pio_sm_set_pins_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 34, struct rp1_pio_sm_set_clkdiv_args)
|
#define PIO_IOC_SM_SET_PINDIRS _IOW(PIO_IOC_MAGIC, 36, struct rp1_pio_sm_set_pindirs_args)
|
||||||
#define PIO_IOC_SM_SET_PINS \
|
#define PIO_IOC_SM_SET_ENABLED _IOW(PIO_IOC_MAGIC, 37, struct rp1_pio_sm_set_enabled_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 35, struct rp1_pio_sm_set_pins_args)
|
#define PIO_IOC_SM_RESTART _IOW(PIO_IOC_MAGIC, 38, struct rp1_pio_sm_restart_args)
|
||||||
#define PIO_IOC_SM_SET_PINDIRS \
|
#define PIO_IOC_SM_CLKDIV_RESTART _IOW(PIO_IOC_MAGIC, 39, struct rp1_pio_sm_restart_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 36, struct rp1_pio_sm_set_pindirs_args)
|
#define PIO_IOC_SM_ENABLE_SYNC _IOW(PIO_IOC_MAGIC, 40, struct rp1_pio_sm_enable_sync_args)
|
||||||
#define PIO_IOC_SM_SET_ENABLED \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 37, struct rp1_pio_sm_set_enabled_args)
|
|
||||||
#define PIO_IOC_SM_RESTART \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 38, struct rp1_pio_sm_restart_args)
|
|
||||||
#define PIO_IOC_SM_CLKDIV_RESTART \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 39, struct rp1_pio_sm_restart_args)
|
|
||||||
#define PIO_IOC_SM_ENABLE_SYNC \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 40, struct rp1_pio_sm_enable_sync_args)
|
|
||||||
#define PIO_IOC_SM_PUT _IOW(PIO_IOC_MAGIC, 41, struct rp1_pio_sm_put_args)
|
#define PIO_IOC_SM_PUT _IOW(PIO_IOC_MAGIC, 41, struct rp1_pio_sm_put_args)
|
||||||
#define PIO_IOC_SM_GET _IOWR(PIO_IOC_MAGIC, 42, struct rp1_pio_sm_get_args)
|
#define PIO_IOC_SM_GET _IOWR(PIO_IOC_MAGIC, 42, struct rp1_pio_sm_get_args)
|
||||||
#define PIO_IOC_SM_SET_DMACTRL \
|
#define PIO_IOC_SM_SET_DMACTRL _IOW(PIO_IOC_MAGIC, 43, struct rp1_pio_sm_set_dmactrl_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 43, struct rp1_pio_sm_set_dmactrl_args)
|
#define PIO_IOC_SM_FIFO_STATE _IOW(PIO_IOC_MAGIC, 44, struct rp1_pio_sm_fifo_state_args)
|
||||||
#define PIO_IOC_SM_FIFO_STATE \
|
#define PIO_IOC_SM_DRAIN_TX _IOW(PIO_IOC_MAGIC, 45, struct rp1_pio_sm_clear_fifos_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 44, struct rp1_pio_sm_fifo_state_args)
|
|
||||||
#define PIO_IOC_SM_DRAIN_TX \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 45, struct rp1_pio_sm_clear_fifos_args)
|
|
||||||
|
|
||||||
#define PIO_IOC_GPIO_INIT _IOW(PIO_IOC_MAGIC, 50, struct rp1_gpio_init_args)
|
#define PIO_IOC_GPIO_INIT _IOW(PIO_IOC_MAGIC, 50, struct rp1_gpio_init_args)
|
||||||
#define PIO_IOC_GPIO_SET_FUNCTION \
|
#define PIO_IOC_GPIO_SET_FUNCTION _IOW(PIO_IOC_MAGIC, 51, struct rp1_gpio_set_function_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 51, struct rp1_gpio_set_function_args)
|
#define PIO_IOC_GPIO_SET_PULLS _IOW(PIO_IOC_MAGIC, 52, struct rp1_gpio_set_pulls_args)
|
||||||
#define PIO_IOC_GPIO_SET_PULLS \
|
#define PIO_IOC_GPIO_SET_OUTOVER _IOW(PIO_IOC_MAGIC, 53, struct rp1_gpio_set_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 52, struct rp1_gpio_set_pulls_args)
|
#define PIO_IOC_GPIO_SET_INOVER _IOW(PIO_IOC_MAGIC, 54, struct rp1_gpio_set_args)
|
||||||
#define PIO_IOC_GPIO_SET_OUTOVER \
|
#define PIO_IOC_GPIO_SET_OEOVER _IOW(PIO_IOC_MAGIC, 55, struct rp1_gpio_set_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 53, struct rp1_gpio_set_args)
|
#define PIO_IOC_GPIO_SET_INPUT_ENABLED _IOW(PIO_IOC_MAGIC, 56, struct rp1_gpio_set_args)
|
||||||
#define PIO_IOC_GPIO_SET_INOVER \
|
#define PIO_IOC_GPIO_SET_DRIVE_STRENGTH _IOW(PIO_IOC_MAGIC, 57, struct rp1_gpio_set_args)
|
||||||
_IOW(PIO_IOC_MAGIC, 54, struct rp1_gpio_set_args)
|
|
||||||
#define PIO_IOC_GPIO_SET_OEOVER \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 55, struct rp1_gpio_set_args)
|
|
||||||
#define PIO_IOC_GPIO_SET_INPUT_ENABLED \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 56, struct rp1_gpio_set_args)
|
|
||||||
#define PIO_IOC_GPIO_SET_DRIVE_STRENGTH \
|
|
||||||
_IOW(PIO_IOC_MAGIC, 57, struct rp1_gpio_set_args)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -28,26 +28,33 @@ static PIO pio_instances[PIO_MAX_INSTANCES];
|
||||||
static uint num_instances;
|
static uint num_instances;
|
||||||
static pthread_mutex_t pio_handle_lock;
|
static pthread_mutex_t pio_handle_lock;
|
||||||
|
|
||||||
void pio_select(PIO pio) { __pio = pio; }
|
void pio_select(PIO pio)
|
||||||
|
{
|
||||||
|
__pio = pio;
|
||||||
|
}
|
||||||
|
|
||||||
PIO pio_get_current(void) {
|
PIO pio_get_current(void)
|
||||||
|
{
|
||||||
PIO pio = __pio;
|
PIO pio = __pio;
|
||||||
check_pio_param(pio);
|
check_pio_param(pio);
|
||||||
return pio;
|
return pio;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pio_get_index(PIO pio) {
|
int pio_get_index(PIO pio)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < PIO_MAX_INSTANCES; i++) {
|
for (i = 0; i < PIO_MAX_INSTANCES; i++)
|
||||||
|
{
|
||||||
if (pio == pio_instances[i])
|
if (pio == pio_instances[i])
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pio_init(void) {
|
int pio_init(void)
|
||||||
|
{
|
||||||
static bool initialised;
|
static bool initialised;
|
||||||
const PIO_CHIP_T *const *p;
|
const PIO_CHIP_T * const *p;
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
@ -55,7 +62,8 @@ int pio_init(void) {
|
||||||
return 0;
|
return 0;
|
||||||
num_instances = 0;
|
num_instances = 0;
|
||||||
p = &__start_piochips;
|
p = &__start_piochips;
|
||||||
while (p < &__stop_piochips && num_instances < PIO_MAX_INSTANCES) {
|
while (p < &__stop_piochips && num_instances < PIO_MAX_INSTANCES)
|
||||||
|
{
|
||||||
PIO_CHIP_T *chip = *p;
|
PIO_CHIP_T *chip = *p;
|
||||||
PIO pio = chip->create_instance(chip, i);
|
PIO pio = chip->create_instance(chip, i);
|
||||||
if (pio && !PIO_IS_ERR(pio)) {
|
if (pio && !PIO_IS_ERR(pio)) {
|
||||||
|
|
@ -75,7 +83,8 @@ int pio_init(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIO pio_open(uint idx) {
|
PIO pio_open(uint idx)
|
||||||
|
{
|
||||||
PIO pio = NULL;
|
PIO pio = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
@ -112,7 +121,8 @@ PIO pio_open(uint idx) {
|
||||||
return pio;
|
return pio;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIO pio_open_by_name(const char *name) {
|
PIO pio_open_by_name(const char *name)
|
||||||
|
{
|
||||||
int err = -ENOENT;
|
int err = -ENOENT;
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
|
|
@ -132,33 +142,38 @@ PIO pio_open_by_name(const char *name) {
|
||||||
return pio_open(i);
|
return pio_open(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
PIO pio_open_helper(uint idx) {
|
PIO pio_open_helper(uint idx)
|
||||||
|
{
|
||||||
PIO pio = pio_instances[idx];
|
PIO pio = pio_instances[idx];
|
||||||
if (!pio || !pio->in_use) {
|
if (!pio || !pio->in_use) {
|
||||||
pio = pio_open(idx);
|
pio = pio_open(idx);
|
||||||
if (PIO_IS_ERR(pio)) {
|
if (PIO_IS_ERR(pio)) {
|
||||||
printf("* Failed to open PIO device %d (error %d)\n", idx,
|
printf("* Failed to open PIO device %d (error %d)\n",
|
||||||
PIO_ERR_VAL(pio));
|
idx, PIO_ERR_VAL(pio));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pio;
|
return pio;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pio_close(PIO pio) {
|
void pio_close(PIO pio)
|
||||||
|
{
|
||||||
pio->chip->close_instance(pio);
|
pio->chip->close_instance(pio);
|
||||||
pthread_mutex_lock(&pio_handle_lock);
|
pthread_mutex_lock(&pio_handle_lock);
|
||||||
pio->in_use = 0;
|
pio->in_use = 0;
|
||||||
pthread_mutex_unlock(&pio_handle_lock);
|
pthread_mutex_unlock(&pio_handle_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pio_panic(const char *msg) {
|
void pio_panic(const char *msg)
|
||||||
|
{
|
||||||
fprintf(stderr, "PANIC: %s\n", msg);
|
fprintf(stderr, "PANIC: %s\n", msg);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep_us(uint64_t us) {
|
void sleep_us(uint64_t us) {
|
||||||
const struct timespec tv = {.tv_sec = (us / 1000000),
|
const struct timespec tv = {
|
||||||
.tv_nsec = 1000ull * (us % 1000000)};
|
.tv_sec = (us / 1000000),
|
||||||
|
.tv_nsec = 1000ull * (us % 1000000)
|
||||||
|
};
|
||||||
nanosleep(&tv, NULL);
|
nanosleep(&tv, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "piomatter/piomatter.h"
|
#include "piomatter/piomatter.h"
|
||||||
|
|
@ -61,7 +62,7 @@ uint32_t pixels[height][width] = {
|
||||||
#undef w
|
#undef w
|
||||||
#undef _
|
#undef _
|
||||||
|
|
||||||
#define rgb(r, g, b) ((r << 16) | (g << 8) | b)
|
#define rgb(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
||||||
|
|
||||||
uint32_t colorwheel(int i) {
|
uint32_t colorwheel(int i) {
|
||||||
i = i & 0xff;
|
i = i & 0xff;
|
||||||
|
|
@ -102,28 +103,42 @@ static void print_dither_schedule(const piomatter::schedule_sequence &ss) {
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
printf(" -> ");
|
||||||
|
std::map<int, int> sums;
|
||||||
|
for (auto s : ss) {
|
||||||
|
for (auto i : s) {
|
||||||
|
sums[-i.shift] += i.active_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto const &i : sums) {
|
||||||
|
printf("{%d %d} ", -i.first, i.second);
|
||||||
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_simple_dither_schedule(int n_planes, int pixels_across) {
|
static void test_simple_dither_schedule(int n_planes, int pixels_across) {
|
||||||
auto ss = piomatter::make_simple_schedule(n_planes, pixels_across);
|
auto ss = piomatter::make_simple_schedule(n_planes, pixels_across);
|
||||||
print_dither_schedule(ss);
|
print_dither_schedule(ss);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
static void test_temporal_dither_schedule(int n_planes, int pixels_across,
|
static void test_temporal_dither_schedule(int n_planes, int pixels_across,
|
||||||
int n_temporal_frames) {
|
int n_temporal_frames) {
|
||||||
auto ss = piomatter::make_temporal_dither_schedule(n_planes, pixels_across,
|
auto ss = piomatter::make_temporal_dither_schedule(n_planes, pixels_across,
|
||||||
n_temporal_frames);
|
n_temporal_frames);
|
||||||
print_dither_schedule(ss);
|
print_dither_schedule(ss);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int n = argc > 1 ? atoi(argv[1]) : 0;
|
int n = argc > 1 ? atoi(argv[1]) : 0;
|
||||||
|
|
||||||
test_simple_dither_schedule(5, 1);
|
test_simple_dither_schedule(7, 1);
|
||||||
test_temporal_dither_schedule(5, 1, 0);
|
test_temporal_dither_schedule(7, 1, 2);
|
||||||
test_temporal_dither_schedule(5, 1, 2);
|
test_temporal_dither_schedule(7, 1, 3);
|
||||||
test_temporal_dither_schedule(5, 1, 4);
|
test_temporal_dither_schedule(7, 1, 4);
|
||||||
|
test_temporal_dither_schedule(7, 1, 5);
|
||||||
|
|
||||||
|
return 0;
|
||||||
test_simple_dither_schedule(6, 1);
|
test_simple_dither_schedule(6, 1);
|
||||||
test_temporal_dither_schedule(6, 1, 0);
|
test_temporal_dither_schedule(6, 1, 0);
|
||||||
test_temporal_dither_schedule(6, 1, 2);
|
test_temporal_dither_schedule(6, 1, 2);
|
||||||
|
|
@ -131,6 +146,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
test_simple_dither_schedule(5, 16);
|
test_simple_dither_schedule(5, 16);
|
||||||
test_temporal_dither_schedule(5, 16, 2);
|
test_temporal_dither_schedule(5, 16, 2);
|
||||||
|
test_temporal_dither_schedule(5, 16, 3);
|
||||||
test_temporal_dither_schedule(5, 16, 4);
|
test_temporal_dither_schedule(5, 16, 4);
|
||||||
|
|
||||||
test_simple_dither_schedule(5, 24);
|
test_simple_dither_schedule(5, 24);
|
||||||
|
|
@ -140,6 +156,8 @@ int main(int argc, char **argv) {
|
||||||
test_simple_dither_schedule(10, 24);
|
test_simple_dither_schedule(10, 24);
|
||||||
test_temporal_dither_schedule(10, 24, 8);
|
test_temporal_dither_schedule(10, 24, 8);
|
||||||
|
|
||||||
|
test_temporal_dither_schedule(5, 128, 3);
|
||||||
|
test_temporal_dither_schedule(5, 192, 3);
|
||||||
test_temporal_dither_schedule(5, 128, 4);
|
test_temporal_dither_schedule(5, 128, 4);
|
||||||
test_temporal_dither_schedule(5, 192, 4);
|
test_temporal_dither_schedule(5, 192, 4);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -166,9 +166,11 @@ The number of pixels in the shift register is automatically computed from these
|
||||||
layout. Decreasing ``n_planes`` can increase FPS at the cost of reduced color fidelity.
|
layout. Decreasing ``n_planes`` can increase FPS at the cost of reduced color fidelity.
|
||||||
The default, 10, is the maximum value.
|
The default, 10, is the maximum value.
|
||||||
|
|
||||||
``n_temporal_planes`` controls temporal dithering of the panel. The acceptable values
|
``n_temporal_planes`` controls temporal dithering of the panel.
|
||||||
are 0 (the default), 2, and 4. A higher setting can increase FPS at the cost of
|
0 or 1 behave the same: All `n_planes` are transmitted every time.
|
||||||
slightly increasing the variation of brightness across subsequent frames.
|
A higher value sets the number of planes that are only transmitted every `1/n_temporal_frames` times.
|
||||||
|
A higher setting can increase FPS at the cost of slightly increasing the variation of brightness across subsequent frames.
|
||||||
|
Settings above 4 are allowed, but generally do not give good results.
|
||||||
|
|
||||||
For simple panels with just 1 connector (2 color lanes), the following constructor arguments are available:
|
For simple panels with just 1 connector (2 color lanes), the following constructor arguments are available:
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue