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.