mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mein MSP3400 und mein MSP3410 wollen nicht funktionieren


Autor: Alex Fxxxx (electronicfox)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich hab schon alle Datenblätter durch und beide ICs probiert.
http://www.alldatasheet.com/datasheet-pdf/pdf/2280...
http://www.alldatasheet.com/datasheet-pdf/pdf/1031...
http://www.alldatasheet.com/datasheet-pdf/pdf/1031...
Nun keines will funktionieren. Die ICs sind noch auf fertigen 
Steckkarten, TV-Karten und Platinen drauf mit gescheiten RESET und 
genauen +5V und +8V.
die Assemblersoftware funktioniert auch soweit drauf, zumindest 
antworten die MSPs und die Spannungen stimmen auch soweit. Sogar das 
Delay wird angesteuert und funktioniert einwandfrei.
Nur kommt kein Ton aus den Lautsprecherausgängen des MSP34x0.

Ich glaub ich hab einen Fehler im Code. Als Test wollte ich nur diesen 
Code ausführen

<80> <00> <80> <00> RESET
<80> <00> <00> <00> INIT
<80> <10> <00> <30> <30> <08> FM-Eingang1
<80> <12> <00> <08> <02> <20> SCART-Eingang1 zu den Lautsprechern
<80> <12> <00> <0E> <13> <01> PAL-B/G
<80> <10> <00> <20> <00> <03> PAL-B/G
<80> <12> <00> <00> <AA> <00> Lautstärke ca. 80%

Nur eine Umschaltung findet nicht statt. Ich bin mir sicher dass ich was 
überlesen habe und hoffe auf eure Hilfe.

Die MSPs wären endlich mal eine günstige Alternative für I2S-Projekte, 
da viele TV-Geräte mit diesen IC verschrottet werden ;)
.include "2313def.inc"

 
.def temp1  = r16
.def temp2  = r17
.def temp3  = r18
.def temp4  = r19
.def ar0    = r20
.def status = r21
.def VOLL   = r22
.def VOLR   = r23
.def BASS   = r28
.def TREB   = r29
.def SWITCH = r30

;**** Global I2C Constants ****
                                    
.equ  SCLP  = 7          ; SCL für M50198P und MSP3400
.equ    DENA    = 4             ; ENABLE für M50198P
.equ  SDAP  = 5          ; SDA für M50198P und MSP3400
.equ    SLED    = 3             ; 
.equ    WLED    = 6             ; 
.equ    STLED   = 2             ; STOERUNG-LED
.equ    MLED    = 1             ; 
.equ    PLED    = 0             ; 


                              
.equ  b_dir  = 0          ; transfer direction bit in i2cadr                                   
.equ  i2crd  = 1
.equ  i2cwr  = 0

;**** Global Register Variables ****
                                    
.def  i2cdelay= r24      ; Delay loop variable
.def  i2cdata  = r25      ; I2C data transfer register
.def  i2cadr  = r26      ; I2C address and direction register
.def  i2cstat  = r27      ; I2C bus status register
 

;-----------------------------------------------------------------------------
;
; Datensegment im RAM
;
;-----------------------------------------------------------------------------
 
.dseg
.org 0x60
Daten:      .byte 2    ; Speicherplatz für Eingangsdaten
.cseg

 
    ldi temp1, RAMEND
    out SPL, temp1

    clr temp1
           
    ;ldi temp1,0        ; Port B = Eingang
    ;out DDRB, temp1
 
    ldi temp1, $FF    ; 
    out DDRD, temp1

;**********************************************************************************



;**********************************************************************************

INIT:
    cbi  DDRB, DENA   ; DENA im Ruhezustand immer auf 1.
    cbi  DDRB, SDAP   ; SCL im Ruhezustand immer auf 1.
  cbi  DDRB, SCLP   ; SDA im Ruhezustand immer auf 1.
  Cbi  DDRB, STLED  ; ST-Led AUS
  
  
rjmp Delay  

Delay:

; Delay= 30ms.

    rcall WARTESCHLEIFE
  rcall WARTESCHLEIFE
  rcall WARTESCHLEIFE
  rcall WARTESCHLEIFE

  sbi   DDRB, DENA   ; DENA beim steuern des M50198P auf LOW

    ldi   temp1, 0b01101110
    rcall Schiebe

    ldi   temp1, 0b00100000
    rcall Schiebe

  rcall   WARTESCHLEIFE      ; Warten für die genaue Werte

    cbi  DDRB, DENA   ; DENA im Ruhezustand immer auf 1.
    cbi  DDRB, SDAP   ; SCL im Ruhezustand immer auf 1.
  cbi  DDRB, SCLP   ; SDA im Ruhezustand immer auf 1.
  cbi  DDRB, STLED  ; ST-Led AUS

    rcall WARTESCHLEIFE
  rcall WARTESCHLEIFE
  rcall WARTESCHLEIFE
  rcall WARTESCHLEIFE
  rjmp START



START:
    rcall IIC
  cbi  DDRB, DENA   ; DENA im Ruhezustand immer auf 1.
    cbi  DDRB, SDAP   ; SCL im Ruhezustand immer auf 1.
  cbi  DDRB, SCLP   ; SDA im Ruhezustand immer auf 1.
  
  rjmp STOP

STOP:
    rjmp STOP

  


;**********************************************************************************

IIC:
    

    rcall WARTESCHLEIFE
                  ; I²C-Busübertragung
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
  sbic  PINB,SDAP     ; if SDA is high
  rjmp    Fehler
    ldi  i2cdata,$00          ; RESET-MSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$80           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop

    rcall WARTESCHLEIFE

  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    ldi  i2cdata,$00          ; INIT-MSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop

    rcall WARTESCHLEIFE

  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; FM1-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$30           ; FM1-LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$30          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$C8           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop

  rcall WARTESCHLEIFE

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    ldi  i2cdata,$12          ; DSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; MATRIX-SCART
    rcall  i2c_do_transfer  
  ldi  i2cdata,$08           ; MATRIX-SCART
    rcall  i2c_do_transfer
  ldi  i2cdata,$02          ; 
    rcall  i2c_do_transfer  
  ldi  i2cdata,$20           ; 
    rcall  i2c_do_transfer
    rcall  i2c_stop

    rcall WARTESCHLEIFE

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    ldi  i2cdata,$12          ; DSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; PAL-BG
    rcall  i2c_do_transfer  
  ldi  i2cdata,$0E           ; PAL-BG
    rcall  i2c_do_transfer
  ldi  i2cdata,$13          ; 
    rcall  i2c_do_transfer  
  ldi  i2cdata,$01           ; 
    rcall  i2c_do_transfer
    rcall  i2c_stop

    rcall WARTESCHLEIFE

  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    ldi  i2cdata,$10          ; DSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; PAL-BG
    rcall  i2c_do_transfer  
  ldi  i2cdata,$20           ; PAL-BG
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; 
    rcall  i2c_do_transfer  
  ldi  i2cdata,$03           ; 
    rcall  i2c_do_transfer
    rcall  i2c_stop

    rcall WARTESCHLEIFE

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    ldi  i2cdata,$12          ; DSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; LAUTSPRECHER-LAUTSTAERKE
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; LAUTSPRECHER-LAUTSTAERKE
    rcall  i2c_do_transfer
  ldi  i2cdata,$AA          ; 
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; 
    rcall  i2c_do_transfer
    rcall  i2c_stop

    

    rcall WARTESCHLEIFE

    ret


Fehler:
    sbi   DDRB, STLED  ; ST-LED leuchtet wenn der MSP3400 nicht antwortet
  rcall Warte
  rjmp Fehler

;Delayeinstellung 


;-----------------------------------------------------------------------------
;
; Die Ausgabe im Schieberegister in das Ausgaberegister übernehmen, wenn ein HC595 verwendet wird.
;
; Dazu am RCK Eingang am Schieberegister einen 0-1-0 Puls erzeugen
;
SchiebeOut:
    cbi   DDRB, DENA
    sbi   DDRB, DENA
    ret
 
;-----------------------------------------------------------------------------
;
; 8 Bits aus temp1 an das Schieberegister ausgeben
Schiebe:
    push  temp2
    ldi   temp2, 8             ; 8 Bits müssen ausgegeben werden
  rcall   WARTESCHLEIFE       ; Warten für die genaue Werte
 
Schiebe_1:
     ;
     ; jeweils das höchstwertige Bit aus temp1 ins Carry-Flag schieben
     ; Je nach Zustand des Carry-Flags wird die Datenleitung entsprechend
     ; gesetzt oder gelöscht
     ;
    rol  temp1                 ; MSB -> Carry
    brcs Schiebe_One           ; Carry gesetzt? -> weiter bei Schiebe_One
  rcall   WARTESCHLEIFE      ; Warten für die genaue Werte
    sbi  DDRB, SDAP     ; Eine 0 ausgeben
  rcall   WARTESCHLEIFE      ; Warten für die genaue Werte
    rjmp Schiebe_Clock         ; und Sprung zur Clock Puls Generierung
Schiebe_One:
    cbi  DDRB, SDAP     ; Eine 1 ausgeben
 
     ;
     ; einen Impuls an CLK zur Übernahme des Bits nachschieben
     ;
Schiebe_Clock:
    
    sbi   DDRB, SCLP    ; Clock-Ausgang auf 0 ...
  rcall   WARTESCHLEIFE      ; Warten für die genaue Werte
    cbi   DDRB, SCLP    ; und wieder zurück auf 1
    rcall   WARTESCHLEIFE      ; Warten für die genaue Werte
    dec   temp2                ; Anzahl der ausgegebenen Bits runterzählen
    brne  Schiebe_1            ; Wenn noch keine 8 Bits ausgegeben -> Schleife bilden
 
    pop   temp2
    ret



delay50us:                              ; 50us Pause
           ldi  temp1, $42
delay50us_:dec  temp1
           brne delay50us_
           ret                          ; wieder zurück
 
 ; Längere Pause für manche Befehle
delay5ms:                               ; 5ms Pause
           ldi  temp1, $21
WGLOOP0:   ldi  temp2, $C9
WGLOOP1:   dec  temp2
           brne WGLOOP1
           dec  temp1
           brne WGLOOP0
           ret                          ; wieder zurück
 

Warte:
; ============================= 
;    
;     8000000 Zyklen:
; ----------------------------- 
; warte 7999992 Zyklen:
          ldi  R20, $48
WGLOOP0a: ldi  R22, $BC
WGLOOP1a: ldi  R21, $C4
WGLOOP2a: dec  R21
          brne WGLOOP2a
          dec  R22
          brne WGLOOP1a
          dec  R20
          brne WGLOOP0a
; ----------------------------- 
; warte 6 Zyklen:
          ldi  R20, $02
WGLOOP3a: dec  R20
          brne WGLOOP3a
; ----------------------------- 
; warte 2 Zyklen:
          nop
          nop
      ret
; ============================= 





WARTESCHLEIFE:
; Warteschleife für die seriellen Daten
; ===================================== 
;   Warteschleife für 4MHz
;     40000 Zyklen:
; ------------------------------------- 
; warte 39999 Zyklen:
          ldi  R20, $43
WGLOOP0b: ldi  R21, $C6
WGLOOP1b: dec  R21
          brne WGLOOP1b
          dec  R20
          brne WGLOOP0b
; ------------------------------------- 
; warte 1 Zyklus:
          nop
; =====================================
          ret

; Warteschleifenende



; Hier die I2C-Routine:

;*********************************************************
;*                                                       *
;* ATMEL-Routine                                         *
;*                                                       *
;*********************************************************




                                    
                                    
;***************************************************************************
;*
;* FUNCTION
;*  i2c_hp_delay
;*  i2c_qp_delay
;*
;* DESCRIPTION
;*  Cristalclock or intern RC-Oscillator up to 4MHz
;*  Control I2C-Device with an ATTINY2313
;*
;*  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  DDRB,SCLP    ; force SCL low
cbi  DDRB,SDAP    ; release SDA
rcall  i2c_hp_delay    ; half period delay
cbi  DDRB,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  DDRB,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  DDRB,SCLP    ; force SCL low
                                    
