65C22N CA1 why no interrupt?

For discussing the 65xx hardware itself or electronics projects.
graeme.harker
Posts: 10
Joined: 18 Aug 2021

65C22N CA1 why no interrupt?

Post 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?
Attachments
image0.jpeg
User avatar
jfoucher
Posts: 94
Joined: 27 Dec 2020
Location: France
Contact:

Re: 65C22N CA1 why no interrupt?

Post 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?
Jonathan Foucher

Take a look at the Planck 6502 computer.
gfoot
Posts: 871
Joined: 09 Jul 2021

Re: 65C22N CA1 why no interrupt?

Post 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.
John West
Posts: 383
Joined: 03 Sep 2002

Re: 65C22N CA1 why no interrupt?

Post 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.
graeme.harker
Posts: 10
Joined: 18 Aug 2021

Re: 65C22N CA1 why no interrupt?

Post 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
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: 65C22N CA1 why no interrupt?

Post 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! :)
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
graeme.harker
Posts: 10
Joined: 18 Aug 2021

Re: 65C22N CA1 why no interrupt?

Post 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 ’.
Attachments
54B907B6-E0C3-4205-B4D1-0DF71A3BE8BD.jpeg
graeme.harker
Posts: 10
Joined: 18 Aug 2021

Re: 65C22N CA1 why no interrupt?

Post 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
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: 65C22N CA1 why no interrupt?

Post 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.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: 65C22N CA1 why no interrupt?

Post 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
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: 65C22N CA1 why no interrupt?

Post 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.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: 65C22N CA1 why no interrupt?

Post 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?
graeme.harker
Posts: 10
Joined: 18 Aug 2021

Re: 65C22N CA1 why no interrupt?

Post 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
graeme.harker
Posts: 10
Joined: 18 Aug 2021

Re: 65C22N CA1 why no interrupt?

Post 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.
graeme.harker
Posts: 10
Joined: 18 Aug 2021

Re: 65C22N CA1 why no interrupt?

Post 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
Post Reply