2016-04-15 2 views
1

Ich habe ein Software-Projekt, das eine A20-OLinuXino-MICRO-4GB board verwenden soll. Ich habe keine Kontrolle darüber, welches Board zu verwenden ist, daher sind Vorschläge zu Alternativen nicht hilfreich.Enable SPI-Controller für Cortex-A7 außerhalb von Linux

Das hat einen Allwinner A20 Dual Core Cortex-A7-Prozessor (Armv7a).

Ich habe versucht, die Arbeit von Linux, aber auch mit maximaler Priorität, PTHREAD_EXPLICIT_SCHED und SCHED_FIFO, konnte ich Interrupts eines zeitkritischen Abschnitts von Steuercode nicht verhindern (müssen alle 10 Mikrosekunden verarbeiten, aber 40 Mikrosekundenlücken etwa 40 mal eine Sekunde).

Mit obiger Einschränkung sind Vorschläge zum Zugriff auf SPI und UART von Linux ebenfalls nicht hilfreich. Die Zeitbeschränkungen für den zweiten Thread (der gesamte CPU-Kern ist dafür reserviert) bedeuten, dass reguläres Linux derzeit keine brauchbare Alternative ist. Vielleicht würde ein volles Echtzeit-Linux den Job erledigen, aber ich habe nicht die Ressourcen, um das zu bauen, nur um zu sehen, ob es könnte funktioniert.

Aktuelle Entwicklungsumgebung:

Gentoo 4.3.3-hardened-r4 
crossdev --kernel =3.18 --libc =2.21-r2 --binutils =2.24-r3 --gcc =4.8.5 

Gebäude u-boot derzeit nicht mit 5.x Versionen von gcc arbeiten, also nicht zu viel Raum, um dort zu bewegen.

Also zum Schreiben als Standalone-Code, der von U-Boot gestartet werden soll. Keine zusätzlichen Verzögerungen, aber jetzt fehlt mir etwas, um andere Module des Kerns zu konfigurieren. Wenn ich versuche, SPI- oder UART-Geräte zu initialisieren und zu konfigurieren (mit Ausnahme von UART0, das für die U-Boot-Konsole verwendet wird), melden alle Register den Wert Null und bleiben auch nach dem Einstellen bestehen. Es verhält sich so, als ob dort nichts (keine Hardware) wäre. UART0 hat vernünftige/erwartete Werte, und die Konfiguration von Standard-GPIO-Pins (Eingang und Ausgang) funktioniert gut. Die Konfiguration der Multiplex-GPIO-Pins, die von SPI oder UART verwendet werden, scheint ebenfalls zu funktionieren, aber die Module weigern sich hartnäckig, zuzugeben, dass sie existieren.

Beispielcode, Makefile und Ausgabe für den Versuch, mit den SPI-Modulen zu sprechen, finden Sie in the olimex forum. Beachten Sie, dass das Beispiel Include-Dateien aus dem Build von U-Boot verwendet Die Hauptdokumentation zum Erstellen dieses Codes ist A20 User Manual.

Hat jemand mit A20, Cortex-A7, armv7a oder ähnlichen Chips gearbeitet und herausgefunden, wie man Zugang zu den Fähigkeiten außerhalb von Linux bekommt?

Weiß jemand, wo man bessere Dokumentation über die Programmierung auf dieser Ebene bekommen kann?

Das Benutzerhandbuch Ich habe viele Informationen über Registeradressen, Offsets, Bitmasken, aber nichts in der Art von Codebeispielen. Ich erwarte, dass ein einfaches eigenständiges C (oder sogar Assembler) Beispiel, das irgendeines der (Gerät-) Module konfigurierte und einen Interrupt einstellte, um damit umzugehen, so hilfreich wäre, den Rest herauszufinden.

Ich habe tatsächlich die SPI-Kommunikation funktioniert durch Bit-Banging der I/O-Pins. Das wird für den UART nicht funktionieren und SPI sieht wie ein einfacherer Fall aus, an dem zuerst gearbeitet wird.

Ich habe seit vielen Jahren auf großen Systemen programmiert, und einige auf sehr kleinen (6502, 8085, arduinio) Systemen, aber keine echte Erfahrung mit der Entwicklung in dieser Art von Umgebung. Ich bin kein Kernel-Programmierer oder irgendetwas in der Nähe.

EDIT: Ich habe die SPI1 Clock-Setup in den Beispielcode hinzugefügt, aber alle SPI-Register immer noch als alle Nullen, vor und nach der Einstellung angezeigt. Die Code-Änderungen:

#include <asm/arch-sunxi/clock_sun4i.h> 
struct sunxi_ccm_reg * clockRegister; 
#define SPI_SCLK_GATING_CLKON 0x80000000 
#define SPI_CLK_SRC_OSC24M  0x00000000 
#define SPI_CLK_DIV_RATION_8 0x00030000 
// ... 
printf ("SPI1 clk cfg %08x\n", clockRegister->spi1_clk_cfg); 
clockRegister->spi1_clk_cfg = 
    SPI_SCLK_GATING_CLKON | SPI_CLK_SRC_OSC24M | SPI_CLK_DIV_RATION_8 | 15; 
printf ("SPI1 clk cfg %08x\n", clockRegister->spi1_clk_cfg); 

Das zeigt, dass die Uhr Konfigurationsänderung von 0x00000000 DID 0x8003000f

+1

Ich würde tatsächlich ein solches Gerät erwarten entweder ein FIFO oder DMA an die Peripherie angebracht haben. – Olaf

+0

Es tut (beides). Allerdings müssen noch ermöglichen, einschalten, konfigurieren, initialisieren, ETWAS das Gerät/Modul – mMerlin

+0

Da Sie vorbei an den Hürden sind zu kompilieren, Booten und Code erhalten lesen und schreiben MMIO, Sie sicher vergessen Cortex-A7, diese Alles dreht sich um Peripheriegeräte auf dem A20-SoC, nicht um die CPU, die mit ihnen verbunden ist - wenn Sie stattdessen einen MIPS-Core einsetzen würden, würde dies die Art des Problems nicht ändern. In der Regel benötigt man bei einem mobilen Teil einige PLLs und eventuell Regler, um nicht-boot-essentielle Peripheriegeräte getaktet und mit Strom versorgt zu bekommen - was verlangt die A20 in dieser Hinsicht? – Notlikethat

Antwort

0

Ich stellte auch diese Frage auf der Microcontroller Based Projects google + Gemeinschaft, und Nikolai Kondrashov (spbnick) dort gesichtet und richtig interpretiert eine Reihe von Informationen in der Dokumentation.

Um Zugriff auf die SPI-Register zu erhalten, müssen sowohl das Gating AHB Clock für SPI «n» -Bit in AHB_GATTING_REG0 als auch das SCLK_GATING-Bit in SPI «n» _CLK_REG gesetzt werden. Sobald diese gesetzt sind, registriert sich das SPI «n» Modul selbst.

potenziell verwirrend Randnotiz: zuerst die AHB-Gating-Bit-Einstellung, dann das SPI-Register zu verweisen versucht, bevor die SCLK-Gating-Bit-Einstellung bewirkt, dass insgesamt einfrieren. Da in einer arbeitenden Anwendung diese normalerweise zusammen gesetzt werden, ist dies normalerweise kein Problem. Nur mit der Debug-Ausgabe angezeigt, um zu sehen, wann die SPI-Register sichtbar wurde.

Ich finde immer noch die Dokumentation eher fehlt. Ein paar Codebeispiele würden es sehr verbessern. Diese Entdeckung ist wahrscheinlich genug, um Zugang zu den meisten SoC-Modulen/Geräten zu erhalten.

Ziemlich minimaler Beispielcode. Dies funktioniert mit dem gleichen Makefile, das für die ursprüngliche Frage angezeigt wird. Welche zieht eine zusätzliche U-Boot-Include-Datei ein.

#include <common.h> 

// Global memory pointers 
uint32_t 
    (*SPIarry1)[11], 
    *SPI1_Cfg, 
    *AHB_Gate0, 
    *SPI1_ClkCfg; 

int spi_test (void); 

int spi_test (void) 
{ 
    AHB_Gate0 = (uint32_t *)(SUNXI_CCM_BASE + 0x60); 
    SPI1_ClkCfg = (uint32_t *)(SUNXI_CCM_BASE + 0xa4); 
    SPIarry1 = (uint32_t (*)[11])SUNXI_SPI1_BASE; 

    printf ("SPI1 Cfg Reg 0x%08x\n", (*SPIarry1)[2]); 
    *SPI1_ClkCfg = 0x80000000; 
    printf ("SPI1 Cfg Reg 0x%08x\n", (*SPIarry1)[2]); 
    *AHB_Gate0 |= 0x00200000; 
    printf ("SPI1 Cfg Reg 0x%08x\n", (*SPIarry1)[2]); 
    return (0); 
} 

aufgenommenen Probe Programmausgabe

## Starting application at 0x42000000 ... 
SPI1 Cfg Reg 0x00000000 
SPI1 Cfg Reg 0x00000000 
SPI1 Cfg Reg 0x0012001c 
## Application terminated, rc = 0x0 
Verwandte Themen