STM32H750 mit W25Q64 QSPI XIP memory mapped mode

Gast #7206068
Lesenswert?

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.
Gast #7206477
Lesenswert?

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...
Gast #7206506
Lesenswert?

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
Gast #7206547
Lesenswert?

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
}
Gast #7206948
Lesenswert?

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.
Gast #7207480
Lesenswert?

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.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren