Forum: Mikrocontroller und Digitale Elektronik Wie I2S Datenstrom mit AVR M88 einlesen


von Peter (Gast)


Lesenswert?

Hallo,

ich suche eine Möglichkeit ein I2S Signal mit einem AVR Mega88 
einzulesen.
Ich will nur den Signalpegel auswerten und über LEDs anzeigen.

Gibt es eine Möglichkeit, ausser die Pin's abzupollen?
Also sowas wie SPI, SIO in irgend einem Modus oder sonst eine Hardware 
unterstützung?

Viele Grüsse,
Peter

von Dirk (Gast)


Lesenswert?

Glaube das wird nicht gehen.
Der M88 kann doch nur mit 24MHz arbeiten und SPI braucht schon >4 Takte 
um was zu empfangen. Pollen wird auch nicht gehen.
I2S ist recht flott, je nach Signal kommen da schon mal 26MHz zusammen.

Ein externes Schieberegister könnte gehen oder ein Prozessor mit I2S 
Eingang.

von Flo (Gast)


Lesenswert?

Erst mal musst du was zur Signalgeschwindigkeit sagen, vorher ist alles 
Rätselraten.
Woher kommt das Signal, wie schnell ist es, Auflösung?

von Jobst M. (jobstens-de)


Lesenswert?

Bis 96kHz/24Bit sollte SPI noch mitmachen. Allerdings kann es sein, daß 
Du Dir noch ein paar clock-Signale erzeugen musst ... Dies ist auch der 
Grenzfall und damit schon sehr Zeitkritisch.

Bei CD (44.1/16) sollte es aber keine Probleme geben.



Gruß

Jobst

von X- R. (x-rocka)


Lesenswert?

Jobst M. schrieb:
> Bis 96kHz/24Bit sollte SPI noch mitmachen.

sicher? I2S läuft mit 32bit, 2 kanäle => 6.144MHz hat dann die SCLK.
gewagt, gewagt...

ich würde auch ein externes Schieberegister nehmen, oder ein CPLD.

von Jobst M. (jobstens-de)


Lesenswert?

Moin!

I2S läuft nicht immer mit 32Bit. Aber ich habe auch mit diesem Fall 
gerechnet. Dann läuft der uC mit 24.576MHz das ist leicht ausserhalb 
seiner Specs. Allerdings sollte der Takt aus dem Datensignal generiert 
werden.
Das dies Grenzwertig ist, habe ich aber geschrieben.

Abgesehen davon, würde ich das Ganze analog machen.

Wenn es unbedingt digital sein muss, kann er ja einen SRC davor 
schalten.


Gruß

Jobst

von Peter (Gast)


Lesenswert?

Danke für die Infos.

Ich habe zur Zeit 32Bit mit maximal 12,xxx MHz auf dem I2S Bus (192KHz 
128FS).
Das kann aber sein das ich noch schneller werden muss.
Nun eine reine Software Lösung schließe ich jetzt auch aus.
Der Einwand mit der SPI habe ich nachgelesen und wird wohl auch nicht 
gehen.

Bleibt wohl nur ein Schieberegister oder ein kleiner ARM Prozessor.
Dumm nur das ich mich mit den ARM Prozessoren nicht auskenne und auch 
keine Tools dafür habe. Was gibt es denn vernünftiges dafür?

Eine AVR Lösung wird mit einem Schieberegister aber auch schwer. Ich 
muss den Inhalt ja abholen bevor das nächste Bit rein kommt. Oder gibt 
es da entsprechende Bausteine die das Ergebnis zwischen speichern?

MfG Peter

von TheMason (Gast)


Lesenswert?

@Peter

Nimm nen ARM.
Ein AT91SAM7S256 z.b. hat direkt eine I2S Schnittstelle inkl. DMA 
On-Board.
Damit wird I2S zur Nebensache. Einem AVR würd ich ohnehin nicht zutrauen 
I2S Deserializing zu machen (es sei denn er macht NUR das), von der 
Verarbeitung mal ganz abgesehen. Jedenfalls nicht wenns CD Qualität 
aufwärts sein soll. 8kHz 16Bit mono bekommt man mit einem AVR sicherlich 
noch hin. Und da wäre auch wohl Verarbeitung noch evtl drin. Aber alles 
was darüber geht ... wenig Chancen.

