Frage zu SPI (Thermometerprogramm)

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
suicided
Posts: 12
Joined: Mon Jul 14, 2008 4:43 pm

Frage zu SPI (Thermometerprogramm)

Post by suicided »

Hallo Forum!

Da ich plane eine DDS (AD9910) mittels der SPI des IOW56 zu steuern beschäftige ich mich gerade mit der Dokumentation dazu und dem Beispielprogramm. Dabei bin ich aber (meiner Meinung nach) auf einen Wiederspruch gestoßen. Im Thermometerprogramm steht:

Code: Select all

if(m_Pid == IOWKIT_PID_IOW56) 
    {
        memset(&m_rep56, 0, IOWKIT56_SPECIAL_REPORT_SIZE);
        m_rep56.ReportID = 0x08; //SPI-Mode
        m_rep56.Bytes[0] = 0x01; //Enable SPI-Mode
        m_rep56.Bytes[1] = 0x01; // mode MSB first, /CPOL, CPHA
        m_rep56.Bytes[2] = 0x00; // 93.75 KBit

        IowKitWrite(iowHandle, IOW_PIPE_SPECIAL_MODE, (char *) &m_rep56, IOWKIT56_SPECIAL_REPORT_SIZE);
    }
Laut Doku sollte aber das 'bit 0' von 'm_rep56.Bytes[1]' 0 gesetzt werden (ungenutzt). Um die kommentierte Funktion zu erreichen sollte da also eigentlich "m_rep56.Bytes[1] = 0x02;" stehen. Oder sehe ich das falsch?

VG
mario
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Frage zu SPI (Thermometerprogramm)

Post by Guido Körber »

Welches Beispielprogramm ist das?
suicided
Posts: 12
Joined: Mon Jul 14, 2008 4:43 pm

Re: Frage zu SPI (Thermometerprogramm)

Post by suicided »

Das steht unter "Windows\Samples\SPI\C++". Betreffende Stelle brfindet sich in "MAXIM6675Dlg.cpp". Aber auch bei Delphi wurde das so gemacht. (VB hab ich mir nicht angeschaut.)
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Frage zu SPI (Thermometerprogramm)

Post by Guido Körber »

Das ist definitiv falsch, das gesetzte Bit wird vom IOW56 nicht benutzt. Da müssen wir dann mal reinschauen. Die Beispiele funktionieren auf jeden Fall.
User avatar
Christoph Jung
Posts: 673
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Frage zu SPI (Thermometerprogramm)

Post by Christoph Jung »

Das ist ein Fehler, der uns in diesem Beispiel unterlaufen ist. Da das Bit nicht benötigt wird maskeirt es der Chip aus (wie Guido schon schrieb). Darum ist es uns beim Testen nicht aufgefallen. Und wenn ein Programm erstmal läuft überfliegt man sowas leider schonmal, vor allem wenn man die Beispiele für mehrere Chips und Programiersprachen anpassen muss. Wir werden es bei der nächsten Revision der Beispiele korrigieren. Danke für den Hinweis.
Software developer
suicided
Posts: 12
Joined: Mon Jul 14, 2008 4:43 pm

Re: Frage zu SPI (Thermometerprogramm)

Post by suicided »

Ich hab mal noch 'ne ergänzende Frage zu SPI mit dem IO-Warrior: Weil mein SPI-Slave nicht auf die Kommunikation reagiert, habe ich mir das ganze mal mit 'nem Logikanalysator angeschaut. Dabei kam folgendes raus:
Image
(von oben: /SS, SCK, MISO, MOSI, IO-Update)
Ich befürchte fast, dass die Pausen zwischen den Bytes den Slave (AD9910) in den sog. "Out-of-Sequence" Modus versetzen und dieser daraufhin nicht mehr reagiert (bis zum nächsten IO-Reset). Es müssen aber immer mindestens 4 Bytes auf einmal übertragen werden.
Gibt es irgendeine Möglichkeit die Daten auch am Stück zu übertragen? Ich hab schon mal in die Quellen der Bibliothek geschaut - das sind aber nur böhmische Dörfer für mich.
Außerdem stören mich ein wenig die Spitzen in /SS.
Last edited by suicided on Wed Aug 20, 2008 4:19 pm, edited 1 time in total.
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Frage zu SPI (Thermometerprogramm)

