Wie I2S Datenstrom mit AVR M88 einlesen

Gast #1644991
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
#1646103
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
Gast #1646507
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
Gast #1646551
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.
Gast #1646654
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.
(Firma: TravelRec.) Persönliche Seite #1646785
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.
(Firma: TravelRec.) Persönliche Seite #1646793
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).
#1647168
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
(Firma: TravelRec.) Persönliche Seite #1647334
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
(Firma: TravelRec.) Persönliche Seite #1648746
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 ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren