drivers: flash: Add MAX32xxx flash driver
Support flash read, write, erase features. Signed-off-by: Mert Vatansever <mert.vatansever@analog.com> Signed-off-by: Sadik Ozer <sadik.ozer@analog.com>
This commit is contained in:
parent
afb7d961d2
commit
d1678a51de
@ -47,6 +47,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ESP32 flash_esp32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_GECKO flash_gecko.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ITE_IT8XXX2 flash_ite_it8xxx2.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_LPC soc_flash_lpc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_MAX32 flash_max32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_MCUX soc_flash_mcux.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NIOS2_QSPI soc_flash_nios2_qspi.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF soc_flash_nrf.c)
|
||||
|
||||
@ -177,6 +177,7 @@ source "drivers/flash/Kconfig.gecko"
|
||||
source "drivers/flash/Kconfig.ifx_cat1"
|
||||
source "drivers/flash/Kconfig.it8xxx2"
|
||||
source "drivers/flash/Kconfig.lpc"
|
||||
source "drivers/flash/Kconfig.max32"
|
||||
source "drivers/flash/Kconfig.mcux"
|
||||
source "drivers/flash/Kconfig.mspi"
|
||||
source "drivers/flash/Kconfig.nios2_qspi"
|
||||
|
||||
12
drivers/flash/Kconfig.max32
Normal file
12
drivers/flash/Kconfig.max32
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2023 Analog Devices, Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SOC_FLASH_MAX32
|
||||
bool "ADI MAX32 flash driver"
|
||||
default y
|
||||
depends on DT_HAS_ADI_MAX32_FLASH_CONTROLLER_ENABLED
|
||||
select FLASH_HAS_DRIVER_ENABLED
|
||||
select FLASH_HAS_EXPLICIT_ERASE
|
||||
select FLASH_HAS_PAGE_LAYOUT
|
||||
help
|
||||
Enable MAX32 internal flash driver.
|
||||
177
drivers/flash/flash_max32.c
Normal file
177
drivers/flash/flash_max32.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2024 Analog Devices, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT adi_max32_flash_controller
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/flash.h>
|
||||
#include <zephyr/init.h>
|
||||
|
||||
#include "flc.h"
|
||||
|
||||
struct max32_flash_dev_config {
|
||||
uint32_t flash_base;
|
||||
uint32_t flash_erase_blk_sz;
|
||||
struct flash_parameters parameters;
|
||||
#if CONFIG_FLASH_PAGE_LAYOUT
|
||||
struct flash_pages_layout pages_layouts;
|
||||
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
||||
};
|
||||
|
||||
struct max32_flash_dev_data {
|
||||
#ifdef CONFIG_MULTITHREADING
|
||||
struct k_sem sem;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MULTITHREADING
|
||||
static inline void max32_sem_take(const struct device *dev)
|
||||
{
|
||||
struct max32_flash_dev_data *data = dev->data;
|
||||
|
||||
k_sem_take(&data->sem, K_FOREVER);
|
||||
}
|
||||
|
||||
static inline void max32_sem_give(const struct device *dev)
|
||||
{
|
||||
struct max32_flash_dev_data *data = dev->data;
|
||||
|
||||
k_sem_give(&data->sem);
|
||||
}
|
||||
#else
|
||||
|
||||
#define max32_sem_take(dev)
|
||||
#define max32_sem_give(dev)
|
||||
|
||||
#endif /* CONFIG_MULTITHREADING */
|
||||
|
||||
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;
|
||||
|
||||
address += cfg->flash_base;
|
||||
MXC_FLC_Read(address, buffer, length);
|
||||
return 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;
|
||||
|
||||
max32_sem_take(dev);
|
||||
|
||||
address += cfg->flash_base;
|
||||
ret = MXC_FLC_Write(address, length, (uint32_t *)buffer);
|
||||
|
||||
max32_sem_give(dev);
|
||||
|
||||
return ret != 0 ? -EIO : 0;
|
||||
}
|
||||
|
||||
static int api_erase(const struct device *dev, off_t start, size_t len)
|
||||
{
|
||||
const struct max32_flash_dev_config *const cfg = dev->config;
|
||||
uint32_t page_size = cfg->flash_erase_blk_sz;
|
||||
uint32_t addr = (start + cfg->flash_base);
|
||||
int ret = 0;
|
||||
|
||||
max32_sem_take(dev);
|
||||
|
||||
while (len) {
|
||||
ret = MXC_FLC_PageErase(addr);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
addr += page_size;
|
||||
if (len > page_size) {
|
||||
len -= page_size;
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
max32_sem_give(dev);
|
||||
|
||||
return ret != 0 ? -EIO : 0;
|
||||
}
|
||||
|
||||
#if CONFIG_FLASH_PAGE_LAYOUT
|
||||
static void api_page_layout(const struct device *dev, const struct flash_pages_layout **layout,
|
||||
size_t *layout_size)
|
||||
{
|
||||
const struct max32_flash_dev_config *const cfg = dev->config;
|
||||
|
||||
*layout = &cfg->pages_layouts;
|
||||
*layout_size = 1;
|
||||
}
|
||||
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
||||
|
||||
static const struct flash_parameters *api_get_parameters(const struct device *dev)
|
||||
{
|
||||
const struct max32_flash_dev_config *const cfg = dev->config;
|
||||
|
||||
return &cfg->parameters;
|
||||
}
|
||||
|
||||
static int flash_max32_init(const struct device *dev)
|
||||
{
|
||||
int ret = MXC_FLC_Init();
|
||||
|
||||
#ifdef CONFIG_MULTITHREADING
|
||||
struct max32_flash_dev_data *data = dev->data;
|
||||
|
||||
/* Mutex for flash controller */
|
||||
k_sem_init(&data->sem, 1, 1);
|
||||
#endif
|
||||
return ret != 0 ? -EIO : 0;
|
||||
}
|
||||
|
||||
static const struct flash_driver_api flash_max32_driver_api = {
|
||||
.read = api_read,
|
||||
.write = api_write,
|
||||
.erase = api_erase,
|
||||
.get_parameters = api_get_parameters,
|
||||
#ifdef CONFIG_FLASH_PAGE_LAYOUT
|
||||
.page_layout = api_page_layout,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if CONFIG_FLASH_PAGE_LAYOUT
|
||||
#define FLASH_MAX32_CONFIG_PAGE_LAYOUT(n) \
|
||||
.pages_layouts = { \
|
||||
.pages_count = DT_INST_FOREACH_CHILD(n, GET_FLASH_SIZE) / \
|
||||
DT_INST_FOREACH_CHILD(n, GET_ERASE_BLOCK_SIZE), \
|
||||
.pages_size = DT_INST_FOREACH_CHILD(n, GET_ERASE_BLOCK_SIZE), \
|
||||
},
|
||||
#else
|
||||
#define FLASH_MAX32_CONFIG_PAGE_LAYOUT(n)
|
||||
#endif
|
||||
|
||||
#define GET_WRITE_BLOCK_SIZE(n) DT_PROP(n, write_block_size)
|
||||
#define GET_ERASE_BLOCK_SIZE(n) DT_PROP(n, erase_block_size)
|
||||
#define GET_FLASH_BASE(n) DT_REG_ADDR(n)
|
||||
#define GET_FLASH_SIZE(n) DT_REG_SIZE(n)
|
||||
|
||||
#define DEFINE_FLASH_MAX32(_num) \
|
||||
static const struct max32_flash_dev_config max32_flash_dev_cfg_##_num = { \
|
||||
.flash_base = DT_INST_FOREACH_CHILD(_num, GET_FLASH_BASE), \
|
||||
.flash_erase_blk_sz = DT_INST_FOREACH_CHILD(_num, GET_ERASE_BLOCK_SIZE), \
|
||||
.parameters = \
|
||||
{ \
|
||||
.write_block_size = \
|
||||
DT_INST_FOREACH_CHILD(_num, GET_WRITE_BLOCK_SIZE), \
|
||||
.erase_value = 0xFF, \
|
||||
}, \
|
||||
FLASH_MAX32_CONFIG_PAGE_LAYOUT(_num)}; \
|
||||
static struct max32_flash_dev_data max32_flash_dev_data_##_num; \
|
||||
DEVICE_DT_INST_DEFINE(_num, flash_max32_init, NULL, &max32_flash_dev_data_##_num, \
|
||||
&max32_flash_dev_cfg_##_num, POST_KERNEL, \
|
||||
CONFIG_FLASH_INIT_PRIORITY, &flash_max32_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(DEFINE_FLASH_MAX32)
|
||||
Loading…
Reference in New Issue
Block a user