Forum: Mikrocontroller und Digitale Elektronik AD7793 an ARM9


von Alexander D. (lieberarm9alsarmab)


Lesenswert?

Hallo,

derzeit versuche ich einen bzw. mehrere A-/D Wandler vom Typ AD7793 über 
SPI anzusprechen. Angeschlossen sind diese an einem AT91SAM9261. Das 
C-Programm läuft im User-Space von Linux.
Die angeschlossenen ADUs tauchen unter /dev auf und können somit über 
den Filedescriptor beschrieben / gelesen werden.

Wenn das C-Programm eine Nachricht über SPI sendet, kann man am 
Oszilloskop sehen, dass ein Clocksignal, Daten an DIN (MOSI) sowie die 
Flankenwechsel am CS-Pin am ADU anliegen.
Also scheint das Schreiben scheinbar zu funktionieren. Mit dem Lesen 
sieht es leider anders aus. Mit dem unten stehenden Programm versuche 
ich zunächst einmal das ID-Register zu lesen. Im Datenblatt konnte ich 
nicht finden, wieviele Bits das Register hat und versuche deswegen 
24-Bits = 3 Bytes auszulesen. >= 32 Bits high an DIN löst einen Reset 
des ADU aus.

Das Programm soll folgendes machen:
- Reset des ADU
- ID-Register lesen an Control Register senden
- 24 Bit lesen
zurück kommt 00 00 00 und keine ID...


Vielleicht hat jemand einen Tipp für mich woran es liegen kann.

Gruß
Alexander


------------------------------------------------------------
static void reset(int fd)
{
  struct spi_ioc_transfer  xfer[2];
  unsigned char    buf[32], *bp;
  int      status;

  memset(xfer, 0, sizeof xfer);
  memset(buf, 0, sizeof buf);

  // 32 Bit high = 4x 8 bit = 4 Byte
  buf[0] = 0xFF;                       // 0xFF = 0b1111
  buf[1] = 0xFF;                       // 0xFF = 0b1111
  buf[2] = 0xFF;                       // 0xFF = 0b1111
  buf[3] = 0xFF;                       // 0xFF = 0b1111

  xfer[0].tx_buf = (__u64) buf;
  xfer[0].len = 4; // 4 Byte = 32 Bit

  status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);

  if (status < 0) {
    perror("SPI_IOC_MESSAGE");
    return;
  }
}

static void do_msg(int fd, int len)
{
  struct spi_ioc_transfer  xfer[2];
  unsigned char    buf[32], *bp;
  int      status;

  memset(xfer, 0, sizeof xfer);
  memset(buf, 0, sizeof buf);

  buf[0] = 0x60;    // 0x60 = 0b(0)1100000 ID-Register lesen

  xfer[0].tx_buf = (__u64) buf;
  xfer[0].len = 1; // 1 Byte = 8 Bit

  xfer[1].rx_buf = (__u64) buf;
  xfer[1].len = len; // 3 Byte = 24 Bit

  status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);

  if (status < 0) {
    perror("SPI_IOC_MESSAGE");
    return;
  }

  printf("response(%2d, %2d): ", len, status);
  for (bp = buf; len; len--)
    printf(" %02x", *bp++);
  printf("\n");
}

int main()
{
  fd = open("/dev/spidev1.3", O_RDWR);
  if (fd < 0)
  {
    perror("open");
    return 1;
  }

  reset(fd);
  do_msg(fd,3);

  fclose(fd);

  return 0;
}
------------------------------------------------------------

von Microman (Gast)


Lesenswert?

Hallo,

wird denn auch die Chip-Select-Leitung angesteuert, oder ist die fest 
auf low? Wenn nicht, wird der Chip nicht reagieren.

Gruß Microman

von Alexander D. (lieberarm9alsarmab)


Lesenswert?

Microman schrieb:
> Hallo,
>
> wird denn auch die Chip-Select-Leitung angesteuert, oder ist die fest
> auf low? Wenn nicht, wird der Chip nicht reagieren.
>
> Gruß Microman

