micropython / micropython

MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems
https://micropython.org
Other
19.3k stars 7.72k forks source link

Porting to STM32F429IGT6, how to mount NAND FLASH? #13014

Open hiltay opened 11 months ago

hiltay commented 11 months ago

I am a developer from China and I'm using translation software. So if there's anything unclear, please let me know.

I'm in the process of porting MicroPython to STM32F429IGT6. I've modified the mpconfigboard.h file and successfully run the code. However, the default FLASH space is quite small, and I need to expand it. After checking the schematic, I found a 512MB NAND FLASH. I want to mount it as an sdcard so that when I connect a USB device, my computer can recognize it, allowing me to store Python code inside. This NAND FLASH uses FMC pins rather than SPI. Now I'm unsure about how to mount it.

Should I modify the mpconfigboard.h file? Or modify the source code? Or access it within the MicroPython program and then mount it externally using os.mount?

The following is some information maybe useful.

NAND FLASH schematic:

image

my mpconfigboard.h

#define MICROPY_HW_BOARD_NAME       "F429IGT6"
#define MICROPY_HW_MCU_NAME         "STM32F429"

#define MICROPY_HW_HAS_SWITCH       (1)
#define MICROPY_HW_HAS_FLASH        (1)
#define MICROPY_HW_ENABLE_RNG       (1)
#define MICROPY_HW_ENABLE_RTC       (1)
#define MICROPY_HW_ENABLE_USB       (1)
#define MICROPY_HW_ENABLE_SERVO     (0)

// HSE is 8MHz
#define MICROPY_HW_CLK_PLLM (25)
#define MICROPY_HW_CLK_PLLN (384)
#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2)
#define MICROPY_HW_CLK_PLLQ (8)

#define MICROPY_HW_UART_REPL        PYB_UART_1
#define MICROPY_HW_UART_REPL_BAUD   115200

// UART config
#define MICROPY_HW_UART1_TX     (pin_A9)
#define MICROPY_HW_UART1_RX     (pin_A10)
#define MICROPY_HW_UART2_TX     (pin_A2)
#define MICROPY_HW_UART2_RX     (pin_A3)
#define MICROPY_HW_UART3_TX     (pin_B10)
#define MICROPY_HW_UART3_RX     (pin_B11)
// #define MICROPY_HW_UART6_TX     (pin_C6)
// #define MICROPY_HW_UART6_RX     (pin_C7)

// I2C buses
#define MICROPY_HW_I2C3_SCL (pin_A8)
#define MICROPY_HW_I2C3_SDA (pin_C9)

// SPI buses
// #define MICROPY_HW_SPI1_NSS     (pin_A4)
// #define MICROPY_HW_SPI1_SCK     (pin_A5)
// #define MICROPY_HW_SPI1_MISO    (pin_A6)
// #define MICROPY_HW_SPI1_MOSI    (pin_A7)
#if defined(USE_USB_HS_IN_FS)
// The HS USB uses B14 & B15 for D- and D+
#else
#define MICROPY_HW_SPI2_NSS  (pin_B12)
#define MICROPY_HW_SPI2_SCK  (pin_B13)
#define MICROPY_HW_SPI2_MISO (pin_B14)
#define MICROPY_HW_SPI2_MOSI (pin_B15)
#endif
// #define MICROPY_HW_SPI4_NSS     (pin_E11)
// #define MICROPY_HW_SPI4_SCK     (pin_E12)
// #define MICROPY_HW_SPI4_MISO    (pin_E13)
// #define MICROPY_HW_SPI4_MOSI    (pin_E14)
#define MICROPY_HW_SPI5_NSS     (pin_F6)
#define MICROPY_HW_SPI5_SCK     (pin_F7)
#define MICROPY_HW_SPI5_MISO    (pin_F8)
#define MICROPY_HW_SPI5_MOSI    (pin_F9)
// #define MICROPY_HW_SPI6_NSS     (pin_G8)
// #define MICROPY_HW_SPI6_SCK     (pin_G13)
// #define MICROPY_HW_SPI6_MISO    (pin_G12)
// #define MICROPY_HW_SPI6_MOSI    (pin_G14)

