mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MOS6581/Commodore SID Timing?


Autor: Edward (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Ich bin seit einigen Monaten ein Projekt mit einem Commodore SID 
(MOS6581)
aufzubauen. Der SID wird dabei mit einem Atmel AVR ATMega gesteuert.

Adressleitungen sind an PORTA angeschlossen, Daten an PORTC
und PORTD5 ist CLK und PORTD7 ist /CS. Reset ist an VCC
angeschlossen und R/W an GND.

Trotzdem kommt mit dem Testprogramm kein Ton raus.

Der C-Source (nur provisorisch zum testen) sieht folgendermaßen aus:

#include <avr/io.h>
#include <util/delay.h>


// 1MHz CLK for SID on PORTD5 (OC1A)
void initTimer(void)
{
        TCNT0 = 0;
        OCR1A = 7;
        TCCR1B = 0b00001001;
        TCCR1A = 0b01000000;
}

void initMos(void)
{
        DDRA = 0xFF;         // ADDR
        DDRC = 0xFF;         // DATA
        DDRD |= (1 << PIND7); // CS

        PORTA = 0x00;
        PORTC = 0x00;

        PORTD |= (1 << PIND7);                             // Initialize with /CS on.
}

void writeMos(uint8_t addr, uint8_t data)
{
        PORTA = addr;
        PORTC = data;
        while(!PORTD5){};       // Wait for sync
        PORTD &= ~(1 << PIND7);
        while(PORTD5){};        // Wait for sync
        PORTD |= (1 << PIND7);
}

void testSID(void)
{
        writeMos(24, 15);
        writeMos(0, 196);
        writeMos(1, 9);
        writeMos(5, 105);
        writeMos(6, 252);
        writeMos(4, 33);
}

int main(void)
{
        _delay_ms(1000);
         DDRD |= (1 << PB5);
        initMos();
        initTimer();
        while(1)
        {
                testSID();

                _delay_ms(2000);
                _delay_ms(2000);
                _delay_ms(2000);
        }
}


Hier noch das original Timing-Diagramm:
http://www.waitingforfriday.com/index.php/Commodor...

Oder verstehe ich das falsch?

Autor: hp-freund (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Prüf mal:

while(!PORTD5){};       // Wait for sync

Autor: Edward (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hp-freund schrieb:
> Prüf mal:
>
> while(!PORTD5){};       // Wait for sync


Was genau meinst du?
Auf PORTD5 liegt das CLK-Signal, welches durch den Timer0 generiert 
wird.

Autor: Torsten S. (tse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probier mal

while(!(PIND >> PD5) & 0x01) {};

Autor: Simon Budig (nomis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PORTD5 ist fest definiert auf 5, d.h. darin wird nicht der Zustand des 
5. Pins von Port D wiedergespiegelt. Das ist nur eine Hilfe um die 
Pin->Bitzuordnung wegzuabstrahieren.

Mit

  while (!(PORTD & (1<<PORTD5))) {}

bzw.
  while (PORTD & (1<<PORTD5)) {}

könnte es besser gehen.

Thorsten schlägt noch vor, PIND zu verwenden, da bin ich mir allerdings 
gerade nicht sicher. Der Port ist ja als Output konfiguriert, von daher 
klingt PORTD eigentlich schon ganz sinnvoll...

Viele Grüße,
          Simon

Nachtrag: Gerade nochmal nachgeguckt, PIND sollte funktionieren: 
"Independent of the setting of Data Direction bit DDxn, the port pin can 
be read through the PINxn Register bit"

Autor: Jobst M. (jobstens-de)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht hilft dies weiter.


Gruß

Jobst

Autor: Edward (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Danke für die bisherigen Tipps.

Mit:
void writeMos(uint8_t addr, uint8_t data)
{
        PORTA = addr;
        PORTC = data;
        while(!(PIND >> PD5) & 0x01) {};
        PORTD &= ~(1 << PIND7);
        while (PIND & (1<<PIND5)) {}
        PORTD |= (1 << PIND7);
}

Im Anhang ein Screenshot vom Logic Analyzer.

Noch leider kommt trotzdem kein Ton raus.

Autor: Edward (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups.

Das war der falsche Copy&Paste-Buffer.

Hier noch mal:
void writeMos(uint8_t addr, uint8_t data)
{
        PORTA = addr;
        PORTC = data;
    
        while(!(PIND >> PIND5) & 0x01) {};
        PORTD &= ~(1 << PIND7);

        while (PIND & (1<<PIND5)){};
        PORTD |= (1 << PIND7);
    
}

Autor: Edward (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Hier noch mal ein neuer source-code.

Das Ganze funktioniert leider immer noch nicht und ich bin langsam
am verzweifeln.

Gruß,
Edward

Autor: Edward (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, im .zip-Archiv fehlten dateien.

Autor: Simon Budig (nomis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, ich lese das Datenblatt so, dass er die Daten bei fallender CLK 
sampled. Solange hältst Du aber das CS nicht.

Versuch mal hinzukriegen, dass die Pegelwechsel sauber in der Mitte der 
Clock-Pulse passieren. Sobald Du Dich da fix an die Flankenwechsel der 
CLK hängst, können sehr schnell irgendwelche Zufallseffekte die 
Kommunikation verhindern.

Viele Grüße,
        Simon

Autor: Edward (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon Budig schrieb:
> Versuch mal hinzukriegen, dass die Pegelwechsel sauber in der Mitte der
> Clock-Pulse passieren. Sobald Du Dich da fix an die Flankenwechsel der
> CLK hängst, können sehr schnell irgendwelche Zufallseffekte die
> Kommunikation verhindern.

Das habe ich in der mos6581.c versucht zu erreichen:
void MOS6581_WriteByte(uint8_t i_addr, uint8_t i_data)
{
        PORT_ADDR = i_addr;                             // Addr on PORT_ADDR.
        PORT_DATA = i_data;                             // Data on PORT_DATA

        while(!(PPIN_OC1A >> PIN_OC1A) & 0x01){};       // Wait until clock
                                                        // state changes.

        PORT_CTL &= ~(_BV(PIN_CS));                     // Set /CS low
                                                        // (SID active).

        while(PPIN_OC1A & _BV(PIN_OC1A)){};             // Wait until clock
                                                        // state changes.

        PORT_CTL |= (_BV(PIN_CS));                      // Set /CS high
}     

Autor: Edward (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bisher noch kein Erfolg. Aber trotzdem vielen Dank fuer die bisherigen
Tips.

Ich hab leider nur einen 8-Kanal Logic-Analyzer hier.
Sonst wuerde ich gerne auch einen Screenshot von
DATA + ADDR + CLK + CS zeigen.

Autor: Simon Budig (nomis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guck Dir mal Deinen Screenshot vom Oszi an: Da wird bei +8us das CS auf 
low gezogen. Bei +8.25 (oder so) geht der schon wieder high und das 
kommt mir komisch vor. Ich vermute, dass er frühestens bei +9us wieder 
high gehen sollte, damit der SID eine Chance hat, den Registerwert bei 
+8.75 zu samplen.

Gegebenenfalls bau das mal auf eine harte Abfolge von Befehlen mit NOPs 
dazwischen um, um das Timing sauber hinzukriegen.

Viele Grüße,
        Simon

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Edward,

kennst Du diese Seite hier?

http://roboterclub-freiburg.de/atmega_sound/atmegaSID.html

Passt vielleicht auch noch zu Deinem Projekt.

Gruß,
chris

Autor: Edward (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, die Seite kenne ich. Wollte jedoch den echten SID verwenden.

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.