Die CS-Leitung wird vom SPI-Master angesteuert. Am Oszilloskop ist der 
Wechsel auf low (aktivieren des ADUs) und nach den Daten wieder auf high 
(deaktivieren des ADUs) zu sehen.

von Arc N. (arc)


Lesenswert?

Alexander D. schrieb:
> Hallo,
>
> derzeit versuche ich einen bzw. mehrere A-/D Wandler vom Typ AD7793 über
> SPI anzusprechen. Angeschlossen sind diese an einem AT91SAM9261. Das
> C-Programm läuft im User-Space von Linux.
> Die angeschlossenen ADUs tauchen unter /dev auf und können somit über
> den Filedescriptor beschrieben / gelesen werden.
>
> Wenn das C-Programm eine Nachricht über SPI sendet, kann man am
> Oszilloskop sehen, dass ein Clocksignal, Daten an DIN (MOSI) sowie die
> Flankenwechsel am CS-Pin am ADU anliegen.
> Also scheint das Schreiben scheinbar zu funktionieren. Mit dem Lesen
> sieht es leider anders aus. Mit dem unten stehenden Programm versuche
> ich zunächst einmal das ID-Register zu lesen. Im Datenblatt konnte ich
> nicht finden, wieviele Bits das Register hat und versuche deswegen
> 24-Bits = 3 Bytes auszulesen. >= 32 Bits high an DIN löst einen Reset
> des ADU aus.

Die haben alle, bis auf DATA, OFFSET und FULLSCALE genau ein Byte.
Die Übertragung läuft normalerweise wie folgt:
Kommando senden, Rückgabewert ignorieren
n mal 0x00 senden, Rückgabewert speichern
Während dessen muss /CS auf Low sein.
Hier müssten also zwei Bytes: 0x60, 0x00 gesendet werden, nicht eins.

von Imon (Gast)


Lesenswert?

Alexander D. schrieb:
> derzeit versuche ich einen bzw. mehrere A-/D Wandler vom Typ AD7793 über
> SPI anzusprechen. Angeschlossen sind diese an einem AT91SAM9261. Das
> C-Programm läuft im User-Space von Linux.
> Die angeschlossenen ADUs tauchen unter /dev auf und können somit über
> den Filedescriptor beschrieben / gelesen werden.

Welchen Treiber nutzt du denn ? ich kann im Vanila Kernel ad hoc kein 
Treiber finden der Das Device anspricht.

Außerdem ist die Frage, bekommt du beim lesen Daten über denn Bus und 
sie Kommen nicht in dein Programm an oder rührt sich da aus denn Buss 
schon gar nichts.

Eine Erfahrung die ich vor ein paar Wochen machen durfte/müsste ist die 
das der atmel spi treiber über DMA Agiert und das es, wenn dein Treiber 
für den AD7791 das nicht berücksichtigt das die Daten via DMA getauscht 
werden können, die Antwort nicht von SPI Bus holt sondern, aus der einer 
cache-page wo halt noch keine Antwort steht.Also sehe dir bitte auch 
denn Kernel Treiber an ob du vielleicht so ein Problem hast.

Der Treiber an denn wir so ein Problem hatten war ein AD Touch AD7877. 
(drivers/input/touchscreen/ad7877.c) .Die lösung des Problem ist mit
commit 3843384a055496dfed3c93ae883d964d8290fdab in den Mainline Kernel 
gegangen.

Es ist nur geraten aber vielleicht drückt der Schuh bei dir ähnlich, so 
das sich zumindest ein blick lohnen würde.

von Alexander D. (lieberarm9alsarmab)


Lesenswert?

Der AD-Wandler verwendet den Standard "spidev"-Treiber.
Die Oszilloskopauswertung hat ergeben, dass die Daten korrekt am Wandler 
ankommen und danach auch Daten an DOUT anliegen.

Allerdings liegt das folgende Problem vor:
Beitrag "Pull up Widerstand an MISO"

Dadurch, dass die Signale auch im Highbereich (Amplitude ca. 0,6 statt 
3,3V) noch als lowSignale interpretiert werden, kommen dann folglich nur 
"00" als Daten an.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.