seit kurzem spiele ich mit einem IOWarrior 56 herum, hauptsächlich um dessen SPI Funktion zu nutzen. Leider habe ich ziemlich merkwürdige Probleme mit dem Auslesen von Werten über den SPI Bus. Ich habe mich nun 4 Tage durchgehend mit der Problematik befasst und bin mittlerweile am Verzweifeln...
Kurz die Situation: Ich programmiere in C auf dem neuesten Ubuntu 9.10; Treiber, aktuelle IOW-Library, etc. ist alles sauber eingerichtet.
Ich nutze die libiowkit.so Library um mit dem IOWarrior56 zu kommunizieren.
An den SPI-Pins des IOWarrior hängt ein SPI slave, der über Output-Pins LEDs schalten kann und über Input-Pins die Position von Schaltern abfragen kann.
Das unverständliche Problem: Es hängt von der Anzahl und Kombination der Schreib-/Lesevorgänge ab, ob sich mein Test-Programm aufhängt oder ob und wann es die Korrekten Werte der Schalter zurück gibt.
Mit dem AllInOne-Tool unter Windows funktioniert die Kommunikation, Auslesen, Schreiben tadellos.
In meinem Test-Programm funktioniert z.B. IowKitWrite() nur dann mehr als 3 Mal hintereinander, wenn zwischen den Writes mindestens eine Pause von 3ms ist und wenn nach den Writes KEIN IowKitRead() mehr folgt. In allen anderen Fällen hängt das Programm sich auf.
Soweit ich verstanden habe, schickt nur IowKitWrite() Daten über den SPI-Bus, IowKitRead() liest nur den Wert aus dem Stack, der von IowKitWrite() dort hineingeschrieben wurde.
Insofern sollte es doch generell funktionieren, wenn man ausschließlich Write/Read-Paare verwendet. Tut es bei mir aber leider nicht: nach vier solchen Paaren ist Schluss, dann steht das Programm.
Da ich im Prinzip nur die Beispieldateien aus dem SDK modifiziert habe, sollte es auch nicht an Typos liegen.
Hier der Quellcode meiner Testdatei inkl. Kommentaren von mir (wie ich es mir erkläre):
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "iowkit.h"
int main(int argc, char* argv[]) {
IOWKIT_HANDLE iowHandle;
IOWKIT56_SPECIAL_REPORT m_rep56;
DWORD m_Pid;
// Open connected device
iowHandle = IowKitOpenDevice();
m_Pid = IowKitGetProductId(iowHandle);
// Enable SPI mode
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] = 0x00; // MSB first, SPI mode 0 <-- hier soll laut Sample 0x01 stehen??...
m_rep56.Bytes[2] = 0x01; // 12MBit <-- hier soll laut Sample 0x00 stehen für 93.75 KBit??...
// Set the device to SPI mode. Nothing is written to the SPI bus itself!
IowKitWrite(iowHandle, IOW_PIPE_SPECIAL_MODE, (char*) &m_rep56, IOWKIT56_SPECIAL_REPORT_SIZE);
}
// Clear the SPI by doing one dummy write/read
if(m_Pid == IOWKIT_PID_IOW56)
{
// Set all bits in m_rep56 to 0
memset(&m_rep56, 0, IOWKIT56_SPECIAL_REPORT_SIZE);
m_rep56.ReportID = 0x09; // SPI-Mode
m_rep56.Bytes[0] = 0x03; // Write / Read 3 bytes (24 bits) to the SPI slave
// Send data to the SPI bus (for the first time) and shift data out of the SPI slave
IowKitWrite(iowHandle, IOW_PIPE_SPECIAL_MODE, (char*) &m_rep56, IOWKIT56_SPECIAL_REPORT_SIZE);
// Take the data that was shifted out by the previous IowKitWrite() and write it to &m_rep56
IowKitRead(iowHandle, IOW_PIPE_SPECIAL_MODE, (char*) &m_rep56, IOWKIT56_SPECIAL_REPORT_SIZE);
}
// Write and read data
if(m_Pid == IOWKIT_PID_IOW56)
{
// Set all (random) bits in m_rep56 to 0 again
memset(&m_rep56, 0, IOWKIT56_SPECIAL_REPORT_SIZE);
m_rep56.ReportID = 0x09; // SPI-Mode
m_rep56.Bytes[0] = 0x03; // Write / Read 3 bytes (24 bits) to the SPI slave
m_rep56.Bytes[1] = 0x00; // flags
m_rep56.Bytes[2] = 0x00; // data
m_rep56.Bytes[3] = 0x00; // data
m_rep56.Bytes[4] = 0x02; // data
// Send data to the SPI bus and shift data out of the SPI slave (real values now)
IowKitWrite(iowHandle, IOW_PIPE_SPECIAL_MODE, (char*) &m_rep56, IOWKIT56_SPECIAL_REPORT_SIZE);
// Take the data that was shifted out by the previous IowKitWrite() and write it to &m_rep56
IowKitRead(iowHandle, IOW_PIPE_SPECIAL_MODE, (char*) &m_rep56, IOWKIT56_SPECIAL_REPORT_SIZE);
if (m_rep56.ReportID == 0x09)
{
printf ("full hex output: %#x\n", ((m_rep56.Bytes[2]<<16) | (m_rep56.Bytes[3]<<8) | m_rep56.Bytes[4]));
}
}
// Disable SPI mode
if(m_Pid == IOWKIT_PID_IOW56)
{
memset(&m_rep56, 0, IOWKIT56_SPECIAL_REPORT_SIZE);
m_rep56.ReportID = 0x08; // SPI-Mode
m_rep56.Bytes[0] = 0x00; // Disable SPI-Mode
// Disable SPI mode. Nothing is written to the SPI bus itself!
IowKitWrite(iowHandle, IOW_PIPE_SPECIAL_MODE, (char*) &m_rep56, IOWKIT56_SPECIAL_REPORT_SIZE);
}
// Close device
IowKitCloseDevice(iowHandle);
return 0;
}
Kennt jemand das Problem oder sieht jemand ganz böse Fehler in obigem Code?
Vielen Dank für eventuelle Hilfe!