This is because a peek command will always wait unti it's finished, whereas
the other commands ("poke" commands) will stack in the command FIFO. If you
add the blue lines (the set_command_time() is redundant BTW) then the call
will wait until all the previous GPIO commands are finished, then it will
read the state, and return the value to the host (this is not an
asynchronous call). All following commands are then delayed, and your
calculation of "time" will be late.

--M

On Tue, Oct 29, 2024 at 11:18 AM hui cj <cjh416593...@gmail.com> wrote:

> Hi everyone,
>
> I built a project that demonstrates how to use the front-panel GPIO pins
> of the USRP X310 to emulate an SPI interface. The SPI communication
> leverages UHD timed commands and RFNoC blocks to drive GPIO signals at
> precise intervals.
> But there is a slow performance when I read GPIO values.
> If I comment the blue part, the code can generate SCK and SDO up to 2MHz.
> But if I add the function of reading gpio, the output clock is slowed down
> to 100Hz.
>
> This is weird. Anyone know why?
>
> The code is open source at https://github.com/cjhonlyone/uhd_gpio_spi.
>
> int UhdGpioSpi::write_and_read(uint8_t* write_buffer, uint8_t*
> read_buffer, uint32_t length) {
>
>     double spi_period = 1.0 / spi_frequency;
>     radio_ctrl->clear_command_time(0);
>     uhd::time_spec_t time = radio_ctrl->get_time_now() +
> uhd::time_spec_t(0.05);
>     time = time + uhd::time_spec_t(spi_period);
>     radio_ctrl->set_command_time(time, 0);
>     radio_ctrl->set_gpio_attr("FP0", "OUT", (~SDO_MASK) & (~SCS_MASK) &
> (cpol ? 0xffffffff : (~SCK_MASK)));
>
>     for (uint32_t i = 0; i < length; i++) {
>         for (uint32_t j = 0; j < 8; j++) {
>             time = time + uhd::time_spec_t(0.5 * spi_period);
>             radio_ctrl->set_command_time(time, 0);
>             if ((cpha & cpol) || ((!cpha) & (!cpol))) { // SCK = 0, SCS = 0
>                 radio_ctrl->set_gpio_attr("FP0", "OUT", (write_buffer[i] &
> (1 << (7 - j))) ? (~SCS_MASK) & (~SCK_MASK) : ((~SCS_MASK) & (~SCK_MASK) &
> (~SDO_MASK)));
>             } else { // SCK = 1, SCS = 0
>                 radio_ctrl->set_gpio_attr("FP0", "OUT", (write_buffer[i] &
> (1 << (7 - j))) ? (~SCS_MASK) : (~SCS_MASK) & (~SDO_MASK));
>             }
>
>             time = time + uhd::time_spec_t(0.5 * spi_period);
>             radio_ctrl->set_command_time(time, 0);
>             if ((cpha & cpol) || ((!cpha) & (!cpol))) { // SCK = 1, SCS = 0
>                 radio_ctrl->set_gpio_attr("FP0", "OUT", (write_buffer[i] &
> (1 << (7 - j))) ? (~SCS_MASK) : (~SCS_MASK) & (~SDO_MASK));
>             } else { // SCK = 0, SCS = 0
>                 radio_ctrl->set_gpio_attr("FP0", "OUT", (write_buffer[i] &
> (1 << (7 - j))) ? (~SCS_MASK) & (~SCK_MASK) : ((~SCS_MASK) & (~SCK_MASK) &
> (~SDO_MASK)));
>             }
>
> //            radio_ctrl->set_command_time(time, 0);
> //            if (radio_ctrl->get_gpio_attr("FP0", "READBACK") & SDI_MASK)
> //                read_buffer[i] |= (1 << (7 - j));
> //            if (j < 7) read_buffer[i] <<= 1;
>         }
>
>         // nop
>         time = time + uhd::time_spec_t(0.5*spi_period);
>         radio_ctrl->set_command_time(time, 0);
>         radio_ctrl->set_gpio_attr("FP0", "OUT", (~SDO_MASK) & (~SCS_MASK)
> & (cpol ? 0xffffffff : (~SCK_MASK)));
>
>     }
>
>     time = time + uhd::time_spec_t(spi_period);
>     radio_ctrl->set_command_time(time, 0);
>     radio_ctrl->set_gpio_attr("FP0", "OUT", SCS_MASK | (cpol ? SCK_MASK :
> 0x00000000));
>
>     return 0;
> }
> _______________________________________________
> USRP-users mailing list -- usrp-users@lists.ettus.com
> To unsubscribe send an email to usrp-users-le...@lists.ettus.com
>
_______________________________________________
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-le...@lists.ettus.com

Reply via email to