ich versuche inzwischen schon länger, bei einem stm32f103VET8 spi2 in
Gang zu setzen. Diese thread nicht weiter:
Beitrag "STM32 - SPI2 will nicht"
Ich habe den code alternativ auf spi1 umgestellt und umgelötet - das lcd
läuft auf anhieb.
Was ist an meinem spi2-code falsch bzw. anders als am spi1-code, der
funktioniert?
1
#define xspi2 0
2
voidlcd_spi_write(u8dat){
3
#if xspi2
4
SPI2->DR=dat;
5
while(SPI2->SR&1<<(7));
6
returnSPI2->DR;
7
#else
8
SPI1->DR=dat;
9
while(SPI1->SR&1<<(7));
10
returnSPI1->DR;
11
#endif
12
}
13
14
voidlcd_spi_init()
15
{
16
SPI_InitTypeDefSPI_InitStructure;
17
GPIO_InitTypeDefGPIO_InitStructure;
18
19
/* Configure SPI1 pins: SCK and MOSI with default alternate function (not remapped) push-pull */
hp-freund schrieb:> #define xspi2 0> und> #if xspi2>> kontrollier das mal.
das ist nur das define, um zwischen spi1 und spi2 umzuschalten:
#define xspi2 0 => führt den code für SPi1 aus
#define xspi2 1 => führt den code für SPi2 aus
Irgendwo muss ein Fehler im code für Spi2 sein, obwohl er entsprechend
dem spi1-code aufgebaut ist. Es kommen zwar Signale auf sck, mosi und
cs, aber das lcd wird nicht initialisiert.
hp-freund schrieb:> Wissen auch alle deine lcd_xx Funktionen das sie auf SPI2 zugreifen
sollen
Es ist doch nur eine einzige lcd-Funktion, die auf Spi zugreift, nämlich
"lcd_spi_write(dat)", Lesefunktionen gibt es nicht, Miso ist nicht
verbunden. lcd_spi_write sollte das eigentlich wissen.
kann nicht Fehlerursache sein, weil durch den Wechsel von spi1 auf spi2
nicht beeinflusst. cs funktioniert, lcd_init ist für spi1 u. spi2
identisch.
Ich muss wohl das Signal, das bei spi2/mosi/sck rauskommt, genauer
untersuchen. Mit meinem china-dso geht das leider nicht. Vielleicht ein
zweiter uc als slave.
Martin schrieb:> while (SPI2->SR & 1<<(7)) ;
#define SPI_SR_TXE ((uint8_t)0x02) /*!< Transmit buffer Empty */
Bit7 ist das Busy Flag, vor dem Senden soll aber das TX Empty abgefragt
werden.
hp-freund schrieb:> Display_IoInit_IfJojo S. schrieb:> Bit7 ist das Busy Flag, vor dem Senden soll aber das TX Empty abgefragt> werden.
das ist zutreffend. Mit dem busy-flag ist der code mglw. langsamer,
funktioniert aber sicher. Wenn es mal geht, kann man das optimieren.
hp-freund schrieb:> Wirklich? Zeig mal.
gerne:
Wenn das richtige lcd_spi_init(); aufgerufen wird ist das ja schon mal
in Ordnung.
lcd_write_reg wäre dann die nächste Frage. Geht mir jetzt aber ein wenig
zu weit.
Ich würde jetzt als Nächstes das lcd_init(); in eine Endlosschleife
legen und die Ausgaben prüfen.
hp-freund schrieb:> Ich würde jetzt als Nächstes das lcd_init(); in eine Endlosschleife> legen und die Ausgaben prüfen.
danke erstmal für die Unterstützung. Ich habe für heute genug von STM.
Ich lass das ganze zunächst auf spi1. Vielleicht probier ich das ganze
mit ein paar Tagen Abstand noch einmal mit spi2.
Jojo S. schrieb:> Laut Doku ist das Busy für den Slavemode, der Slave soll das Ende> signalisieren wenn Busy aus ist.
Der verwendete code stammt von Fat-Elm-Chan, der fragt das bsy-flag ab.
Müsste eigentlich auch so funktionieren.
Nachdem auch spi1 nicht mehr zuverlässig lief, habe ich die Stm-Vorlage
ausprobiert:
/* Write in the DR register the data to be sent */
7
SPIx->DR=Data;
8
}
Diese ist etwa 10% langsamer, der Chip lässt sich aber mit hw-spi -
zumindest spi1 - wieder programmieren. Möglicherweise ist dieses
merkwürdige stm-assert_param für den zuverlässigen Betrieb erforderlich.
das assert prüft nur ob der parameter ein gültiger Pointer ist, also
&SPI1, 2 oder 3.
ST erwähnt im Handbuch mehrfach das TXE Flag zu verwenden, warum sollen
die lügen?
'Note: Do not use the BSY flag to handle each data transmission or
reception. It is better to use the
TXE and RXNE flags instead.'
'Note: The software must ensure that the TXE flag is set to 1 before
attempting to write to the Tx
buffer. Otherwise, it overwrites the data previously written to the Tx
buffer.'
Ein Unterschied ist ja noch das SPI1/2 um den Faktor 2 unterschiedlich
schnell sind, da kann das durchaus ein Timingproblem sein. Du hast ja
geschrieben das auch Daten gesendet werden, aber falsche. Das wäre der
Effekt wenn die Daten schon während der Übertragung verändert werden.
Hast du denn schon probiert das TXE Flag anstelle des BSY abzufragen?
Jojo S. schrieb:> TXE Flag anstelle des BSY
Ich habe alle erdenklichen Variationen TXE RXNE BSY ausprobiert.
Prescaler zwischen 2 und 256.
Das Problem ist, dass der Fehler nicht 100% reproduzierbar ist. D.h.
identischer code geht mal, beim nächsten Flashen dann wieder nicht.
Gerade funktioniert das LCD mit Prescaler_2/kompletter Bildaufbau
0,17sec recht ordentlich. Als nächstes werde ich den enc28j60
anschließen. Probleme gibts dann wahrscheinlich mit dem Wechsel zwischen
Spimode_0 und Spimode_3.
Das Problem war, dass sich
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
nicht mit der txe/rxne-abfrage verträgt.
while ((SPI2->SR & _BV(1))) ;//0_rxne 1_txe 7_bsy
ist offensichtlich falsch. gewartet werden soll, solange tx not empty
ist.
er funktionierte zeitweilig aber trotzdem: Stm-Mysterium
Im fullduplex-modus funktioniert es dann einwandfrei. Entschädigt wird
man durch eine enorme spi-Geschwindigkeit: 100-facher Bildaufbau in
7sec.
Wäre vielleicht noch durch DMA zu toppen? Allerdings sind 36 MHz SPI
auch schon recht zügig, wieviel verträgt das Display denn?
Jedenfalls danke für die Auflösung. Wenn ich meinen STM mal wieder
rauskrame erinnere ich mich hoffentlich noch an diesen Thread :-)
Jojo S. schrieb:> 36 MHz SPI
240x320x2Bytesx100/7sec ~=2,2 Mbyte/sec. Ein bischen
TFT-Register-Überbau ist noch dabei. Der Stm ist jedenfalls deutlich
schneller als ein 100-Mhz LPC1768 mit dem gleichen Code (10sec per SSP).
DMA ist der übernächste Schritt, jetzt kommt erstmal sdio.
grundschüler schrieb:> Der Stm ist jedenfalls deutlich> schneller als ein 100-Mhz LPC1768 mit dem gleichen Code (10sec per SSP).
Das passt, der LPC kann max 12,5 MHz, der STM 18 MHz. Ist also 44 %
schneller und damit werden aus 7 s dann 10 s.
Mehr geht also nicht, beim STM und SPI1 musst du min. einen Teiler von 4
einstellen um nicht über die 18 MHz zu kommen. Die ~2,2 MB/s sind ~17,6
MHz, also schon am Limit. Die CPU ist jetzt allerdings nur mit dem
Display beschäfftigt, wäre die beim DMA frei für andere Rechnerei oder
wird der Bus trotzdem (teilweise) blockiert?
Beim SPI Takt ist mir noch aufgefallen das tw (Pulsweite SCK) mit 50-60
ns angegeben ist, wie geht das bei 18 MHz Takt (= 55 ns Periodendauer)?
Nachtrag:
wobei die 12,5 MHz beim LPC nur für die SPI Schnittstelle gelten, die
SSP die auch SPI kann soll 50 MBit/s schaffen. Ganz schön verwirrend das
SPI Zeugs.
Jojo S. schrieb:> SPI1 musst du min. einen Teiler von 4
das mit den unterschiedlichen Geschwindigkeiten zwischen spi1 und spi2
habe ich im manual nicht gefunden. Das TFT hängt jetzt an spi2. Ich
werde das aber noch einmal wechseln und bei spi1 verschiedene
Geschwindigkeiten ausprobieren. Vielleicht geht die Begrenzung aber auch
über die Stm-assert-Parameter. Für irgendwas müssen die ja nützlich
sein.
> wäre die beim DMA frei für andere Rechnerei
müsste eigentglich so sein, es gibt ja auch mehrere AHB-Busse.
> 12,5 MHz beim LPC nur für die SPI Schnittstelle
Kann ich nicht bestätigen. LPC-Spi ist gefühlt deutlich langsamer. SSP
war bei 10sec. Wenn ich mein Projekt fertig habe, werde ich mal die
verschiedenen Geschwindigkeiten bitbang/hwSpi für avr stm und lpc
gegenüberstellen.
Weißt du wie das mit spi3 und der SWD-Programmierschnittstelle -beide
A13,A14 - läuft? Kann man dann nicht mehr programmieren?
An spi3 soll ein At45DB32MBit-Speicher, der würde das Board deutlich
aufwerten:
http://www.ebay.de/itm/291221786470?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT
Mysterium spi2: Mit einem mal ging nichts mehr auf spi2. Mittels
spi-Selbsttestprogramm konnte festgestellt werden, dass spi2 erst dann
anläuft, wenn nach der Initialisierung nochmals die spi2-Geschwindigkeit
mit
SPI2->CR1|=7<<3;// /256
eingestellt wird. Warum, ist für mich nicht nachvollziehbar, denn in der
Initialisierung war das schon genau so drin:
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
Der Spi-Selbsttest:
holger schrieb:>>Mysterium spi2:
es kommt zu Überlagerungen zwischen den spi-Registern. Die
Geschwindigkeit Spi1 ändert sich über das SPI2-Register:
lcd_init();
SPI2->CR1&=~(7<<3);SPI2->CR1|=(2<<3);// spi2 schnell, spi1 schnell
//SPI1->CR1&=~(7<<3);// spi2 langsam, spi1 langsam
lcd_clear(RED);
holger schrieb:> Mysterium spi2:>> SPI2 läuft ohne Probleme auch ohne Tricks.
So siehts aus.
Ich nutze bei SPI1 eeprom und den enc28j60 und beim spi2 den Touch, ich
arbeite mit dem STM32F103ZET6.
solche Probleme wie grundschüler hat naja... .
ismaell schrieb:> solche Probleme wie grundschüler hat naja... .
Danke für diesen Beitrag.
Inzwischen läuft spi2 wieder. Das Problem lag an der Schreibsequenz:
1
u8xlcd_spi_write(u8dat){
2
3
SPI2->DR=dat;
4
//_delay_us(50);//ok
5
while(!(SPI2->SR&1<<0));//0_rxne 1_txe 7_bsy// ok
6
//while (!(SPI2->SR & 1<<1));//0_rxne 1_txe 7_bsy//not ok
7
// while ((SPI2->SR & _BV(7))) ;//0_rxne 1_txe 7_bsy//not ok
8
return(u8)SPI2->DR;/**/
9
//SPI1->DR = dat;
10
//while (SPI1->SR & _BV(7)) ;
11
//return (u8)SPI1->DR;
12
}
Während bei spi1 bsy- und tx-Flag so funktionieren wie man das erwartet,
geht bei spi2 nur mit dem rx-Flag. Warum, ist mir unerklärlich.