Skip to content

drivers: flash: max32: Add read support with ECC workaround #93437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions drivers/flash/flash_max32.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024 Analog Devices, Inc.
* Copyright (c) 2023-2025 Analog Devices, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -11,7 +11,7 @@
#include <zephyr/drivers/flash.h>
#include <zephyr/init.h>

#include "flc.h"
#include "wrap_max32_flc.h"

struct max32_flash_dev_config {
uint32_t flash_base;
Expand Down Expand Up @@ -52,21 +52,35 @@ static inline void max32_sem_give(const struct device *dev)
static int api_read(const struct device *dev, off_t address, void *buffer, size_t length)
{
const struct max32_flash_dev_config *const cfg = dev->config;
int ret = 0;
unsigned int key = 0;

address += cfg->flash_base;
MXC_FLC_Read(address, buffer, length);
return 0;

key = irq_lock();

ret = Wrap_MXC_FLC_Read(address, buffer, length);

irq_unlock(key);

return ret != 0 ? -EIO : 0;
}

static int api_write(const struct device *dev, off_t address, const void *buffer, size_t length)
{
const struct max32_flash_dev_config *const cfg = dev->config;
int ret = 0;
unsigned int key = 0;

max32_sem_take(dev);

address += cfg->flash_base;
ret = MXC_FLC_Write(address, length, (uint32_t *)buffer);

key = irq_lock();

ret = Wrap_MXC_FLC_Write(address, length, (uint32_t *)buffer);

irq_unlock(key);

max32_sem_give(dev);

Expand All @@ -79,9 +93,11 @@ static int api_erase(const struct device *dev, off_t start, size_t len)
uint32_t page_size = cfg->flash_erase_blk_sz;
uint32_t addr = (start + cfg->flash_base);
int ret = 0;
unsigned int key = 0;

max32_sem_take(dev);

key = irq_lock();
while (len) {
ret = MXC_FLC_PageErase(addr);
if (ret) {
Expand All @@ -95,6 +111,7 @@ static int api_erase(const struct device *dev, off_t start, size_t len)
len = 0;
}
}
irq_unlock(key);

max32_sem_give(dev);

Expand Down
4 changes: 3 additions & 1 deletion soc/adi/max32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_include_directories(common)
zephyr_sources(soc.c)

zephyr_library_sources_ifdef(CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS mpu_regions.c)

zephyr_library_sources_ifdef(CONFIG_PM power.c)
zephyr_linker_sources_ifdef(CONFIG_SOC_FLASH_MAX32 SECTIONS flash.ld)
zephyr_linker_sources_ifdef(CONFIG_SOC_FLASH_MAX32 RAMFUNC_SECTION flash.ld)
if(CONFIG_SOC_MAX78000 OR CONFIG_SOC_MAX78002)
zephyr_linker_sources(SECTIONS max7800x.ld)
endif()
Expand Down
1 change: 1 addition & 0 deletions soc/adi/max32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ config SOC_FAMILY_MAX32_M33
select ARM
select CPU_CORTEX_M_HAS_SYSTICK
select CPU_HAS_ARM_MPU
select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS
select CPU_HAS_FPU
select CLOCK_CONTROL
select CPU_CORTEX_M33
Expand Down
7 changes: 2 additions & 5 deletions soc/adi/max32/flash.ld
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/*
* Copyright (c) 2023 Analog Devices, Inc.
* Copyright (c) 2023-2025 Analog Devices, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

SECTION_DATA_PROLOGUE(.flashprog,, SUBALIGN(4))
{
KEEP(*(.flashprog*)) /* Flash program */
}
KEEP(*(.flashprog*)) /* Flash program */
49 changes: 49 additions & 0 deletions soc/adi/max32/mpu_regions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 Analog Devices, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/devicetree.h>
#include <zephyr/storage/flash_map.h>
#include <zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h>

/*
* Define noncacheable flash region attributes using noncacheable SRAM memory
* attribute index.
*/
#define MAX32_FLASH_NON_CACHEABLE(base, size) \
{ \
.rbar = RO_Msk | NON_SHAREABLE_Msk, \
.mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, \
.r_limit = REGION_LIMIT_ADDR(base, size), \
}

#define MAX32_MPU_REGION(name, base, attr, size) MPU_REGION_ENTRY(name, (base), attr((base), size))

/*
* The MPU regions are defined in the following way:
* - Cacheable flash region
* - Non-cacheable flash region, i.e., storage area at the end of the flash
* - SRAM region
* If the storage partition is not defined, the flash region spans the whole
* flash.
*/
static const struct arm_mpu_region mpu_regions[] = {
#if FIXED_PARTITION_EXISTS(storage_partition)
#define STORAGE_ADDR (CONFIG_FLASH_BASE_ADDRESS + FIXED_PARTITION_OFFSET(storage_partition))
#define STORAGE_SIZE (FIXED_PARTITION_SIZE(storage_partition) >> 10)
MAX32_MPU_REGION("FLASH", CONFIG_FLASH_BASE_ADDRESS, REGION_FLASH_ATTR,
KB(CONFIG_FLASH_SIZE - STORAGE_SIZE)),
MAX32_MPU_REGION("STORAGE", STORAGE_ADDR, MAX32_FLASH_NON_CACHEABLE, KB(STORAGE_SIZE)),
#else
MAX32_MPU_REGION("FLASH", CONFIG_FLASH_BASE_ADDRESS, REGION_FLASH_ATTR,
KB(CONFIG_FLASH_SIZE)),
#endif
MAX32_MPU_REGION("SRAM", CONFIG_SRAM_BASE_ADDRESS, REGION_RAM_ATTR, KB(CONFIG_SRAM_SIZE)),
};

const struct arm_mpu_config mpu_config = {
.num_regions = ARRAY_SIZE(mpu_regions),
.mpu_regions = mpu_regions,
};
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ manifest:
groups:
- fs
- name: hal_adi
revision: 16829b77264678f31a2d077a870af7bdca2d39bd
revision: d2886b8b8e3f71058a221f6351a8200fba80f229
path: modules/hal/adi
groups:
- hal
Expand Down