'-------------------------------------------------------------------------------
Option Explicit

' BX-01 definitions.
'>>Public Const PinOC1A As Byte = 15
'>>Public Const PinOC1B As Byte = 29

' BX-24 definitions.
Public Const PinOC1A As Byte = 26  ' Also green LED.
Public Const PinOC1B As Byte = 27

' BX-35 definitions.
'>>Public Const PinOC1A As Byte = 19
'>>Public Const PinOC1B As Byte = 18
'-------------------------------------------------------------------------------
Sub Main()

' This program exercises the PWM capability of pins OC1A and OC1B. The
' duty cycle of OC1A is cycled from 0 % to 100 % in increments of 10 %,
' with a 1 second delay between each change. OC1B is handled similarly
' except with an inverted duty cycle.
'
' Warning -- the Com2 serial port should not be used in this program because
' of conflicts with Timer1.

    Dim i As Integer
    Dim DutyCycle As Single

    Debug.Print "Dual PWM demonstration"

    Call InitializePWM(5)

    Do
        For i = 0 To 10

            DutyCycle = CSng(i) / 10.0

            ' OCR1A gets the normal duty cycle.
            Call PutPinPWM(PinOC1A, DutyCycle)

            ' OCR1B gets an inverted duty cycle.
            Call PutPinPWM(PinOC1B, 1.0 - DutyCycle)

            ' Display the duty cycle value (percent).
            Debug.Print CStr( CInt(DutyCycle * 100.0) ); " %"

            Call Delay(1.0)
        Next
    Loop

End Sub
'-------------------------------------------------------------------------------
Public Sub InitializePWM( _
    ByVal RateSetting As Byte)

    Const PWMmode8bit  As Byte = bx0000_0001
    Const PWMmode9bit  As Byte = bx0000_0010
    Const PWMmode10bit As Byte = bx0000_0011
    Const PWMmodeOff   As Byte = bx0000_0000

    Const MaskOC1A As Byte = bx1000_0000
    Const MaskOC1B As Byte = bx0010_0000

    ' Turn off Timer1.
    Register.TCCR1B = 0

    ' Set Timer1 to 8-bit PWM mode.
    Register.TCCR1A = PWMmode8bit

    ' Initialize pin directions.
    Call PutPin(PinOC1A, bxOutputLow)
    Call PutPin(PinOC1B, bxOutputLow)

    ' Clear duty cycles on both OCR1A and OCR1B pins.
    Register.OCR1AH = 0
    Register.OCR1AL = 0

    Register.OCR1BH = 0
    Register.OCR1BL = 0

    ' Start Timer1 according to the specified rate setting.
    Register.TCCR1B = RateSetting

    ' Enable PWM for both pins.
    Register.TCCR1A = Register.TCCR1A Or MaskOC1A
    Register.TCCR1A = Register.TCCR1A Or MaskOC1B

End Sub
'-------------------------------------------------------------------------------
Public Sub PutPinPWM( _
    ByVal PinNumber As Byte, _
    ByVal DutyCycle As Single)

' This procedure starts a PWM pulse train on the specified pin number. The
' nondimensional DutyCycle should be in range 0.0 to 1.0.

    Dim iDutyCycle As Byte

    ' Scale and enforce range constraints.
    If (DutyCycle < 0.0) Then
        iDutyCycle = 0
    ElseIf (DutyCycle > 1.0) Then
        iDutyCycle = 255
    Else
        iDutyCycle = FixB((DutyCycle * 255.0) + 0.5) ' Round off.
    End If

    ' Set the proper pin.
    If (PinNumber = PinOC1A) Then
        Register.OCR1AH = 0
        Register.OCR1AL = iDutyCycle
    ElseIf (PinNumber = PinOC1B) Then
        Register.OCR1BH = 0
        Register.OCR1BL = iDutyCycle
    End If

End Sub
'-------------------------------------------------------------------------------
