Forum: Mikrocontroller und Digitale Elektronik ARM und WS2812 LEDs mit DMA und ATF16V8B?


von Torsten C. (torsten_c) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

kömplementär zu dem Beitrag "STM32Fxx und WS2812 LEDs ohne DMA" möchte 
ich die LEDs mit DMA ansteuern. Diese STM32F4-Bibliothek erzeugt 
PWM-Werte für die Datenleitung und schiebt sie dann per DMA raus, das 
finde ich aber doof:
1
void p_WS2812_calcTimerBuf(void)
2
{
3
  uint32_t n;
4
  uint32_t pos;
5
  WS2812_RGB_t led;
6
7
  if(ws2812_channel==0) return;
8
9
  pos=0;
10
  // timingzeiten fuer alle LEDs setzen
11
  for(n=0;n<ws2812_maxanz;n++) {
12
    led=ws2812_ptr[n];
13
14
    // Col:Green , Bit:7..0
15
    WS2812_TIMER_BUF[pos]=WS2812_LO_TIME;
16
    if((led.green&0x80)!=0) WS2812_TIMER_BUF[pos]=WS2812_HI_TIME;
17
    pos++;
18
    /* ... ähnliche Zeilen übersprungen ... */
19
    // Col:Red , Bit:7..0
20
    /* ... ähnliche Zeilen übersprungen ... */
21
    // Col:Blue , Bit:7..0
22
    /* ... ähnliche Zeilen übersprungen ... */
23
  } 
24
25
  // nach den Farbinformationen eine Pausenzeit anhängen (2*30ms)
26
  for(n=0;n<WS2812_PAUSE_ANZ*WS2812_BIT_PER_LED;n++) {
27
    WS2812_TIMER_BUF[pos]=0;  // 0 => fuer Pausenzeit
28
    pos++;
29
  }
30
}
Quelle: http://mikrocontroller.bplaced.net/wordpress/?page_id=3665

DENN: Ich möchte 8 Ausgänge haben und kann den Speicher und die 
Rechenzeit nicht verschwenden und möchte die PWM-Signale daher nicht im 
µC berechnen.

Am besten: Per DMA aus der SD-Karte raus und ohne Bit-Magie per DMA 
wieder zu den LEDs.

Meine Idee: Ich nehme einen ATF16V8B (EEPLD für etwa 1€) und 
programmiere ihn so, dass er das entsprechende 1-wire-Protokoll erstellt 
(s. Anlage).

Das ganze soll billig sein (OK, ist kommerziell, muss ich zugeben).

Es geht erstmal nur um kleine Stückzahlen, wo wir keine Pin-Abstände 
unter 1.27mm verbauen wollen. Der LPC1114FN28 ist im DIL-Gehäuse, ginge 
also, hat aber leider kein DMA.

Also ein Modul statt ein µC:

Ein XMC4500 Relax Kit scheint mir das günstigste mit DMA zu sein, 
billiger als ein STM32F4Discovery.

Und der ATF16V8B + ein paar Logik-ICs (z.B. 74AC573 Latch) ist wohl die 
günstigste Lösung, um die DMA-Daten in das 1-wire-Protokoll zu wandeln, 
oder was meint Ihr?

: Bearbeitet durch User
von Uwe B. (derexponent)


Lesenswert?

das Timing der WS2812 ist nicht unkritisch

wenn sich die SD-Karte beim lesen mal eine Pause
von 50us zwischen zwei Bytes genemigt
hast du ein Problem

ob das funktioniert, würde ich also zuerst mal prüfen

und das hier :

Torsten C. schrieb:
> Hallo zusammen,
>
> und kann den Speicher und die
> Rechenzeit nicht verschwenden und möchte die PWM-Signale daher nicht im
> µC berechnen.
>

das berechenen der Signale läuft parallel zum DMA-Transfer ab
(da wird also keine Zeit verschwendet)

und der Speicherplatz bei 192kByte RAM vom F4 sollte auch nicht das 
Problem sein es sei den deine restliche Anwendung braucht den Platz.

Gruss Uwe

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Also das Timing kenne ich, ist nicht mein erstes Projekt mit der WS2912.

Wegen "Zeit verschwendet" kann ich Dir Recht geben.