brcc  i2c_write_low    ; if bit high
nop        ;  (equalize number of cycles)
cbi  DDRB,SDAP    ;  release SDA
rjmp  i2c_write_high
i2c_write_low:        ; else
sbi  DDRB,SDAP    ;  force SDA low
rjmp  i2c_write_high    ;  (equalize number of cycles)

i2c_write_high:
rcall  i2c_hp_delay    ; half period delay
cbi  DDRB,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  DDRB,SCLP    ; force SCL low
cbi  DDRB,SDAP    ; release SDA
rcall  i2c_hp_delay    ; half period delay
cbi  DDRB,SCLP    ; release SCL
                                    
i2c_get_ack_wait:
sbis  PINB,SCLP    ; wait SCL high 
                                              ;(In case wait states are inserted)
rjmp i2c_get_ack_wait

                                    
clc        ; clear carry flag
sbic  PINB,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  DDRB,SCLP    ;   force SCL low
rcall  i2c_hp_delay    ;  half period delay
                                    
cbi  DDRB,SCLP    ;  release SCL
rcall  i2c_hp_delay    ;  half period delay
                                    
clc        ;  clear carry flag
sbic  PINB,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  DDRB,SCLP    ; force SCL low
ror  i2cstat      ; get status bit
brcc  i2c_put_ack_low    ; if bit low goto assert low
cbi  DDRB,SDAP    ;  release SDA
rjmp  i2c_put_ack_high

i2c_put_ack_low:      ; else
sbi  DDRB,SDAP    ;  force SDA low
i2c_put_ack_high:
                                    
rcall  i2c_hp_delay    ; half period delay
cbi  DDRB,SCLP    ; release SCL
i2c_put_ack_wait:
sbis  PINB,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  DDRB,SCLP    ; force SCL low
sbi  DDRB,SDAP    ; force SDA low
rcall  i2c_hp_delay    ; half period delay
cbi  DDRB,SCLP    ; release SCL
rcall  i2c_qp_delay    ; quarter period delay
cbi  DDRB,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  PORTB,i2cstat    ; set I2C pins to open colector
out  DDRB,i2cstat
ret




;*****************************************************************************************************
;*                                                                                                   *
;* Ende der ATMEL-Applikation                                                                        *
;*                                                                                                   *
;*****************************************************************************************************



Autor: Alex Fxxxx (electronicfox)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
irgentwo ist der Wurm drin. Ich bring es einfach nicht fertig einen 
MSP3410 ( Multi-Sound-Processor ) anzusteuern. Bei TDA8420, TDA8421, 
TDA8425, TDA9840, TDA9860, TDA6200, TDA6610 und TDA7313 ging das ohne 
Probleme, so dass ich glaube, dass der Fehler in meiner Assemblerfile 
steckt. Der MSP3410 sollte doch nur zum Test ganz einfach das NF-Signal 
von SCART3 auf den Lautsprecherausgang übertragen, was nicht klappt. Ich 
habe mich sogar extra dran gehalten den Demodulator zuerst zu justieren 
und danach die Audioeinstellungen. Auf das RESET habe ich eh nicht 
vergessen und da glaub ich ist der Wurm drin. Nach dem Reset über den 
I2C-Bus setzt mir der MSP3410 SDA und SCL auf Low und verbleibt in 
diesem Zustand. Den Hardware-Reset über den /RESET-Pin mache ich für ca. 
1 Sekunde bevor der Mikrocontroller ( ATMEGA32 ) das Protokol startet.
 Vielleicht findet jemand den Fehler für mich, da der IC schon recht 
Klasse ist und billig kriegt und derzeit bei fast 80% der TV-Geräte zu 
finden ist. Alleine die I2S-Ports könnte man für viele sinnvolle 
Projekte verwenden. Ich hab sogar extra auf die INITs geachtet und nacht 
10 bis 12 Protokollen legen mir die MSPs die I2C_Ports auf Masse und der 
MSP macht dicht und lässt das Signal nicht durch.
 Ich bedanke mich jetzt schon für jede Hilfe.
.include "m32def.inc"

.cseg
.org 0
 
.def temp1  = r16
.def temp2  = r17
.def temp3  = r18
.def temp4  = r19
.def ar0    = r20
.def status = r21
.def TESTING= r31
.def  i2cdelay= r24      ; Delay loop variable
.def  i2cdata  = r25      ; I2C data transfer register
.def  i2cadr  = r26      ; I2C address and direction register
.def  i2cstat  = r27      ; I2C bus status register

