Discussion of issues related specifically to writing code for native mode devices. This includes ZBasic code as well as assembly language code and C code, both inline and standalone.
I'm trying to write my first ISR. I'm more familiar with doing this on PICs so am a bit confused by register names and which registers I need to mess with. I want to use PCINT0 on the ZX-328n and from my reading of the datasheet, think I need to set...
ISR PCINT0()
If (GetPin(RF_IN)=1) Then
Call GetMicroTime(micro)
rfSTX=0
Else
rfSTX=GetElapsedMicroTime(micro)
If (rfSTX>minSTX) And (rfSTX<maxSTX) Then
Register.PCICR.0=0
Call GetRF()
Register.PCICR.0=1
End If
End If
End ISR
Are there any other registers I need to deal with?
I want to measure the width of a pulse and, when it is within the defined range, capture the following pulsetrain. In the absence of a valid signal, the RF receiver outputs a nearly continuous stream of short noise pulses. Some can be very brief. What will happen if the pin state falls before both statements of the first condition execute?
GetRF() uses InputCaptureEX. Is it necessary to disable PCINT0 before calling it?
ZBasic doesn't support the setting/clearing of individual bits using the .N notation. You can either use the SetBits() subroutine or write out the code to set/clear the individual bit. Examples of both methods (setting bit zero to one) are given below.
Call SetBits(Register.PCICR, &H01, &H01)
Register.PCICR = (Register.PCICR And &HFE) Or &H01
Some can be very brief. What will happen if the pin state falls before both statements of the first condition execute?
That could give rise to a problem, e.g. if the code waits for a series of events that will never occur you'll be stuck in the ISR.
GetRF() uses InputCaptureEX. Is it necessary to disable PCINT0 before calling it?
No. All interrupts are deferred for the duration of ISR execution. (This is not mandatory, of course, but it is generally inadvisable to allow interrupts to nest.) Note, that when the ISR return, any interrupts that occurred during the execution of that ISR will then be serviced.
It is generally advisable to write ISRs so that the execute in a very small amount of time. How long is the maximum pulse train you expect?
ZBasic doesn't support the setting/clearing of individual bits using the .N notation.
That's what happens when jumping between PICBasicPro and ZBasic. Do I need to initialize any other registers?
Some can be very brief. What will happen if the pin state falls before both statements of the first condition execute?
That could give rise to a problem, e.g. if the code waits for a series of events that will never occur you'll be stuck in the ISR.
I don't think it will get stuck waiting. When the pin goes high, the ISR initializes the microtimer and rfSTX and then exits. My concern was if a falling edge occurs while it's doing these things but your response to the following question appears to say it cannot respond to the falling edge until it exits.
GetRF() uses InputCaptureEX. Is it necessary to disable PCINT0 before calling it?
No. All interrupts are deferred for the duration of ISR execution. (This is not mandatory, of course, but it is generally inadvisable to allow interrupts to nest.) Note, that when the ISR return, any interrupts that occurred during the execution of that ISR will then be serviced.
OK
It is generally advisable to write ISRs so that the execute in a very small amount of time. How long is the maximum pulse train you expect?
Far too long - I'll need to rewrite this to call GetRF() after exiting the ISR.
ISR PCINT0()
If (GetPin(RF_IN)=1) Then
Call GetMicroTime(micro)
rfSTX=0
Else
rfSTX=GetElapsedMicroTime(micro)
End If
End ISR
I can test rfSTX in my main loop and call GetRF() from there.
dlh wrote:Do I need to initialize any other registers?
Not in the ISR. However, as part of the initial setup you probably should clear the corresponding bit in the PCIFR (doing so will prevent an immediate interrupt from occurring when the bit in PCICR is enabled). As strange as it may seem, you clear a bit in the PCIFR by writing a 1 to it, e.g.
will clear bit zero in the PCIFR. Writing zero does nothing. This somewhat strange behavior is present for all of the "interrupt occurred" flag bits.
Also, you need to set the bits in PCMSK0 corresponding to the inputs that you want to generate a pin change interrupt. If you read the register descriptions carefully you'll find that bit zero in the PCICR enables pin change interrupts for zero to eight inputs depending on the content of PCMSK0. Similarly, bit one in the PCICR enables pin change interrupts for zero to eight inputs depending on the content of PCMSK1, etc.