Zum "Speicherplatz": Bei 8000 LEDs wäre ein Frame "ausgerollt" 192kB 
groß.

Die RGB-Daten allein wären nur 24kB. Verstehst Du das Problem?

Wegen der Pausen beim SD-Karten lesen benötige ich ja mehr als einem 
Puffer.

Und wie soll ich Deiner Meinung nach 8 Ausgänge realisieren?

Und nur zum Verständnis: Ein XMC4500 Relax Kit kostet deutlich weniger 
als ein STM32F4Discovery. Sollte ich ein STM32F4Discovery nehmen? Falls 
ja, warum?

: Bearbeitet durch User
von Daniel H. (Firma: keine) (commander)


Lesenswert?

Torsten C. schrieb:
> DENN: Ich möchte 8 Ausgänge haben und kann den Speicher und die
> Rechenzeit nicht verschwenden und möchte die PWM-Signale daher nicht im
> µC berechnen.

Torsten C. schrieb:
> Zum "Speicherplatz": Bei 8000 LEDs wäre ein Frame "ausgerollt" 192kB
> groß.

Hast du 8000 LEDs pro Kanal oder insgesamt, d.h. 1000 LEDs pro Kanal? Im 
letzteren Fall könntest du den Speicherbedarf doch schon einmal um den 
Faktor 8 reduzieren indem du für alle Kanäle den gleichen Buffer 
verwendest und nur entsprechend neu beschreibst.

Torsten C. schrieb:
> Zum "Speicherplatz": Bei 8000 LEDs wäre ein Frame "ausgerollt" 192kB
> groß.

Welche Framerate benötigst du denn und was soll der ARM sonst noch so 
nebenher machen? Immerhin rennt die Kiste (wenn ich das richtig sehe) 
mit 120 MHz, bei 1 FPS dürfte sie sich selbst bei 8000 LEDs doch arg 
langweilen.

von Uwe B. (derexponent)


Lesenswert?

8000 LEDs ?!?

bei 80 EUR pro Rolle (a 240 LEDs) komme ich da auf einen Preis
von über 2500 EUR....respekt !

zum Speicherplatz : Daniel hat recht
mit meiner Library würden 8000 LEDs (4CH a 2000 LEDs) 117 kByte 
benötigen

wenn man die LIB umschreibt auf 8CH mit zwei Timern
nur noch 70 kByte

zur Hardware : das musst du wissen was du einsetzen willst

und noch was : wenn du die Farbdaten auf der SD-Karte speicherst,
musst du die Daten von JEDEM Frame erzeugen und speichern !!

das bedeutet du musst Offline (z.B. am PC) eine Software haben
die dir diese Daten erzeugt und somit ist das ganze sehr unflexibel

der Vorteil von der Berechnung zur Laufzeit ist,
du kannst dir beliebige "Farbspiele" sehr leicht realisieren
z.B. alle LEDs mit Regenbogenfarben füllen und diese dann
per "Rotate" Befehl durschieben lassen
das sind ein paar Zeilen Code :
1
for(n=0;n<LED_ANZ;n++) {
2
  set_led(n,farbe);
3
  farbe++;
4
}
5
while(1) {
6
  refresh();
7
  rotate_leds();
8
  pause(ms)
9
}

wenn du diesen Effekt auf der SD-Karte abbilden willst,
musst du im Vorfeld alle Frames berechnen und diese dann
als zich Einzelfiles abspeichern und dann in der CPU wieder laden

aber mach wie du denkst

und schreib ob es geklappt hat

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Angehängte Dateien:

Lesenswert?

Anbei mal ein Screenshot von der Logik des EEPLDs.

SCLK ist der SPI-Clock

"OE" geht an den Output-Enable des 8-Bit Schieberegisters.

"HL" geht über einen Widerstand an die Ausgänge des Schieberegisters.

Die Logik ist dann so, dass entweder ein "High" aus "HL" kommt, oder die 
Daten aus dem Schieberegister (dann ist "HL" hochohmig) oder es kommt 
ein "Low" aus "HL".

Dahinter sitzen 8 Schmitt-Trigger, um die unsauberen Signale 
aufzufrischen.

Was meint Ihr?

Daniel H. schrieb:
> Welche Framerate benötigst du denn

Also bei 20 FPS und darunter fängt das "ruckeln" an, die meisten wollen 
daher 30 FPS.

Daniel H. schrieb:
> für alle Kanäle den gleichen Buffer
> verwendest

Dann muss ich die LEDs nacheinander beschreiben. Diese Option kann ich 
für einen zweiten oder dritten SPI ziehen, um das System skalierbar zu 
halten.

Über einen SPI will ich 8 Ketten Synchron aktualisieren. Ob der 
Zeitversatz sichtbar wäre, weiss ich nicht, aber das wäre vielleicht 
auch noch ein Nachteil von "nacheinander".

Uwe B. schrieb:
> wenn man die LIB umschreibt auf 8CH mit zwei Timern
> nur noch 70 kByte

Braucht man dann nicht 8 SPIs dafür? Ich habe die LIB noch nicht im 
Detail analysiert.

Uwe B. schrieb:
> der Vorteil von der Berechnung zur Laufzeit ist,
> du kannst dir beliebige "Farbspiele" sehr leicht realisieren

So habe ich das in meinem Wohnzimmer gemacht. Gefordert sind aber 
beliebige Farbmuster oder "Filme" auf SD-Karte. Zu rechnen hat der µC 
dann trozdem noch: Helligkeit oder Farbtemperatur verstellen, Daten vom 
PC auf die SD-Karte laden (während das Programm läuft) usw.

von Torsten C. (torsten_c) Benutzerseite


Angehängte Dateien:

Lesenswert?

Torsten C. schrieb:
> "HL" geht über einen Widerstand an die Ausgänge des Schieberegisters.

Eigentlich gefällt mir das nicht. Die Anforderung ist:
• Wenn OE = 1 ist, muss das Signal aus "HL"
  an allen 8 Ausgängen anliegen, und
• wenn OE = 0 ist, muss das Signal aus dem Schieberegister
  an allen 8 Ausgängen anliegen.

Im Bild oben war noch ein Fehler. Anbei die Korrektur und eine Ergänzung 
des Slave-Select-Signals (SS) um den Zustandsautomaten zu initialisieren 
und ein Latch-Enabe, um das Schieberegister alle 8 SPI-Takte auf die 
Latches zu übertragen.

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Uwe B. schrieb:
> … zur Hardware: das musst du wissen was du einsetzen willst …
> … aber mach wie du denkst …
> … schreib ob es geklappt hat …

Warum klingt das so gleichgültig. Ich dachte, unsere Gedanken könnten 
uns gegenseitig konstruktiv unterstützen.

Uwe B. schrieb:
> das bedeutet du musst Offline (z.B. am PC) eine Software haben
> die dir diese Daten erzeugt und somit ist das ganze sehr unflexibel

So machen das die meisten, mit T-1000S controller und der Software 
"LEDEdit 2012", siehe Beitrag "RGB LED Controller mit SD-Card - Erfahrungen?"

Also ich habe mir ein eigenes LEDEdit programmiert und ich finde, ich 
bin damit sehr flexibel.

Aber zurück zum Thema: Wie programmiere ich einen ATF16V8B? Ich habe nix 
gefunden. Hat jemand einen Tipp?

Alternative: Ein EPM3032A im PLCC44 und ein USB Blaster Clone.

Billig und kommt ohne separate (Schiebe-) Register und Latches aus.

: Bearbeitet durch User
von Uwe B. (derexponent)


Lesenswert?

Torsten C. schrieb:
> Warum klingt das so gleichgültig. Ich dachte, unsere Gedanken könnten
> uns gegenseitig konstruktiv unterstützen.

sorry, das sollte nicht gleichgültig klingen

aber deine Vorgehensweise unterscheidet sich von meiner
dementsprechend kann ich da nicht viel beisteuern

wenn ich dazu komme und meine 8Kanal Version (in Software)
fertig ist, poste ich den Sourcode hier (falls gewünscht)

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Uwe B. schrieb:
> aber deine Vorgehensweise unterscheidet sich von meiner

OK. :-) Hat ja alles Vor- und Nachteile.

> dementsprechend kann ich da nicht viel beisteuern

Vielleicht doch, nur zum Verständnis: "8 parallel" geht bei Deiner 
Vorgehensweise doch nur mit 8 SPIs, oder?

Bei 8 Strängen könnte man die Bits für alle Stränge parallel raus geben, 
also immer:

0xFF - Daten - 0x00

Dann hätte man nur 3-fachen "Overhead", nicht 8-fachen.

Der PLD wäre, um den "Overhead" von Drei auf Eins (also kein Overhead) 
zu bekommen. Ob ein EPM3032A im PLCC44 die richtige Lösung ist, weiss 
ich noch nicht. Evt. kann man ja auch mit dem 3-fachen "Overhead" leben.

von N. Rokpop (Gast)


Lesenswert?

Mann mann.. das sieht mir so aus, als wenn Du ein möglicherweise 
irrelevantes Detailproblem lösen willst, anstatt einfach mal das Ding 
aufzubauen. Uwe ist sehr höflich. Meine Prognose: Das Projekt wird nie 
fertig.

Das Speicherproblem bei dem DMA-Ansatz kann man übrigens einfach mit 
einem Ringbuffer lösen. Die CPU ist schnell genug, diesen nebenher 
wieder aufzufüllen.

Ob ein "Relaxkit" billger als ein STM32F4 Nucleo (10 EUR) ist, ist ja 
wohl völlig irrelevant. Für letzteres gibt es aber deutlich mehr 
Codebeispiele für das Problem, so dass sich die Entwicklungszeit wohl 
deutlich reduzieren sollte.

von Uwe B. (derexponent)


Lesenswert?

Torsten C. schrieb:
> Vielleicht doch, nur zum Verständnis: "8 parallel" geht bei Deiner
> Vorgehensweise doch nur mit 8 SPIs, oder?

ich benutze gar kein SPI sondern im Moment einen Timer
mit seinen 4 PWM-Kanälen und erzeuge daraus
4 PWM-Signale die nach jedem Bit per DMA einen neuen Wert
zugeteilt bekommen. (von den 4 ist immer nur ein PWM aktiv)

für 8 Kanäle müsste man also noch einen zweiten Timer
und dessen 4 PWM Ausgänge benutzen

ob man das Timing vom WS2812 auch per SPI hinbekommt,
kann ich dir nicht sagen (hab ich nicht probiert).

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Uwe B. schrieb:
> ob man das Timing vom WS2812 auch per SPI hinbekommt

Haben schon viele gemacht, aber das heißt, dass ein Bit in 8 Bits 
umgewandelt wird und ein SPI pro LED-Strang gebraucht wird.

SPI => Speicherbedarf Faktor 8,0

Uwe B. schrieb:
> mit meiner Library würden 8000 LEDs (4CH a 2000 LEDs) 117 kByte
> benötigen

Guten Morgen, Herr Torsten_C! Sorry, erst jetzt hab ich Deinen Ansatz 
richtig verstanden. Also:

Timer => Speicherbedarf Faktor 2,5 Richtig?

Mein Gedanke war, per DMA immer 8 Bits parallel raus zu schieben, also

0xFF, 0xFF, 0XFF, 0x00 für 'ne 1 oder
0xFF, 0x00, 0X00, 0x00 für 'ne 0, also

0xFF, Daten, Daten, 0x00, das heißt:

parallel => Speicherbedarf Faktor 4,0

Die Lösung mit dem EPM3032A hätte einen Faktor von 1,0. Das lohnt sich - 
wenn überhaupt - nur, wenn man (trotz Ringspeicher) mit dem RAM Speicher 
an die Grenze kommt, oder die Timer nicht reichen.

N. Rokpop schrieb:
> Uwe ist sehr höflich.
Und Du wahrscheinlich normalerweise auch?

N. Rokpop schrieb:
> Ob ein "Relaxkit" billger als ein STM32F4 Nucleo (10 EUR) ist, ist ja
> wohl völlig irrelevant.

Mal abgesehen vom Tonfall: Danke für den Hinweis, das Nucleo kannte ich 
noch gar nicht! Bei einem kommerziellem Projekt machen 3€ durchaus einen 
Unterschied. Und ich bin froh, dass trotzdem jemand auf meinen Betrag 
antwortet.

