Author Topic: Flip-flop frustration  (Read 7833 times)

0 Members and 1 Guest are viewing this topic.

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Flip-flop frustration
« on: November 29, 2013, 01:31:16 am »

Hi

I've been trying to get something working which I expect the guys on here will have a simple answer to, please

I have a Z80 board which I'd like to connect to an AVR chip for I/O purposes.

The theory is that a 74LS74 D type flip-flop catches the Z80 IORQ events and pulls down WAIT (with the Q output) while the AVR chip, which had been polling Q, does the I/O work.  When the AVR chip has done, it sets the flip-flop output HIGH again, letting the Z80 continue.

On startup, the AVR chip drives the Z80 RESET pin low to reset it.  It then drives the flip-flop clock LOW and then HIGH.  The D input is connected to the positive rail so the Q output should go HIGH.

The Z80 IORQ pin is connected to the flip-flop CLR pin.  When an I/O instruction is executed, this pin goes low, clearing the flip-flop, which should then cause the WAIT to start.  The AVR does what it needs to and then takes the flip-flop CLK pin LOW and HIGH (to set Q high again) and then off we go again, with the AVR watching Q going low again for the next I/O.

Does anyone see any flaws in this theory ?  Any idea why it doesn't work ?  Maybe there's a better way to do it ?

Thanks
 

Offline Jebnor

  • Regular Contributor
  • *
  • Posts: 170
  • Country: ca
  • Absolutely! Yes, kind of, sort of, not really, no.
Re: Flip-flop frustration
« Reply #1 on: November 29, 2013, 06:26:11 am »
I think a schematic would be useful. Parsing schematic into language, and vice versa, are error prone.
Before this, there was a typo.
 

Offline Kremmen

  • Super Contributor
  • ***
  • Posts: 1289
  • Country: fi
Re: Flip-flop frustration
« Reply #2 on: November 29, 2013, 06:58:04 am »
When exactly does the Z80 IORQ pin return to high state?
Nothing sings like a kilovolt.
Dr W. Bishop
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: Flip-flop frustration
« Reply #3 on: November 29, 2013, 07:23:53 am »
How exactly doesn't it work, and are you doing an input or an output?

So you're using the /IORQ line to clear the DFF and bring the /WAIT line of the Z80 low. So far seems OK.

I'm assuming an input cycle, so after the AVR sees Q go low, does it then put data on the Z80 data lines and release the /WAIT (by clocking the DFF) ??

Does the AVR wait long enough for the Z80 to latch the data, before changing the lines? the Z80 will latch the data bus for an input cycle on the first falling edge of the Z80 clock after the completion of the wait cycle. 

Again, how is it failing exactly, with what symptoms? you just said it didn't work but didn't tell us what you were doing or what you expected.

 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #4 on: November 29, 2013, 08:42:05 am »
Thanks for the answers guys.

It was really late (or should that be early ?) when I wrote the message so I didn't get all the detail in.

As it happens, I actually had the thing working hours before.  I was successfully dumping nibbles of data from the Z80 to the serial console.  However, there were two breadboards plus my Z80 card and it stopped working, at all.  I had to strip it right back but failed to remember exactly how I'd got it working.  I blame the cheap breadboards.  The metal inserts seem to lose their springiness really quickly so you end up with unreliable connections.  I was at it for the rest of the day and got to the point where the frustration of not getting it right just stopped me from seeing clearly anymore.

I have another idea so I'll give that a blast and report back thanks.
 

Offline woodchips

  • Frequent Contributor
  • **
  • Posts: 594
  • Country: gb
Re: Flip-flop frustration
« Reply #5 on: November 29, 2013, 12:26:08 pm »
Be a little cautious of the 7474, it is edge triggered and will also happily latch from glitches coming in on the Q outputs. What might be better is to use the set and clear inputs and solidly tie the clock to 0V.
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #6 on: November 30, 2013, 12:34:57 am »
All working ok now thanks.  It's basically like I said previously but this time I soldered a socket onto some board and soldered all the wires so as to avoid the flaky breadboard and unpredictable results.

IORQ resets the flip-flop which takes WAIT low

AVR notices this by monitoring IORQ which stays low once WAIT has been taken low.  Previously, the AVR was monitoring Q.

AVR does what it needs to do and the sets the flip-flop and the Z80 carries on.

D is tied low.

At the moment, the I/O handler just sends a message down the serial port and then sets the flip-flop.  I was missing some output data from the setup.  Scoping the IORQ and WAIT lines, I noticed that the IO requests were erratic even though the Z80 code is just running a series of OUTs.  Moving the wires on the AVR down from 8, 9 and 10 to 5, 6 and 7 cleared that up. Looks like there's something happening inside the AVR besides my own stuff (every pin does seem to have million functions).
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #7 on: December 04, 2013, 02:53:00 pm »
Hi guys

I spoke too soon and have spent days trying to get it right but I'm missing something.

I attach the schematic, the Z80 source code, the Arduino main loop and relevant subroutine code and some logic traces.

IORQ is ORed with RD to provide IORD and IORQ is ORed with WR to provide IOWR.

D and CLK are connected to ground to prevent spurious actions.

When an I/O WRITE is performed, the flip-flop should be cleared by IOWR, forcing the Z80 to WAIT until the Arduino code takes SET low, allowing the Z80 to continue.

If the flip-flop is not connected to WAIT, I get a very nice clean trace of the two INs and the five OUTs.

IORDs are not associated with the flip-flop but I should still be able to detect the five OUTs which I cannot.  Of course, if I cannot detect them, I cannot reset the flip-flop to get the Z80 going again after a wait.

If the flip-flop is connected to WAIT as it is meant to be, I get the odd results shown in the second trace.  While the WAIT process seems to have worked on the first Z80 OUT command, after it has been cleared, subsequent ones seem wrong, not following through with the IOWRs.

Please can anyone explain what is going wrong here ?

Thanks

Z80 source code

.org        0
           
            in   a,(0)
            in   a,(0)
            out (0),a
            out (0),a
            out (0),a
            out (0),a
            out (0),a
            halt


Arduino code

void loop()
{
  while (digitalRead(Z80_IOWR) == HIGH) {};

  // Deal with the I/O requests here

  z80_reset_wait();
}

// Clear the wait condition

void z80_reset_wait()
{
  digitalWrite(Z80_WAIT_RESET_PIN, LOW);
  digitalWrite(Z80_WAIT_RESET_PIN, HIGH);
}
 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Flip-flop frustration
« Reply #8 on: December 04, 2013, 03:22:34 pm »
DigitalRead and DigitalWrite are really slow. When there is another IOWR while the arduino sets the flip-flop it will be missed.
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #9 on: December 04, 2013, 03:40:00 pm »
DigitalRead and DigitalWrite are really slow. When there is another IOWR while the arduino sets the flip-flop it will be missed.

Thanks for the suggestion.  However, my theory is that the IOWR operation should be picked up VERY quickly by the flip-flop, putting the Z80 into the wait state, waiting for the Arduino to detect the IOWR operation at it's leisure.

 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Flip-flop frustration
« Reply #10 on: December 04, 2013, 03:47:48 pm »
However, my theory is that the IOWR operation should be picked up VERY quickly by the flip-flop
But not while /S is low. Which take a long time due the slowness of DigitalWrite. How fast is the Z80 clock?
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #11 on: December 04, 2013, 03:51:23 pm »
3.6864MHz
 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Flip-flop frustration
« Reply #12 on: December 04, 2013, 04:08:13 pm »
I measured your z80_reset_wait() on my arduino. The set pulse is 6.5us long. That's about 24 Z80 clocks. While this duration any new IOWR will be ignored by the flip-flop.

Make your measurements again and trace /S too. I think you will see it.
« Last Edit: December 04, 2013, 04:09:55 pm by sync »
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #13 on: December 04, 2013, 04:51:25 pm »
As requested ...

Thanks
 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Flip-flop frustration
« Reply #14 on: December 04, 2013, 05:47:37 pm »
As I suspected the set pulse is too long. With your circuit it must be shorter than two Z80 clocks (~540ns) when two sequent IO cycles occur. It's possible with the arduino when using direct port manipulation. See http://arduino.cc/en/Reference/PortManipulation.

Here is an example which makes a 125ns pulse on a 16MHz Uno.
Code: [Select]
  noInterrupts();         // disables interrupts
  PORTD &= ~(1 << 4);     // set port D pin 4 low
  PORTD |= 1 << 4;        // set port D pin 4 high
  interrupts();           // enable interrupts
When a interrupt occurs between the set low and the set high command then the pulse will be longer. Disabling the interrupts prevent this.

Edit: Oops. That will not work with your circuit. The pulse must be longer that one Z80 clock so the Z80 can reliably detect the cleared /WAIT. When /S goes high then /WAIT will go low again because /IOWR is still low.

That's a drawback of your circuit. Better set the flip-flop on the falling edge of /IOWR.

« Last Edit: December 04, 2013, 06:21:57 pm by sync »
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #15 on: December 04, 2013, 06:28:58 pm »
Let me say that I really appreciate your assistance with this.  It's been doing my head in  |O

I'd found that your initial suggestion didn't follow through as planned.  If I amend the wiring on the board now as you suggested, would it definitely work as originally planned ?

Thanks again.
« Last Edit: December 04, 2013, 06:38:25 pm by netdudeuk »
 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Flip-flop frustration
« Reply #16 on: December 04, 2013, 07:07:31 pm »
When there are no other errors then it will work as planned. ;D
Sorry, I can't give you a guarantee. But I think it should work. If not then do the measurements again. This is a timing critical circuit. There are many thing which can go wrong. Your logic analyzer (or scope) is the first debugging tool for such problems.
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #17 on: December 04, 2013, 07:34:23 pm »
Understood thanks.  I'll put the iron on.

Would it be better for the Arduino to be monitoring the Z80 WAIT pin to detect the OUTs, looping around until it sees a LOW ?  Or do you think there's a better option ?
 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Flip-flop frustration
« Reply #18 on: December 05, 2013, 01:55:35 pm »
You can use an interrupt on the arduino to detect a Z80 WAIT. But the interrupt code will be asynchronously executed from the main ardunio code. This is error prone. Stay with looping.
 

Offline netdudeukTopic starter

  • Frequent Contributor
  • **
  • Posts: 447
  • Country: gb
Re: Flip-flop frustration
« Reply #19 on: December 05, 2013, 05:03:12 pm »
Hi

So I followed up your suggestion and now it seems to be working well   :)

The only thing that's interesting now is why it takes so long to clear up after the first wait.  I'm guessing that this is the Arduino catching up from doing the Z80 reset to performing the first iteration of the loop.

I've learned a couple of things (like digitalWrite being pants) and the frustration has eased for now  |O  Many thanks for your help.


 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf