Hi folks,
So, here's the answer, let's start with the worst case:
Quote:
115200 = 347 clock cycles between received characters less 285 clock cycles worst case = 62 free clock cycles between characters
The only acceptable criteria for the software is whether our code will
always work; not work on average, nor with our fingers crossed, but always.
So, the normal way to work out whether there is enough time to service interrupts is to do exactly what's described above. We compare the minimum time between interrupts with the worst-case interrupt time.
If the worst-case interrupt service < that minimum time, then our interrupt code will always work.And this is correct as far as it goes, the code will always work in those circumstances. But, it turns out this isn't the true criteria for whether interrupts can be serviced adequately.
The real requirement is that a device must be serviced (after its interrupt has been triggered) before its next interrupt would occur, and that's not quite the same thing. In the case of a serial port (with a one byte buffer, which the 65C51 has, we must service the interrupting
device before the next byte has arrived.
It turns out that because the worst-case scenario can't occur twice in succession, we will always have time to service the ACIA and process the CRC at 115200 baud. Let's look at the worst-cases.
An RTC and ACIA receive interrupt go off: [ 61c (IRQ processing)+109c (RTC)+63c (Serial In) ] + 65c (CRC) + 52c (Serial Out).
So, here there's 233c between the RTC interrupt and the Serial In code (which clears that interrupt somewhere in that code). 233c is much less than the time between two received characters (we have over 100c left). So, although the CRC code follows, it doesn't
yet prevent the ACIA buffer overflowing.
Then the CRC is processed and the Serial Out is processed, that's another 117c, which takes us over the limit (350c). This means another serial interrupt has been generated before the end of the old interrupt code. And this means an ACIA interrupt is generated as soon as we exit this one.
But this time, there won't be another RTC interrupt, because only 350µs have elapsed. So, then we will be able to process the next byte in time, because we have:
[ 61c (IRQ processing)+63c (Serial In) ] + 65c (CRC) + 52c (Serial Out) = 241c, 106c free-The_Few_Cycles_During_The_Previous_IRQ_When_The_ACIA_IRQ_Was_Asserted; so there will be nearly a 0.1ms period before the next interrupt and so, even after a worst-case, we'll be OK. The fact that a 6502 instruction might take up to 7 cycles doesn't affect this by very much (we've lost maybe 14cycles, around 14% to 20% of our free space).
The next character will interrupt at: 694µs, so the 1ms interrupt won't have happened yet and by the time that interrupt exits 935+some cycles will have elapsed; so the 1ms interrupt will happen almost immediately and by the time we poll the ACIA, it will pick up the char, giving us:
[ 61c (IRQ processing)+109c/2 (to process the 1ms interrupt?)+63c (Serial In) ] + 65c (CRC) + 52c (Serial Out) = 295.5, about 50c free.
Or we could consider the scenario where there was a pending SerialOut, but when the Serial In was polled, there was no interrupt yet (it occurred 1 cycle later), which is followed by a worst-case RTC and serial In, then we get:
[52c (SerialOut)+31c (IRQ post processing?)]+[30c (IRQ Pre-processing) + 109c+63c (Serial In) ] + 65c (CRC)
This 285c before we process the CRC, so again we're OK. There's no scenario where a Serial In IRQ happens during the CRC calculation.
And so, it turns out that every scenario is of a similar form. It's possible for two individual RTC interrupts requiring processing in successive IRQs, but in either case there's at least 50c free at the end. Also, it never happens that an RTC interrupt is then followed by the worst-case, there must be a gap of at least two characters before the worst case can occur.
It may be that there's not enough time for the foreground processing to take place - but that's a problem for another day, as far as the IRQ requirements are concerned, this byte parallel routine will in fact work.
-cheers from Julz