Ich hatte vorher jedenfalls nicht so den Überblick über die 
Umsetzungsmöglichkeiten wie jetzt. Danke!

Ich verfolge den Gedanken mit einem PLD am SPI trotzdem mal weiter, da 
der Ansatz sehr skalierbar ist. Außerdem muss man ja eh das Problem der 
Leitungslängen und der Pegel-Umsetzung lösen, da ist ein PLD vielleicht 
nur ein "kleines Addon".

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Angehängte Dateien:

Lesenswert?

So hätte ich das wohl diskret gemacht, mit Zähler und Decodern im 
ATF16V8B. Das Diagramm sah ja schon ganz gut aus:

http://www.mikrocontroller.net/attachment/231478/ATF16V8B.PNG

Aber drei Augänge aufeinander geht natürlich nicht im "Quartus II", wäre 
auch diskret nicht die feine Art gewesen, selbst wenn immer nur ein 
Tristate-Ausgang durchschaltet.

Ich muss mich wohl mit VHDL oder AHDL oder Verilog beschäftigen. Mal 
sehen. Falls keiner mehr einen Tipp hat, bis später!

BTW: Warum wird der EPM3032A eigentlich nur bis zum Release 13 
unterstützt? Ich hatte erst das Release 14.0 von "Quartus II" 
ausprobiert, aber da ist der EPM3032A nicht (mehr?) dabei.

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

PS: Hinweis von Dirk K. (dekoepi)
20 KB SRAM, 7 timers, Up to 2 SPIs, 7-channel DMA controller
Reicht für 6000 LEDs und kostet 5,20€.
ebay 111452091277

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Torsten C. schrieb:
> Ich muss mich wohl mit VHDL oder AHDL oder Verilog beschäftigen.
Die Lösung lautet hier nicht einfach VHDL, denn VHDL ist nur eine 
portable Textbeschreibung (das D in VHDL) einer Schaltung. Du brauchst 
für eine funktionierende VHDL-Beschreibung also vorher eine 
funktionierende Schaltung. Und das, was du da hingemalt hast, bekommst 
du aus erkanntem Grund nicht in einen programmierbaren Baustein.


In deiner PN schreibst du:
> Der Zähler wird an der steigenden und der fallenden Flanke eines
> SPI-Takts incrementiert und bei Slave-Select 1->0 zurückgesetzt.
Das geht natürlich so "geradeheraus" nicht, denn es gibt kein Flipflop, 
das auf 3 verschiedene Takte reagiert (SCK steigend, SCK fallend, SS 
fallend). Deshalb muss hier ein "Mastertakt" her (Hast du sowas? Welche 
Takt- und Übertragungsfrequenzen treten da überhaupt auf?), der diese 
SPI Signale überabtastet und dann mit einer Flankenerkennung drauf 
losgeht. Ab da wird es dann "relativ einfach". Allerdings kannst du dich 
von dem Gedanken an CPLDs gleich verabschieden, die haben für deine 
Aufgabe entschieden zu wenig Ressourcen. Und bei FPGAs geht es dann etwa 
dort los:
http://www.mouser.de/ProductDetail/Lattice/LCMXO2-256HC-4SG32C/?qs=sGAEpiMZZMsLKVrzu2LM0KUctzsle5Ju

: Bearbeitet durch Moderator
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> Allerdings kannst du dich von dem Gedanken an CPLDs gleich
> verabschieden, die haben für deine Aufgabe entschieden zu wenig
> Ressourcen. Und bei FPGAs geht es dann etwa dort los …

Hmmm, danke, aber bei 0.5mm pitch QFN-32 bin ich für Prototypen und 
kleine Serien bis 20 Stück überfordert. PLCC44 mit DIL-Sockel geht noch.

Ich würde ja auch ein externes Schieberegister nehmen, damit ich 
Bastler-freundliche Gehäuse habe.

Bei größeren Stückzahlen kann der PLCC44 dann einfach direkt aufgelötet 
werden.

Eine Schaltung mit "Ausgänge aufeinander" und externem Schieberegister 
hat mit WINCUPL sogar in ein ATF16V8B gepasst (siehe ATF16V8B.PNG), 
Source am Ende.