// CAN buses
#define MICROPY_HW_CAN1_TX (pin_B9)
#define MICROPY_HW_CAN1_RX (pin_B8)
#define MICROPY_HW_CAN2_TX (pin_B13)
#define MICROPY_HW_CAN2_RX (pin_B12)

// USRSW is pulled low. Pressing the button makes the input go high.
#define MICROPY_HW_USRSW_PIN        (pin_A0)
#define MICROPY_HW_USRSW_PULL       (GPIO_NOPULL)
#define MICROPY_HW_USRSW_EXTI_MODE  (GPIO_MODE_IT_RISING)
#define MICROPY_HW_USRSW_PRESSED    (1)

// LEDs
#define MICROPY_HW_LED1             (pin_B0) // red
#define MICROPY_HW_LED2             (pin_B1) // green
#define MICROPY_HW_LED_ON(pin)      (mp_hal_pin_high(pin))
#define MICROPY_HW_LED_OFF(pin)     (mp_hal_pin_low(pin))

// USB config
// #define MICROPY_HW_USB_HS              (1)
// #define MICROPY_HW_USB_HS_IN_FS        (1)
#define MICROPY_HW_USB_FS              (1)
#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_C13)
#define MICROPY_HW_USB_OTG_ID_PIN      (pin_B12)

// SDRAM
#define MICROPY_HW_SDRAM_SIZE  (32 * 1024 * 1024)  // 32M Bytes
#define MICROPY_HW_SDRAM_STARTUP_TEST             (1)
#define MICROPY_HEAP_START  ((sdram_valid) ? sdram_start() : &_heap_start)
#define MICROPY_HEAP_END    ((sdram_valid) ? sdram_end() : &_heap_end)

// Timing configuration for 90 Mhz (11.90ns) of SD clock frequency (180Mhz/2)
#define MICROPY_HW_SDRAM_TIMING_TMRD        (2)
#define MICROPY_HW_SDRAM_TIMING_TXSR        (8)
#define MICROPY_HW_SDRAM_TIMING_TRAS        (6)
#define MICROPY_HW_SDRAM_TIMING_TRC         (6)
#define MICROPY_HW_SDRAM_TIMING_TWR         (2)
#define MICROPY_HW_SDRAM_TIMING_TRP         (2)
#define MICROPY_HW_SDRAM_TIMING_TRCD        (2)
#define MICROPY_HW_SDRAM_REFRESH_RATE       (64) // ms

#define MICROPY_HW_SDRAM_BURST_LENGTH       2
#define MICROPY_HW_SDRAM_CAS_LATENCY        3
#define MICROPY_HW_SDRAM_COLUMN_BITS_NUM    9
#define MICROPY_HW_SDRAM_ROW_BITS_NUM       13
#define MICROPY_HW_SDRAM_MEM_BUS_WIDTH      16
#define MICROPY_HW_SDRAM_INTERN_BANKS_NUM   4
#define MICROPY_HW_SDRAM_CLOCK_PERIOD       2
#define MICROPY_HW_SDRAM_RPIPE_DELAY        1
#define MICROPY_HW_SDRAM_RBURST             (0)
#define MICROPY_HW_SDRAM_WRITE_PROTECTION   (0)
#define MICROPY_HW_SDRAM_AUTOREFRESH_NUM    (8)

