Timer counter mode counting only half of the actual pulses ?

LePennec

New Member
Greetings,

I'm trying to interface a PICAXE 28X2 with a Z80. The interface uses a 74HC373 for communications from the Z80A to the PICAXE, and the OUT instruction of the Z80 (i.e. the data from the Z80 gets latched by the 74HC373 when IORQ goes low, WR goes low, and the A0-A7 address lines correspond to the PICAXE interface address). The PICAXE also receives the latch pulse on pin C.0 so that it is aware that new data has been latched into the 74HC373 and is ready to be read.
I configured the timer as a counter, and set it up so that it overflows at each pulse received on C.0 and triggers an interrupt for the PICAXE, like so:
Code:
symbol NEWBYTE = bit0
.../...
let dirsC = %00000010
settimer count 65535
let toflag = 0
let timer = 65535
setintflags %10000000, %10000000
.../...
main:
if NEWBYTE = 1 then
let NEWBYTE = 0
; recover byte and deal with it
endif
goto main
.../...
interrupt:
let toflag = 0
let timer = 65535
setintflags %10000000, %10000000
let NEWBYTE = 1
return
So far so good... Until I actually tried to output something from the Z80 to the PICAXE: only (and exactly) one out of two OUTs are actually detected, even when the two consecutive OUTs are separated by a very long pause (even seconds). I tried at various PICAXE clock speeds (up to 64MHz), but to no avail. I however remarked that below 16MHz, the PICAXE was missing even more pulses, so I made the latter longer, by simply adding a diode between the output of the gate generating the latching pulse for the 74HC373 and pin C.0, with a capacitor (tried up to 470pF) and a resistor (tried up to 4.7K) in parallel, between pin C.0 and ground (this results in pulses that last up to 2.5µs on C.0). With the pulse lengthening, the PICAXE detects the pulses in the same way at all clock frequencies, but alas still only one pulse out of two !

My questions are therefore:
  • Which PIC18F25K22 timer (0,1,3,5) is actually used by the PICAXE 28X2 firmware to implement its "timer" ?
  • Is there any defined limitation on the pulse width ? Is the PICAXE able to sample individual pulses on C.0, or only a clock signal ?
  • What did I do wrong ?
 
Last edited:

Technical

Technical Support
Staff member
The timer count (timer 1) is edge triggered, not pulse triggered, so are you sure the Z80 is lowering the signal line before the PICAXE reaches the 'return' line of interrupt?
 

LePennec

New Member
The timer count (timer 1) is edge triggered, not pulse triggered, so are you sure the Z80 is lowering the signal line before the PICAXE reaches the 'return' line of interrupt?
It certainly was before I added the pulse lengthening diode/capacitor/resistor, and lowering the PICAXE clock to 4MHz gave even worst results (while using just as fast a clock as the Z80, but executing BASIC: no doubt the OUT was over and the pulse back to low level before even the second instruction of the interrupt had started). Plus, I don't see why it would matter, since the triggering only happens on rising edges (so if the pulse ends after the interrupt returns, it's not an issue, as long as another OUT is not issued before the pulse is over, which was the case in the tests I did).
I also made a variant of the PICAXE program with, instead of interrupts, a polling of the timer variable in the main loop, like so:
Code:
symbol OLDTIMER = w2
.../...
let dirsC = %00000010
settimer count 65535
.../...
let timer = 0
main:
if timer != OLDTIMER then
	let OLDTIMER = timer
	; byte retrieval/processing here
endif
goto main
And got exactly the same results as with the interrupts, i.e. the timer getting incremented only every two OUTs...

EDIT: I added a "do until pinC.0 = 0 loop" just after the interrupt label, i.e. I'm now ensuring C.0 is back to the low level before doing anything in the interrupt routine, and I get the same results...
 
Last edited:

LePennec

