From: Hársfalvi Levente (hlpublic_at_freestart.hu)
Date: 2004-11-03 17:56:56
Hi!,
Thinking it over, t1 doesn't even have to be touched... it's well
enough, if -- upon the input capture interrupt -- the needed pulse width
is added to the value read from ICR, and written to OCR1x . Another
advantage of this is, that no "calculated" or experimental offsets must
be added to the value; cpu originate delays simply don't count.
However, I slowly realise that fullfilling both 1.) generating fast
transitions, ie. low delays caused by the external series resistor, ie.
low external resistor value and 2.) releasing the output _before_ the
start of the next SID measurement cycle could be tricky, or better said,
would need some extra effort =). "Releasing" the outputs, = setting both
OC pins to input a few cycles after the second output capture event,
triggered by one of the OCR interrupts could be possible, ...but at the
highest pulse widths, the end of this irq service and the start of the
next measurement cycle's IRQ service would be very close to each other.
...For the cycle exact timing, it's none of a problem, as the above
method could handle this still well (a great advantage... =) ). The
critical part is to deactivate the output, before the end of the SID's
512th cycle, so the start of the new cycle can be captured.
Another little quirk is the "reset" of the two OC pins to 0, so they can
be turned to "1" by the output capture event. This could be solved by an
"extra" OC event in the IC interrupt handler, still when the OC outputs
are set to inputs. ...So, extending the idea (it either works or not,
theoretical experiment |-))) ) :
Init: enable t1, input capture event, ic polarity (falling edge), ic
interrupt, etc... set both output capture pins to input, but write '1'
to the ports (this way, a weak pull-up will be activated in the chip).
Upon input capture interrupt:
-- Enable "toggle portbit" for both output capture events. Add a few
cycles offset to the value read from _t1_ and write this to OCR1a. (This
will bring the oc1a pin to low). After that, calculate the real value of
the pulse moment from the value calculated by (probably) the main
routine, and the value read from ICR. Write this to OCR1a. Do the same
with OC1b. Set both pins to output. Compare the two cycle length values
(the originals), and enable the OC interrupt of the higher one. Clear OC
interrupt flags. Finally, subtract a previously stored ICR value from
the current ICR value, and store it as the last measured full cycle
length for the main program. Then store the current ICR value in place
of the previous ICR value.
-- In the OC interrupt routine (this needs that both OC1x interrupt
vectors point to the same routine) set both output pins to input. The
actual time it takes to charge up the SID capacitors is a function of
the series resistor used, and so is the number of cycles (nops) that
need to be added to the interrupt handler to ensure a 0-->1 transition
for the SID. On the other hand, the higher the external resistor, the
less chances to generate the highest values without overrun problems. As
I think it over, the IRQ itself will also need some cycles to execute.
If the deactivating was put right after the register saves, it could
well happen just few (6-10) cycles after the OC1x event, so -- provided
that the caps charge up in this short time -- 254 is within reach. 255
would be tricky; would really depend on the charging current and the
number of cycles it takes in the IRQ to shut down the outputs (a
trickier interrupt handler could probably help this, but I'm not sure).
Finally, disable further OC interrupts.
It's still a little dependent on the inhibition of all but the above
interrupt sources (the IC interrupt isn't anymore, but the OC interrupt
-- the de-activation of the outputs -- is).
Best regards!,
L.
Message was sent through the cbm-hackers mailing list
Archive generated by hypermail pre-2.1.8.