;*********************************************************************************************
;* *
;* Testprogramm für den Siemens TDA6200! *
;* *
;*********************************************************************************************
.include "m32def.inc"
;**** Global I2C Constants ****
.equ SCLP = 0 ; SCL Pin number (port C)
.equ SDAP = 1 ; SDA Pin number (port C)
.equ b_dir = 0 ; transfer direction bit in i2cadr
.equ i2crd = 1
.equ i2cwr = 0
;**** Global Register Variables ****
.def i2cdelay= r16 ; Delay loop variable
.def i2cdata = r17 ; I2C data transfer register
.def i2cadr = r18 ; I2C address and direction register
.def i2cstat = r19 ; I2C bus status register
.def sreg_save = r20
;**** Interrupt Vectors ****
rjmp RESET ; Reset handle
; ( rjmp EXT_INT0 ) ; ( IRQ0 handle )
; ( rjmp TIM0_OVF ) ; ( Timer 0 overflow handle )
; ( rjmp ANA_COMP ) ; ( Analog comparator handle )
; Freie Register
.def speca = r23
.def specb = r24
.def vol = r25
.def bass = r26
.def sw = r27
.def treb = r22
; Sonderregister
.def sw2 = r1
.def tda6200 = r2
.def tda6200w = r3
;**********************************************************
;* *
;* RESET *
;* *
;**********************************************************
RESET:
; Stackpointer Init
ldi r16, LOW(RAMEND)
out SPL, r16
ldi r16, HIGH(RAMEND)
out SPH, r16
; Portbestimmungen
ldi r20, 0x00
out ddra, r20
ldi r20, 0x00
out ddrb, r20
ldi r20, 0xFF
out ddrd, r20
rcall i2c_init ; initialize I2C interface
ldi sw, 2
ldi speca,96
mov sw2, speca
ldi speca, 128
mov tda6200, speca
ldi speca, 129
mov tda6200w, speca
ldi speca, 176
mov vol, speca
ldi speca, 220
mov bass, speca
ldi speca, 208
mov treb, speca
mov i2cadr,tda6200w
rcall i2c_rep_start
clc
rcall i2c_read
mov specb,i2cdata
out PORTD, specb
clc
rcall i2c_read
rcall i2c_stop
rjmp STEREO
rjmp IIC
main:
mov i2cadr,tda6200w
rcall i2c_rep_start
clc
rcall i2c_read
mov specb,i2cdata
and specb, speca
out PORTD, specb
clc
rcall i2c_read
rcall i2c_stop
rcall Warte2
in r16, PINB
cpi r16, 0b01111111
breq VOLDN ; Lauter
cpi r16, 0b10111111
breq VOLUP ; Leiser
cpi r16, 0b11011111
breq DUAL1 ; Links
cpi r16, 0b11101111
breq DUAL2 ; Rechts
cpi r16, 0b11110111
breq RAUM ; Raumklang
cpi r16, 0b11111011
breq QUASI ; Quasi-Stereo
cpi r16, 0b11111101
breq STEREO ; Stereo
cpi r16, 0b11111110
breq MUTE ; Stumm
rjmp main
VOLUP:
ldi r16, 191
cp vol, r16
breq VOLDN
inc vol
mov r16, vol
out PORTD, vol
rcall IIC
rjmp main
VOLDN:
ldi r16, 128
cp vol, r16
breq VOLUP
dec vol
out PORTD, vol
rcall IIC
rjmp main
STEREO:
ldi speca, 2
mov sw, speca
ldi speca,96
mov sw2, speca
ldi speca, 223
rjmp IIC2
QUASI:
ldi speca, 0b00000111
mov sw, speca
ldi speca, 0b01110000
mov sw2, speca
ldi speca, 255
rjmp IIC2
DUAL1:
ldi speca, 0
mov sw, speca
ldi speca,104
mov sw2, speca
ldi speca, 255
rjmp IIC2
DUAL2:
ldi speca, 8
mov sw, speca
ldi speca, 104
mov sw2, speca
ldi speca, 255
rjmp IIC2
RAUM:
ldi speca, 4
mov sw, speca
ldi speca,96
mov sw2, speca
ldi speca, 255
rjmp IIC2
MUTE:
ldi speca, 0b00110000
mov sw, speca
ldi speca, 0b01000000
mov sw2, speca
ldi speca, 239
rjmp IIC2
IIC:
mov i2cadr,tda6200
rcall i2c_start
mov i2cdata,vol
rcall i2c_do_transfer
mov i2cdata,vol
rcall i2c_do_transfer
rcall i2c_stop
rcall Warte2
mov i2cadr,tda6200
rcall i2c_start
mov i2cadr,bass
rcall i2c_do_transfer
mov i2cadr,treb
rcall i2c_do_transfer
rcall i2c_stop
rcall Warte2
mov i2cadr,tda6200
rcall i2c_start
mov i2cdata,sw
rcall i2c_do_transfer
rcall i2c_stop
rcall Warte2
mov i2cadr,tda6200
rcall i2c_start
mov i2cdata,sw2
rcall i2c_do_transfer
rcall i2c_stop
rcall Warte2
rjmp main
IIC2:
rjmp IIC
;**********************************************************
;* *
;* Warteschleifen *
;* *
;**********************************************************
WARTE2:
ldi R29, $43
WGLOOP0a:
ldi R30, $C6
WGLOOP1a:
dec R30
brne WGLOOP1a
dec R29
brne WGLOOP0a
ret
;*********************************************************
;* *
;* ATMEL-Routine *
;* *
;*********************************************************
;***************************************************************************
;*
;* FUNCTION
;* i2c_hp_delay
;* i2c_qp_delay
;*
;* DESCRIPTION
;* Cristalclock or intern RC-Oscillator up to 8MHz
;* Control AT24C02 with an ATMEGA
;*
;* SEE DOCUMENTATION !!!
;*
;* USAGE
;* no parameters
;*
;* RETURN
;* none
;*
;***************************************************************************
i2c_hp_delay:
ldi i2cdelay,2
i2c_hp_delay_loop:
dec i2cdelay
brne i2c_hp_delay_loop
ret
i2c_qp_delay:
ldi i2cdelay,1
i2c_qp_delay_loop:
dec i2cdelay
brne i2c_qp_delay_loop
ret
;***************************************************************************
;*
;* FUNCTION
;* i2c_rep_start
;*
;* DESCRIPTION
;* Assert repeated start condition and sends slave address.
;*
;* USAGE
;* i2cadr - Contains the slave address and transfer direction.
;*
;* RETURN
;* Carry flag - Cleared if a slave responds to the address.
;*
;* NOTE
;* IMPORTANT! : This funtion must be directly followed by i2c_start.
;*
;***************************************************************************
i2c_rep_start:
sbi DDRC,SCLP ; force SCL low
cbi DDRC,SDAP ; release SDA
rcall i2c_hp_delay ; half period delay
cbi DDRC,SCLP ; release SCL
rcall i2c_qp_delay ; quarter period delay
;***************************************************************************
;*
;* FUNCTION
;* i2c_start
;*
;* DESCRIPTION
;* Generates start condition and sends slave address.
;*
;* USAGE
;* i2cadr - Contains the slave address and transfer direction.
;*
;* RETURN
;* Carry flag - Cleared if a slave responds to the address.
;*
;* NOTE
;* IMPORTANT! : This funtion must be directly followed by i2c_write.
;*
;***************************************************************************
i2c_start:
mov i2cdata,i2cadr ; copy address to transmitt register
sbi DDRC,SDAP ; force SDA low
rcall i2c_qp_delay ; quarter period delay
;***************************************************************************
;*
;* FUNCTION
;* i2c_write
;*
;* DESCRIPTION
;* Writes data (one byte) to the I2C bus. Also used for sending
;* the address.
;*
;* USAGE
;* i2cdata - Contains data to be transmitted.
;*
;* RETURN
;* Carry flag - Set if the slave respond transfer.
;*
;* NOTE
;* IMPORTANT! : This funtion must be directly followed by i2c_get_ack.
;*
;***************************************************************************
i2c_write:
sec ; set carry flag
rol i2cdata ; shift in carry and out bit one
rjmp i2c_write_first
i2c_write_bit:
lsl i2cdata ; if transmit register empty
i2c_write_first:
breq i2c_get_ack ; goto get acknowledge
sbi DDRC,SCLP ; force SCL low
brcc i2c_write_low ; if bit high
nop ; (equalize number of cycles)
cbi DDRC,SDAP ; release SDA
rjmp i2c_write_high
i2c_write_low: ; else
sbi DDRC,SDAP ; force SDA low
rjmp i2c_write_high ; (equalize number of cycles)
i2c_write_high:
rcall i2c_hp_delay ; half period delay
cbi DDRC,SCLP ; release SCL
rcall i2c_hp_delay ; half period delay
rjmp i2c_write_bit
;***************************************************************************
;*
;* FUNCTION
;*
;* DESCRIPTION
;* Get slave acknowledge response.
;*
;* USAGE
;* (used only by i2c_write in this version)
;*
;* RETURN
;* Carry flag - Cleared if a slave responds to a request.
;*
;***************************************************************************
i2c_get_ack:
sbi DDRC,SCLP ; force SCL low
cbi DDRC,SDAP ; release SDA
rcall i2c_hp_delay ; half period delay
cbi DDRC,SCLP ; release SCL
i2c_get_ack_wait:
sbis PINC,SCLP ; wait SCL high
;(In case wait states are inserted)
rjmp i2c_get_ack_wait
clc ; clear carry flag
sbic PINC,SDAP ; if SDA is high
sec ; set carry flag
rcall i2c_hp_delay ; half period delay
ret
;***************************************************************************
;*
;* FUNCTION
;* i2c_do_transfer
;*
;* DESCRIPTION
;* Executes a transfer on bus. This is only a combination of i2c_read
;* and i2c_write for convenience.
;*
;* USAGE
;* i2cadr - Must have the same direction as when i2c_start was called.
;* see i2c_read and i2c_write for more information.
;*
;* RETURN
;* (depends on type of transfer, read or write)
;*
;* NOTE
;* IMPORTANT! : This funtion must be directly followed by i2c_read.
;*
;***************************************************************************
i2c_do_transfer:
sbrs i2cadr,b_dir ; if dir = write
rjmp i2c_write ; goto write data
;***************************************************************************
;*
;* FUNCTION
;* i2c_read
;*
;* DESCRIPTION
;* Reads data (one byte) from the I2C bus.
;*
;* USAGE
;* Carry flag - If set no acknowledge is given to the slave
;* indicating last read operation before a STOP.
;* If cleared acknowledge is given to the slave
;* indicating more data.
;*
;* RETURN
;* i2cdata - Contains received data.
;*
;* NOTE
;* IMPORTANT! : This funtion must be directly followed by i2c_put_ack.
;*
;***************************************************************************
i2c_read:
rol i2cstat ; store acknowledge
; (used by i2c_put_ack)
ldi i2cdata,0x01 ; data = 0x01
i2c_read_bit: ; do
sbi DDRC,SCLP ; force SCL low
rcall i2c_hp_delay ; half period delay
cbi DDRC,SCLP ; release SCL
rcall i2c_hp_delay ; half period delay
clc ; clear carry flag
sbic PINC,SDAP ; if SDA is high
sec ; set carry flag
rol i2cdata ; store data bit
brcc i2c_read_bit ; while receive register not full
;***************************************************************************
;*
;* FUNCTION
;* i2c_put_ack
;*
;* DESCRIPTION
;* Put acknowledge.
;*
;* USAGE
;* (used only by i2c_read in this version)
;*
;* RETURN
;* none
;*
;***************************************************************************
i2c_put_ack:
sbi DDRC,SCLP ; force SCL low
ror i2cstat ; get status bit
brcc i2c_put_ack_low ; if bit low goto assert low
cbi DDRC,SDAP ; release SDA
rjmp i2c_put_ack_high
i2c_put_ack_low: ; else
sbi DDRC,SDAP ; force SDA low
i2c_put_ack_high:
rcall i2c_hp_delay ; half period delay
cbi DDRC,SCLP ; release SCL
i2c_put_ack_wait:
sbis PINC,SCLP ; wait SCL high
rjmp i2c_put_ack_wait
rcall i2c_hp_delay ; half period delay
ret
;***************************************************************************
;*
;* FUNCTION
;* i2c_stop
;*
;* DESCRIPTION
;* Assert stop condition.
;*
;* USAGE
;* No parameters.
;*
;* RETURN
;* None.
;*
;***************************************************************************
i2c_stop:
sbi DDRC,SCLP ; force SCL low
sbi DDRC,SDAP ; force SDA low
rcall i2c_hp_delay ; half period delay
cbi DDRC,SCLP ; release SCL
rcall i2c_qp_delay ; quarter period delay
cbi DDRC,SDAP ; release SDA
rcall i2c_hp_delay ; half period delay
ret
;***************************************************************************
;*
;* FUNCTION
;* i2c_init
;*
;* DESCRIPTION
;* Initialization of the I2C bus interface.
;*
;* USAGE
;* Call this function once to initialize the I2C bus. No parameters
;* are required.
;*
;* RETURN
;* None
;*
;* NOTE
;* PORTC and DDRC pins not used by the I2C bus interface will be
;* set to Hi-Z (!).
;*
;* COMMENT
;* This function can be combined with other PORTC initializations.
;*
;***************************************************************************
i2c_init:
clr i2cstat ; clear I2C status register (used
; as a temporary register)
out PORTC,i2cstat ; set I2C pins to open colector
out DDRC,i2cstat
ret
;*****************************************************************************************************
;* *
;* Ende der ATMEL-Applikation *
;* *
;*****************************************************************************************************
|