65C22N CA1 why no interrupt?
-
graeme.harker
- Posts: 10
- Joined: 18 Aug 2021
65C22N CA1 why no interrupt?
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?
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?
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?
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?
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.
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?
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.
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?
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.
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!
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.
Jeff
PS: Welcome!
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
-
graeme.harker
- Posts: 10
- Joined: 18 Aug 2021
Re: 65C22N CA1 why no interrupt?
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 ’.
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 ’.
-
graeme.harker
- Posts: 10
- Joined: 18 Aug 2021
Re: 65C22N CA1 why no interrupt?
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
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: 65C22N CA1 why no interrupt?
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!
Re: 65C22N CA1 why no interrupt?
graeme.harker wrote:
CA2 is tied to the bus enable of my downstream device. Without that, there’s no data to read.
BigDumbDinosaur wrote:
A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: 65C22N CA1 why no interrupt?
Dr Jefyll wrote:
BigDumbDinosaur wrote:
A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.
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!
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: 65C22N CA1 why no interrupt?
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- 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?
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
-
graeme.harker
- Posts: 10
- Joined: 18 Aug 2021
Re: 65C22N CA1 why no interrupt?
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.
-
graeme.harker
- Posts: 10
- Joined: 18 Aug 2021
Re: 65C22N CA1 why no interrupt?
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.
BigDumbDinosaur wrote:
A statement such as lda #(via_pcr_ca2_hi) is non-standard syntax for an immediate load.
-- Jeff
Code: Select all
lda #(via_pcr_ca2_lo|via_pcr_ca1_rising_edge)
-
graeme.harker
- Posts: 10
- Joined: 18 Aug 2021
Re: 65C22N CA1 why no interrupt?
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- 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?
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