von Peter (Gast)


Lesenswert?

Ich will die Daten nur einlesen und den Pegel anzeigen (LEDs).
Wenn es geht, auch noch als 8Bit Wert über I²C bereitstellen.

Das ein ARM7 das packt ist mir auch klar, aber den kenne ich nicht.

MfG, Peter

von TheMason (Gast)


Lesenswert?

Also wenn du dir den RMS Wert anzeigen lassen willst ist es noch etwas 
zu tun bis dahin ...

Du mußt jedes Sample (also jedes empfangene Datenwort) quadrieren, 
aufsummieren, am Ende der Summation (alle x Werte, wobei x deine 
Fenstergröße vorgibt) dann durch x teilen, die Wurzel daraus ziehen und 
dann kannst du den Wert in dB umrechnen.
Bei CD-Qualität ist der Aufwand (wenn man nicht gravierende 
Vereinfachungen macht) für einen AVR nicht zu schaffen.

Lösung a) :
  - nur 8 von den 16 bzw 24 Bits verarbeiten.
  - Fenstergröße fest auf 2'er Potenz
  - Wurzelfkt. stark optimieren (Tabellen usw)

Lösung b) :
  - I2S nach analog Wandeln, analog filtern und mit dem ADC des AVR's 
einlesen

Wenn du es rein digital machen willst denke ich kannst du das vergessen.
Quadrieren von 24 bzw 32 Bit. Teilen einer 32 bzw 64 Bit Zahl durch 16 
bzw 32 Bit. Wurzelziehen aus einer 32 Bit Zahl. Und das alles in 10-20µs 
(200-400 Takte bei 20MHz pro Sample). Sehr sportlich.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Habe ich mal gemacht. Dabei taste ich nicht den kompletten Datenstrom 
ab, sondern immer nur Stichproben, damit noch Zeit zum Rechnen und für 
die Darstellung bleibt. Für eine LED-Anzeige gar kein Problem. Hier 
waren die 12.288Mhz MasterClock auch gleich die Taktfrequenz für den 
Controller, so daß man 4 Takte pro Samplebit zur Verfügung hat. Über 
LRCLK wurde der Frame synchronisiert, wenn ich mich recht erinnere, habe 
ich 16Bit/48kHz ausgewertet, logarithmiert und auf 2x10 LEDs angezeigt. 
Nettes Gimmick ist eine Peak-Hold-Funktion. Das Projekt läuft in einer 
digitalen DI-Box, Controller ist ein Mega16, der auch für die Akkuladung 
zuständig ist.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

TheMason schrieb:
> Wenn du es rein digital machen willst denke ich kannst du das vergessen.
> Quadrieren von 24 bzw 32 Bit. Teilen einer 32 bzw 64 Bit Zahl durch 16
> bzw 32 Bit. Wurzelziehen aus einer 32 Bit Zahl. Und das alles in 10-20µs
> (200-400 Takte bei 20MHz pro Sample). Sehr sportlich.

Es gibt auch LookUp-Tables, die im oben beschriebenen 
Stichproben-Betrieb schnell genug sind. Es kommt hier nicht auf 100,000% 
Genauigkeit an. Es soll habwegs glaubhaft blinken und bei der Findung 
des optimalen Pegels helfen (nehme ich an).

von Rene B. (themason) Benutzerseite


Lesenswert?

@travelrec

Einverstanden. Ich bin (leider) davon ausgegangen es so akkurat wie 
möglich zu machen, und hab natürlich die wichtigsten 
Optimierungsmöglichkeiten ausgelassen. Scheiß Perfektionismus :-)
Aber so gesehen lässt sich da schon was machen.

von Peter (Gast)


Lesenswert?

@Travel Rec.

Das ist genau das was ich machen will.
Existiert das Projekt noch?
Und ist der Code Öffentlich?

MfG Peter

von Jörg H. (idc-dragon)


Lesenswert?

Ich bin auch zuversichtlich, daß der Mega88 das kann.
Ich habe gerade das Umgekehrte gebaut, eine I²S Ausgabe, 48 kHz Stereo 
16 Bit. Und die Samples muß der arme Controller auch noch errechenen 
(DDS mit nachgeschalteter linearer Interpolation zwischen den 
Tabellenwerten).

Nimm nicht den SPI, sondern den USART im synchronen Modus. SPI hat beim 
Mega88 leider keine Doppelpufferung, USART schon.

