\ IR_RC5_to_I2CF_Soft_Master.f \ Copyright (C) <2016> \ \ This program is free software: you can redistribute it and/or modify \ it under the terms of the GNU General Public License as published by \ the Free Software Foundation, either version 3 of the License, or \ (at your option) any later version. \ \ This program is distributed in the hope that it will be useful, \ but WITHOUT ANY WARRANTY\ without even the implied warranty of \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \ GNU General Public License for more details. \ \ You should have received a copy of the GNU General Public License \ along with this program. If not, see . \ --------------------------------------\ \ example of App running under interrupt \ --------------------------------------\ \ FORTH driver for IR remote compatible with the PHILIPS RC5 protocol, with select new/repeated command \ target : any MSP430FRxxxx @ 8Mhz \ prerequisites : your launchpad is wired as described in launchpad.pat file : UART0, Soft_Master(SDA,SCL), IR_RC5 parts. \ FastForth runs @ 8MHz \ add 3k3 pull up resistors on SDA and SCL lines. \ usage : create a logical network drive ( a: b: ...as you want) from your local copy of Gitlab FAST FORTH \ with scite.exe open this file MSP430-FORTH\IR_RC5_to_I2CF_Soft_Master.f, \ select "tools" menu, "preprocess" item 1 (CTRL+0), \ a dialog box asks you for 4 parameters $(1) to $(4), \ in the 2th param. field, type your launchpad to select the launchpad.pat to be used : for example MSP_EXP430FR5969, \ result : the word START starts the app that runs under LPMx. \ to recover the console input (i.e. to quit LPMx), type a space. Then you can enter a command, for example STOP. \ select one initial state : WIPE \ to suppress any previous app \ RST_STATE \ to conserve the previous app protected against \ PWR_STATE \ to conserve the previous app protected against POWER OFF NOECHO \ comment if an error occurs, to detect it with new download \ HERE \ uncomment for a dump, part 1 \ \ -------------------------------------------------------------------------------------------------------------------\ \ I2CF Soft MASTER driver, FAST MODE, 8MHz \ -------------------------------------------------------------------------------------------------------------------\ VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0 2 ALLOT \ data1,data2 VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0 2 ALLOT \ data1,data2 \ \ ------------------------------\ ASM I2C_MTX \ MASTER TX \ shared code for address and TX data \ ------------------------------\ BEGIN \ ADD.B X,X \ 1 l shift one left U>= IF \ 2 l carry set ? BIC.B #MSDA,&I2CSM_DIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor ELSE \ 2 l BIS.B #MSDA,&I2CSM_DIR \ 4 l no : SDA as output ==> SDA low THEN \ l _ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high) BEGIN \ 14/16~l BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released 0<> UNTIL \ 2 h _ BIS.B #MSCL,&I2CSM_DIR \ 4 h v_ SCL as output : force SCL low SUB #1,W \ 1 l count of bits 0= UNTIL \ 2 l BIC.B #MSDA,&I2CSM_DIR \ 5 l _ SDA as input : release SDA high to prepare read Ack/Nack RET ENDASM \ \ \ ******************************\ \ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use \ ******************************\ ASM INT_RC5 \ wake up on P1.2 change interrupt \ IP,TOS,W,X,Y are free for use \ ------------------------------\ BIC #$F8,0(RSP) \ SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPMx_LOOP with pending interrupt \ BIC #$B8,0(RSP) \ {SCG1,OSCOFF,CPUOFF,GIE}=OFF after RETI to force goto label "LPMx_LOOP" with any pending interrupt \ ------------------------------\ \ define LPM mode for ACCEPT \ uncomment a line \ ------------------------------\ \ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx \ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2 \ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value \ ------------------------------\ \ \ in : SR(9)=old Toggle bit memory (ADD on) \ \ SMclock = 8|16|24 MHz \ \ use : IP,TOS,W,X,Y, TA0 timer, TA0R register \ \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0 \ \ SR(9)=new Toggle bit memory (ADD on) \ ------------------------------\ \ RC5_FirstStartBitHalfCycle: \ \ ------------------------------\ MOV #0,&TA0EX0 \ predivide by 1 in TA0EX0 register ( 8 MHZ), reset value \ MOV #1,&TA0EX0 \ predivide by 2 in TA0EX0 register (16 MHZ) \ MOV #2,&TA0EX0 \ predivide by 3 in TA0EX0 register (24 MHZ) MOV #1778,X \ RC5_Period in us MOV #14,W \ count of loop BEGIN \ \ ------------------------------\ \ RC5_TopSynchro: \ <--- loop back ---+ with readjusted RC5_Period \ ------------------------------\ | here, we are just after 1/2 RC5_cycle MOV #%1011100100,&TA0CTL \ (re)start timer_A | SMCLK/8 : 2us time interval,free running,clear TA0_IFG and TA0R \ RC5_Compute_3/4_Period: \ | RRUM #1,X \ X=1/2 cycle | MOV X,Y \ Y=1/2 ^ RRUM #1,Y \ Y=1/4 ADD X,Y \ Y=3/4 \ RC5_Wait_1_1/4 \ wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle+1 BEGIN CMP Y,&TA0R \ CMP &TA0R with 3/4 cycle value 0= UNTIL \ \ ------------------------------\ \ RC5_Sample: \ at 5/4 cycle, we can sample RC5_input, ST2/C6 bit first \ ------------------------------\ BIT.B #RC5,&IR_IN \ C_flag = IR bit ADDC IP,IP \ C_flag <-- IP(15):IP(0) <-- C_flag MOV &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change SUB #1,W \ decrement count loop \ \ count = 13 ==> IP = x x x x x x x x |x x x x x x x /C6 \ \ count = 0 ==> IP = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1 0<> WHILE \ ----> out of loop ----+ \ RC5_compute_7/4_Time_out: \ | ADD X,Y \ | out of bound = 7/4 period \ RC5_WaitHalfCycleP1.2_IFG: \ | BEGIN \ | CMP Y,&TA0R \ | TA0R = 5/4 cycle test 0>= IF \ | if cycle time out of bound BIC #$30,&TA0CTL \ | stop timer_A0 RETI \ | then quit to do nothing THEN \ | \ ------------------------------\ | BIT.B #RC5,&IR_IFG \ ^ | test P1.2_IFG 0<> UNTIL \ | | MOV &TA0R,X \ | | get new RC5_period value REPEAT \ ----> loop back --+ | \ ------------------------------\ | \ RC5_SampleEndOf: \ <---------------------+ \ ------------------------------\ MOV #$30,&TA0CTL \ stop timer_A0 RLAM #1,IP \ IP = x /C6 Tg A4 A3 A2|A1 A0 C5 C4 C3 C2 C1 C0 1 0 \ ******************************\ \ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit \ ******************************\ MOV @RSP,X \ retiSR(9) = old RC5 toggle bit RLAM #4,X \ retiSR(11,10,9)= X(11,10,9) --> X(15,14,13) XOR IP,X \ (new XOR old) Toggle bit (13) BIT #BIT13,X \ X(13) = New_RC5_command 0= IF RETI \ case of repeated RC5_command : RETI without SR(9) change THEN \ XOR #UF1,0(RSP) \ change Toggle bit memory, User Flag 1 = SR(9) \ ******************************\ \ RC5_ComputeNewRC5word \ \ ******************************\ MOV.B IP,S \ S = C5 C4 C3 C2 C1 C0 0 0 RRUM #2,S \ S = 0 0 C5 C4 C3 C2 C1 C0 \ ******************************\ \ RC5_ComputeC6bit \ \ ******************************\ BIT #BIT14,IP \ test /C6 bit in IP 0= IF BIS #BIT6,S \ set C6 bit in S THEN \ S = 0 C6 C5 C4 C3 C2 C1 C0 \ ******************************\ \ RC5_CommandByteIsDone \ RC5_code -- \ ******************************\ \ ------------------------------\ \ Prepare I2C_MASTER \ \ ------------------------------\ SWPB S \ 1 high byte = data ADD #1,S \ 1 low byte = count MOV S,&I2CM_BUF \ 3 MOV #%0010100,&I2CS_ADR \ MSP-EXP430FRxxx I2C slave address \ ------------------------------\ \ echo code to terminal option \ \ ------------------------------\ \ SUB #2,PSP \ MOV TOS,0(PSP) \ MOV.B S,TOS \ LO2HI \ cr ." $" HEX 2 U.R \ HI2LO \ ==================================\ \ CODE I2C_M \ fast I2C soft Master, only 8 MHz \ ==================================\ \ \ in I2CS_ADR/I2CM_BUF as RX/TX buffer requested by I2CS_ADR(0(0)) \ \ I2CS_ADR(0) = I2C_Slave_addr&R/w \ \ I2CM_BUF(0) = TX/RX count of datas \ \ I2CM_BUF(0) = 0 ==> send only I2C address \ \ used S BUF ptr \ \ T datas countdown \ \ W bits countdown \ \ X data \ \ out I2CSLA_ADR & (R/W) unCHNGd \ \ S = BUF PTR pointing on first data not exCHNGd \ \ T = count+1 of TX/RX datas exCHNGd \ \ I2CS_ADR(0) = unCHNGd \ \ I2CM_BUF(0) = count of data not exCHNGd (normally = 0) \ \ I2CM_BUF(0) = -1 <==> Nack on address \ ----------------------------------\ \ I2C_MR_DC_ListenBeforeStart: \ test if SCL & SDA lines are idle (high) \ ----------------------------------\ BIC.B #M_BUS,&I2CSM_DIR \ SDA & SCL pins as input BIC.B #M_BUS,&I2CSM_OUT \ preset output LOW for SDA & SCL pins MOV #2,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 8 MHz \ MOV #4,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 16 MHz \ MOV #6,T \ I2C_MR_DC_Wait_Start_Loop = 8 µs @ 24 MHz BEGIN \ BEGIN \ BEGIN \ BIT.B #MSCL,&I2CSM_IN \ 4 P1DIR.3 SCL high ? 0<> UNTIL \ 2 BIT.B #MSDA,&I2CSM_IN \ 4 P1IN.2 SDA high ? 0<> UNTIL \ 2 SUB #1,T \ 1 0= UNTIL \ 2 here the I2C bus is idle \ ----------------------------------\ \ I2C_Master_Start_Cond: \ here, SDA and SCL are in idle state \ ----------------------------------\ BIS.B #MSDA,&I2CSM_DIR \ 4 l force SDA as output (low) MOV #I2CM_BUF,W \ 2 h W=buffer out MOV.B @W+,T \ 2 h T=datas countdown MOV #I2CS_ADR,S \ 2 h S=buffer in MOV.B @S+,X \ 2 h X=Slave address to TX BIT.B #1,X \ 1 h test I2C R/w flag 0= IF \ 2 h if write MOV W,S \ 2 h S= buffer out ptr THEN \ S= buffer ptr BIS.B #MSCL,&I2CSM_DIR \ 4 h force SCL as output (low) \ ----------------------------------\ \ I2C_Master_Start_EndOf: \ \ ----------------------------------\ \ I2C_Master_Send_address \ may be SCL is held low by slave \ ----------------------------------\ ADD #1,T \ 1 l to add address in count MOV #8,W \ 1 l prepare 8 bit Master writing CALL #I2C_MTX \ 21 l to send address \ ----------------------------------\ \ I2C_Master_Loop_Data \ \ ----------------------------------\ BEGIN \ 4 l here ack/nack is received/transmitted \ --------------------------------\ l \ Master TX/RX ACK/NACK \ \ --------------------------------\ l _ BIC.B #MSCL,&I2CSM_DIR \ 3 l _^ release SCL (high) BEGIN \ BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released 0<> UNTIL \ 2 h BIT.B #MSDA,&I2CSM_IN \ 3 h _ get SDA BIS.B #MSCL,&I2CSM_DIR \ 3 h v_ SCL as output : force SCL low \ --------------------------------\ l \ I2C_Master_Loop_Data \ \ --------------------------------\ 0<> IF BIS #Z,SR \ 5 l if Nack (TX), force Z=1 ==> StopCond ELSE SUB.B #1,T \ 3 l else dec count THEN \ l \ --------------------------------\ \ I2C_Master_CheckCountDown \ count=0 (TX) or Nack received \ --------------------------------\ 0= IF \ 2 l send stop \ ----------------------------\ \ Send Stop \ \ ----------------------------\ _ BIS.B #MSDA,&I2CSM_DIR \ 4 l v_ SDA as output ==> SDA low SUB.B T,&I2CM_BUF \ 4 l _ refresh buffer length and reach tSU:STO BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high) BEGIN \ BIT.B #MSCL,&I2CSM_IN \ 3 h SCL released ? 0<> UNTIL \ 2 h BIC.B #MSDA,&I2CSM_DIR \ 4 h _^ SDA as input ==> SDA high with pull up resistor \ MOV @RSP+,PC \ RET ====> RETI \ THEN \ MOV.B #8,W \ 1 l prepare 8 bits transaction BIT.B #1,&I2CS_ADR \ 3 l I2C_Master Read/write bit test 0= IF \ 2 l write flag test \ ============================\ \ I2C_Master_TX \ \ ============================\ MOV.B @S+,X \ 2 l next byte to transmit CALL #I2C_MTX \ l to send data ELSE \ l \ ============================\ \ I2C_Master_RX: \ here, SDA is indetermined, SCL is strech low by master \ ============================\ BIC.B #MSDA,&I2CSM_DIR \ 5 l _ After ACK we must release SDA BEGIN \ \ ------------------------\ _ \ send bit \ SCL _| |_ \ ------------------------\ _ BIC.B #MSCL,&I2CSM_DIR \ 4 l _^ release SCL (high) BEGIN \ 14/16~l BIT.B #MSCL,&I2CSM_IN \ 3 h test if SCL is released 0<> UNTIL \ 2 h BIT.B #MSDA,&I2CSM_IN \ 4 h _ get SDA BIS.B #MSCL,&I2CSM_DIR \ 4 h v_ SCL as output : force SCL low 13~ ADDC.B X,X \ 1 l C <-- X <--- C SUB #1,W \ 1 l count of bits 0= UNTIL \ 2 l MOV.B X,0(S) \ 3 l store byte in buffer ADD #1,S \ 1 l \ ----------------------------\ \ Compute Ack Or Nack \ here, SDA is released by slave, SCL is strech low by master \ ----------------------------\ CMP.B #1,T \ 0<> IF \ 2 l BIS.B #MSDA,&I2CSM_DIR \ 5 l yes : send Ack THEN \ THEN \ AGAIN \ 2 l ENDASM \ \ \ ------------------------------\ CODE START \ \ ------------------------------\ \ init PORT M_BUS (complement) \ when reset occurs all I/O are set in input with resistors pullup BIC.B #M_BUS,&I2CSM_OUT \ preset SDA + SCL output low BIC.B #M_BUS,&I2CSM_REN \ SDA + SCL pullup/down disable \ ------------------------------\ \ init PORT IR (complement) default I/O are input with pullup resistors BIS.B #RC5,&IR_IE \ enable interrupt for TSOP32236 BIC.B #RC5,&IR_IFG \ clear int flag for TSOP32236 \ ------------------------------\ \ init interrupt vectors \ \ ------------------------------\ MOV #INT_RC5,&IR_Vec \ init IR vector interrupt \ ------------------------------\ \ define LPM mode for ACCEPT \ \ ------------------------------\ \ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx \ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2 \ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value \ ------------------------------\ LO2HI ." RC5toI2CF_Master is running. Type STOP to quit" \ NOECHO \ uncomment to run this app without terminal connexion LIT RECURSE IS WARM \ insert this starting routine between COLD and WARM... (WARM) ; \ ...and continue with WARM (very, very usefull after COLD or RESET !:-) \ : STOP \ stops multitasking, must to be used before downloading app ['] (WARM) IS WARM \ remove START app from FORTH init process ECHO COLD \ reset CPU, interrupt vectors, and start FORTH ; \ ECHO \ DUP HERE SWAP - DUMP \ uncomment for a dump, part 2 \ \ select one end state : RST_HERE \ this app is protected against POWER OFF, , COLD, ...and STOP that executes COLD. \ PWR_HERE \ this app is protected only againt POWER OFF \ nothing \ this app is volatile ! \ all lines beyond START command are ignored \ --------------------------------------------------\ \ PHILIPS IR REMOTE RC5/RC6 protocol \ \ --------------------------------------------------\ \ first half bit = no light, same as idle state \ second half bit : 32 IR-light pulses of 6,944us,light ON/off ratio = 1/3 \ |<------32 IR light pulses = second half of first start bit ------->| \ |_ _ _ _ _ _ _ _ _ _ _ _| \ ...____| |___| |___| |___| |___| |___| |...| |___| |___| |___| |___| |___| |____________________________________... \ | | \ \ at the output of IR receiver TSOPxxx during the first start bit : \ ...idle state ->|<----- first half bit ------>|<- second half bit (IR light) ->| \ ..._____________|_____________________________| |_________... \ | | | \ | | | \ | |________________________________| \ 32 cycles of 27,777us (36kHz) = 888,888 us \ one bit = 888,888 x 2 = 1778 us. \ 14 bits of active message = 24.889 ms \ + 50 bits of silent (idle) = 88.888 ms \ = RC5 message = 113.792 ms \ \ RC5_message on IR LIGHT \ idle state = light off \ 89ms>|<--------------------------------------------------24.889 ms-------------------------------------------------->|<88, \ | | \ | | | | | | | | | | | | | | | \ | ST1 | ST2/C6| Tog | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | \ | | | | | | | | | | | | | | | \ 1 1 1 1 0 0 1 1 1 1 1 1 1 1 \ ___ ___ ___ _______ ___ ___ ___ ___ ___ ___ ___ ___ ___ \ ^ | ^ | ^ | ^ | | | ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^ | \ idle____| |___| |___| |___| v___| v_______| |___| |___| |___| |___| |___| |___| |___| |____ \ \ \ notice that each cycle contains its bit value preceded by its complement \ the same RC5_message inverted at the output of IR receiver : idle state = 1 \ \ | | | | | | | | | | | | | | | \ | ST1 | ST2/C6| Tog | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | \ | | | | | | | | | | | | | | | \ 1 1 1 1 0 0 1 1 1 1 1 1 1 1 \ idle_____ ___ ___ ___ ___ _______ ___ ___ ___ ___ ___ ___ ___ __idle \ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | | \ v___| v___| v___| v_______| |___| v___| v___| v___| v___| v___| v___| v___| v___| \ I R R R R R R R R R R R R R \ \ notice that each cycle contains its bit value followed by its complement \ principe of the driver : 13 samples at 1/4 period and Resynchronise (R) on 1/2 period (two examples) \ 0,888 ms \ |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->| \ | | | | | | | | | | | | | | | | \ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | |C0 | \ | | | | | | | | | | | | | | | | \ 1 1 1 1 0 0 1 1 1 1 1 1 1 | 1 \ idle_____ _s_ _s_ _s_ ___ _____s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_ __idle \ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | | \ v___| v___| v___| v_____s_| |_s_| v___| v___| v___| v___| v___| v___| v___| v___| \ S R R R R R R R R R R R R ^ ^ \ samples : 1 2 3 4 5 6 4 8 9 10 11 12 13 | | \ | | \ I I \ 0,888 ms \ |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->| \ | | | | | | | | | | | | | | | | \ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | |C0 | \ | | | | | | | | | | | | | | | | \ 1 1 1 1 0 0 1 1 1 1 1 1 1 | 1 \ idle_____ _s_ _s_ ___ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ ______idle \ | | | | | | | ^ | ^ | | | | | | | | | | | | | ^ \ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o___s_| \ S R R R R R R R R R R R R ^ \ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13| \ | \ I \ good ! but we have too many of RC5_Int... \ So, to avoid these RC5_Int after end : 13+1=14 samples, then the result is shifted one to right (two examples) \ 0,888 ms \ |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->| \ | | | | | | | | | | | | | | | | \ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | | \ | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | | \ | | | | | | | | | | | | | | | | \ idle_____ _s_ _s_ _s_ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_ _s_idle \ | | | | | | | ^ | ^ | | | | | | | | | | | | | | | | \ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| \ S i R i R i R R i R R i R i R i R i R i R i R i R i \ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \ \ \ 0,888 ms \ |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->| \ | | | | | | | | | | | | | | | | \ | ST1 | ST2/C6| Toggle| A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 | | \ | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | \ | | | | | | | | | | | | | | | | \ idle_____ _s_ _s_ ___ _o_ _o___s_ _s_ _s_ _s_ _s_ _s_ _s_ _o___s_idle \ | | | | | | | ^ | ^ | | | | | | | | | | | | | ^ \ v___| v_o_| v_o_| v_o___s_| |_s_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o_| v_o___s_| \ S i R i R i R R i R R i R i R i R i R i R i R R \ samples : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \ S = Wake up on RC5_Int at 1/2 cycle : clear and start timer \ i = useless RC5_Int (not periodic) at 4/4 cycle \ s = sample RC5_intput at (1/2+3/4) = 5/4 cycle = 1/4 cycle+1 and clear useless RC5_Int \ R = usefull (periodic) RC5_Int at 6/4 cycle = 1/2 cycle+1 : cycle value = timer value then clear it and restart it \ o = RC5_Int time out at 7/4 cycle = 3/4 cycle+1, used to detect (samples<14) truncated RC5_message \ see also : http://www.sbprojects.com/knowledge/ir/rc5.php \ http://laurent.deschamps.free.fr/ir/rc5/rc5.htm \ Code RC5 : http://en.wikipedia.org/wiki/RC-5 \ ---------------------------------------------------------------------------------------------------------------------\ \ SCL clock generation, timing, and test of data(s) number are made by I2C_Master. \ slave can strech SCL low after Start Condition and after any bit. \ \ address Ack/Nack is generated by the slave on SDA line (released by the master) \ Two groups of eight addresses (000xxxy and 1111xxxy) are not allowed (reserved) \ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver \ data Ack/Nack are generated by the receiver (master or slave) on SDA line \ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit \ Stop or restart conditions must be generated by master after a Nack bit. \ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions. \ \ \ first byte = address + R/W flag | byte data (one, for example) \ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ _ \ SDA \____/_MSB_R9_____R9_..._R9_LSB_R9__R10__x_ACK_x_MSB_R9_____R9_..._R9_____R9_LSB_R9_ACK_R9___/ \ _____ _ _ _ _ _ _ _ _ _ _ ___ \ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \ ^ ^ ^ ^ ^ ^ ^ \ | |SSL |SSL |SSL |SSL |SSL | \ | | \ |Start Condition |stoP Condition \ \ first byte = address + R/W flag | byte data (one, for example) \ __ _____ _____ _..._ _____ __R__ _NAK_ _____ _____ _..._ _____ _____ _NAK_ ___ \ SDA \____/_MSB_R9_____R9_..._R9_LSB_R9__R10__x_ACK_x_MSB_R9_____R9_..._R9_____R9_LSB_R9_ACK_R9 \____... \ _____ _ _ _ _ _ _ _ _ _ _ ____ \ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_... \ ^ ^ ^ ^ ^ ^ ^ \ | |SSL |SSL |SSL |SSL |SSL | \ | | \ |Start Condition |reStart Condition \ \ SSL : Slave can strech SCL low \ tHIGH : SCL high time \ tLOW : SCL low time \ tBUF : SDA high time between Stop and Start conditions \ tHD:STA : Start_Condition SCL high time after SDA is low \ tSU:STO : Stop_Condition SCL high time before SDA rise \ tSU:STA : Start_Condition SCL high time before SDA fall \ tHD:DAT : SDA data change time after SCL is low \ the SDA line must be strobe just after SCL is high \ the SDA data must be change just after SCL is low \ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs \ tLOW = tSU:STA = tBUF = 4,7µs \ tHD:DAT <= 3,45 µs \ -------------------------------------------------------------------------------------------------------------------\