0

I'm trying to implement a synchronous protocol to talk from my Pi (Model 3B V1.2) to a separate processor (6502/6522). I started by using pigpio. I observed that I have to insert calls to usleep(0) or sched_yield(). Otherwise the communication does not work correctly. So my solution works but it is much slower than expected.

To test if the problem is related to pigpio I switched to bcm2835 (https://www.airspayce.com/mikem/bcm2835/). The result is exactly the same: The calls to the functions is still necessary and the throughput is identical (bad).

So can anybody explain the cause behind this? And is there any way to get away with these calls?

The code to read a byte looks like this. GPIO_READ etc. are macros which direct to the function of pigpio or bcm2835. YIELD is a macro which uses usleep(0) or sched_yield(). I also tried a memory barrier via __sync_synchronize(). But this did not have any effect.

static void wait_data_ready_rx()
{
  while( GPIO_READ(PIN_DATAREADY_RX) != 0 ) {
    ;
  }
  YIELD;
}

static void data_taken_rx()
{
  GPIO_WRITE(PIN_DATATAKEN_RX, 0);
  YIELD;
  GPIO_WRITE(PIN_DATATAKEN_RX, 1);
}

static unsigned char read_byte()
{
  int bit;
  int bitno = 0;
  unsigned char byte = 0;

  for(bitno=0; bitno<8; ++bitno) {
    wait_data_ready_rx();
    bit = GPIO_READ(PIN_DATA_RX_0);
    byte = byte << 1 | bit;
    data_taken_rx();
  }
  return byte;
}

Update: Thank you for your hints. It really is a timing issue: A delay is necessary between the two GPIO_WRITE. It's a coincidence that sched_yield() is just the right time for this. This simply brought me on the wrong track.

In the meantime I think I understand the logic behind it. And I'm able to optimize the communication between the two computers.

Dottore
  • 1
  • 1
  • What if you rpi is so incredibly fast, that remote doesn't register any change? What if there is a big capacity that smooths out the change? There are datasheets which should specify the maximum timings of voltages changes on lines. – KamilCuk Jul 07 '23 at 11:28
  • Did you verify your generated signals on the GPIO lines? What is maximum speed for the 6502, what speed do you create without the sleep functions? – Gerhardh Jul 07 '23 at 11:36
  • @KamilCuk: That's a valid point. But I can't even remove YIELD from wait_data_ready_rx. This is a yield between a read and a write. So timing should be no problem. – Dottore Jul 07 '23 at 12:12
  • "So timing should be no problem." yes, it could. In `wait_data_ready_rx` you only wait until the pin is low. If you are too quick, you might enter that function again before the 6502 even had a chance to bring the line up again. – Gerhardh Jul 07 '23 at 12:23

0 Answers0