New Member
Since you told me that the timer used is timer1 of the PIC18F25K22, I suppose it is also used in asynchronous counter mode. In this case, there's a note, in paragraph 12.2.2 of the PIC's datasheet, that might be of interest and could perhaps explain that strange behaviour, depending on how the PICAXE 28X2 firmware is implemented:
Note: In Counter mode, a falling edge must be registered by the counter prior to the first incrementing rising edge after any one or more of the following conditions:
• Timer1/3/5 enabled after POR
• Write to TMRxH or TMRxL
• Timer1/3/5 is disabled
• Timer1/3/5 is disabled (TMRxON = 0) when TxCKI is high then Timer1/3/5 is enabled (TMRxON=1) when TxCKI is low.
I am guessing that "settimer count 65535" results in a write to TMR1H and TMR1L as soon as (and every time) an overflow occurs (timer incremented following the rising edge of the pulse), meaning that if the pulse's falling edge occurs before that action is taken, then the next rising edge will be missed... There would then be a constraint on the minimum pulse width, depending on the PICAXE clock frequency (the pulse would have to be long enough to let time to the PICAXE firmware to reset TMR1H and TMR1L before its falling edge happens)... It also means that after a power on, the first pulse will always be missed (which is what I am observing as well), since no falling edge will ever occur on C.0 before the first pulse arrives.
 
Last edited:

LePennec

New Member
OK, I think I guessed right...

I worked around this quirk in the PICAXE, by ORing on C.0, with diodes, both the latch enable signal and the C.2 pin, with a pull down resistor on C.0 (i.e. when compared to my last modification, I added a diode between C.2 and C.0 and removed the "pulse lengthening" capacitor that was wired between C.0 and the ground). I then used the following code, which works nicely:

Code:
symbol NEWBYTE = bit0
.../...
; See note in paragraph 12.2.2 of the PIC18F25K22 datasheet...
; C.2 (ORed to C.0 via diodes with the 74HC373 latching signal) is used to get a falling edge on C.0 after the PICAXE resets TMR1L/H - C.1 is used to read from the 74HC373 (active low... alas...), C.0 is used to "count" latching pulses.
let dirsC = %00000110

high C.2 ; force C.0 high, so that it can go low (without triggering a count) after settimer has set TMR1L/H: this avoids missing the first pulse after power on/reset...
settimer count 65535
low C.2 ; there... no more missing pulse detection after power on/reset...
let toflag = 0
let timer = 65535
setintflags %10000000, %10000000
.../...
main:
if NEWBYTE = 1 then
let NEWBYTE = 0
; recover byte and deal with it
endif
goto main
.../...
interrupt:
high C.2 ; force C.0 high now so that it can go low after we re-enable interrupts
let toflag = 0
let timer = 65535
setintflags %10000000, %10000000
low C.2 ; we are now sure that the PICAXE firmware had plenty enough time to reset TMR1L/H to the value (65535) defined in "settimer count"
let NEWBYTE = 1
return
Of course, I'm loosing C.2 in the process... I'll probably have to make another board, using C.1 (used to enable the outputs on the 74HC373, active low), via an inverter transistor, to play as well the role of C.2 here, and I'll have to read the data from the interrupt routine itself, instead of the main loop (since I'd not be able to use C.1 out of the interrupt routine without triggering a spurious interrupt).

You guys should really document this (serious) issue in the PICAXE manual (especially the fact the first pulse is always missed after a power on/reset, regardless of the pulse width), and also provide a value for the minimum pulse width for each PICAXE clock speed...
 

eggdweather

Senior Member
The 74HC373 has a minimum input/enabling pulse width of 16nS and it is highly unlikely your Z80 is producing any pulses with the OUT command that are faster than that. It appears the D-Type latch is acting as a divider (divide by 2) which it can be configured to do if there is a feedback path, so what is you wiring arrangement / circuit between the Z80 HC373 and the PICAXE, I think that is where the issue is being introduced?

What is the Z80 supply voltage (5volts?) the HC373 and Picaxe, are they all common and do you have a common ground?

Observations: a pulse has a fixed amount of energy in it, you can't get something for nothing, you could use a diode and RC network to act as an integrator and stretch the pulse, but you would lose voltage as you stretch time to maintain the energy equilibrium, that then can make the switching thresholds for the PICAXE marginal - too low to be registered, but the second pulse would 'pump' up the stretching circuit which then gets detected by the PICAXE, but what then discharges it, ready for the next pulse?
 

LePennec

New Member
The 74HC373 has a minimum input/enabling pulse width of 16nS and it is highly unlikely your Z80 is producing any pulses with the OUT command that are faster than that. It appears the D-Type latch is acting as a divider (divide by 2) which it can be configured to do if there is a feedback path, so what is you wiring arrangement / circuit between the Z80 HC373 and the PICAXE, I think that is where the issue is being introduced?