Post by Guido Körber »

Die kurzen Pausen zwischen den Bytes sind normal und unvermeidlich, SPI hat meistens kein double-buffering im Sender, daher entsteht eine kurze Pause wenn das nächste Byte nachgeladen wird.

Die Spikes auf der /SS Leitung sehen komisch aus, die kommen auf jeden Fall nicht vom IO-Warrior. Wie lang sind denn die Leitungen zum externen Chip?
suicided
Posts: 12
Joined: Mon Jul 14, 2008 4:43 pm

Re: Frage zu SPI (Thermometerprogramm)

Post by suicided »

Die Leitung war ca. 30 cm lang und jeder zweite Draht (Flachbandkabel) war GND. Die Spikes stören mich auch weniger, da ich auf das /SS Signal nicht angewiesen bin (...nur ein Slave). Aus diesem Grund hab ich die bei der Messung nicht weiter verfolgt.
So langsam werd ich mich wohl damit abfinden müssen, dass der IO-Warrior inkompatibel zum AD9910 ist - auch wenn ich es immer noch nicht so recht wahrhaben will. Ich kann mir sonst einfach nicht erklären, warum das nicht geht, denn eigentlich ist alles genau so, wie bei der AD-eigenen Steuerung auf dem Evaluation-Board - nur eben mit diesen Pausen zwischen den Bytes. Schade eigentlich... alles andere auf dem Markt läßt sich nur mit sehr viel mehr Aufwand programmieren.
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Frage zu SPI (Thermometerprogramm)

Post by Guido Körber »

Nein, inkompatibel sind die Chips mit Sicherheit nicht.

Eine Verbindung über SPI zum Laufen zu kriegen ist meistens mit ein paar Fehlversuchen verbunden. Alleine schon CPOL/CPHA sorgen da immer wieder für Spaß.
suicided
Posts: 12
Joined: Mon Jul 14, 2008 4:43 pm

Re: Frage zu SPI (Thermometerprogramm)

Post by suicided »

Sooo schwer ist das aber nicht. Der AD9910 verlangt die Datenübernahme an der steigenden Flanke und SCK ist vor und nach der Übertragung "don't care". Also CPOL=1; CPHA=1 oder CPOL=0; CPHA=0. Hier mal ein Ausschnitt aus meinem Programm (C#):

Code: Select all

IntPtr devHandle;
byte[] rep = new byte[8];
byte[] srep = new byte[64];

private void button4_Click(object sender, EventArgs e)
{
    /* SPI aktivieren */
    srep[0] = 0x08; // ID für SPI
    srep[1] = 0x01; // SPI enable
    srep[2] = 0x00; // MSB first, CPOL=0, CPHA=0
    srep[3] = 0x77; // 200 kHz
    iowkit.IowKitWrite(devHandle, 1, srep, (uint)srep.Length);

    /* Daten senden */
    srep[0] = 0x09; // ID für SPI-Data
    srep[1] = 0x09; // 9 Bytes
    srep[2] = 0x00; // kein DRDY, /SS nach der Übertragung nicht mehr aktiv
    srep[3] = 0x0E; // Instruction-Byte und 8 Byte Registerdaten
    srep[4] = 0x00;
    srep[5] = 0x00;
    srep[6] = 0x00;
    srep[7] = 0x00;
    srep[8] = 0x0F;
    srep[9] = 0x00;
    srep[10] = 0x00;
    srep[11] = 0x00;
    iowkit.IowKitWrite(devHandle, 1, srep, (uint)srep.Length);

    /* SPI deaktivieren */
    srep[0] = 0x08; // ID für SPI
    srep[1] = 0x00; // SPI disable
    iowkit.IowKitWrite(devHandle, 1, srep, (uint)srep.Length);

    /* IO-Update */
    rep[1]  |= 0x08; // IO-Update-Pin an Port 0.3
    iowkit.IowKitWrite(devHandle, 0, rep, (uint)rep.Length);
    Thread.Sleep(10);
    rep[1] &= ^0x08;
    iowkit.IowKitWrite(devHandle, 0, rep, (uint)rep.Length);
}
Ich werde morgen aber mal noch die anderen Einstellungen probieren.
Post Reply