;*************************************************** ; Test TWI via USI-Interface ; MCU: ATMEL ATtiny4313 ; Clock: 4 MHz ; TWI/I2C-PortB PB7=SCL; PB5=SDA ; OLED ; P7 P6 P5 P4 P3 P2 P1 P0 ; ; Device slave address: $3C ; ; Rev.: 25022026 ;*************************************************** ; ;Assembler direktives: ; .nolist .include "tn4313def.inc" .list ; ; ; SRAM Definitions: ; .dseg ; Datasegment (SRAM) Start on .org 0x0060 ; address 0x0060 ; ; ; Constants: .equ daten = portb .equ delay0 = 1000 .equ delay1 = 65535 ; ; ; Register synonyma: .def inttemp = r12 ; backup register for Interrupt-Routines .def intreg = r14 ; backup register for SREG on ISRs .def temp = r16 ; universal register for arithmetcs .def temp1 = r17 .def temp2 = r18 .def temp3 = r19 ; .cseg ; Codesegment .org 0x0000 ; Start address rjmp reset ; Interrupt vektors jump into addresses (default) ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .org 0x0001 ; ext IRQ0 edge rjmp INT00 .org 0x0002 ; ext IRQ1 edge rjmp INT10 .org 0x0003 ; Timer 1 capt rjmp ICP10 .org 0x0004 ; Timer 1 comp match A rjmp OC100 .org 0x0005 ; Timer 1 overflow rjmp OVF10 .org 0x0006 ; Timer 0 overflow rjmp OVF00 .org 0x0007 ; UART Receive Complete rjmp URXC0 .org 0x0008 ; UART Data Register Empty rjmp UDRE0 .org 0x0009 ; UART Transmit Complete rjmp UTXC0 .org 0x000A ; Analog Comparator Interrupt rjmp ACI00 .org 0x000B ; Pin Change Interrupt Request B rjmp PCIBA .org 0x000C ; Timer 1 comp match B rjmp OC1BA .org 0x000D ; Timer 0 comp match A rjmp OC0AA .org 0x000E ; Timer 0 comp match B rjmp OC0BA .org 0x000F ; USI Start Condition rjmp USIST .org 0x0010 ; USI Overflow rjmp USIOV .org 0x0011 ; Eprom read ready rjmp ERDYA .org 0x0012 ; Watchdog Timer Overflow rjmp WDTAD .org 0x0013 ; Pin Change Interrupt Request A rjmp PCIAA .org 0x0014 ; Pin Change Interrupt Request D rjmp PCIDA ; ;Interrupt Service Routines - Interrupt Handler ;- - - - - - - - - - - - - - - - - - - - - - - - - INT00: ; ISR not in use reti INT10: ; ISR not in use reti ICP10: ; ISR not in use reti OC100: ; ISR not in use reti OVF10: ; ISR not in use reti OVF00: ; ISR not in use reti URXC0: ; ISR not in use reti UDRE0: ; ISR not in use reti UTXC0: ; ISR not in use reti ACI00: ; ISR not in use reti PCIBA: ; ISR not in use reti OC1BA: ; ISR not in use reti OC0AA: ; ISR not in use reti OC0BA: ; ISR not in use reti USIST: ; ISR not in use reti USIOV: ; ISR not in use reti ERDYA: ; ISR not in use reti WDTAD: ; ISR not in use reti PCIAA: ; ISR not in use reti PCIDA: ; ISR not in use reti ; reset: cli ; disable all interrupts ldi temp, low(ramend) ; Stackpointer set up out spl, temp ldi temp, high(ramend) ; out sph, temp rcall regclr ; register reset rcall portinit ; init I/O-Ports rcall twimain ; TWI/I2C-Setup rcall oledinit ; OLED-initialization sei ; enable all interrupts again rjmp main ; jump to main program ; regclr: ; set all registers to zero clr inttemp clr intreg ldi temp, 0x00 ldi temp1, 0x00 ldi temp2, 0x00 ldi temp3, 0x00 ret ; portinit: ; Init I/O-Ports ldi temp, 0xFF ; PortB output TWI out ddrb, temp out portb, temp out ddrd, temp ldi temp, 0xFF out portd, temp ret ; main: ; Main program rjmp endless ; endless: ; Endless loop rjmp endless ; ;- - - - Delay routines - - - - - - - ; wait1: rcall wait3 nop rcall wait3 ret ; wait2: ; delay loop 2: push yl ; save registers to stack... push yh push temp push temp1 push temp2 in temp2, SREG ; ...status register, too push temp2 ldi yl, low(delay0) ; load constant into 16 bit register ldi yh, high(delay0) ; using previous declared "delay0" rjmp repeatx ; jump to shared subroutine ; wait3: ; delay loop 3: push yl ; save registers to stack... push yh push temp push temp1 push temp2 in temp2, SREG ;...status register, too push temp2 ldi yl, low(delay1) ; load constant into 16 bit register ldi yh, high(delay1) ; using previous declared "delay1" rjmp repeatx ; jump to shared counter subroutine ; repeatx: ; 16 Bit subtracting routine: sbiw yl:yh, 1 ; decrements register pair brne repeatx ; counts to zero pop temp2 ; reestablish all on stack saved registers out SREG, temp2 pop temp2 pop temp1 pop temp pop yh pop yl ret ; ; TWI/I2C Routines via USI Interface (ATtiny2313/4313) ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - twimain: cli rcall twiinit rcall twistart ldi temp, 0x78 ; address contains A0,A1,A2=GND + R/W-Bit (W=0; R=1) sei rcall twiout ;brts end ; if NACK (T-flag in SREG previous set to H), ret ; then jump to end ; end: rjmp endless ; twiinit: sbi portb, 7 ; SCL high sbi portb, 5 ; SDA high sbi ddrb, 7 ; PortB7 (SCL) configured as output sbi ddrb, 5 ; PortB5 (SDA) configured as output ldi temp, 0xFF out USIDR, temp ; fill up data register with ones completely ldi temp, 0x20 ; (1<no TWI clock out USICR,temp ret ; twidown: clr temp out USICR, temp ; set off USI-function, PortB5, PortB7 use as normal ret ; twistop: cbi portb, 5 ; SDA->L cbi USIDR, 7 ; data register MSB->L nop nop nop nop nop sbi portb, 7 ; SCL->H ; twistop1: sbis pinb, 7 ; wait for SCL=H rjmp twistop1 sbi portb, 5 sbi USIDR, 7 ; SDA->H ret ; twistart: sbi portb, 5 ; SDA->H sbi USIDR, 7 ; data register MSB->H nop nop nop sbi portb, 7 ; SCL->H ; twistart1: sbis pinb, 7 ; wait for SCL=H rjmp twistart1 ; cbi USIDR, 7 ; data register MSB->L nop nop nop cbi portb, 7 ; SCL->L nop nop nop nop nop ret ; twiout: ; send slave's address together with R/W-Bit on temp push temp push temp1 out USIDR, temp ; addresse/data in data register ldi temp, 0xF8 ; reset USI-status register IR-Flags, counter on 8 out USISR,temp ; (1<H (USI clock toggle mode) ; twiout2: sbis pinb, 7 ; wait for SCL=H rjmp twiout2 nop nop nop nop sbi USICR, USITC ; SCL H->L (USI clock toggle mode) nop nop nop nop sbi USICR, USICLK ; shifting data register +1 and counter +1 nop dec temp1 ; counter for remaining bits left cpi temp1, 0x00 brne twiout1 ; loop, until reached zero ldi temp, 0xFF ; reset all flags in USI-status register out USISR, temp cbi ddrb, 5 ; SDA -> configured as input sbi USICR, USITC ; SCL L->H (USI clock toggle mode; read ACK/NACK) nop nop nop nop nop set ; set T-flag in SREG sbis pinb, 5 ; SDA already H (NACK)? clt ; no-> clear T-flag in SREG sbi USICR, USITC ; SCL H->L (USI clock toggle mode) sbi ddrb, 5 ; SDA reconfigured to output nop nop nop pop temp1 pop temp ret ; oledinit: ; rcall wait1 ; wait for LCD power on self reset rcall twistart rcall twiout ; OLED->0x78 rcall oled_init_01 ; OLED-Init_01 rcall oled_init_02 ; OLED-Init_02 rcall oled_pixel_01 ; OLED pixel sample rcall oled_pixel_02 ret ; oled_init_01: ldi temp, 0x00 ; command mode rcall twiout ret ; oled_init_02: ldi temp, 0xAE ; display off rcall twiout ldi temp, 0xD5 ; set clock divide ratio rcall twiout ldi temp, 0x80 rcall twiout ldi temp, 0xA8 ; set multiplex tatio (64) rcall twiout ldi temp, 0x3F rcall twiout ldi temp, 0x8D ; charge pump rcall twiout ldi temp, 0x14 ; charge pump rcall twiout ldi temp, 0xAE ; display off rcall twiout rcall wait1 rcall twistop ret ; oled_pixel_01: rcall twistart ldi temp, 0x78 ; Adresse rcall twiout ldi temp, 0x40 ; Control Byte: Data Mode rcall twiout ldi temp1, 0xFF mov temp, temp1 rcall twiout rcall wait1 rcall twistop ret ; oled_pixel_02: rcall twistart ldi temp2, 0x78 mov temp, temp2 rcall twiout ldi temp2, 0x00 ; Command Mode mov temp, temp2 rcall twiout ; ; Page setzen (B0h - B7h) ldi temp, 0x00 rcall twiout ldi temp, 0xB1 rcall wait1 rcall twiout ;ldi temp, 0x7F ;rcall wait1 rcall twiout ; ; Spalte Low Nibble (00h - 0Fh) ;ldi temp, 0x22 ;rcall wait1 ;rcall twiout ldi temp, 0x00 rcall wait1 rcall twiout ldi temp, 0x0F rcall wait1 rcall twiout rcall wait1 ;rcall twistop ;ldi temp, 0x00 rcall twiout rcall wait1 ldi temp, 0xAF rcall twiout ret ;- fin -