| /**************************************************************************** |
| * boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_flash.c |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <nuttx/config.h> |
| #include <nuttx/mtd/mtd.h> |
| #include <nuttx/mtd/configdata.h> |
| #include <nuttx/fs/nxffs.h> |
| #include <nuttx/fs/smart.h> |
| #include <nuttx/fs/fs.h> |
| |
| #include <debug.h> |
| #include <stdio.h> |
| |
| #include "nucleo-wl55jc.h" |
| #include "hardware/stm32wl5_flash.h" |
| |
| /**************************************************************************** |
| * Pre-Processor Definitions |
| ****************************************************************************/ |
| |
| /* Define default values to silent compiler warning about undefined macro */ |
| |
| #ifndef CONFIG_ARCH_BOARD_FLASH_BL_PROG_SIZE |
| #define CONFIG_ARCH_BOARD_FLASH_BL_PROG_SIZE 0 |
| #endif |
| |
| #ifndef CONFIG_ARCH_BOARD_FLASH_CPU1_PROG_SIZE |
| #define CONFIG_ARCH_BOARD_FLASH_CPU1_PROG_SIZE 0 |
| #endif |
| |
| #ifndef CONFIG_ARCH_BOARD_FLASH_CPU2_PROG_SIZE |
| #define CONFIG_ARCH_BOARD_FLASH_CPU2_PROG_SIZE 0 |
| #endif |
| |
| #ifndef CONFIG_ARCH_BOARD_FLASH_PART1_SIZE |
| #define CONFIG_ARCH_BOARD_FLASH_PART1_SIZE 0 |
| #endif |
| |
| #ifndef CONFIG_ARCH_BOARD_FLASH_PART2_SIZE |
| #define CONFIG_ARCH_BOARD_FLASH_PART2_SIZE 0 |
| #endif |
| |
| #ifndef CONFIG_ARCH_BOARD_FLASH_PART3_SIZE |
| #define CONFIG_ARCH_BOARD_FLASH_PART3_SIZE 0 |
| #endif |
| |
| #ifndef CONFIG_ARCH_BOARD_FLASH_PART4_SIZE |
| #define CONFIG_ARCH_BOARD_FLASH_PART4_SIZE 0 |
| #endif |
| |
| #if (CONFIG_ARCH_BOARD_FLASH_BL_PROG_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_CPU1_PROG_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_CPU2_PROG_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART1_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART2_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART3_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART4_SIZE) > 128 |
| # error "Sum of all flash pertitions cannot be bigger than 128" |
| #endif |
| |
| #if (CONFIG_ARCH_BOARD_FLASH_BL_PROG_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_CPU1_PROG_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_CPU2_PROG_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART1_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART2_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART3_SIZE + \ |
| CONFIG_ARCH_BOARD_FLASH_PART4_SIZE) < 128 |
| # warning "There is unused space on flash" |
| #endif |
| |
| #define FLASH_PAGE_SIZE STM32WL5_FLASH_PAGESIZE |
| |
| /**************************************************************************** |
| * Private Definitions |
| ****************************************************************************/ |
| |
| struct part_table |
| { |
| int size; /* partition size in pages */ |
| const char *name; /* name of the partition */ |
| const char *mnt; /* mount point for the partition */ |
| const char *fs; /* fs type (smart, raw, nxffs) */ |
| }; |
| |
| /* partition table, first entry *must always* be program flash memory */ |
| |
| static const struct part_table part_table[] = |
| { |
| #if CONFIG_ARCH_BOARD_FLASH_BL_PROG_SIZE > 0 |
| { |
| .size = CONFIG_ARCH_BOARD_FLASH_BL_PROG_SIZE, |
| .name = "bl-progmem", |
| .mnt = NULL, |
| .fs = "rawfs" |
| }, |
| #endif |
| |
| { |
| .size = CONFIG_ARCH_BOARD_FLASH_CPU1_PROG_SIZE, |
| .name = "cpu1-progmem", |
| .mnt = NULL, |
| .fs = "rawfs" |
| }, |
| |
| #if CONFIG_ARCH_BOARD_FLASH_CPU2_PROG_SIZE > 0 |
| { |
| .size = CONFIG_ARCH_BOARD_FLASH_CPU2_PROG_SIZE, |
| .name = "cpu2-progmem", |
| .mnt = NULL, |
| .fs = "rawfs" |
| }, |
| #endif |
| |
| { |
| .size = CONFIG_ARCH_BOARD_FLASH_PART1_SIZE, |
| .name = CONFIG_ARCH_BOARD_FLASH_PART1_NAME, |
| .mnt = CONFIG_ARCH_BOARD_FLASH_PART1_MNT, |
| .fs = CONFIG_ARCH_BOARD_FLASH_PART1_FS |
| }, |
| |
| #if CONFIG_ARCH_BOARD_FLASH_PART2_SIZE > 0 |
| { |
| .size = CONFIG_ARCH_BOARD_FLASH_PART2_SIZE, |
| .name = CONFIG_ARCH_BOARD_FLASH_PART2_NAME, |
| .mnt = CONFIG_ARCH_BOARD_FLASH_PART2_MNT, |
| .fs = CONFIG_ARCH_BOARD_FLASH_PART2_FS |
| }, |
| #endif /* CONFIG_ARCH_BOARD_FLASH_PART2_SIZE */ |
| |
| #if CONFIG_ARCH_BOARD_FLASH_PART3_SIZE > 0 |
| { |
| .size = CONFIG_ARCH_BOARD_FLASH_PART3_SIZE, |
| .name = CONFIG_ARCH_BOARD_FLASH_PART3_NAME, |
| .mnt = CONFIG_ARCH_BOARD_FLASH_PART3_MNT, |
| .fs = CONFIG_ARCH_BOARD_FLASH_PART3_FS |
| }, |
| #endif /* CONFIG_ARCH_BOARD_FLASH_PART3_SIZE */ |
| |
| #if CONFIG_ARCH_BOARD_FLASH_PART4_SIZE > 0 |
| { |
| .size = CONFIG_ARCH_BOARD_FLASH_PART4_SIZE, |
| .name = CONFIG_ARCH_BOARD_FLASH_PART4_NAME, |
| .mnt = CONFIG_ARCH_BOARD_FLASH_PART4_MNT, |
| .fs = CONFIG_ARCH_BOARD_FLASH_PART4_FS |
| }, |
| #endif /* CONFIG_ARCH_BOARD_FLASH_PART4_SIZE */ |
| }; |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| int stm32wl5_flash_init(void) |
| { |
| struct mtd_dev_s *mtd; |
| struct mtd_dev_s *mtd_part; |
| int offset; |
| int mtdconfig_minor; |
| int mtdblk_minor; |
| int smart_minor; |
| int nxf_minor; |
| int ret; |
| int i; |
| |
| /* Silent compiler warning in case these filesystems are not enabled */ |
| |
| UNUSED(nxf_minor); |
| UNUSED(smart_minor); |
| UNUSED(mtdconfig_minor); |
| |
| /* create an instance of the stm32 flash program memory device driver */ |
| |
| if ((mtd = progmem_initialize()) == NULL) |
| { |
| ferr("ERROR: progmem_initialize failed %d\n", errno); |
| return -1; |
| } |
| |
| /* create partitions, this does not actually write anything |
| * to flash memory, we only create partition table in ram |
| */ |
| |
| mtdconfig_minor = 0; |
| mtdblk_minor = 0; |
| smart_minor = 0; |
| nxf_minor = 0; |
| offset = 0; |
| |
| for (i = 0; i != sizeof(part_table) / sizeof(struct part_table); i++) |
| { |
| int size; |
| const char *name; |
| const char *mnt; |
| const char *fs; |
| |
| /* Silent compiler warning in case where only non mountable |
| * partitions are defined. |
| */ |
| |
| UNUSED(mnt); |
| |
| size = part_table[i].size; |
| name = part_table[i].name; |
| mnt = part_table[i].mnt; |
| fs = part_table[i].fs; |
| |
| finfo("[%s] creating partition, size: %d, fs: %s, offset: %d\n", |
| name, size, fs, offset); |
| |
| /* create mtd partition */ |
| |
| mtd_part = mtd_partition(mtd, offset, size); |
| |
| /* calculate offset for next partition */ |
| |
| offset += size; |
| |
| if (mtd_part == NULL) |
| { |
| ferr("[%s]ERROR: mtd_partition() failed %d\n", name, errno); |
| continue; |
| } |
| |
| if (mtd_setpartitionname(mtd_part, name)) |
| { |
| ferr("[%s]ERROR: mtd_setpartitionname() failed %d\n", name, errno); |
| continue; |
| } |
| |
| /* initialize filesystems */ |
| |
| if (strcmp(fs, "rawfs") == 0) |
| { |
| /* for raw fs just create mtdblock using ftl */ |
| |
| if ((ret = ftl_initialize(mtdblk_minor, mtd_part))) |
| { |
| ferr("[%s]ERROR: ftl_initialize failed %d\n", name, ret); |
| continue; |
| } |
| |
| mtdblk_minor++; |
| } |
| |
| #if defined(CONFIG_FS_NXFFS) |
| else if (strcmp(fs, "nxffs") == 0) |
| { |
| if (nxf_minor) |
| { |
| ferr("[%s]ERROR: only 1 nxffs is allowed, ignoring\n", name); |
| continue; |
| } |
| |
| /* attach mtd to nxffs */ |
| |
| if ((ret = nxffs_initialize(mtd_part))) |
| { |
| ferr("[%s]ERROR: nxffs_initialize failed %d\n", name, ret); |
| continue; |
| } |
| |
| /* mount nxffs */ |
| |
| if ((ret = nx_mount(NULL, mnt, "nxffs", 0, NULL))) |
| { |
| ferr("[%s]ERROR: nx_mount failed: %d", name, ret); |
| continue; |
| } |
| |
| nxf_minor++; |
| } |
| #endif |
| |
| #if defined(CONFIG_FS_SMARTFS) |
| else if (strcmp(fs, "smartfs") == 0) |
| { |
| /* attach mtd to smartfs */ |
| |
| char src[32]; |
| snprintf(src, sizeof(src), "/dev/smart%d", smart_minor); |
| |
| if ((ret = smart_initialize(smart_minor, mtd_part, NULL))) |
| { |
| ferr("[%s]ERROR: smart_initialize() failed %d\n", name, ret); |
| continue; |
| } |
| |
| /* mount smartfs */ |
| |
| if ((ret = nx_mount(src, mnt, "smartfs", 0, NULL))) |
| { |
| ferr("[%s]ERROR: nx_mount failed: %d\n", name, ret); |
| if (ret == ENODEV) |
| { |
| syslog(LOG_INFO, "[%s] mtd, smartfs seems unformatted. " |
| "Did you run 'mksmartfs %s'?\n", name, src); |
| } |
| |
| continue; |
| } |
| |
| smart_minor++; |
| } |
| #endif |
| |
| #if defined(CONFIG_MTD_CONFIG) |
| else if (strcmp(fs, "mtdconfig") == 0) |
| { |
| if (mtdconfig_minor) |
| { |
| ferr("[%s]ERROR: only 1 mtdconfig is allowed, ignoring\n", |
| name); |
| continue; |
| } |
| |
| /* attach mtd to mtdconfig driver */ |
| |
| if (mtdconfig_register(mtd_part) != 0) |
| { |
| ferr("[%s]ERROR: mtdconfig_register() failed %d\n", |
| name, errno); |
| continue; |
| } |
| |
| mtdconfig_minor++; |
| } |
| #endif |
| } |
| |
| return 0; |
| } |