Page 1 of 2

65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 7:06 am
by graeme.harker
I have set up a 65C22N to generate an IRQ on the falling edge of CA1 to read data from a downstream device.
My downstream device generates a falling edge on CA1 when there's data ready for the VIA to read from the downstream device.
When I stream data to the VIA at low speed this works reliably.

When I stream data to the VIA at higher speeds, it works for the first few data bytes, then I see that the CA1 falling edge fails to generate an IRQ.

In the screenshot
cyan is CA1
yellow is IRQ
purple is CA2 (which my interrupt handler sets lo and high manually by writing to the VIA's PCR)

There are no other I/O devices on the CPU's IRQ and there are no other interrupts enabled on the VIA.

The only timing consideration I can find in the VIA datasheet is that the falling edge must be less than 70ns. it is, plus I've tried to speed it up by putting a couple of HC inverters in between my downstream device and the VIA's CA1 line. No change. I've tried swapping the VIA. No change.

Any ideas?

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 7:26 am
by jfoucher
I’m only on my first cup of coffee but it looks to me like the yellow line goes down each time the cyan line goes down, so it seems you do get an IRQ every time CA1 goes down. Maybe the problem is that CA1 does not come back up? What is the thin cyan vertical line after the third time CA1 goes down?

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 8:19 am
by gfoot
Yes it looks like CA1 wasn't high for long enough between lows. Possibly you need to delay your CA2 response until CA1 goes high? Or add a wait state at the other end to ensure a delay after CA1 goes high.

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 8:33 am
by John West
I'm guessing that the spike on CA1 (at the same time as the rising edge of CA2) is the result of the device providing more data immediately after the CA2 handshake: device says "I have data" on CA1, you get an interrupt, CA2 says "OK, read it", CA1 goes high and then low again because there's already more data to send.
How wide is that pulse? The documentation is ambiguous and too often silent on the details, but I would not be surprised if there has to be at least one falling edge of phi2 (or maybe a rising edge, or maybe both) in there to give the 6522's internals a chance to reset themselves.

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 6:39 pm
by graeme.harker
John West wrote:
I'm guessing that the spike on CA1 (at the same time as the rising edge of CA2) is the result of the device providing more data immediately after the CA2 handshake: device says "I have data" on CA1, you get an interrupt, CA2 says "OK, read it", CA1 goes high and then low again because there's already more data to send.
How wide is that pulse? The documentation is ambiguous and too often silent on the details, but I would not be surprised if there has to be at least one falling edge of phi2 (or maybe a rising edge, or maybe both) in there to give the 6522's internals a chance to reset themselves.
390ns

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 7:12 pm
by Dr Jefyll
It does seem as if the device is providing more data immediately after CA2 goes high. And it's noteworthy that "more data" doesn't result in the VIA pulling /IRQ low again. :!:

One explanation (not necessarily the only explanation) is an error in how the ISR is written. Forgive me if I mention a basic issue, but these are sometimes the easiest to overlook.

In the VIA's Interrupt Flag Register, the CA1 bit (IFR bit 1) is set by a CA1 active edge and cleared by reading or writing Register 1 (ORA/IRA). And it's crucial that the ISR should read IRA to get the data before manually writing to the VIA's PCR to set CA2 set low then high.

If the read of IRA occurs after pulsing CA2, you have the possibility that the downstream device could send another byte immediately. This byte can't set IFR bit 1 because it's already set, and -- more to the point -- is about to be cleared when the ISR reads IRA. The read of IRA will squelch the subsequent interrupt which you intended to occur.
Quote:
When I stream data to the VIA at low speed this works reliably.
Yup. This seems consistent with the theory I suggested. The problem only becomes evident when one byte arrives on the heels of its predecessor. Can you check this aspect of your ISR, or perhaps post the ISR? Cheers,

Jeff

PS: Welcome! :)

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 8:05 pm
by graeme.harker
Thanks. That’s plausible. I AM writing to the PCR in my ISR to set CA2 low before I read port A ‘cos CA2 is tied to the bus enable of my downstream device. Without that, there’s no data to read.

I did investigate the “pulse is too narrow” hypothesis by putting a monostable in between my downstream device and CA1 which is set up to cause an IRQ on falling edge. That fixed it (see the screenshot)

Yellow is the problematic line from my downstream device (that was previously directly connected to CA1)
Cyan is this signal post-monostable (now connected to CA1) and
Purple is IRQ

Will continue to investigate the race condition in the IRQ handler ’.

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 8:11 pm
by graeme.harker

Code: Select all

irq:
    pha
    phx
    lda #(via_pcr_ca2_lo)
    sta via_pcr

    ; load the char and clear the interrupt

    lda via_a_data 

    ; store the char in the ftdi buffer at the write pointer

    ldx ftdi_write_pointer
    sta ftdi_buffer,x
    lda #(via_pcr_ca2_hi)
    sta via_pcr

    inc ftdi_write_pointer
    plx
    pla
    rti

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 8:41 pm
by BigDumbDinosaur
graeme.harker wrote:

Code: Select all

irq:
    pha
    phx
    lda #(via_pcr_ca2_lo)
    sta via_pcr

    ; load the char and clear the interrupt

    lda via_a_data 

    ; store the char in the ftdi buffer at the write pointer

    ldx ftdi_write_pointer
    sta ftdi_buffer,x
    lda #(via_pcr_ca2_hi)
    sta via_pcr

    inc ftdi_write_pointer
    plx
    pla
    rti

Which assembler are you using? A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.

Re: 65C22N CA1 why no interrupt?

Posted: Wed Aug 18, 2021 11:48 pm
by Dr Jefyll
graeme.harker wrote:
CA2 is tied to the bus enable of my downstream device. Without that, there’s no data to read.
Hmm... Dunno if this is feasible with your setup, but maybe you can solve the problem by arranging things so both edges of the CA2 pulse have significance. Let the ISR begin by setting CA2 low, which causes the downstream device to have its output enabled. Next, the ISR reads the data from IRA. Then the ISR sets IFR sets CA2 high again, which the downstream device interprets as permission to send the next byte.
BigDumbDinosaur wrote:
A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.
graeme.harker, are the parentheses something you added optionally of your own volition, or does the assembler require them? If they're optional, I'd say their inclusion is pretty harmless and unremarkable.

-- Jeff

Re: 65C22N CA1 why no interrupt?

Posted: Thu Aug 19, 2021 1:36 am
by BigDumbDinosaur
Dr Jefyll wrote:
BigDumbDinosaur wrote:
A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.
graeme.harker, are the parentheses something you added optionally of your own volition, or does the assembler require them? If they're optional, I'd say their inclusion is pretty harmless and unremarkable.

I only mentioned it because assemblers have been known on occasion to do silly things when something odd appears in the input stream. I agree that the parentheses are likely harmless, but being the assembly language aficionado that I am, I am curious.

Re: 65C22N CA1 why no interrupt?

Posted: Thu Aug 19, 2021 2:28 am
by floobydust
I'll make a few other observations...

1- What clock rate are you running the CPU at? I don't recall seeing it mentioned. Also, which CPU is it?

2- CA2... your ISR toggles it, but it's purpose is not described. Is it handshake to the external device?

3- Your ISR increments an index which is 8-bits. In short, after collecting 256 data inputs, you start overwriting your buffer space.

Finally, perhaps a schematic and picture of the setup you've built for this?

Re: 65C22N CA1 why no interrupt?

Posted: Thu Aug 19, 2021 10:58 am
by graeme.harker
BigDumbDinosaur wrote:
graeme.harker wrote:

Code: Select all

irq:
    pha
    phx
    lda #(via_pcr_ca2_lo)
    sta via_pcr

    ; load the char and clear the interrupt

    lda via_a_data 

    ; store the char in the ftdi buffer at the write pointer

    ldx ftdi_write_pointer
    sta ftdi_buffer,x
    lda #(via_pcr_ca2_hi)
    sta via_pcr

    inc ftdi_write_pointer
    plx
    pla
    rti

Which assembler are you using? A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.
Volker Barthelmann´s vasm6502_oldstyle -wdc02 -dotdir

Re: 65C22N CA1 why no interrupt?

Posted: Thu Aug 19, 2021 11:04 am
by graeme.harker
Dr Jefyll wrote:
graeme.harker wrote:
CA2 is tied to the bus enable of my downstream device. Without that, there’s no data to read.
Hmm... Dunno if this is feasible with your setup, but maybe you can solve the problem by arranging things so both edges of the CA2 pulse have significance. Let the ISR begin by setting CA2 low, which causes the downstream device to have its output enabled. Next, the ISR reads the data from IRA. Then the ISR sets IFR sets CA2 high again, which the downstream device interprets as permission to send the next byte.
BigDumbDinosaur wrote:
A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.
graeme.harker, are the parentheses something you added optionally of your own volition, or does the assembler require them? If they're optional, I'd say their inclusion is pretty harmless and unremarkable.

-- Jeff
In a previous test I tried to see if the VIA would recognise a rising edge on CA1. My IRQ code was

Code: Select all

 
lda #(via_pcr_ca2_lo|via_pcr_ca1_rising_edge)
I just left the parenthesis in the code in case I needed to logical or my PCR with something else. You're right. I don't need them in the case of a falling-edge triggered interrupt.

Re: 65C22N CA1 why no interrupt?

Posted: Thu Aug 19, 2021 11:09 am
by graeme.harker
floobydust wrote:
I'll make a few other observations...

1- What clock rate are you running the CPU at? I don't recall seeing it mentioned. Also, which CPU is it?

2- CA2... your ISR toggles it, but it's purpose is not described. Is it handshake to the external device?

3- Your ISR increments an index which is 8-bits. In short, after collecting 256 data inputs, you start overwriting your buffer space.

Finally, perhaps a schematic and picture of the setup you've built for this?
1) it's a WDC65C02S at 1MHz - nothing too crazy
2) CA2 is the OE# (output enable) of my downstream device
3) it's a standard circular "ring buffer" with read and write pointers (with a check to see if the buffer is nearly full) - pretty standard