001#include "reg51.h"
002#include "irq52.h"
003#include <stdio.h>
004
005near unsigned int       RC5_Word;
006     unsigned char bit  RC5_LastBit;
007near unsigned char      RC5_Timer;
008near unsigned char      RC5_BitCount;
009     unsigned char bit  RC5_Valid;
010     unsigned char bit  RC5_MediumBit;
011near unsigned char      RC5_Command;
012near unsigned char      RC5_System;
013
014IRQ_VECTOR(int1,IRQ_INT1)
015
016void int1 (void) interrupt                  //Routine for decoding RC5. Works but could use some refining.
017{
018    //Puls from 1 to 0 detected, depending on the timing from the last puls a bit is decoded.
019    #asm
020                PUSH    PSW
021                PUSH    ACC
022                MOV     A,_RC5_Timer
023                MOV     _RC5_Timer,#255     //Reset timer to calculate next RC5 bit timing
024                CPL     A                   //Timing is negative so make it positive "makes it easier to understand"
025                CLR     C                   //Carry flag need to be 0 before subtracting with borrow
026                SUBB    A,#44               //Timer <44 short lenght pulse detected. No bit change
027                JC      RC5_ShortPulse      //The Timer is smaller than 44. Carry was set.
028                SUBB    A,#18               //Timer <62 medium length pulse detected. 001 or 100 sequence     
029                JC      RC5_MediumPulse
030                SUBB    A,#18               //Timer <80 long length pulse detected. Bit change.
031                JC      RC5_LongPulse
032                MOV     A,_RC5_BitCount     //End of 13 bits. Check if last bit was detected
033                CJNE    A,#12,RC5_13Bits    //Last bit detected?. If not add a zero bit to the sequence
034                CLR     _RC5_LastBit
035                ACALL   RC5_ShiftBit        //Add a zero bit
036                MOV     A,_RC5_BitCount     //End of 13 bits. Check if last bit was detected
037RC5_13Bits:     CJNE    A,#13,RC5_Error     //We started halfway the RC5 code.  Try again.
038                MOV     A,_RC5_Word         //Calculate Command en System codes.
039                ANL     A,#0x3F
040                MOV     _RC5_Command,A
041                MOV     A,_RC5_Word
042                RL      A
043                RL      A
044                ANL     A,#0x03
045                MOV     _RC5_System,A
046                MOV     A,_RC5_Word+1
047                ANL     A,#0x1f
048                RL      A
049                RL      A
050                ORL     _RC5_System,A
051                SETB    _RC5_Valid          //RC5 is valid and ready to be read.
052
053RC5_Error:      SETB    _RC5_LastBit        //Clear variables to default values
054                MOV     _RC5_BitCount,#0
055                CLR     _RC5_MediumBit
056
057RC5_Ok:         POP     ACC
058                POP     PSW
059                RETI
060
061RC5_ShiftBit:   MOV     A,_RC5_Word         //Make room for the next received bit
062                MOV     C,_RC5_LastBit      //Copy lastbit value into the 16 bit register
063                RLC     A               
064                MOV     _RC5_Word,A
065                MOV     A,_RC5_Word+1
066                RLC     A
067                MOV     _RC5_Word+1,A
068                INC     _RC5_BitCount
069                RET
070    
071RC5_MediumPulse:CPL     _RC5_MediumBit      //First medium bit adds 2 bits Second only 1 bit
072                MOV     C,_RC5_MediumBit     
073                JNC     RC5_2ndMBit
074                MOV     C,_RC5_LastBit
075                JNC     RC5_001
076                CLR     _RC5_LastBit
077                ACALL   RC5_ShiftBit
078                ACALL   RC5_ShiftBit
079                SJMP    RC5_Ok
080RC5_001:        CLR     _RC5_LastBit
081                ACALL   RC5_ShiftBit
082RC5_2ndMBit:    CPL     _RC5_LastBit        //Copy lastbit and then inverted lastbit into RC5_Word
083                ACALL   RC5_ShiftBit
084                SJMP    RC5_Ok
085
086RC5_LongPulse:  CPL     _RC5_LastBit        //2 Bits received. Either 101 or 010 sequence
087                ACALL   RC5_ShiftBit
088                CPL     _RC5_LastBit
089RC5_ShortPulse: ACALL   RC5_ShiftBit                
090                SJMP    RC5_Ok
091        #endasm
092}
093
094void RC5_Init (void)        //Make RC5 receiption possible. 
095{
096    IT1 =1;      // EXT1 is edge-triggered
097    PX1 =0;      // EXT1 2nd highest priority interrupt
098    EX1 =1;      // Enable external 1 interrupt
099}
100
101void RC5_Test (void)        //For checking what codes the RC5 produces.
102{
103    if (RC5_Valid)
104    {
105        printf("RC5 command:%X  sys:%X\r\n",RC5_Command,RC5_System);
106        RC5_Valid=0;
107    }
108}
109
110char RC5_GetCommand(void)   //Check if a new Command code is available, returns 255 if not.
111{
112    if (RC5_Valid)
113    {
114        RC5_Valid=0;
115        return RC5_Command;
116    }
117    else return 255;
118}
119
120char RC5_GetSystem(void)    //Read the last valid System code.
121{
122    return RC5_System;
123}
124
125char RC5_PeekCommand(void)  //Read the last valid Command code.
126{
127    return RC5_Command;
128}