.equ  SCLP  = 0          ; SCL für MSP3400
.equ    DENA    = 2             ; 
.equ  SDAP  = 1          ; SDA für MSP3400                            
.equ  b_dir  = 0          ; transfer direction bit in i2cadr                                   
.equ  i2crd  = 1
.equ  i2cwr  = 0

    ldi temp1, RAMEND
    out SPL, temp1
  ldi temp1, RAMEND
    out SPH, temp1

    clr temp1
           
    ldi temp1,0        ; Port C = Eingang
    out DDRC, temp1
 
    ldi temp1, $FF     ; Port D = Ausgang
    out DDRD, temp1

INIT:
    
    cbi  DDRB, DENA   ; DENA im Ruhezustand immer auf 1.
    cbi  DDRB, SDAP   ; SCL im Ruhezustand immer auf 1.
  cbi  DDRB, SCLP   ; SDA im Ruhezustand immer auf 1.
  
    rcall MSP_INIT
  rjmp RESET_MSP

RESET_MSP:

    rcall MSP_SEKUNDE
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE
    ldi  i2cdata,$00          ; RESET-MSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$80           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
    rcall MSP_SEKUNDE
  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE  
    ldi  i2cdata,$00          ; INIT-MSP
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
    rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
  rjmp AD_CV

AD_CV:
      
  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$BB           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$05          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$D0           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp AUDIO_PLL

AUDIO_PLL:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE  
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$02           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$D7           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp FIR_REG_1

FIR_REG_1:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$01           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,18           ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp FIR_REG_2

FIR_REG_2:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$05           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,18           ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp MODE_REG

MODE_REG:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$83           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$0C          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$94           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp DCO_1_LO

DCO_1_LO:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$93           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$03          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$8E           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp DCO_1_HI

DCO_1_HI:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$9B           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$04          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$C6           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
    rjmp AD_CV_I

AD_CV_I:
  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$BB           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$05          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$D0           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp AUDIO_PLL_I

AUDIO_PLL_I:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE  
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$02           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$D7           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp FIR_REG_1_I

FIR_REG_1_I:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$01           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,18           ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp FIR_REG_2_I

FIR_REG_2_I:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$05           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,18           ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp MODE_REG_I

MODE_REG_I:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$83           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$0C          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$94           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp DCO_1_LO_I

DCO_1_LO_I:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start  
    rcall MSP_SEKUNDE
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$93           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$03          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$8E           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp DCO_1_HI_I

DCO_1_HI_I:

    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$10          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$9B           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$04          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$C6           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
  rcall MSP_SEKUNDE
    rjmp VOLUME

VOLUME:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$6A          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp BALANCE

BALANCE:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$01           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp BASS

BASS:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE  
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$02           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$40          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp TREBLE

TREBLE:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$03           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$50          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp LOUDNESS

LOUDNESS:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$04           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$04          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$04           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp STEREO

STEREO:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$05           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp HEAD

HEAD:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$06           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp INPUT_PEGEL

INPUT_PEGEL:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$07           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$7F          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp SOUND_OUT

SOUND_OUT:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$08           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$02          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$20           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$09           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$02          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$20           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$0A           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$02          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$20           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
  ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$0B           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$02          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$20           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp SCART_P

SCART_P:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$0D           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$7F          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp IF_FM

IF_FM:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$0E           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$7F          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$01           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp DEEMPHASIS

DEEMPHASIS:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$0F           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp NICAM

NICAM:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$10           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp NICAM_DEEM

NICAM_DEEM:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$11           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp INPUT

INPUT:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE      
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$13           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,0b11000011   ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$00           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp BEEP_OFF

BEEP_OFF:
    
    ldi  i2cadr,$80           ; MSP3400
    rcall  i2c_start
    rcall MSP_SEKUNDE    
    ldi  i2cdata,$12          ; STATUS-REGISTER
    rcall  i2c_do_transfer  
    ldi  i2cdata,$00           ; HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$14           ; LOW
    rcall  i2c_do_transfer
  ldi  i2cdata,$00          ; CONTROL-HIGH
    rcall  i2c_do_transfer  
  ldi  i2cdata,$01           ; CONTROL-LOW
    rcall  i2c_do_transfer
    rcall  i2c_stop
  rcall MSP_SEKUNDE
    rjmp STOP

