Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 8023

General • Re: RP2350 PIO DMA performance question 2 for fast IO response

$
0
0
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.)

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 11#define nCS_INV 0#define nSRD 10#define nSRD_INV 0#define ADDR_BASE 12#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)&regRespArr) & ~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}}
Assembly (the main part):

Code:

MOVS            R0, #0xFFMOV.W           R1, #0x200000LDR             R4, =regRespArrUXTB            R2, R2loc_200001C4prevData = R2           ; u32MRC             p0, 0, R3,c0,c8, 0gpioAddr = R3           ; u32TST.W           gpioAddr, #0xC00BNE             loc_200001C4UBFX.W          R3, R3, #9, #0xBORRS            R3, R4LDRH            R3, [R3]UXTH            R3, R3EORS            prevData, R3val = R2                ; u32MCR             p0, 1, val,c0,c0, 0MCR             p0, 2, R0,c0,c4, 0MCR             p0, 3, R1,c0,c0, 0MRC             p0, 0, val,c0,c0, 0UXTB            R2, R2loc_200001ECprevData = R2           ; u32MRC             p0, 0, R3,c0,c8, 0gpioAddr = R3           ; u32TST.W           gpioAddr, #0xC00BEQ             loc_200001ECMCR             p0, 3, R0,c0,c4, 0MCR             p0, 2, R1,c0,c0, 0B               loc_200001C4


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)):

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 waitAccs
I am not sure when/if I'll test more.

Statistics: Posted by wisi — Fri Dec 26, 2025 4:36 pm



Viewing all articles
Browse latest Browse all 8023

Trending Articles