Das beim STM32F103 USB und CAN nicht gleichzeitig gehen ist bekannt. Die
vom Pinpout gleiche STM32F303 Serie hat ein etwas anderes USB Modul und
die USB-Interrupts kann man remappen damit sie nicht von CAN mitbenutzt
werden.
Bleibt der gemeinsam benutzte SRAM von 512byte bei den kleinen und
1024byte bei den größeren. z.B.
STM32F303RB 64pin 512byte SDRAM für CAN/USB
STM32F303RD(E) 64pin 1024byte SDRAM für CAN/USB
Im Referenz-Manual steht im Abschnitt 32.3 (Seite 1055)
2. The STM32F303xD/E embeds a full-speed USB device peripheral compliant
with the USB
specification version 2.0. The USB interface implements a full-speed (12
Mbit/s) function
interface with added support for USB 2.0 Link Power Management. It has
software-
configurable endpoint setting with packet memory up-to 1 Kbytes (256
bytes are used for CAN
peripheral if enabled) and suspend/resume support.
3. When the CAN peripheral clock is enabled in the RCC_APB1ENR register,
only the first
768 Bytes are available to USB while the last 256 Bytes are used by CAN.
Das liest sich für mich so, dass bei den D/E Typen USB und CAN
gleichzeitig benutzt werden kann, wenn ich mich bei USB mit 768byte
zufrieden gebe. Was bei den Typen mit 512byte passiert bleibt offen.
Die Frage ist: Hat schon mal jemand von euch USB und CAN gleichzeitig
benutzt mit einem Vertreter der STM32F303 Serie?
temp schrieb:> Das liest sich für mich so, dass bei den D/E Typen USB und CAN> gleichzeitig benutzt werden kann, wenn ich mich bei USB mit 768byte> zufrieden gebe.
Richtig.
> Was bei den Typen mit 512byte passiert bleibt offen.
Da kannst du sie nicht gleichzeitig nutzen.
> Hat schon mal jemand von euch USB und CAN gleichzeitig> benutzt mit einem Vertreter der STM32F303 Serie?
Irgendwer hat das hier im Forum schon gemacht und dazu berichtet, dass
man den Interrupt vom USB auf eine andere Nummer um-mappen muss.
Normalerweise benutzt du den Interrupt 20 (USB_LP_CAN_RX0_IRQHandler)
entweder für USB oder CAN. Wenn du beide Schnittstellen gleichzeitig
benutzen willst, musst du USB umkonfigurieren, so dass dieser
stattdessena auf Interrupt 25 ausweicht (USB_LP_IRQHandler). Siehe
Register SYSCGFG->CFGR1 Bit 5 USB_IT_RMP.
Ich habe das nicht ausprobiert.
Ich hatte eine Anfrage an Olimex gemacht ob sie nicht folgendes Board:
https://www.olimex.com/Products/Duino/STM32/open-source-hardware
mit einer alternativen CPU ausstatten könnten, welche diese
Einschränkungen nicht hat. Zuerst hatte ich es nicht für möglich
gehalten, dass der STM32F303RB diese Einschränkung hat, wurde aber eines
besseren belehrt.
Ich hab erst mal ein Nucleo-F303RE bestellt, damit teste ich mal selbst.
temp schrieb:> So, zur Info. Ich habe das Nucleo-STM32F303RE getestet und damit> gehen> USB und CAN gleichzeitg.
Hättest du vllt ein Beispielprojekt, was du hochladen könntest?
Das ist schwierig, weil nur Quick und Dirty zusammen gestückelt um es zu
testen. Keine HAL oder STDLIB, dafür aber Codeteile die ich nicht
rausgeben kann. Die einzige Besonderheit ist das Ummappen der
USB-Interrupts. Alles andere ist so wie bei den anderen STM32F303 auch.
Du kannst das Projekt von Stefan Frings:
http://stefanfrings.de/stm32/stm32f3.html
für den STM32F303RE ohne HAL benutzen um erst mal den USB-Teil zum
laufen zu kriegen. Wenn du das am Laufen hast, kann ich dir gern sagen
was du zum ummappen der iRQs machen musst.
Ich hab hier mal noch einen Nachtrag zu dem Beispielprojekt von Stefan
das auf dem Code von WS basiert. Die Problematik mit der Nop()
Implementierung und eventuellen Compileroptimierungen wurde ja an
anderer Stelle schon mal besprochen. Ich hatte das mal als Projekt für
Crossworks gemacht und bin immer wieder über diese Stelle gestolpert und
musste nachtunen. Blöd ist auch, dass die eine entscheidende Stelle im
Code am Ende der Funktion WriteControlBlock sehr häufig aufgerufen wird
und da jedesmal diese Delays eingebaut werden.
1
intWriteControlBlock(byte*PBuffer,intcount)
2
{
3
#if ENABLE_TRACING
4
charbuf[30];
5
sprintf(buf,"wrCtrlBlock count=%i\n",count);
6
trace(buf);
7
#endif
8
UMEM_FAKEWIDTHA,L;
9
UMEM_FAKEWIDTH*P;
10
inti,n;
11
12
if(count>EpCtrlMaxLen)
13
count=EpCtrlMaxLen;
14
EpTable[0].TxCount=count;
15
16
if(count)
17
{
18
A=0;
19
i=0;
20
n=0;
21
P=(UMEM_FAKEWIDTH*)EPControlTxBuffer;
22
while(i<count)
23
{
24
L=*PBuffer++;
25
A=A|(L<<n);
26
n+=8;
27
if(n>8)
28
{
29
n=0;
30
*P++=A;
31
A=0;
32
}
33
++i;
34
}
35
if(n)
36
*P=A;
37
}
38
ValidateBuffer(logEpCtrl);
39
40
// temp: Auskommentiert da nicht nötig
41
// Nop(100); /* muß sein, sonst keine Enumeration! */
42
returncount;
43
}
Das habe ich bei anderen Implementierungen so noch nicht gesehen. Eine
Analyse ergab, dass das auch nicht nötig ist. Die einzige Stelle an der
die Verzögerung bei mir nötig war ist in der Funktion:
1
voidDoSetAddress(void)
2
{
3
ACK();// das muß bei diesem Core davor!
4
// temp: Nop neu hinzugefügt
5
Nop(1000);
6
USB_SetAddress(CMD.SetupPacket.wValue);
7
}
Die wird im Normalfall nur genau ein mal bei der Enumeration aufgerufen
und hier ist die Zeit auch ziemlich unkritisch. Nachdem ich diese beiden
Änderungen gemacht habe läuft es komplett rund egal ob ich den STM mit
72MHz oder 48MHz laufen lasse und egal welche Optimierung verwendet
wird.
Damit habe ich ein wesentlich besseres Gefühl mit dem gesamten USB Code
von WS da immer wiederkehrende Delayschleifen komplett entfallen.
temp schrieb:> Die einzige Stelle an der> die Verzögerung bei mir nötig war ist in der Funktion
Ich habe deinen Änderungsvorschlag mit einem STM32F103C8 und einem
STM32F303CC verifiziert. Funktioniert.
Ich freue mich immer, wenn wir uns gegenseitig unterstützen können.
Stefanus F. schrieb:> Ich freue mich immer, wenn wir uns gegenseitig unterstützen können.
Freut mich auch.
Bei dieser USB-Implementierung war es vor allem deshalb sehr nervig weil
die NOP()-Schleifen im Interrupt laufen, also genau da wo sie mit
Sicherheit nicht haben will.
moin moin,
bin auf Malle, da dauert alles etwas laenger...
>>Die Frage ist: Hat schon mal jemand von euch USB und CAN gleichzeitig>>benutzt mit einem Vertreter der STM32F303 Serie?
ja, geht. siehe auch:
Beitrag "stm32f303cc USB mappen"
Bei den Olimex-Boards ist mir zuviel drauf.
Benutze daher Black-Pills mit F303CC,
die Pins sind so wie bei den Blue-Pills.
so, nun wieder in die Sonne.
Pieter
Hast du das wirklich einmal probiert? Die Interrups sind ja nur ein Teil
des Problems. Der STM32F303CC hat im Gegensatz zum STM32F303RE nur
512byte SDRAM für USB und CAN gemeinsam. Im Manual zum RE steht, dass
von den 1024Byte gemeinsamen RAM die obersten 256Byte für CAN drauf
gehen wenn enabled. Bleiben also noch 768Byte für USB übrig. Wie das
beim 303CC ist steht da nicht. Deshalb würde mich brennend interesieren
was in dieser Konstellation passiert. Hast du ein Demo-Projekt dafür?
Soweit ich weiß, kann der STM32F303CC nicht gleichzeitig USB und CAN.
Im Referenzhandbuch vom STM32F302CC Kapitel 32.3 "USB implementation"
steht ganz am Anfang:
"The 512 bytes are totally available to USB; nothing is shared with CAN"
Was letztendlich bedeutet, das CAN dann tot ist, weil es kein RAM hat.
Im Referenzhandbuch vom STM32F303CC ist der Wortlaut etwas anders:
"When the CAN peripheral clock is enabled in the RCC_APB1ENR register,
only the first 768 Bytes are available to USB while the last 256 Bytes
are used by CAN."
Da das CC Modell nur 512 Bytes RAM hat, bleibt für CAN nichts mehr
übrig.
Meine Meinung dazu ist: ST hätte auch einfach klipp und klar schreiben
können: "On devices with 512 Bytes buffer USB and CAN cannot be used
together". Aber mir ist schon mehrmals aufgefallen, dass sie eventuell
überraschende Einschränkungen gerne verheimlichen.
Ich verstehe den Beitrag von Pieter so, dass er gerne die Black-Pill
Boards verwendet, ungeachtet der USB+CAN Einschränkung.
Ich gerade in diesem Zusammenhang einen Hammer in dem Errata Dokument
entdeckt.
------------------------------------------------------------------
Data Read when the CPU accesses successively SRAM address “A”and SRAM
address “A + offset of 16 KBytes (0x4000)”
Description:
If the CPU writes to an address A in the SRAM memory and immediately
(the cycle after) reads an address B in the SRAM memory, while B =
A+0x4000, the read operation will return the content at address A
instead of the content of address B.
Workaround:
Revision Z devices: The likelihood of such condition to occur is rare
and will happen with a code having more than 16 Kbytes of RAM usage. In
case of hand-written assembly code, the work-around is to insert a NOP
between consecutive write and read from addresses A and A+0x4000
respectively. With a C compiler, it is advised to limit the SRAM usage
to 16 Kb instead of 40 Kb. The 8 Kb of CCM memory can also be used for
data to have a 24 Kb total RAM space available.
Revision Y devices: fixed
------------------------------------------------------------------
WTF?
Ich soll im Ernst auf mehr als 50% vom RAM verzichten, weil er bei
Lesezugriffen auf die höheren Adressen sporadisch die falschen Zellen
ausliest?
Also eigentlich müsste das zu einer Rückrufaktion führen.
Was hat es mit dem Y und Z auf sich? Ich hätte jetzt erwartet, dass
Revision Z die neuere ist, aber dann kann der Kommentar "fixed" bei Y
nicht passen.
So jetzt von mir Hammer Nr. 2:
vor mir liegt folgendes Board:
https://robotdyn.com/catalog/development-boards/stm-boards-and-shields/stm32f303cct6-256-kb-flash-stm32-arm-cortexr-m4-mini-system-dev-board-3326a9dd-3c19-11e9-910a-901b0ebb3621.html
Mit einem stm32f303cc. Da habe ich jetzt die Software installiert die
ich im Zusammenhang mit dem xxRE gemacht habe. Ein einfaches
USB-CAN-Interface mit SLCAN Protokol. Einzig die Adressierungsart des
USB-Speichers (1x16bit, 2x 16bit) habe ich da angepasst. Der darin
enthaltene USB-Code (WS) nimmt sich 484Bytes vom USB Ram. Eigentlich
sollte das ja nicht gemeinsam mit CAN gehen. Aber oh Wunder, es
funktioniert genauso wie mit dem STM32F303RE. Dass muss ich erst mal
verdauen. Welchen Speicher benutzt denn dann das CAN-Interface?
Eventuell haben beide 1024byte. Der eine in 512/512Byte geteilt und der
andere in 768/256Byte mit dem Hintergrund bei den größeren Typen mehr
für den USB Teil zu ermöglichen.
Auf alle Fälle schaufelt sich der Rechner über das Board und einem
USBtin im 1ms Takt bei 125kbaud fröhlich Daten hin und her.
Die Frage die sich dabei stellt ist was sich STM dabei denkt.
Stefanus F. schrieb:> Was hat es mit dem Y und Z auf sich? Ich hätte jetzt erwartet, dass> Revision Z die neuere ist, aber dann kann der Kommentar "fixed" bei Y> nicht passen.
Ich denke Y ist die neuere. Im Register DBGMCU->IDCODE kannst du das
auslesen. Bei mir steht da 0x1003 drin. Das bedeutet 'Y'. Demnach keine
Panik! Der letzte Eintrag in der revision history ist von 2016. Ich
denke die 'Z' Variante wirst du kaum noch auftreiben könnnen.
Ich hab noch einen zum Thema USB-Code von WS.
Die Ursache Delays in den Interruphandler einzubauen hatte folgende
Ursache:
1
volatileuint8_tDeviceAddress=0;
2
voidDoSetAddress(void)
3
{
4
ACK();// das muß bei diesem Core davor!
5
DeviceAddress=CMD.SetupPacket.wValue;
6
// Nop(1000);
7
// USB_SetAddress(CMD.SetupPacket.wValue);
8
}
Wenn der PC dem Device seine zukünftige Adresse mitteilt, muss das wie
oben mit ACK() beantwortet werden. Allerdings darf die während dieses
Transfers noch nicht im Register USB_DADDR gesetzt werden. Erst wenn das
Packet draussen ist darf die neue Addresse da hinein geschrieben werden.
Deshalb merke ich mir die an Stelle nur und setze sie dann erst im
Interrupthandler:
temp schrieb:> Das liest sich für mich so, dass bei den D/E Typen USB und CAN> gleichzeitig benutzt werden kann
Ich habe mir das nochmal in Ruhe angeschaut und die Wortlaute auch mit
anderen STM Serien verglichen. Dadurch bin ich zum Schluss gekommen,
dass man wohl bei allen STM32F303 Modellen USB und CAN gleichzeitig
verwenden kann.
Der Unterschied ist:
STM32F303xB und xC haben 512 Bytes für USB + 512 Bytes Speicher für CAN.
STM32F303xD und xE haben 1024 Bytes für USB und CAN, wovon die letzten
256 byte von CAN belegt werden, wenn man beides nutzt.
Die Fußnoten, die im Eröffnungsbeitrag zitiert wurden, beziehen sich nur
auf die 1kB Modelle (xD und xE).
In der AN4879 auf Seite 4 habe ich klare Aussagen gefunden:
https://www.st.com/content/ccc/resource/technical/document/application_note/group0/0b/10/63/76/87/7a/47/4b/DM00296349/files/DM00296349.pdf/jcr:content/translations/en.DM00296349.pdf
STM32F102, STM32F103 haben gemeinsam genutzt 512B, also können USB und
CAN nicht zugleich benutzt werden.
STM32F070x6/B, STM32F072, STM32F078, STM32F04x, STM32F302x6/8,
STM32F302xD/E, STM32F303xD/E haben 1KB gemeinsam genutzten Speicher.
Davon sind 768 Bytes für USB und 256 Bytes für CAN, wenn man beide
Schnittstellen zugleich verwendet.
STM32F105/107, STM32F302xB/C, STM32F303xB/C, STM32F373, STM32F4,
STM32F7, STM32H7, STM32L0, STM32L1, STM32L2, STM32L3 und STM32L4 haben
für USB und CAN unabhängige Speicher.
moin,
bei unserem Hotel funktioniert Internet nur bei schoenem Wetter...und
dann bin ich am Strand.
Das Black-Pil hat einen STM32F303CC drauf und stellet bei mir einen
USB-HID<->CAN Umsetzer bereit.
Die USB-HID Unit ( Pascal ) ist fuer 103C8 und 303CC identisch, beim 303
wird nur zusaetzlich der USB Interrupt umgebogen, zeigt aber auf die
selbe ISR wie beim 103.
so, nun wieder in die Sonne.
Pieter