.cdecls C,LIST, "msp430g2231.h" ;------------------------------------------------------------------------------ .text ; Progam Start ;***************************************************************************** ; MSP–FET430X110 Demo – Decode RC5 IR Remote Control / TX to PC @ 2400 ; ; Description: Decode 12–bit bi–phase RC5 format IR packet using Timer_A. ; Timer_A CCR1 is used to decode IR packet, capture mode to detect mid–bit ; edge and compare mode to latch data bit. CCR2 is used for decoder ; over–run detection. Received packet is TXed to PC using Timer_A CCR0 as ; a UART function. Packet sent as four ACII bytes, preceded by a CR and LF ; character. P1.0 is set if channel+ is RXed, reset if not. ; IR data are received MSB first. 2 Start, C and 11–bits of data. ; S1–S2–C–A4–A3–A2–A1–A0–C5–C4–C3–C2–C1–C0 ; ; Demonstrate with IR monitor – TX IRData as CR, LF, 4 ASCII Bytes ; ; MSP430F1121 ; ––––––––––––––––– ; /|\| XIN|– ; | | | 32kHz ; ––|RST XOUT|– ; | | ; IR Receiver–>|P1.2/CCR1 P1.0|––> LED ; | P1.1|––> 2400 8N1 ; ; Bit pattern as seen at MSP430 ; ; 1.78ms ; +––– +––– +––– –––– –––+ +––– ; | | | | | | | | | | | ; –––+ –––+ +––+––– +––+ +–––––+ +–– ; ^Start^Start^ 1 ^ 0 ^ 0 ^ ; ; CPU registers used RXTXData .equ R4 BitCnt .equ R5 IRData .equ R6 IRBit .equ R7 ; ; Conditions for 2400 Baud SW UART, ACLK = 32768 Bitime_5 .equ 06 ; .5 bit length + small adj. Bitime .equ 014 ; 427us bit length ~ 2341 baud ; mit1 .equ 039h ; my own LED0 .equ 001h ; LED0 on P1.0 TXD .equ 002h ; TXD on P1.1 IRIN .equ 004h ; IR input on P1.2 Bit_50 .equ 29 ; 890 us @ 32768 ACLK Bit_75 .equ 44 ; 1348 us @ 32768 ACLK Ch_up .equ 32 ; Ch_dwn .equ 33 ; LF .equ 0ah ; ASCII Line Feed CR .equ 0dh ; ASCII Carriage Return ; ; M. Buccini ; Texas Instruments, Inc ; July 2001 ;***************************************************************************** ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– .text ; Program Start ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– RESET mov.w #0280h,SP ; Initialize stackpointer call #Init_Sys ; Initialize System Peripherals ; Mainloop call #IR_Ready ; Ready IR decoder bis.w #LPM3,SR ; Enter LPMx, stop, save power call #TXIR_2_PC ; TX received command call #LED_Disp ; Test for Channel +/– jmp Mainloop ; ; ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– Init_Sys; Initialize System Peripherals ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT SetupTA mov.w #TASSEL0+MC1,&TACTL ; ACLK, continuous SetupC0 mov.w #OUT,&CCTL0 ; TXD Idle as Mark SetupP1 bis.b #IRIN+TXD,&P1SEL ; P1.2 CCR1, P1.1 CCR0 bis.b #LED0+TXD,&P1DIR ; P1.0, TXD outputs bic.b #LED0,&P1OUT ; P1.0, low, LED off eint ; ret ; Return from subroutine ; ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– IR_Ready; Subroutine to prepare to receive 12–bit RC5 into IRData ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– clr.w IRData ; mov.w #014,IRBit ; 12 data + 1 start + completion SetupC1 mov.w #CM1+SCS+CAP+CCIE,&CCTL1 ; CAP CCI1A, falling edge, int ret ; ; ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– TXIR_2_PC; Subroutine to send CR, LF and IRData as four ASCII bytes to PC ; R15 used as working register and not saved ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– mov #CR,RXTXData ; CR to UART buffer call #TX_Byte ; CR ––> PC/user mov #LF,RXTXData ; LF to UART buffer call #TX_Byte ; CR ––> PC/user ; TX_Word_ASCII; TX Word from IRData as four ASCII bytes swpb IRData ; IRData = 3412 call #TX_Byte_ASCII ; swpb IRData ; IRData = 1234 ; TX_Byte_ASCII; TX Byte from IRData as two ASCII bytes mov.b IRData,R15 ; transmit ..x. of value call #NUM_ASCIR ; mov.b IRData,R15 ; transmit ...x of value jmp NUM_ASCIA ; ; NUM_ASCIR rrc.b R15 ; 1. and 3. pass rrc.b R15 ; rrc.b R15 ; rrc.b R15 ; ; NUM_ASCIA and.b #0fh,R15 ; 2. and 4. pass add.b #030h,R15 ; cmp.b #03ah,R15 ; jlo NUM_End ; add.b #mit1,R15 ; NUM_End mov.b R15,RXTXData ; load transmit buffer, FALL ; ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– TX_Byte; Subroutine to TX Byte from RXTXData Buffer using CCR0 UART ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– mov.w &TAR,&CCR0 ; Current state of TA Counter add.w #Bitime,&CCR0 ; Some time till first bit bis.w #0100h, RXTXData ; Add mark stop bit to RXTXData rla.w RXTXData ; Add space start bit mov.w #10,BitCnt ; Load Bit Counter, 8 data + SP mov.w #OUTMOD0+CCIE,&CCTL0 ; TXD = mark = idle TX_Wait tst.w BitCnt ; Wait for TX completion jnz TX_Wait ; ;ret ; ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– TA0_ISR ; RXTXData Buffer holds UART Data. ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– add.w #Bitime,&CCR0 ; Time to Next Bit UART_TX bic.w #OUTMOD2,&CCTL0 ; TX Mark rra.w RXTXData ; LSB is shifted to carry jc TX_Test ; Jump ––> bit = 1 TX_Space bis.w #OUTMOD2,&CCTL0 ; TX Space TX_Test dec.w BitCnt ; All bits sent (or received)? jnz TX_Next ; Next bit? bic.w #CCIE,&CCTL0 ; All Bits TX/RX, Disable Int. TX_Next reti ; ; ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– TAX_ISR; Common ISR – CCR1–4 and overflow ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– add.w &TAIV,PC ; Add Timer_A offset vector reti ; CCR0 – no source jmp TA1_ISR ; CCR1 jmp TA2_ISR ; CCR2 ; reti ; CCR3 ; reti ; CCR4 ;TA_over reti ; Return from overflow ISR ; TA1_ISR bit.w #CAP,&CCTL1 ; jc RX_edge ; Jump –> Edge captured ; RX_Bit dec.w IRBit ; jz RX_Comp ; Test of end of packet RX_Cont bit.w #SCCI,&CCTL1 ; Carry = Data bit in SCCI rlc.w IRData ; Carry –> IRData mov.w #CM1+CM0+CAP+CCIE+SCS,&CCTL1 ; CAP CCI1A,both edges, int push.w &CCR1 ; Max time till next edge add.w #Bit_50,0(SP) ; pop.w &CCR2 ; mov.w #CCIE,&CCTL2 ; Enable timeout interrupt ;reti ; RX_Comp clr.w &CCTL1 ; Disable CCR1 and.w #0FFFh,IRData ; Isolate 12–bit packet mov.w #GIE,0(SP) ; Decode = Active in Mainloop ;reti ; RX_edge clr.w &CCTL2 ; Disable CCR2 timeout mov.w #CCIE,&CCTL1 ; Compare mode w/ int. add.w #Bit_75,&CCR1 ; Time to middle of data bit ;reti ; TA2_ISR clr.w &CCTL2 ; Disable CCR2 timeout call #IR_Ready ; ERROR – restart RX sequence reti ; Return from interrupt ; ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– LED_Disp; LED0 (P1.0) set if IRData = Channel+ code (32) ;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– and.w #03Fh,IRData ; Isolate 6–bit command code LED_off bic.b #01h,&P1OUT ; LED0 off LED0_tst cmp.w #Ch_up,IRData ; Test for Channel+ (32) jne LED_exit ; bis.b #01h,&P1OUT ; LED0 on LED_exit ret ; Return from subroutine ;------------------------------------------------------------------------------ ; Interrupt Vectors ;------------------------------------------------------------------------------ .sect ".reset" ; MSP430 RESET Vector .short RESET ; .sect ".int09" ; Timer_A0 Vector .short TA0_ISR ; .end