#define MICROPY_HW_FMC_SDCKE0   (pin_C3)
#define MICROPY_HW_FMC_SDNE0    (pin_C2)
//#define MICROPY_HW_FMC_SDCKE1   (pin_B5)
//#define MICROPY_HW_FMC_SDNE1    (pin_B6)
#define MICROPY_HW_FMC_SDCLK    (pin_G8)
#define MICROPY_HW_FMC_SDNCAS   (pin_G15)
#define MICROPY_HW_FMC_SDNRAS   (pin_F11)
#define MICROPY_HW_FMC_SDNWE    (pin_C0)
#define MICROPY_HW_FMC_BA0      (pin_G4)
#define MICROPY_HW_FMC_BA1      (pin_G5)
#define MICROPY_HW_FMC_NBL0     (pin_E0)
#define MICROPY_HW_FMC_NBL1     (pin_E1)
#define MICROPY_HW_FMC_A0       (pin_F0)
#define MICROPY_HW_FMC_A1       (pin_F1)
#define MICROPY_HW_FMC_A2       (pin_F2)
#define MICROPY_HW_FMC_A3       (pin_F3)
#define MICROPY_HW_FMC_A4       (pin_F4)
#define MICROPY_HW_FMC_A5       (pin_F5)
#define MICROPY_HW_FMC_A6       (pin_F12)
#define MICROPY_HW_FMC_A7       (pin_F13)
#define MICROPY_HW_FMC_A8       (pin_F14)
#define MICROPY_HW_FMC_A9       (pin_F15)
#define MICROPY_HW_FMC_A10      (pin_G0)
#define MICROPY_HW_FMC_A11      (pin_G1)
#define MICROPY_HW_FMC_A12      (pin_G2)
#define MICROPY_HW_FMC_D0       (pin_D14)
#define MICROPY_HW_FMC_D1       (pin_D15)
#define MICROPY_HW_FMC_D2       (pin_D0)
#define MICROPY_HW_FMC_D3       (pin_D1)
#define MICROPY_HW_FMC_D4       (pin_E7)
#define MICROPY_HW_FMC_D5       (pin_E8)
#define MICROPY_HW_FMC_D6       (pin_E9)
#define MICROPY_HW_FMC_D7       (pin_E10)
#define MICROPY_HW_FMC_D8       (pin_E11)
#define MICROPY_HW_FMC_D9       (pin_E12)
#define MICROPY_HW_FMC_D10      (pin_E13)
#define MICROPY_HW_FMC_D11      (pin_E14)
#define MICROPY_HW_FMC_D12      (pin_E15)
#define MICROPY_HW_FMC_D13      (pin_D8)
#define MICROPY_HW_FMC_D14      (pin_D9)
#define MICROPY_HW_FMC_D15      (pin_D10)

core board:

78a6f6276797b4848432ce0b613eab98

andrewleech commented 11 months ago

Hi @hiltay the F429 is generally a very well supported chip on micropython, I've used it a number of times myself.

However I don't believe anyone has ever written a driver to use the nand flash interface at all before, so one would need to be written to use this flash chip.

The FMC port is used in the SDRAM driver in https://github.com/micropython/micropython/blob/master/ports/stm32/sdram.c That would be a good starting point to use as reference for a nand driver, though I presume a fair number of register settings would need to change to put it in nand mode. Once that was written I presume the flash would be exposed at a memory address range, at this point it would be fairly easy to map that into a VFS block device that could be mounted and formatted.

hiltay commented 10 months ago

Hi @hiltay the F429 is generally a very well supported chip on micropython, I've used it a number of times myself.

However I don't believe anyone has ever written a driver to use the nand flash interface at all before, so one would need to be written to use this flash chip.

The FMC port is used in the SDRAM driver in https://github.com/micropython/micropython/blob/master/ports/stm32/sdram.c That would be a good starting point to use as reference for a nand driver, though I presume a fair number of register settings would need to change to put it in nand mode. Once that was written I presume the flash would be exposed at a memory address range, at this point it would be fairly easy to map that into a VFS block device that could be mounted and formatted.

Thanks for reply! I attempted to write a driver for the NAND flash, but due to my limited expertise it did not work well. Now I'm using an another SD card for storage.