Den Mastertakt würde ich vom µC ausgeben (ATF16V8B.PNG erste Zeile).

Du meinst, das Schieberegister passt nicht mehr in den EPM3032A? Dann 
muss ich beim externen bleiben, den WINCUPL-Code nur nach VHDL 
übersetzen und fertig.

Oder ich nehme für den Prototypen so ein Breakout:
http://www.ah-ed.de/catalog/baugruppen-ahed-mach-xo2-fpga-break-out-board-p-30.html

Aber für Kleinserien habe ich dann noch keine Lösung.

Lothar Miller schrieb:
> Du brauchst für eine funktionierende VHDL-Beschreibung also vorher eine
> funktionierende Schaltung.

Ich dachte ein paar For-Schleifen oder so, und alles passt in den 
EPM3032A. Ich hab nur noch keinen Anfang. Man kann das ja durch "dumme" 
programmierung auch ineffizient umsetzen.

Oder meinst Du, ich sollte nicht "zu Fuss" VHDL programmieren, sondern 
mit dem Block-Diagramm-Editor 'ne Schaltung aufbauen, bei der keine 
Ausgänge aufeinander gehen? Wie gesagt: Ich weiss nicht, wo man da am 
besten anfängt.

ATF16V8B-Code für externes Schieberegister:
1
Device g16v8a;
2
PIN  1 = Clk;
3
PIN  2 = SCLK;
4
PIN  3 = SS;
5
PIN 12 = SCKB;
6
PIN 13 =  A;
7
PIN 14 =  B;
8
PIN 15 =  C;
9
PIN 16 =  D;
10
PIN 17 = OE;
11
PIN 18 = HL;
12
PIN 19 = LE;
13
FIELD St1 = [SS, D, C, B, A, SCKB];
14
FIELD St2 = [D.d, C.d, B.d];
15
TABLE St1 => St2 {
16
  1E => 0;
17
  00 => 0;
18
  01 => 0;
19
  03 => 0;
20
  02 => 1;
21
  04 => 1;
22
  05 => 1;
23
  07 => 1;
24
  06 => 2;
25
  08 => 2;
26
  09 => 2;
27
  0B => 2;
28
  0A => 3;
29
  0C => 3;
30
  0D => 3;
31
  0F => 3;
32
  0E => 4;
33
  10 => 4;
34
  11 => 4;
35
  13 => 4;
36
  12 => 5;
37
  14 => 5;
38
  15 => 5;
39
  17 => 5;
40
  16 => 6;
41
  18 => 6;
42
  19 => 6;
43
  1B => 6;
44
  1A => 7;
45
  1C => 7;
46
  1D => 7;
47
  1F => 7;
48
  [20..3F] => 0;
49
}
50
SCKB.d = SCLK;
51
A.d = SCKB & !SS;
52
FIELD input = [D, C, B, A];
53
FIELD output = [OE, HL];
54
TABLE input => output {
55
 0 => 0;
56
 [1..5] => 1;
57
 [6..A] => 3;
58
 [B..F] => 0;
59
}
60
HL.oe = !OE;
61
TABLE St1 => LE.d {
62
  [00..1D] => 0;
63
  1E => 1;
64
  [1F..3F] => 0;
65
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Torsten C. schrieb:
> VHDL programmieren
Das ist keine Programmiersprache, sondern eine Beschreibungssprache. 
Denn wenn du VHDL so hinschreibst wie C, dann kommt nur Müll raus. So 
wie da:
> Ich dachte ein paar For-Schleifen oder so
Eine Schleife in VHDL macht etwas ganz anderes als du erwartest. 
Schleifen verfielfältigen Funktionen: jeder Schritt einer Schleife in 
VHDL fügt einfach eine zusätzliche gleiche "Schaltung" dazu...

Wenn du mit VHDL in CPLDs oder FPGAs etwas schrittweise machen willst, 
dann brauchst du Zustandsautomaten (jeder Zähler und jedes 
Schieberegister ist ein Zustandsautomat).

Torsten C. schrieb:
> Oder meinst Du, ich sollte nicht "zu Fuss" VHDL programmieren, sondern
> mit dem Block-Diagramm-Editor 'ne Schaltung aufbauen, bei der keine
> Ausgänge aufeinander gehen? Wie gesagt: Ich weiss nicht, wo man da am
> besten anfängt
Zeichne doch besser mal einen Übersichtsplan mit abstrakten 
Funktionsgruppen, Eingängen und Ausgängen. Und da darf immer nur ein 
Ausgang pro Netz auftauchen. Und dazu ein Timingdiagramm, wo man sieht 
was durch was ausgelöst wird, und was unabhängig ist...

> Oder meinst Du, ich sollte nicht "zu Fuss" VHDL programmieren, sondern
> mit dem Block-Diagramm-Editor 'ne Schaltung aufbauen
Ehrlich: ich wäre der Letzte, der dir sowas raten würde... ;-)
Siehe den Beitrag "Re: kruder Fehler bei FPGA-Programmierung (ISE WEBpack-Schematic)"

