Hallo, hat jemand eine funktionierende Demo mit STM32H750 und W25Q64 QSPI im XIP memory mapped mode? Programm im QSPI und flashloader Programm im internen Flash. (am liebsten als STM32CubeIDE Projekt) Danke
Zunächst mal FV oder JV? Und wo soll da das Problem sein? Man muss vor dem Einschalten des Memory Mapped Mode einmal ein Indirekt Read mit Instruktion und dem passenden Mode Byte (XIP an, als Alternate Byte) auslösen und dann beim Memory Mapped Mode keine Instruktion, ein Alternate Byte (mit dem passenden Mode Byte für XIP an) konfigurieren. Und zum Ausschalten erstmal ein Abort, dann Indirekt Read ohne Instruktion, Adresse 0 und passendem Mode Byte (für XIP aus) auslösen. Adresse 0, weil man u. U. nicht sicher sein kann, ob der Flash im XIP-Modus ist oder nicht, also das erste Byte der Adresse eventuell als Instruktion fehlinterpretiert werden könnte. Und 0x00 ist kein gültige Intruktion.
A. B. schrieb: > Zunächst mal FV oder JV? JV ... spielt das eine Rolle im Code? > Und wo soll da das Problem sein? Also ich habe zuerst ein paar STM32 Beispiele mit dem STM32H750B Disco Board ausprobiert die mit Program-Code via externem QSPI laufen. Das funktioniert gut. Das STM Beispiel-Projekt (ext Flash Booter) für den Code auf dem internen STM32-Flash lautet "ExtMem_Boot". Ich habe jetzt ein ähnliches Board, aber mit einem (in China) besser erhältlichen QSPI von Windbond W25Q64JV (single). Jetzt habe ich versucht das "ExtMem_Boot" Projekt so anzupassen, dass es für den W25Q64 passt. Beim Debuggen verhält es sich jedoch anders, d.h. der externe Flash zeigt nach der "EnableMemoryMappedMode" Funktion überall den Inhalt 888888888 und das Program geht dann in den void MemManage_Handler(void).... also irgendwas läuft was falsch. Anpassungen habe ich im qspi.c und memory_msp.h File durchgeführt. Das angepasste "ExtMem_Boot" Projekt findet man hier (Code im Bereich ifdef W25Q64): https://drive.google.com/drive/folders/1n7dnF52jlO1vyJ8ENyKqWqMjwYVJ1sRY?usp=sharing Die Anpassungen habe ich gemäss folgendem Projekt versucht zu übernehmen jedoch mit Pin-Mapping PB2,6, PF6,7,8,9 (das Board/Projekt ist/sollte für ein W25Q64 chip geschrieben sein): https://github.com/osos11-https://github.com/osos11-Git/STM32H743VIT6_Boring_TECH_QSPI/tree/main/Memory%20Mapped%20Mode/H743_QSPI_XIP_1 > Man muss vor dem Einschalten des Memory Mapped Mode einmal ein Indirekt > Read mit Instruktion und dem passenden Mode Byte (XIP an, als Alternate > Byte) auslösen und dann beim Memory Mapped Mode keine Instruktion, ein > Alternate Byte (mit dem passenden Mode Byte für XIP an) konfigurieren. > Und zum Ausschalten erstmal ein Abort, dann Indirekt Read ohne > Instruktion, Adresse 0 und passendem Mode Byte (für XIP aus) auslösen. > > Adresse 0, weil man u. U. nicht sicher sein kann, ob der Flash im > XIP-Modus ist oder nicht, also das erste Byte der Adresse eventuell als > Instruktion fehlinterpretiert werden könnte. Und 0x00 ist kein gültige > Intruktion. Die (HAL) Prozedur im Code ist aktuell wie folgt:
1 | 1.) QSPI GPIOs initialisieren |
2 | |
3 | 2.) ClockPrescaler, FifoThreshold, Sampleshifting, FlashSize, ChipSelectHighTime, ClockMode, FlashID=0?? initialisieren. |
4 | |
5 | 3.) ResetMemory |
6 | |
7 | 4.) AutoPollingMemReady |
8 | |
9 | 5.) Config (0x35 und 0x50 und 0x31 und 0x15 und 0x11 command instruction) |
10 | |
11 | 6.) EnableMemoryMappedMode |
bin für jeden Hinweis dankbar...
das ist witzig .. hatte damit auch meine probleme ... liegt am interrupt ich habs dann zum laufen bekommen zwar der W25Q16JV mit den GPIOs den HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0); HAL_NVIC_EnableIRQ(QUADSPI_IRQn); und die dummycycles richtig setzen
1 | uint8_t CSP_QSPI_EnableMemoryMappedMode(void) { |
2 | |
3 | QSPI_CommandTypeDef sCommand = {0}; |
4 | QSPI_MemoryMappedTypeDef sMemMappedCfg = {0}; |
5 | |
6 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
7 | sCommand.Instruction = 0xEB; |
8 | sCommand.AddressMode = QSPI_ADDRESS_4_LINES; |
9 | sCommand.DataMode = QSPI_DATA_4_LINES; |
10 | sCommand.NbData = 0; |
11 | sCommand.Address = 0; |
12 | |
13 | switch ( jedecID ){ |
14 | case 0x1540ef: |
15 | case 0x1640ef: |
16 | sCommand.DummyCycles = 6; |
17 | sCommand.AddressSize = QSPI_ADDRESS_24_BITS; |
18 | break; |
19 | |
20 | case 0x1871f: |
21 | case 0x1861f: |
22 | sCommand.DummyCycles = 4; |
23 | sCommand.AddressSize = QSPI_ADDRESS_32_BITS; |
24 | break; |
25 | }
|
26 | |
27 | sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; |
28 | sMemMappedCfg.TimeOutPeriod = 0; |
29 | |
30 | if (QSPI_WriteEnable() != HAL_OK) { |
31 | return HAL_ERROR; |
32 | }
|
33 | if (HAL_QSPI_MemoryMapped(&hqspi, &sCommand, &sMemMappedCfg) != HAL_OK) { |
34 | return HAL_ERROR; |
35 | }
|
36 | return HAL_OK; |
37 | }
|
einen dummyread vorher machen
achso das war der bootloader !! die applikation fässt den QSPI nicht wieder an ich hab ewig gesucht ... erst mit aktivieren des QSPI interrupts funktioniert das mit dem memory mapped...
1 | void MX_QUADSPI_Init(void){ |
2 | hqspi.Instance = QUADSPI; |
3 | hqspi.Init.ClockPrescaler = 480/75; |
4 | hqspi.Init.FifoThreshold = 1; |
5 | hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; |
6 | hqspi.Init.FlashSize = 20; |
7 | hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE; |
8 | hqspi.Init.ClockMode = QSPI_CLOCK_MODE_3; |
9 | hqspi.Init.FlashID = QSPI_FLASH_ID_1; |
10 | hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE; |
11 | |
12 | if (HAL_QSPI_Init(&hqspi) != HAL_OK){ |
13 | Error_Handler(); |
14 | }
|
15 | }
|
16 | |
17 | // bootloader main
|
18 | int main(void){ |
19 | SystemInit(); |
20 | HAL_Init(); |
21 | SystemClock_Config(); |
22 | SystemCoreClockUpdate(); |
23 | MX_GPIO_Init(); |
24 | |
25 | if( CSP_QSPI_Init() != HAL_OK) { |
26 | goto error; |
27 | }
|
28 | |
29 | volatile int firstbyte = 0; |
30 | CSP_QSPI_ReadMemory( (uint8_t*)&firstbyte , (0x000000), 4 ); |
31 | |
32 | if (CSP_QSPI_EnableMemoryMappedMode() != HAL_OK){ |
33 | goto error; |
34 | }
|
35 | if( *((uint32_t*) QSPI_BASE ) == 0xFFFFFFFF ){ |
36 | while(1); |
37 | }
|
38 | |
39 | SysTick->CTRL = 0 ; |
40 | boot_jump( QSPI_BASE ); |
41 | }
|
opzuiziziz schrieb: > erst mit aktivieren des QSPI interrupts funktioniert das mit dem memory > mapped... Ok, danke schon mal. Bei mir ist der Interrupt aktiviert, aber ich werde jetzt mal versuchen Schritt für Schritt deine Parameter zu übernehmen...
wichtig ist der adressmode(16/24/32 bit ) und die dummybytes ich habe das so gemacht das erstmal grundlegend alle schreib / lese funktionen das tun was sie sollen Danach erst den memory mapped
epika schrieb: > A. B. schrieb: >> Zunächst mal FV oder JV? > JV ... spielt das eine Rolle im Code? Da manche Kommandos nur in einem der beiden verfügbar sind, ganz offensichtlich. > Das STM Beispiel-Projekt (ext Flash Booter) für den Code auf dem > internen STM32-Flash lautet "ExtMem_Boot". > > Ich habe jetzt ein ähnliches Board, aber mit einem (in China) besser > erhältlichen QSPI von Windbond W25Q64JV (single). > > Jetzt habe ich versucht das "ExtMem_Boot" Projekt so anzupassen, dass es > für den W25Q64 passt. > Beim Debuggen verhält es sich jedoch anders, d.h. der externe Flash > zeigt nach der "EnableMemoryMappedMode" Funktion überall den Inhalt > 888888888 und das Program geht dann in den void > MemManage_Handler(void).... also irgendwas läuft was falsch. Die 88888888 ist eher ein Symptom, dass 1-Line/4-Line Modi zwischen QSPI-Interface und Flash nicht passen. Man man aber strikt zwischen Programmausführung (nur Lesen, und zwar im Memory Mapped Mode) und Löschen/Schreiben/Konfigurieren unterscheiden. XIP geht nur, wenn der Flash ausschließlich Reads bekommt. > Die (HAL) Prozedur im Code ist aktuell wie folgt: > >
1 | > 1.) QSPI GPIOs initialisieren |
2 | >
|
3 | > 2.) ClockPrescaler, FifoThreshold, Sampleshifting, FlashSize, |
4 | > ChipSelectHighTime, ClockMode, FlashID=0?? initialisieren. |
5 | >
|
6 | > 3.) ResetMemory |
7 | >
|
8 | > 4.) AutoPollingMemReady |
9 | |
10 | AutoPolling veträgt sich grundsätzlich nicht mit XIP, denn dabei werden |
11 | Read Status Reg. Kommandos gesendet. Bei Lesen ist AutoPolling aber ohnehin sinnfrei. |
12 | |
13 | > 5.) Config (0x35 und 0x50 und 0x31 und 0x15 und 0x11 command |
14 | > instruction) |
15 | >
|
16 | > 6.) EnableMemoryMappedMode |
17 | >
|
Und das mit XIP? Das KANN so nicht gehen, denn der Flash bekommt dabei ja gar kein Befehlsbyte mehr. Es muss erst einmal das Read-Kommando (inkl. Befehlsbyte) geschickt werden, und am Ende des Kommandos gibt das Mode Byte an "bleibe in diesem Modus". Der erste Lesezugriff muss also MIT Befehlsbyte, alle weiteren müssen OHNE arbeiten. Also können die von vornherein nicht mit derselben Konfiguration des QSPI-Interface arbeiten. Nach dem "Anstoßen" des XIP-Modus muss also das QSPI-Interface umkonfiguriert werden, und das geht bekanntlich nur im "gestoppten" Zustand.
opzuiziziz schrieb: > die dummycycles richtig setzen Jetzt läuft schon mal was, vielen Dank :-D ... Komisch nur, dass der erste Buchstabe von "Hello..." im Memory nicht abgebildet wird, aber im readbuf dann schon (siehe Anhang Bild). Weiss jemand da was?? Änderungen: Memory Mapped Mode von 0x6B auf 0xEB gewechselt, dummycycles von 8 auf 6, und dann war "gpio_init_structure.Alternate" teils falsch gesetzt, AF9 statt AF10 oder umgekehrt. Für was ist Alternate überhaupt? Ist das entscheidend? Vielen Dank für die Inputs.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.