mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-08-09 04:22:44 +03:00
Fix WAIT GPIO n
for n > 32 and when using gpio_base = 16 (#2265)
- fix bug: pioasm was spilling bit 5 of arg2 into arg1 - make pio_add_program flip bit 5 of a WAIT GPIO instruction if gpio_base is 16 Note: pioasm will encode only the bits 4-0 of arg2 (the GPIO number), however it does indicate whether 0-15 means 0-15 or 32-47. This can only be fixed up when loading the program, and indeed once the GPIO base is known. pio_can_add_program and friends already detected the cases where this was impossible
This commit is contained in:
@@ -79,6 +79,10 @@ static inline uint _pio_major_instr_bits(uint instr) {
|
|||||||
return instr & 0xe000u;
|
return instr & 0xe000u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint _pio_arg1(uint instr) {
|
||||||
|
return (instr >> 5) & 0x7u;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint _pio_encode_instr_and_args(enum pio_instr_bits instr_bits, uint arg1, uint arg2) {
|
static inline uint _pio_encode_instr_and_args(enum pio_instr_bits instr_bits, 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)
|
||||||
|
@@ -162,6 +162,15 @@ static int add_program_at_offset(PIO pio, const pio_program_t *program, uint off
|
|||||||
if (rc != 0) return rc;
|
if (rc != 0) return rc;
|
||||||
for (uint i = 0; i < program->length; ++i) {
|
for (uint i = 0; i < program->length; ++i) {
|
||||||
uint16_t instr = program->instructions[i];
|
uint16_t instr = program->instructions[i];
|
||||||
|
#if PICO_PIO_USE_GPIO_BASE
|
||||||
|
if (pio_instr_bits_wait == _pio_major_instr_bits(instr) && !((_pio_arg1(instr) & 3u))) {
|
||||||
|
// wait GIO will include only the 5 lower bits of the GPIO number, so if the GPIO
|
||||||
|
// base is 16 we need to flip bit 4 (which is equivalent to subtracting 16 from
|
||||||
|
// the original number 16-47 stored as 16-31 and 0-15)
|
||||||
|
static_assert(PIO_GPIOBASE_BITS == 16, ""); // only works for gpio base being 0 or 16
|
||||||
|
instr ^= pio_get_gpio_base(pio);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
pio->instr_mem[offset + i] = pio_instr_bits_jmp != _pio_major_instr_bits(instr) ? instr : instr + offset;
|
pio->instr_mem[offset + i] = pio_instr_bits_jmp != _pio_major_instr_bits(instr) ? instr : instr + offset;
|
||||||
}
|
}
|
||||||
uint32_t program_mask = (1u << program->length) - 1;
|
uint32_t program_mask = (1u << program->length) - 1;
|
||||||
|
@@ -292,7 +292,7 @@ uint instruction::encode(program &program) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// note we store the 6th bit of arg2 above the 16 bits of instruction
|
// note we store the 6th bit of arg2 above the 16 bits of instruction
|
||||||
return (((uint) raw.type) << 13u) | (((uint) _delay | (uint) _sideset) << 8u) | (raw.arg1 << 5u) | raw.arg2 | ((raw.arg2 >> 5) << 16);
|
return (((uint) raw.type) << 13u) | (((uint) _delay | (uint) _sideset) << 8u) | (raw.arg1 << 5u) | (raw.arg2 & 0x1fu) | ((raw.arg2 >> 5) << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_encoding instruction::raw_encode(program& program) {
|
raw_encoding instruction::raw_encode(program& program) {
|
||||||
|
Reference in New Issue
Block a user