[CCC DEV] Servo fix update
Steve Pretty
steve.g.pretty at btinternet.com
Tue Feb 1 19:57:43 GMT 2011
I have settled on the fix shown in the code below. The fix assumes that
either the COMnA1/ COMnA0 or COMnB1/COMnB0 bits of TCCRnA.bits will be
non zero. A zero value would mean that we do not actually wish to use an
OCR pin as part of the configuration (false). A test on these bits can
determine if the A or B OCR is being programmed, and an appropriate
TCCRnA.mask can be found.
To set TCCRnA, read the existing value, use the mask to preserve the
bits of the other OCR and OR in the bits for the OCR being configured.
No elegant code, I am afraid - but it works.
--{{{ PROC pwm8.setup
--* Sets up phase-correct Pulse Width Modulation on an 8 bit timer.
--
-- Be aware that not every pin on any given board or architecture
-- can be operated as a PWM Pin. Consult your board for information on which
-- pins can produce PWM.
--
-- @param avr.pin The [@em AVR] pin to activate PWM on.
-- @param prescale The prescaler value to set with PWM.
PROC pwm8.setup (VAL INT avr.pin, prescale)
PLACED [MAX.PORT]BYTE ports 0:
#PRAGMA DEFINED ports
INT TCCRnA, TCCRnB, OCRnx:
BYTE TCCRnA.bits, TCCRnB.bits, TCCRnA.mask:
SEQ
TCCRnA, TCCRnB, OCRnx, TCCRnA.bits, TCCRnB.bits := pwm8.lookup
(avr.pin)
TCCRnB.bits := pwm8.TCCRnB.helper (TCCRnB.bits, prescale)
-- TCCRnA has mode bits for OCRnA and OCRnB. If we are configuring
OCRnA, we
-- must read and preserve the state of OCRnB, and vice versa. The following
-- IF statement creates a mask to achieve this.
IF
(TCCRnA.bits /\ #C0) = 0
TCCRnA.mask := #C0
TRUE
TCCRnA.mask := #30
ports[TCCRnA] := (ports[TCCRnA] /\ TCCRnA.mask) \/ TCCRnA.bits
ports[TCCRnB] := TCCRnB.bits
-- ports[TCCRnA] := ports[TCCRnA] \/ TCCRnA.bits
-- ports[TCCRnB] := ports[TCCRnB] \/ TCCRnB.bits
ports[OCRnx] := 0
:
--}]}
--{{{ PROC pwm16.setupn
--* Sets up phase-and-frequency-correct Pulse Width Modulation on a
-- 16 bit timer.
--
-- Be aware that not every pin on any given board or architecture
-- can be operated as a PWM Pin, and [@em not every PWM pin operates on a 16
-- bit timer].
--
-- Consult your board's reference manual for information on which pins can
-- produce 16 bit PWM.
--
-- @param avr.pin The [@em AVR] pin to activate PWM on.
-- @param prescale The prescaler value to set with PWM.
PROC pwm16.setup (VAL INT avr.pin, prescale)
PLACED [MAX.PORT]BYTE ports 0:
#PRAGMA DEFINED ports
INT TCCRnA, TCCRnB, OCRnx:
BYTE TCCRnA.bits, TCCRnB.bits, TCCRnA.mask:
SEQ
TCCRnA, TCCRnB, OCRnx, TCCRnA.bits, TCCRnB.bits := pwm16.lookup
(avr.pin)
TCCRnB.bits := pwm16.TCCRnB.helper (TCCRnB.bits, prescale)
-- TCCRnA has mode bits for OCRnA and OCRnB. If we are configuring
OCRnA, we
-- must read and preserve the state of OCRnB, and vice versa. The following
-- IF statement creates a mask to achieve this.
IF
(TCCRnA.bits /\ #C0) = 0
TCCRnA.mask := #C0
TRUE
TCCRnA.mask := #30
ports[TCCRnA] := (ports[TCCRnA] /\ TCCRnA.mask) \/ TCCRnA.bits
ports[TCCRnA] := (ports[TCCRnA] /\ #F0) \/ TCCRnA.bits
ports[TCCRnB] := TCCRnB.bits
-- ports[TCCRnA] := ports[TCCRnA] \/ TCCRnA.bits
-- ports[TCCRnB] := ports[TCCRnB] \/ TCCRnB.bits
ports[OCRnx] := 0
:
--}}}
More information about the developers
mailing list