Torsten C. schrieb:
> Am besten: Per DMA aus der SD-Karte raus und ohne Bit-Magie per DMA
> wieder zu den LEDs.
Ob DMA oder nicht, das ist doch eigentlich schnurzegal. Erst mal muss 
die Chose so laufen. DMA dient dann nur noch zur Entlastung des 
Prozessors.

> Der LPC1114FN28 ist im DIL-Gehäuse, ginge also, hat aber leider kein
> DMA.
Wenn er sonst ausreichend schnell ist, dann brauchst du keine DMA. DMA 
ist nur der "Turbo" für den Motor. Wenn der Motor so schon potent genug 
ist und die Leistung reicht, dann musst du nichts mehr dranbasteln...

: Bearbeitet durch Moderator
von Bernd (Gast)


Lesenswert?

Noch so nebenbei bemerkt wäre ein STM32 Discovery für ein kommerzielles 
Produkt laut Lizenz nicht zulässig...

von Torsten C. (torsten_c) Benutzerseite


Angehängte Dateien:

Lesenswert?

Bernd schrieb:
> nebenbei bemerkt wäre ein STM32 Discovery für ein kommerzielles
> Produkt laut Lizenz nicht zulässig
OK, danke. Das Board (Hinweis von Dirk K. / dekoepi) ˄˄ ist vielleicht 
ausreichend.

Lothar Miller schrieb:
> Zeichne doch besser mal einen Übersichtsplan mit abstrakten
> Funktionsgruppen, Eingängen und Ausgängen.

Das hätte ich längst mal machen sollen sorry. Hier die Beschreibung:

Der SPI (SCLK) wird hier mit 6,4MHz getaktet, MOSI und SS gehören zum 
SPI.

MCLK = Master-Clock (z.B. 16MHz) wird z.B. über ein Compare-Output 
erzeugt.

Der Zustandsautomat (Zähler) wird an der fallenden Flanke von SS auf „0“ 
initialisiert, wird an beiden Flanken von SCLK incrementiert und läuft 
im Kreis (nach 15 kommt 0).

„HiLo“ ist
* in den Zuständen 1..3 auf High,
* bei 13..15 und 0 auf Low und
* bei 4..12 „d.c.“

„Selection“ wählt
* in den Zuständen 0..3 und 13..15 „HiLo“ (8 gleiche Bits) und
* in den Zuständen 4..12 die Daten vom Schieberegister.

„Latch-Enable“ ist nur im Zustand 15 aktiv.

Am Ende kommt dan 8 x parallel das Muster aus dem Ursprungspost heraus.

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> Allerdings kannst du dich von dem Gedanken an CPLDs gleich verabschieden,
> die haben für deine Aufgabe entschieden zu wenig Ressourcen.

Es geht jetzt bitte nicht ums "Recht haben", ich bin totaler Neuling. 
Was mich freut ist:

> Family           MAX3000A
> Total macrocells 30 / 32 ( 94 % )
> Total pins       16 / 34 ( 47 % )
> Device           EPM3032ALC44-4

Naja, vielleicht habe ich ja auch noch was vergessen, und es passt doch 
nicht. Vielleicht lässt sich aber auch noch was optimieren?

Mit dem Simulator für die Verifikation komme ich noch nicht klar. 
Fragen:

① Sollte ich einen Sub-Thread im Forum "FPGA, VHDL & Co." aufmachen?

② Bin ich grundsätzlich auf dem richtigen Weg?

③ Kann jemand was zu den "???" sagen?

④ Sind die else-Pfade nötig?
1
module WS2812_2 (
2
    mclk,   // master Clock (about 16MHz) Input
3
    sclk,   // SPI serial clock Input, 6.4 MHz for double speed, 3.2 MHz for low speed
4
    ss,     // SPI slave select Input, active low
5
    mosi,   // SPI "master out slave in" Input
6
    LEDdata // WS2812 Data lines Output
7
  );
8
  // ----------- Input declaration
9
  input mclk, sclk, ss, mosi;
10
  // ----------- Output declaration
11
  output LEDdata[7:0];
12
  // ----------- Port data types
13
  wire mclk, sclk, ss, mosi;
14
  reg [7:0] LEDdata;
15
  // ??? kann man sclk an dieser Stelle als reg definieren und damit ssclk sparen?
16
  // ----------- Code
17
  reg ssclk;              // gespeicherter sclk (??? ist das nötig?)
18
  reg ssclk_prev;         // ssclk vom vorherigen Takt
19
  reg [7:0] shiftReg;     // Schieberegister (dynamisch)
20
  reg [7:0] shiftRegOut;  // Schieberegister Output Register
21
  reg [3:0] stateCount;   // Zustandsautomat
22
  always @(posedge mclk)
23
  begin // ??? sollte hier ein Block-Name stehen, z.B. ": ssclk_Generation", was bringt das?
24
    ssclk_prev <= ssclk;                   // ssclk vom vorherigen Takt merken
25
    ssclk <= sclk;
26
    if (ss) begin                          // stateCount bei ss = 1 initialisieren
27
      stateCount <= 0;
28
    end else begin
29
      if (ssclk_prev != ssclk) begin       // stateCount an beiden Flanken incrementieren
30
        stateCount <= stateCount + 1;
31
      end else begin
32
        stateCount <= stateCount;
33
      end
34
    end
35
    if (!ss && !ssclk_prev && ssclk) begin // mosi an der steigenden Flanke ins Schieberegister schieben
36
      shiftReg    <= shiftReg << 1;
37
      shiftReg[0] <= mosi;
38
    end else begin
39
      shiftReg    <= shiftReg;
40
    end
41
    if (stateCount == 15) begin            // Schieberegister im Zustand 15 speichern
42
      shiftRegOut <= shiftReg;
43
    end else begin
44
      shiftRegOut <= shiftRegOut;
45
    end
46
    case (stateCount)                      // LEDdata-Ausgänge je nach Zustand setzen
47
      0,13,14,15 : LEDdata <= 0;
48
      1,2,3 : LEDdata <= 255;
49
      default : LEDdata <= shiftRegOut;
50
    endcase
51
  end
52
endmodule

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Angehängte Dateien:

Lesenswert?

alea iacta est

Ich habe mich für ein µC-Board entschieden, es ist nicht nur wegen der 
Lizenz-Gründe nicht von STM. 8 Stück, ohne dass der Zoll Geld will:

http://www.aliexpress.com/snapshot/6267810802.html

Nochmal zum Speicherbedarf im "ausgerollten" DMA-Source-Buffer:

Ich schrieb:
> 0xFF - Daten - 0x00
> Dann hätte man nur 3-fachen "Overhead"
Das war falsch, da man damit das Timing nicht einhält. Richtig ist, was
hier ich schrieb:
> 0xFF, Daten, Daten, 0x00, das heißt:
> parallel => Speicherbedarf Faktor 4,0

Torsten C. schrieb:
> Timer => Speicherbedarf Faktor 2,5 Richtig?

Nein. Timer => Speicherbedarf Faktor 16!
... oder halt nacheinander, wenn man will.

Wärend ich auf den Postboten warte, mache ich die Basis-Platine fertig. 
Die ist fexibel (Bild). Ggf. kann ich über JP1 eine Huckepack-Platine 
erweitern, wenn ich das wirklich noch mit dem EPM3032A machen will.

: Bearbeitet durch User
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.