What is the Z80 supply voltage (5volts?) the HC373 and Picaxe, are they all common and do you have a common ground?

Observations: a pulse has a fixed amount of energy in it, you can't get something for nothing, you could use a diode and RC network to act as an integrator and stretch the pulse, but you would lose voltage as you stretch time to maintain the energy equilibrium, that then can make the switching thresholds for the PICAXE marginal - too low to be registered, but the second pulse would 'pump' up the stretching circuit which then gets detected by the PICAXE, but what then discharges it, ready for the next pulse?
1.- The pulse length resulting from an OUT on a Z80 is 2 clock cycles long (500ns for a Z80 @ 4MHz). The problem is not with the 74HC373 latching (which happens just fine), but with the PICAXE failing to detect the latching pulse.
2.- There's no divider at all on the74HC373. It's a transparent latch type. Please, read the datasheet.
3.- The Z80 is indeed a 5V device (it used to be a NMOS CPU, now a CMOS one, but still 5V and fully 74HC compatible). Please, don't underestimate my skills... Of course it got a common ground and +5V supply !!!
4.- The "energy" is dependent on the current that the gate can provide. Charging a 470pF capacitor with a 500ns pulse via a 74HC gate output (that can source up to 6mA, only 1mA being "sunk" by the 4.7K pull-down resistor: i.e. the resistor discharges the capacitor 5 times slower (at peak voltage) than the gate charges it) is a non-issue. The diode I use is a BAT85 (Schottky diode), allowing minimal loss in peak voltage and maximum switching speed. The trace on my oscilloscope actually shown a valid, 2.5µs pulse, 4V peak to peak. Please also *read* my first post: the "pulse lengthening" modification was added *after* I noticed that strange 1/2 pulse detection quirk and it did indeed *improve* things (from less than 1/2 pulse to 1/2 exactly) for lower PICAXE clock speeds.
5-.- Please read my last post above, the issue is because the PICAXE firmware is not fast enough to reset the TMR1L/H register before the pulse falling edge, a falling edge that *must* happen *after* a TMR1H/L register change for the next rising edge to be taken into account. See the note in chapter 12.2.2 of the PIC18F25K22 datasheet (more like a data book...).
 
Last edited:

eggdweather

Senior Member
OK, just trying to help, any questions are to aid clarity and remove uncertainty. Can you stretch the Z80 pulse length? Your timing information is useful. Have you got a function generator to simulate the Z80 latch output / picaxe input.

It looks like your application is outside the PICAXE specification.
 

LePennec

New Member
OK, just trying to help, any questions are to aid clarity and remove uncertainty. Can you stretch the Z80 pulse length? Your timing information is useful. Have you got a function generator to simulate the Z80 latch output / picaxe input.
Please, read post #5. I found the solution, thanks to the information that the PICAXE timer is actually timer 1 of the PIC18F25K22 and thanks to that PIC datasheet, chapter 12.2.2, in the note... Read by yourself.

It looks like your application is outside the PICAXE specification.
Oh, really ?... How so ?!?

It rather looks like the PICAXE firmware coder(s) overlooked a limitation when they wrote the documentation, that limitation being that when the TMR1 register overflows (and must therefore be reloaded by the firmware with the preload value that was passed via "settimer count NNNN"), then the next rising edge will be missed unless the TMR1 register can be reloaded before the ongoing pulse falling edge happens. They also overlooked that the first pulse after a power on/reset will always be missed.

I'd now like to get from Technical or a PICAXE firmware coder the confirmation of these inferences of mine, as well as precise timings for the various PICAXE clock speeds, so that we can know what minimum pulse width allows to avoid that "one pulse out of 2 counted" quirk.
 

Technical

Technical Support
Staff member
The principle role of the 'settimer count' command (both in raw silicon and in PICAXE firmware) is to count multiple consecutive pulses, the overflag flag is primarily designed to tell you when the count overflows, not as a constantly reset edge trigger for an interrupt after just a single pulse.

If we understand correctly, you seem to be just looking for an edge/pulse, in which case it would be far simpler to use the hardware interrupt pins e.g. hint0 via hintsetup/setintflags. We do not really understand why you are trying to do this via the far more complex timer count method, is there a particular requirement?
 

LePennec

