;I2C/TWI MASTER INTERRUPT XMEGA-ASSEMBLERBAUSTEIN ;(c)2012 J.KORDAS jkordas(at)web.de ;--------------------------------------------------------------------------------- ;CPU: ATxmega32A4U @ 4.9152 MHz, TWI: PortE/Master ;Beispiel I2C-Hardware: HH10D (Feuchtesensor), HYT271 (Feuchte/Temperatursensor) .DEF TSREG = r9 ;Statusregister-Sicherung ;GPIOR0 Belegung: ;**************** .EQU I2C = 0 ;GPIOR0/0 =1: I2C AKTIV .EQU I2CE = 1 ;GPIOR0/1 =1: I2C ERROR ;Interruptvektor: ;**************** ; ... jmp i2cint ;[5CH] TWI PORT E Master ; ... ;MAIN ; ... ldi r16,$2 ;Enable Medium Interrupt Priority sts PMIC_CTRL,r16 ;Interrupt Controller ldi r16,20 ;INIT I2C Baudrate sts TWIE_MASTER_BAUD,r16 ;(4915200/2*(5+20) = 98.304 kHz sei ; ... ;I2C Funktions-Initialisierung: ;****************************** ;I2CFN: Funktionsnummer (0...x) ;I2CDEV: I2C Deviceadresse ;I2CRXC: zu lesende Bytes ;I2CWXC: zu schreibende Bytes ;I2CRBP: Pointer auf Lesebuffer ;I2CWBP: Pointer auf Schreibbuffer i2cinit: clr XL ;RESET I2C sts TWIE_MASTER_CTRLA,XL ldi XL,$b8 ;I2C INIT (Medium Level INT) sts TWIE_MASTER_CTRLA,XL ldi XL,1 sts TWIE_MASTER_STATUS,XL ;Forces logic to Idle State sbi GPIO_GPIOR0,I2CE lds XL,TWIE_MASTER_STATUS andi XL,3 cpi XL,1 brne error ;No Idle State cbi GPIO_GPIOR0,I2C ;RESET I2C PROCESS FLAG cbi GPIO_GPIOR0,I2CE ;RESET I2C ERROR FLAG lds XL,I2CDEV ;INIT NEW FUNCTION(I2CDEV) sts TWIE_MASTER_ADDR,XL ;-> Start I2C Interrupt ; ... wenn fertig ist I2C gesetzt! ;error: ... wenn Fehler ist I2CE gesetzt! ;I2C Interrupt: ;************** i2cint: in TSREG,CPU_SREG push XL push XH push YL push YH push ZL push ZH lds XH,TWIE_MASTER_STATUS ;I2C ERROR TEST mov XL,XH andi XL,$f cpi XL,2 breq i2cint2 ;I2C Status(Owner)OK! sbi GPIO_GPIOR1,I2CE ;ARB/BUS/STATE-ERROR: sbr XL,$e0 sts TWIE_MASTER_STATUS,XL ;RESET ERROR+INTFLAGS i2cint1: pop ZH pop ZL pop YH pop YL pop XH pop XL out CPU_SREG,TSREG reti i2cint2: clt sbrs XH,6 ;WIF TEST: rjmp i2cint4 ;NO WRITE ACTION BEFORE sbrs XH,4 ;TEST ACKNOWLEDGE FROM SLAVE: rjmp i2cint4 ;SLAVE SENT ACK: OK! set ;SLAVE SENT NACK: SLAVE NOT OK ;SEND STOP+ INIT NEXT FUNCTION i2cint4: lds YL,I2CFN ldi YH,0 ldi ZL,low(i2cft) ldi ZH,high(i2cft) add ZL,YL adc ZH,YH ijmp ;JUMP TO I2C FUNCTION TAB: i2cft: rjmp HH10D_R ;FUNCTION 00H: HH10D READ rjmp HYT_MR ;FUNCTION 01H: HYT271 MR rjmp HYT_DF ;FUNCTION 02H: HYT271 DF ; ... ;FUNCTION xxH (add Functions here) hh10d_r: ;READ HH10D EEPROM (10-13) brts hh10d_r1 ;No Slave ACK rcall writex ;Write 1 Byte (EE WORD ADDRESS) brne hh10d_r2 rcall rstart ;REPEATED=READ START brne hh10d_r2 rcall readx ;Receive 4 Bytes (HH10D Parameter) brne hh10d_r2 hh10d_r1: rcall tstop ;Transfer STOP hh10d_r2: rjmp i2cint1 hyt_mr: ;HYT271 MEASURING REQUEST rcall tstop ;Transfer STOP ; ... ;ggf. nächste Funktion initialisieren rjmp i2cint1 hyt_df: ;HYT271 DATA FETCH brts hyt_dft1 ;WIF: No Slave ACK hyt_dft: rcall readx ;Receive 4 Bytes brne i2cint9 hyt_dft1: rcall tstop ;Transfer STOP ; ... ;ggf. nächste Funktion initialisieren i2cint9: rjmp i2cint1 ;I2C Commands ;************ rstart: lds XL,I2CDEV ;Repeated=Read START sez sbrc XL,0 ret ;FINISHED / NOT AVAILABLE sbr XL,1 sts I2CDEV,XL sts TWIE_MASTER_ADDR,XL ret writex: lds XL,I2CWXC ;WRITEX (I2CWXC Bytes) tst XL breq writex2 ;NO BYTES TO WRITE! lds YL,I2CWBP lds YH,I2CWBP+1 ;YH:YL->WRITEBUFFER ld XH,Y+ ;XH= WRITE BYTE sts I2CWBP,YL sts I2CWBP+1,YH sts TWIE_MASTER_DATA,XH dec XL sts I2CWXC,XL clz writex2: ret readx: lds XL,I2CRXC ;READX (I2CRXC Bytes) tst XL breq readx2 ;NO BYTES TO RECEIVE! ldi XH,1 sts TWIE_MASTER_CTRLB,XH ;Enable Smartmode! clr XH ;Receiving not finished: cpi XL,1 brne readx1 ;Acknowledge= ACK sts TWIE_MASTER_CTRLB,XH ;Last Byte: No Smartmode, ldi XH,4 ;Acknowledge= NACK readx1: sts TWIE_MASTER_CTRLC,XH ;SET Acknowledge Action lds YL,I2CRBP lds YH,I2CRBP+1 ;YH:YL->READBUFFER lds XH,TWIE_MASTER_DATA ;XH= RECEIVED BYTE st Y+,XH ;Save in READBUFFER sts I2CRBP,YL sts I2CRBP+1,YH dec XL sts I2CRXC,XL readx2: ret tstop: ldi XL,3 ;TRANSFER STOP sts TWIE_MASTER_CTRLC,XL sbi GPIO_GPIOR0,I2C ;I2C ret ;--------------------------------------------------------------------------------- .DSEG ;Verwendete Variablen: I2CFN: .BYTE 1 ;I2C CONTROL: FUNCTION NUMBER I2CDEV: .BYTE 1 ;I2C CONTROL: DEVICE ADDRESS I2CRXC: .BYTE 1 ;I2C CONTROL: READX COUNTER I2CWXC: .BYTE 1 ;I2C CONTROL: WRITEX COUNTER I2CRBP: .BYTE 2 ;I2C CONTROL: READ BUFFER POINTER I2CWBP: .BYTE 2 ;I2C CONTROL: WRITE BUFFER POINTER