[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