New Member
The principle role of the 'settimer count' command (both in raw silicon and in PICAXE firmware) is to count multiple consecutive pulses, the overflag flag is primarily designed to tell you when the count overflows, not as a constantly reset edge trigger for an interrupt after just a single pulse.
Such an application (single pulse count) is perfectly valid and documented as such in the PICAXE manual, page 223: "To increment the timer variable on every external pulse, simply set the preload value to 65535". Please note that the issue is not at all about the toflag and interrupt that ensues (see also this post in which I describe another method I used, letting the timer variable being incremented freely, and not using an interrupt: the same problem occurred), but rather because of the fact, that when the PIC TMR1 register (NOT the PICAXE firmware 'timer' variable) overflows, then it must be reloaded by the firmware with 65535 (or whatever value that was passed in "settimer count': the same issue with missing short pulse counts will occur with another preload value, but just less often) and that if the pulse falling edge occurs before this happens, then the next rising edge is missed.

If we understand correctly, you seem to be just looking for an edge/pulse, in which case it would be far simpler to use the hardware interrupt pins e.g. hint0 via hintsetup/setintflags. We do not really understand why you are trying to do this via the far more complex timer count method, is there a particular requirement?
The 8 pins of the B port (which got all the HINT pins) is used for interfacing the PICAXE with the 74HC373, so to retrieve the data from it. I can't use port C for this purpose, because I need special functions only available on port C (HSER, I2C, SPI, etc), and port A only got 4 available pins on the 28X2.
 
Last edited:

Technical

Technical Support
Staff member
If both the PIC silicon and PICAXE firmware don't do what you want then you need to find another solution.

As already suggested it would be trivial to swap C.0 and B.0, you can then read the 8 data lines as follows

b1 = pinsB and 254 or pinC.0
 

LePennec

New Member
If both the PIC silicon and PICAXE firmware don't do what you want then you need to find another solution.
I found the solution (see post #5), but you should make it clear, in the PICAXE documentation, that the pulses on C.0 must last long enough (i.e be wide enough) to allow the firmware to reset the TMR1 register to the preload count (N, as set with 'settimer count N') on overflow (which will always happen, at some point, be it at every pulse, for N=65535, or every 65536 pulses for N=0), else the next pulse rising edge is *missed* ! Of course, you should give the min pulse width value, in ns or µs, for each PICAXE clock speed (only you can know this, by counting the clock cycles needed by your closed source firmware to reset TM1R after an overflow). You should also make it clear that, after a power on or reset, the first pulse on C.0 is missed.

So, please, would you provide us with the necessary info: again, what is the minimum pulse width with regards to the various clock speeds ?...

As already suggested it would be trivial to swap C.0 and B.0, you can then read the 8 data lines as follows

b1 = pinsB and 254 or pinC.0
Too slow, too cumbersome, too inelegant... Not to mention pinsB are also used for the pullup resistors (not present on port C), when the 74HC373 outputs are in tri-state mode. Also, this would add more complexity on the single sided printed circuit.

Had I known that constraint on the pulse width, I'd have designed things differently from the ground up. Now, it's too late.
 

Technical

Technical Support
Staff member
So, please, would you provide us with the necessary info: again, what is the minimum pulse width with regards to the various clock speeds ?...
There is no answer to that, the PIC silicon only has one interrupt vector and hence all interrupts are all serviced in turn within one interrupt routine. Therefore if two or three interrupts are occurring at the same time, as they do, (e.g. your external clock pulse and also an internal timer interrupt) that duration will change.
 

LePennec

New Member
There is no answer to that, the PIC silicon only has one interrupt vector and hence all interrupts are all serviced in turn within one interrupt routine. Therefore if two or three interrupts are occurring at the same time, as they do, (e.g. your external clock pulse and also an internal timer interrupt) that duration will change.
Well, there *must* be a safe lower boundary for that pulse width... Else, it'd mean that there is no reliability at all in the counts done on C.0 !... There must also be an absolute minimum (the time the firmware takes when it is only processing the interrupt resulting from TMR1 overflow, with no other interrupt to service); this data is also extremely interesting to have when designing a circuit using a PICAXE.
 

eggdweather

Senior Member
I've been to London today and went through Trafalgar Square, which for some reason made me feel joyful, but I'm not sure why it had that affect on me, after all it was raining hard and it was dark from the overcast clouds.
 
Top