STOP:
rjmp STOP


MSP_INIT:
; ============================= 
;   Warteschleifen-Generator 
;     20000000 Zyklen:
; ----------------------------- 
; warte 19999992 Zyklen:
          ldi  R17, $BF
MSP0:     ldi  R18, $A7
MSP1:     ldi  R19, $D0
MSP2:     dec  R19
          brne MSP2
          dec  R18
          brne MSP1
          dec  R17
          brne MSP0
; ----------------------------- 
; warte 6 Zyklen:
          ldi  R17, $02
MSP3:     dec  R17
          brne MSP3
; ----------------------------- 
; warte 2 Zyklen:
          nop
          nop
; ============================= 
ret

Warte:
; ============================= 
;    
;     8000000 Zyklen:
; ----------------------------- 
; warte 7999992 Zyklen:
          ldi  R20, $48
WGLOOP0a: ldi  R22, $BC
WGLOOP1a: ldi  R21, $C4
WGLOOP2a: dec  R21
          brne WGLOOP2a
          dec  R22
          brne WGLOOP1a
          dec  R20
          brne WGLOOP0a
; ----------------------------- 
; warte 6 Zyklen:
          ldi  R20, $02
WGLOOP3a: dec  R20
          brne WGLOOP3a
; ----------------------------- 
; warte 2 Zyklen:
          nop
          nop
      ret
; ============================= 

WARTESCHLEIFE:
; Warteschleife für die seriellen Daten
; ===================================== 
;   Warteschleife für 4MHz
;     40000 Zyklen:
; ------------------------------------- 
; warte 39999 Zyklen:
          ldi  R20, $43
WGLOOP0b: ldi  R21, $C6
WGLOOP1b: dec  R21
          brne WGLOOP1b
          dec  R20
          brne WGLOOP0b
; ------------------------------------- 
; warte 1 Zyklus:
          nop
; =====================================
          ret

MSP_SEKUNDE:
; ============================= 
;   Warteschleifen-Generator 
;     2400000 Zyklen:
; ----------------------------- 
; warte 2399820 Zyklen:
          ldi  temp1, $14
SE0:      ldi  temp2, $C6
SE1:      ldi  temp3, $C9
SE2:      dec  temp3
          brne SE2
          dec  temp2
          brne SE1
          dec  temp1
          brne SE0
; ----------------------------- 
; warte 180 Zyklen:
          ldi  temp1, $3C
SE3:      dec  temp1
          brne SE3
; ============================= 


; Warteschleifenende
                        
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
                                    
                                
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
                                   
i2c_start:        
mov  i2cdata,i2cadr    ; copy address to transmitt register
sbi  DDRC,SDAP    ; force SDA low
rcall  i2c_qp_delay    ; quarter period delay
                                  
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
                                 
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
                                  
i2c_do_transfer:
sbrs  i2cadr,b_dir    ; if dir = write
rjmp  i2c_write    ;  goto write data
                                   
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
                                    
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
                                    
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
                                   
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


Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wichtige Regeln - erst lesen, dann posten!

* Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Wäre doch zu schön, wenn sich die Leute dran hielten.

Autor: Nörgler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hoffe, dass sich das keiner durchliest....gRRRR

Autor: Verwandter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. Firefly schrieb:
> Wäre doch zu schön, wenn sich die Leute dran hielten.
Wäre aber auch kein Problem, die Zeichen zu zählen.

Autor: Alex Fxxxx (electronicfox)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habe den Fehler übrigens gefunden.
Man muss dazwischen auch noch die ganzen NICAM-Sachen justieren, dann 
funktioniert auch die einfache Soundsteuerung.
Obwohl ich NICAM beim MSP3400 garnicht im IC habe, benötigt der den 
ganzen Sch§§§. OK, ein negativer Punkt für den IC, abe der Sound der 
jetzt raus komt ist einfach nur super.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.