Thanks, maybe better the threads are separate.
RP2350A: With the following code (default compiler settings; SDK 2.2.0) the time from active /SRD signal to data out (DBG_OUT_SIG) is 21-22cycles, which is basically the same as with PIO + DMA (a channel getting the addr from PIO RX FIFO and writing it to readAddr of another channel, writing to PIO TX FIFO with the response that for that reg).
(Input synchronizers enabled.)
Previously-tested PIO code (completely standard: Y preloaded with upper regsRespValues addr bits, two bits under the reg addr bits are always 0 (each reg uses a whole word)):I am not sure when/if I'll test more.
RP2350A: With the following code (default compiler settings; SDK 2.2.0) the time from active /SRD signal to data out (DBG_OUT_SIG) is 21-22cycles, which is basically the same as with PIO + DMA (a channel getting the addr from PIO RX FIFO and writing it to readAddr of another channel, writing to PIO TX FIFO with the response that for that reg).
(Input synchronizers enabled.)
Code:
static inline u32 gpioGetOut(void) {#if PICO_USE_GPIO_COPROCESSOR return gpioc_lo_out_get();#else return sio_hw->gpio_out;#endif}#define nCS 16#define nCS_INV 0#define nSRD 17#define nSRD_INV 0#define ADDR_BASE 20#define ADDR_WDTH 8#define DATA_BASE 0#define DATA_WDTH 8#define DATA_OE_MSK 0xFF#define DBG_OUT_SIG 21void __time_critical_func(core1RegRespArm)(void) {u32 gpioAddrMask = (1<<ADDR_WDTH)-1;const u32 gpioAccsMsk = ((1^nCS_INV)<<nCS) | ((1^nSRD_INV)<<nSRD);const u32 gpioAccsVal = ((0^nCS_INV)<<nCS) | ((0^nSRD_INV)<<nSRD);u32 val, dir, addr, gpioAddr;const u32 gpioDataMask = DATA_OE_MSK;u32 prevData = gpioGetOut() & gpioDataMask;while (1) {addr = ((u32)®RespArr) & ~gpioAddrMask;while (1) {gpioAddr = gpio_get_all();if ((gpioAddr & gpioAccsMsk) == gpioAccsVal) break;//same code as above mostly; more readable}gpioAddr >>= ADDR_BASE;gpioAddr &= gpioAddrMask;addr |= gpioAddr;val = ((vu8*)addr)[0];val <<= DATA_BASE;val ^= prevData;//in shifted stategpio_xor_mask(val);gpio_set_dir_out_masked(gpioDataMask);//enable outgpio_clr_mask(1<<DBG_OUT_SIG);//debug: outEn indicatorprevData = gpioGetOut() & gpioDataMask;while (1) {gpioAddr = gpio_get_all();if ((gpioAddr & gpioAccsMsk) != gpioAccsVal) break;}gpio_set_dir_in_masked(gpioDataMask);gpio_set_mask(1<<DBG_OUT_SIG);//debug: outOff indicator}}Code:
.program pioRegResp_A.side_set 1 opt//SideSet shows when data is being output (while low). Autopush 32bit, autopull, 32bit, in shift left..wrap_targetpublic entryPoint:in y, (32-10) side 1//Last instr should leave ISR empty.waitAccsNoRst:wait 0 gpio nSRDjmp pin waitAccsNoRst//Check for /CS to this device.in pins, 10out pins, 32//Output data (uses autopull).mov pindirs, !nullwait 1 gpio nSRD//Wait /SRD end.mov pindirs, null.wrap//jmp waitAccsStatistics: Posted by wisi — Fri Dec 26, 2025 4:36 pm