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