;-------------------------------------------------------------------------------
; Set up Timer A
;-------------------------------------------------------------------------------
SetupTA mov.w #CCIE,&CCTL0 ; CCR0 interrupt enabled
bit.b #001h,Option ;
jz BlinkClk ;
mov.w Blk_Clk,R4 ;
mov.w R4,&CCR0 ; Set TACCR0 for ramp up period
jmp TAGo ;
BlinkClk mov.w Blk_Clk,R4 ;
mov.w R4,&CCR0 ; Set TACCR0 for ramp up period for Blinker
TAGo mov.w #0210h,&TACTL ; SMCLK, Upmode
;-------------------------------------------------------------------------------
; Main program - turns on LED and then shuts off CPU and waits for interrupts
;-------------------------------------------------------------------------------
Mainloop mov.b #007h,&P1OUT ; Turn LED on
bis.w #CPUOFF+GIE,SR ; CPU off, interrupts enabled
nop ; Required only for debugger
;
;-------------------------------------------------------------------------------
TA0_ISR; Timer A Interrupt Routine
;-------------------------------------------------------------------------------
bic.w #00030h,TACTL ; turn off Timer A
mov.w TAR,R4 ; Save current TimerA value
bit.b #001h,Option ; Fader or Blinker Mode?
jz BlinkMode ; If Blink Mode, jump to BlinkMode
;-------------------------------------------------------------------------------
; Fader Mode
; Duty Cycle and Period Testing Channel A -- LED is On during D, Off during 1-D
;-------------------------------------------------------------------------------
FadeMode bit.b #004h,Option ; Walk Thru Mode?
jz ChA ; No?, Then Goto Normal Fader Routine
cmp.w LoopCtr,WlkCtr ; Has Loop Count been passed?
jn ChA ; No, Goto Fader Mode
FdPh1 cmp.b #000h,FdWlkCtr ; If 0, then Phase=0
jne FdPh2 ; Not 0? Then goto FdPh2
inc.b FdWlkCtr ; Increment the Fade Walk Counter
mov.w NoPhase,Phase ; Set Phase to 0
mov.b #007h,Ctrl ; Set Bits in Ctrl Register (U/D bits)
clr.w DutyLEDA ; Clear Duty Cycle for LED A
clr.w DutyLEDB ; Clear Duty Cycle for LED B
clr.w DutyLEDC ; Clear Duty Cycle for LED C
add.w Phase,DutyLEDB ; Set initial Duty Cycle Ch B
jmp PreA ;
FdPh2 cmp.b #001h,FdWlkCtr ; If 1, then 3 Ch Phasing
jne FdPh3 ;
inc.b FdWlkCtr ; Increment FdWlkCtr
mov.w PhsAng2,Phase ; Set 2 Ch Phasing
mov.b #007h,Ctrl ; Set Bits in Ctrl Register (U/D bits)
clr.w DutyLEDA ; Clear Duty Cycle for LED A
clr.w DutyLEDB ; Clear Duty Cycle for LED B
clr.w DutyLEDC ; Clear Duty Cycle for LED C
add.w Phase,DutyLEDB ; Set initial Duty Cycle Ch B
jmp PreA ;
FdPh3 clr.b FdWlkCtr ; If FdWlkCtr <> 0 or 1, then it is 2
mov.w PhsAng3,Phase ; Set 3 Ch phasing
mov.b #007h,Ctrl ; Set Bits in Ctrl Register (U/D bits)
clr.w DutyLEDA ; Clear Duty Cycle for LED A
clr.w DutyLEDB ; Clear Duty Cycle for LED B
clr.w DutyLEDC ; Clear Duty Cycle for LED C
add.w Phase,DutyLEDB ; Set initial Duty Cycle Ch B
add.w Phase,DutyLEDC ; Set initial Duty Cycle Ch C
bic.b #004h,Ctrl ; Set DutyC to decrement
PreA clr.w WlkCtr ; Clear Walk Thru Counter
bic.b #001h,Option ; End Fader Mode
bis.b #002h,Option ; Start Blinker Mode
ChA cmp.w PerLED,PerCtr ; Test if LED Period reached
jn ChkDutyA ; Jump if NOT reached (ChAPerCtr < PerLED)
bis.b #008h,Ctrl ; Set LED Period Check flag
clr.w PerCtr ; Period reached, count from 0 again
jmp LEDs_ON ; Period reached, Turn LEDs On
ChkDutyA cmp.w DutyLEDA,PerCtr ; Test if Duty Cycle A reached
jn LEDA_ON ; Jump if NOT reached (PerCtr < DutyLEDA)
LEDA_OFF bic.b #001h,&P1OUT ; Turn LED A OFF
jmp ChkDutyB ; Jump to look at Duty Cycle B
LEDA_ON bis.b #001h,P1OUT ; Turn LED A On
ChkDutyB cmp.w DutyLEDB,PerCtr ; Test if Duty Cycle B reached
jn LEDB_ON ; Jump if NOT reached (PerCtr < DutyLEDB)
LEDB_OFF bic.b #002h,&P1OUT ; Turn LED B OFF
jmp ChkDutyC ; Jump to look at Duty Cycle C
LEDB_ON bis.b #002h,P1OUT ; LED B On
ChkDutyC cmp.w DutyLEDC,PerCtr ; Test if Duty Cycle C reached
jn LEDC_ON ; Jump if NOT reached (PerCtr < DutyLEDC)
LEDC_OFF bic.b #004h,&P1OUT ; Turn LED C Off
jmp ChkMainPer ; Jump to look at Main Period
LEDC_ON bis.b #004h,P1OUT ; LED A On
jmp ChkMainPer ; Jump to look at Main Period
LEDs_ON bis.b #007h,&P1OUT ; Turn LEDA, B, C On
;-------------------------------------------------------------------------------
; Look at the Duty Cycle and Increment/Decrement if necessary
;-------------------------------------------------------------------------------
ChkMainPer cmp.w Period,Counter ; Test if counter has reached max
jn CtrIncr ; If NOT, then goto increment counter
clr.w Counter ; Counter reached max, reset to zero
inc.w PerCtr ; Increment Period Counter
jmp DutyDir ; Done, Check LED Duty Cycle
CtrIncr inc.w Counter ; Increment Ch A counter
DutyDir bit.b #008h,Ctrl ; Was the LED Period reached?
jz EndInt ; If, NOT reached, then End Interrupt
ChkDtyA bit.b #001h,Ctrl ; Is Duty Cycle A Incrementing?
jz ChkDutyALow ; If not, Check if Duty Cycle = 0
cmp.w PerLED,DutyLEDA ; Is Duty Cycle < Period?
jn DutyAIncr ; If Yes, go to increment Duty Cycle
bic.b #001h,Ctrl ; If No, then Duty Max'd, Clr Incr Bit
inc.w WlkCtr ; Walk Thru Counter Increment
jmp DutyADecr ; Jump to Decrement Duty Cycle
ChkDutyALow cmp.w #00000h,DutyLEDA ; Is Duty Cycle at its minimum?
jne DutyADecr ; No, then goto decrement Duty Cycle
bis.b #001h,Ctrl ; Set to increment Duty Cycle
DutyAIncr inc.w DutyLEDA ; Increment Duty Cycle
jmp ChkDtyB ; Jump to Clear Check Duty Cycle B
DutyADecr dec.w DutyLEDA ; Decrement Duty Cycle A
ChkDtyB bit.b #002h,Ctrl ; Is Duty Cycle B Incrementing?
jz ChkDutyBLow ; If not, Check if Duty Cycle = 0
cmp.w PerLED,DutyLEDB ; Is Duty Cycle < Period?
jn DutyBIncr ; If Yes, go to increment Duty Cycle
bic.b #002h,Ctrl ; If No, then Duty Max'd, Clr Incr Bit
inc.w WlkCtr ; Walk Thru Counter Increment
jmp DutyBDecr ; Jump to Decrement Duty Cycle
ChkDutyBLow cmp.w #00000h,DutyLEDB ; Is Duty Cycle at its minimum?
jne DutyBDecr ; No, then goto decrement Duty Cycle
bis.b #002h,Ctrl ; Set to increment Duty Cycle
DutyBIncr inc.w DutyLEDB ; Increment Duty Cycle
jmp ChkDtyC ; Jump to Clear Check Duty Cycle C
DutyBDecr dec.w DutyLEDB ; Decrement Duty Cycle B
ChkDtyC bit.b #004h,Ctrl ; Is Duty Cycle C Incrementing?
jz ChkDutyCLow ; If not, Check if Duty Cycle = 0
cmp.w PerLED,DutyLEDC ; Is Duty Cycle < Period?
jn DutyCIncr ; If Yes, go to increment Duty Cycle
bic.b #004h,Ctrl ; If No, then Duty Max'd, Clr Incr Bit
inc.w WlkCtr ; Walk Thru Counter Increment
jmp DutyCDecr ; Jump to Decrement Duty Cycle
ChkDutyCLow cmp.w #00000h,DutyLEDC ; Is Duty Cycle at its minimum?
jne DutyCDecr ; No, then goto decrement Duty Cycle
bis.b #004h,Ctrl ; Set to increment Duty Cycle
DutyCIncr inc.w DutyLEDC ; Increment Duty Cycle
jmp EndInt ; Jump to End Interrupt
DutyCDecr dec.w DutyLEDC ; Decrement Duty Cycle C
jmp EndInt ; Jump to End Interrupt
;-------------------------------------------------------------------------------
; End Fader Mode
;-------------------------------------------------------------------------------
; Blink Mode
;-------------------------------------------------------------------------------
BlinkMode bit.b #004h,Option ; Is Walk Thru Mode Set?
jz Blk_Per ; No? Then Go to Normal Routine
cmp.w LoopCtr,WlkCtr ; Has Loop Count been hit?
jne Blk_Per ; No, Goto Current Blink Mode
clr.w WlkCtr ; Clear Walk Thru Counter
bit.w #00001h,BlinkCfg ; Current Blink Mode All?
jz BlkWlkFwd ; No? See if it is Fwd Mode
bic.w #0000fh,BlinkCfg ; End All Blink Mode
bis.w #00002h,BlinkCfg ; Start Fwd Mode
jmp Blk_Per ; Goto Current Blink Mode
BlkWlkFwd bit.w #00002,BlinkCfg ; Is Current Blink Mode Fwd?
jz BlkWlkRev ; No? See if it is Rev Mode
bic.w #0000fh,BlinkCfg ; End Fwd Mode
bis.w #00004h,BlinkCfg ; Start Rev Mode
jmp Blk_Per ; Goto Current Blink Mode
BlkWlkRev bit.w #00004,BlinkCfg ; Is Current Blink Mode Fwd?
jz BlkWlkPhs ; No? Must be Phase Mode, Go there
bic.w #0000fh,BlinkCfg ; End Rev Mode
bis.w #00008h,BlinkCfg ; Start Phase Mode
jmp Blk_Per ; Goto Current Blink Mode
BlkWlkPhs bic.w #0000fh,BlinkCfg ; End Phase Mode
bis.w #00001h,BlinkCfg ; Start All Blink Mode
bic.b #002h,Option ; End Blink Mode
bis.b #001h,Option ; Start Fader Mode
Blk_Per cmp.w BlkPer,BlkCtr ; Has Counter Reached Period?
jne EndBlk ; If NO, then goto increment counter
clr.w BlkCtr ; If Yes, then Clear Counter
inc.w WlkCtr ; Increment Walk Counter (only used in walk thru mode)
AllBlk bit.w #00001h,BlinkCfg ; All Blink?
jz ChkFwd ;
bit.w #00100h,BlinkCfg ; LEDs On? (Only need to check if one is on)
jz BlkAllOn ; If Off, then turn them On
BlkAllOff bic.w #00700h,BlinkCfg ; Else, turn them all off
jmp LEDsA
BlkAllOn bis.w #00700h,BlinkCfg ; Set All LEDs to ON
jmp LEDsA ;
ChkFwd bit.w #00002h,BlinkCfg ; Forward Chase?
jz ChkRev ;
bit.w #00100h,BlinkCfg ; LEDA on?
jz FwdCkB ; No, Check LEDB
bic.w #00500h,BlinkCfg ; LEDA Off (turn LEDC off for good measure)
bis.w #00200h,BlinkCfg ; LEDB On
jmp LEDsA ;
FwdCkB bit.w #00200h,BlinkCfg ; LEDB on?
jz FwdC ; No, Then C Must be On, Jump There
bic.w #00300h,BlinkCfg ; LEDB Off (turn LEDA off for good measure)
bis.w #00400h,BlinkCfg ; LEDC On
jmp LEDsA ;
FwdC bic.w #00600h,BlinkCfg ; LEDC Off (turn LEDB off for good measure)
bis.w #00100h,BlinkCfg ; LEDA On
jmp LEDsA ;
ChkRev bit.w #00004h,BlinkCfg ; Reverse Chase?
jz BlinkPhase ; If not, then it must be Blink Out of Phase
bit.w #00100h,BlinkCfg ; LEDA on?
jz RevCkC ; No, Check LEDC
bic.w #00300h,BlinkCfg ; LEDA Off (turn LEDB off for good measure)
bis.w #00400h,BlinkCfg ; LEDC On
jmp LEDsA ;
RevCkC bit.w #00400h,BlinkCfg ; LEDC on?
jz RevB ; No, Then B Must be On, Jump There
bic.w #00500h,BlinkCfg ; LEDC Off (turn LEDA off for good measure)
bis.w #00200h,BlinkCfg ; LEDB On
jmp LEDsA ;
RevB bic.w #00600h,BlinkCfg ; LEDB Off (turn LEDC off for good measure)
bis.w #00100h,BlinkCfg ; LEDA On
jmp LEDsA ;
BlinkPhase bit.w #00100h,BlinkCfg ; Is LEDA On?
jz BlkPhsB ; NO - LEDB is On, Goto Turn LEDA On with LEDC
BlkPhsAC bic.w #00500h,BlinkCfg ; Turn LEDA and LEDC Off
bis.w #00200h,BlinkCfg ; Turn LEDB On
jmp LEDsA ;
BlkPhsB bic.w #00200h,BlinkCfg ; Turn LEDB Off
bis.w #00500h,BlinkCfg ; Turn LEDs A and C On
LEDsA bit.w #00100h,BlinkCfg ; Is LEDA to be ON?
jz LEDsAoff ; No, Goto Turn A Off
bis.b #001h,&P1OUT ; Turn LEDA On
jmp LEDsB ;
LEDsAoff bic.b #001h,&P1OUT ; Turn LEDA Off
LEDsB bit.w #00200h,BlinkCfg ; Is LEDB to be ON?
jz LEDsBoff ; No, Goto Turn B Off
bis.b #002h,&P1OUT ; Turn LEDB On
jmp LEDsC ;
LEDsBoff bic.b #002h,&P1OUT ; Turn LEDB Off
LEDsC bit.w #00400h,BlinkCfg ; Is LEDC to be ON?
jz LEDsCoff ; No, Goto Turn C Off
bis.b #004h,&P1OUT ; Turn LEDC On
jmp EndInt ;
LEDsCoff bic.b #004h,&P1OUT ; Turn LEDC Off
jmp EndInt ;
EndBlk inc.w BlkCtr ; Increment Counter
;-------------------------------------------------------------------------------
; End of Interrupt Routine