STM32CubeH7
STM32CubeH7 copied to clipboard
NOR Flash driver does not support x8 commands
Describe the set-up Nucleo-H743ZI2 with attached parallel NOR flash. CubeMX project with just FMC, STM32H7 HAL version 1.10.0, arm-none-eabi-gcc 12.1.0.
Describe the bug
In the latest version of stm32h7xx_hal_nor.c
, the HAL_NOR_Init()
function gets an invalid command set and asserts when an 8-bit data bus is in use. HAL_NOR_Init()
enters CFI mode like so,
/* Get the value of the command set */
NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
hnor->CommandSet = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_ADDRESS_COMMAND_SET);
where uwNORMemoryDataWidth
is NOR_MEMORY_8B
, NOR_CMD_ADDRESS_FIRST_CFI
is 0x0055
, and NOR_ADDRESS_COMMAND_SET
is 0x0098
.
Per the datasheets for Infineon S29GL-P/S/T and Micron MT28EW memories, the address for CFI Enter is 0x00AA
in byte mode. Furthermore, the address of every CFI entry is shifted left by one, e.g. 'Q', 'R', and 'Y' are at 0x20, 0x22, and 0x24, and the command set is at 0x26.
How To Reproduce
-
Set up Nucleo-H743ZI2 project in STM32CubeMX
-
Configure FMC NOR bank 1, chip select NE1, address 24 bits, data 8 bits, no clock, no address valid, asynchronous wait, pull-up on NWAIT.
-
Connect parallel NOR flash that supports byte mode
-
Compile, flash and run
-
See that the HAL NOR driver is getting an invalid command set and returns an error
Additional context
Command addresses in byte mode seem to be the same as the addresses in word mode, shifted left by one, e.g. 0x555
becomes 0xAAA
. However word mode 0x2AA
becomes byte mode 0x555
.
For my application I'm adding a second set of defines for byte-mode command addresses, and a macro:
// stm32h7xx_hal_nor.c
#define NOR_CMD_ADDRESS_FIRST_BYTE (uint16_t)0x0AAA
#define NOR_CMD_ADDRESS_FIRST_CFI_BYTE (uint16_t)0x00AA
#define NOR_CMD_ADDRESS_SECOND_BYTE (uint16_t)0x0555
// stm32h7xx_hal_nor.h
#define NOR_ADDR_SHIFT_CMD(__NOR_ADDRESS, __NOR_MEMORY_WIDTH_, __ADDRESS__) \
((uint32_t)(((__NOR_MEMORY_WIDTH_) == NOR_MEMORY_16B)? \
((uint32_t)((__NOR_ADDRESS) + (__ADDRESS__))): \
((uint32_t)((__NOR_ADDRESS) + (2U*(__ADDRESS__))))))
and making the appropriate changes:
// stm32h7xx_hal_nor.c HAL_NOR_Init()
/* Get the value of the command set */
uint16_t cfi_enter = uwNORMemoryDataWidth == NOR_MEMORY_16B ? NOR_CMD_ADDRESS_FIRST_CFI : NOR_CMD_ADDRESS_FIRST_CFI_BYTE;
NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, cfi_enter), NOR_CMD_DATA_CFI);
hnor->CommandSet = *(__IO uint16_t *) NOR_ADDR_SHIFT_CMD(deviceaddress, uwNORMemoryDataWidth, NOR_ADDRESS_COMMAND_SET);
ST Internal Reference: 132128
After further manual testing I believe the particular device I was using (Infineon S29GL01GP) is broken in byte mode. A-1 is ignored in the CFI address space (leading to the assertion), and it does not seem to respond to program or erase commands.