# LabVIEW-Projekt und FPGA

URL: https://irs.systems/docs/resolver-simulation/labview-project-and-fpga

## LabVIEW-Projekt

### Allgemeines

Das Projekt enthält die vollständige Software für das Target:

- FPGA
- Echtzeitsystem: RT_ResSi & RT_RVDT
- Computer: PC_ResSi & PC_RVDT

Die Targets cRIO-9074, cRIO-9075 und sbRIO-9602 sind bereits für einen Kanal vordefiniert und vorkompiliert; weitere Targets und/oder Kanäle lassen sich jedoch einfach zum Projekt hinzufügen.

Hinweis 1: Die PC-Software dient ausschließlich Demonstrationszwecken.

Hinweis 2: Das RT-System ist nicht zwingend erforderlich, wird aber empfohlen. Das FPGA kann auch direkt von einem Computer angesteuert werden, dieses Handbuch behandelt jedoch nur den empfohlenen Weg (FPGA <-> RT <-> Network Shared Variables <-> PC).

### Neues RIO-Target hinzufügen

Ein neues RIO-Target lässt sich sehr einfach hinzufügen. Im Folgenden eine kurze Beschreibung:

1. Legen Sie ein neues Target-Gerät an
   - Klicken Sie mit der rechten Maustaste auf das Projekt -> New -> Targets and Devices…
   - Wählen Sie das Target aus
   - Das neue Target erscheint im Project Explorer
2. Kopieren Sie die benötigten Elemente aus den alten Targets an dieselbe Stelle im neuen Target
   - Ordner: RT, RT_ResSi, RT_RVDT
   - Fügen Sie das FPGA-Target hinzu (Rechtsklick auf das neue Chassis -> New -> FPGA Target)
   - Kopieren Sie die FPGA-Elemente: „[0]_ResSi“ (Ordner & Gerät), „FPGA“, „Memory“, „SPI_Resolver_Clock“
3. Legen Sie neue Build-Spezifikationen für FPGA, RT_ResSi und RT_RVDT an und verwenden Sie dabei die alten als Vorlagen (ändern Sie nur „Name“ [1] und „Target Directory“ [2] und aktualisieren Sie „Source Files“ [3])
4. Führen Sie den Build der FPGA-Build-Spezifikation aus und warten Sie, bis er abgeschlossen ist (dauert einige Zeit) -> Bitdatei
5. Fügen Sie die neue Bitdatei zu „RT_ResSi/RT_OpenFPGA.vi“ hinzu:
   - Duplizieren Sie das Unterdiagramm (Duplicate Subdiagram)
   - Setzen Sie das Symbol auf „DeviceCode“ und den Wert auf den Gerätecode des Targets und klicken Sie dann auf „OK“ (den Gerätecode erhalten Sie per Rechtsklick auf das neue Target -> Properties -> Conditional Disable Symbols -> DeviceCode)
   - Konfigurieren Sie „Open FPGA VI Reference“ so, dass es auf die neu erzeugte FPGA-Bitdatei verweist
6. Führen Sie den Build der benötigten RT-Build-Spezifikation aus („Run as startup“)

<figure>
  <img src="/docs/assets/resolver-simulation/images/ressi-add-target-1-3.png" alt="LabVIEW Project Explorer und Eigenschaften der Build-Spezifikation, markierte Schritte 1 bis 3">
  <figcaption>Abbildung 13: Neues RIO-Target hinzufügen (Schritte 1–3)</figcaption>
</figure>

<figure>
  <img src="/docs/assets/resolver-simulation/images/ressi-add-target-5.png" alt="Blockdiagramm von RT_OpenFPGA.vi mit dem Dialog Configure Condition">
  <figcaption>Abbildung 14: Neues RIO-Target hinzufügen (Schritt 5)</figcaption>
</figure>

## FPGA

Dieser Teil behandelt den Code für das FPGA. Er ist für ein Gerät in Steckplatz 1 (Kanal 0) eingerichtet und bereits für die Erweiterung um weitere Kanäle vorbereitet.

### Top-VI & FPGA-Schnittstelle

Das Top-VI enthält alle Ein- und Ausgangsvariablen, die für den Betrieb benötigt werden.

<figure>
  <img src="/docs/assets/resolver-simulation/images/ressi-fpga-top-vi.png" alt="Frontpanel von FPGA_Top.vi mit Ein- und Ausgängen">
  <figcaption>Abbildung 15: FPGA-Top-VI</figcaption>
</figure>

#### Eingänge

**LUT Update Section** (siehe: [Sinus- und Kosinus-Lookup-Tabellen](/docs/resolver-simulation/labview-project-and-fpga#sinus-und-kosinus-lookup-tabellen))

Bedienelemente zum Aktualisieren der Sinus- und Kosinus-Lookup-Tabellen. Verwenden Sie DMA_FIFO zum Schreiben neuer Werte.

| Parameter | Beschreibung |
| --- | --- |
| LutUpdate_ChannelNb | Kanalnummer für den LUT-Schreibvorgang (nur Kanal 0 ist vordefiniert) |
| LutUpdate_WriteSine | Setzen, um das Schreiben in die Sinus-LUT zu starten (DMA_FIFO). |
| LutUpdate_WriteCosine | Setzen, um das Schreiben in die Kosinus-LUT zu starten (DMA_FIFO). |

**ResSi_Settings[x], Speed_Set_[RPM][x], Speed_Gradient_Set_[RPM/s][x]**

Steuerwerte der Resolver-Simulation (Arrays, deren Index **x** die Kanalnummer darstellt).

| Parameter | Beschreibung |
| --- | --- |
| SampleRate_[Ticks] | **ResSi-Modus:** Aktualisierungsrate der Ausgangsabtastwerte zur Festlegung der Drehzahl. Wenn **RPM** die gewünschte Drehzahl in Umdrehungen pro Minute ist: `SampleRate[Ticks] = (40^6 * 60) / (RPM * 1024)`. **RVDT-Modus:** Änderungsgeschwindigkeit des Winkels. Wenn `[delta_phi/sec]` die gewünschte Winkeländerung pro Sekunde ist: `SampleRate[Ticks] = (abs(phi_max) * 40^6) / ([delta_phi/sec] * (1023 >> 1))` |
| Position_fixed_LUT | Legt eine konstante Position der Simulation fest. Der Wert liegt im Bereich 0…1023. **ResSi-Modus:** `Range = 0° … 360°`. **RVDT-Modus:** `Range = -phi_max … 0° … phi_max` (0° -> Position = 1023>>1 = 511) |
| SYNC_Phase_LUT | **ResSi-Modus:** Legt den 0°-Simulationswert relativ zur positiven Flanke des SYNC-Eingangssignals fest. Der Wert liegt im Bereich 0…1023 und entspricht einem Winkel von 0…360°. `SYNC_Phase_LUT = Angle * 1024/360` |
| PGA_Setting | Maximales Übersetzungsverhältnis, wenn die Sinus-/Kosinus-LUT auf Vollaussteuerung definiert ist (Amplitude 100 %). `Û_OUT = 0.078125 * 2^PGA * Û_LUT` mit PGA = 0…7. **Setzen Sie diesen Wert bei Hardwareversion 1.3 auf „2“!** |
| Direction | **ResSi-Modus:** Legt die Drehrichtung fest. FALSE: links. TRUE: rechts |
| Rotate_Enable | **ResSi-Modus:** TRUE: Es wird eine rotierende Maschine simuliert. FALSE: Es wird eine feste Position simuliert |
| SYNC_Enable | **ResSi-Modus:** TRUE: Die Drehzahl wird aus der Frequenz des SYNC-Eingangs abgeleitet. FALSE: Die Drehzahl wird aus dem Eingang Sample_Rate[Ticks] abgeleitet |
| RVDT_Mode_(Rotation) | TRUE: RVDT-Modus. FALSE: Resolver-Simulationsmodus (Standard) |
| Speed_Set_[RPM] | **ResSi-Modus:** Zieldrehzahl der Drehzahlrampe in RPM |
| Speed_Gradient_Set_[RPM/s] | **ResSi-Modus:** Drehzahländerungsrate in RPM pro Sekunde; bei 0 wird die neue Drehzahl sofort übernommen. Andernfalls 1 RPM/s bis 16e6 RPM/s |

#### Ausgänge

- **LUT_Size-1:** Konstante: Der Wert stellt den letzten Index der Sinus- und Kosinus-Lookup-Tabellen dar.
- **FirmwareVersion:** Konstante: Datum der FPGA-Firmwareversion (HEX-Format: yyyymmdd)
- **ResSi_Values[x]:** Statuswerte der Resolver-Simulation (Array, dessen Index **x** die Kanalnummer darstellt).

| Parameter | Beschreibung |
| --- | --- |
| Sync_Period_[Ticks] | **ResSi-Modus:** Anzahl der Ticks zwischen zwei positiven Flanken am SYNC-Eingang (Ticks zu 25 ns) |
| Position_actual_LUT | Aktuelle Position der Simulation (siehe „Position_fixed_LUT“). |
| SampleRate_Actual_[Ticks] | **ResSi-Modus:** Aktuelle Aktualisierungsrate der Ausgangsabtastwerte, die die Drehzahl festlegt. |
| Sync_PosEdge | **ResSi-Modus:** Externes Drehzahlsignal auf die positive Flanke synchronisieren. |

### Sinus- und Kosinus-Lookup-Tabellen

Die Ausgangssignalverläufe sind in zwei Lookup-Tabellen mit je 1024 vorzeichenbehafteten 16-Bit-Integer-Elementen gespeichert. Eine LUT ist für den Sinusausgang zuständig, die zweite für den Kosinusausgang. Diese Tabellen können (sollten) vom Anwender aktualisiert werden. Dazu stehen drei Bedienelemente und ein DMA zur Verfügung.

Zum Aktualisieren kann der Entwickler „RT_PC_LUT_Write.vi“ im Ordner „RT_Share“ verwenden. Es führt die folgenden Schritte aus:

- Schreibt die gewünschte Kanalnummer in „LutUpdate_ChannelNb“. Im Standardzustand ist nur ein Kanal verfügbar.
- Setzt „LutUpdate_WriteSine“ oder „LutUpdate_WriteCosine“ auf true, um eine neue Übertragung einzuleiten.
- Schreibt 1024 Werte in den DMA „DMA_FIFO“ und wartet anschließend einige Millisekunden.
- Setzt den binären Schreibwert wieder auf false zurück.

<figure>
  <img src="/docs/assets/resolver-simulation/images/ressi-fpga-lut-update.png" alt="LUT Update Handler in FPGA_Top.vi">
  <figcaption>Abbildung 16: FPGA&#95;Top.vi – LUT-Update</figcaption>
</figure>

### Neuen Kanal hinzufügen

- Legen Sie einen neuen Steckplatz an
  - Rechtsklick auf das FPGA-Target -> New -> C Series Module -> New target or device -> C Series Module
  - Name: „[x]_ResSi“, wobei x = Kanalnummer (in diesem Beispiel x = 1)
  - Type: cRIO-generic. Anmerkung: Wenn diese Option nicht verfügbar ist, muss die folgende Zeile in die Datei LabVIEW.ini eingefügt werden (LabVIEW muss dabei geschlossen sein): `cRIO_FavoriteBrand=generic`
  - Location: Steckplatznummer

<figure>
  <img src="/docs/assets/resolver-simulation/images/ressi-new-channel.png" alt="Kontextmenü New, Dialog C Series Module und Dialog New C Series Module">
  <figcaption>Abbildung 17: Neuen Kanal im FPGA anlegen</figcaption>
</figure>

- Erstellen Sie eine Kopie aller Speicherelemente außer DMA_FIFO (ändern Sie den Namen jedes Speicherelements so, dass er die neue Kanalnummer wiedergibt, hier 1).

<figure>
  <img src="/docs/assets/resolver-simulation/images/ressi-copy-memories.png" alt="FPGA-Speicherordner mit kopierten Speicherelementen für Kanal 1">
  <figcaption>Abbildung 18: FPGA-Speicherelemente kopieren</figcaption>
</figure>

- Folgende Änderungen sind erforderlich:
  - **FPGA_Top.vi -> SPI Handlers:** Duplizieren Sie den Frame und setzen Sie die neuen Port-Pins (hier „[1]_ResSi/...“).
  - **FPGA_Top.vi -> Speed Ramp Generator:** Erhöhen Sie die Array-Größe der beiden Eingangsvariablen um eins (hier auf 2): Rechtsklick auf die Variable -> Properties -> Size -> Fixed. Duplizieren Sie den Frame, setzen Sie das neue Speicherelement (hier „[1]_RampSampleRate_[Ticks]“) und verbinden Sie das VI mit den nächsten Array-Elementen (durch Erweitern der „Index Array“-Elemente)
  - **FPGA_LutUpdate.vi:** Duplizieren Sie das Case-Element und aktualisieren Sie die Speicherelemente (hier „[1]_LUT_Sine“ und „[1]_LUT_Cosine“).
  - **FPGA_ResolverSim.vi:** Erhöhen Sie die Größe von „ResSi-Settings“ um eins (hier auf 2) und wiederholen Sie diesen Schritt auch im Top-VI. Duplizieren Sie den Frame und aktualisieren Sie alle Konstanten (hier „[1]_...“). Verbinden Sie die Ein- und Ausgangsvariable mit dem neuen Array-Eintrag.
- Kompilieren Sie das FPGA-Target neu (Rebuild)
- Wenn Sie das Echtzeitsystem verwenden, müssen Sie eine Kopie der Netzwerkvariablen für den neuen Kanal anlegen. Weitere Informationen finden Sie unter [Echtzeitsystem – Neuen Kanal hinzufügen](/docs/resolver-simulation/real-time-system#neuen-kanal-hinzufuegen).