Ein weiterer "Trick" in meinem System war, nested Interrupts zuzulassen, 
um die Latenz klein zu kriegen. Und die Codierung der Haupt-ISR in 
Assembler...

Jörg

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Naja, leider kann man den synchronen UART nur als Master-SPI gebrauchen, 
was bei der vorliegenden Anwendung keine Vorteile bringt.

Hier der betreffende Codeabschnitt, es werden keine Hardware-Interfaces 
benutzt. Engegen meiner Annahme werden nur je 8 obere Bits für den 
linken und rechnten Kanal benutzt, was für 10 LEDs aber ausreicht.
1
;reads I2S data, 8 MSB for each channel
2
GetSoundADC:
3
 cli
4
 
5
_GSA1:
6
 sbic  PinC, LRCK                  ;syncronize to LRCK
7
 rjmp  _GSA1
8
9
_GSA2:
10
 sbis  PinC, LRCK
11
 rjmp  _GSA2
12
 
13
 nop
14
 clr  Temp
15
 clc
16
 sbic  PinC, SDIN
17
 sec
18
 rol  Temp
19
 clc
20
 sbic  PinC, SDIN
21
 sec
22
 rol  Temp
23
 clc
24
 sbic  PinC, SDIN
25
 sec
26
 rol  Temp
27
 clc
28
 sbic  PinC, SDIN
29
 sec
30
 rol  Temp
31
 clc
32
 sbic  PinC, SDIN
33
 sec
34
 rol  Temp
35
 clc
36
 sbic  PinC, SDIN
37
 sec
38
 rol  Temp
39
 clc
40
 sbic  PinC, SDIN
41
 sec
42
 rol  Temp
43
 clc
44
 sbic  PinC, SDIN
45
 sec
46
 rol  Temp
47
 clc
48
 sbic  PinC, SDIN    
49
 sec
50
 rol  Temp
51
52
 brcc  _TCLeft        ;convert 2s complement to positive value
53
 neg  Temp
54
55
_TCLeft:
56
 sts  LeftLow, Temp
57
58
59
_GSA4:
60
 sbic  PinC, LRCK 
61
 rjmp  _GSA4
62
63
 nop
64
 clr  Temp
65
 clc
66
 sbic  PinC, SDIN
67
 sec
68
 rol  Temp
69
 clc
70
 sbic  PinC, SDIN
71
 sec
72
 rol  Temp
73
 clc
74
 sbic  PinC, SDIN
75
 sec
76
 rol  Temp
77
 clc
78
 sbic  PinC, SDIN
79
 sec
80
 rol  Temp
81
 clc
82
 sbic  PinC, SDIN
83
 sec
84
 rol  Temp
85
 clc
86
 sbic  PinC, SDIN
87
 sec
88
 rol  Temp
89
 clc
90
 sbic  PinC, SDIN
91
 sec
92
 rol  Temp
93
 clc
94
 sbic  PinC, SDIN
95
 sec
96
 rol  Temp
97
 clc
98
 sbic  PinC, SDIN
99
 sec
100
 rol  Temp
101
102
 brcc  _TCRight      ;convert 2s complement to positive value
103
 neg  Temp
104
105
_TCRight:
106
 sts  RightLow, Temp
107
 
108
 sei
109
 ret

von Peter (Gast)


Lesenswert?

Danke an alle.

Nun versuche ich mal das alles umzusetzen.
Melde mich wieder, wenn ich was neues berichten kann.

Peter

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Ja, mach mal. Die erhaltenen Daten mußt Du eigentlich nur maximieren 
(Peak detection) und diesen Maximalwert relativ langsam (10% 
Laufbandlänge /100ms) herunterzählen. Neue Peaks werden sofort 
übernommen. Das sieht dann optisch schon gut aus. Aufwerten läßt sich 
das durch ein Peak-Hold, bei dem die Spitzenpunkte 2s lang auf der 
Anzeige bleiben, bevor sie mit kleineren Werten geladen werden. Dabei 
kann dann die Release-Zeit des Gesamtbandes wieder etwas zügiger sein, 
so daß man schnellere Reaktionen sieht. Viel Spaß beim Proggen! Ich mach 
mal gelegentlich ein Filmchen von meinen Anzeigen ;-)

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?


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.