From a09a2ea6fe1b2b2c263115e754c5553a6cff8aab Mon Sep 17 00:00:00 2001 From: Yuqiang Wang <2053731441@qq.com> Date: Mon, 24 Apr 2023 07:30:42 +0800 Subject: [PATCH] [bsp][lpc55sxx] Added drv_soft_spi functionality and fixed drv_soft_i2c pin errors (#7251) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.lpc55sxx添加软件模拟SPI驱动 2.lpc55s69 board在Kconfig中添加软件SPI配置项 3.lpc55s69添加通用GPIO引脚定义 4.lpc55s69修正Kconfig中关于软件i2c配置项 --- bsp/lpc55sxx/Libraries/drivers/SConscript | 5 +- bsp/lpc55sxx/Libraries/drivers/drv_soft_i2c.h | 15 +- bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.c | 223 +++++++++++++++ bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.h | 69 +++++ bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig | 41 ++- .../board/MCUX_Config/board/pin_mux.c | 99 +++++++ .../board/MCUX_Config/board/pin_mux.h | 43 +++ .../board/ports/easyflash/ef_fal_port.c | 189 +++++++++++++ .../board/ports/fal/fal_cfg.h | 49 ++++ .../board/ports/fal/fal_sample.c | 266 ++++++++++++++++++ .../board/ports/soft_spi_flash_init.c | 38 +++ 11 files changed, 1009 insertions(+), 28 deletions(-) create mode 100644 bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.c create mode 100644 bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.h create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/easyflash/ef_fal_port.c create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_cfg.h create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_sample.c create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/soft_spi_flash_init.c diff --git a/bsp/lpc55sxx/Libraries/drivers/SConscript b/bsp/lpc55sxx/Libraries/drivers/SConscript index b864761e98..892b3e6201 100644 --- a/bsp/lpc55sxx/Libraries/drivers/SConscript +++ b/bsp/lpc55sxx/Libraries/drivers/SConscript @@ -51,7 +51,10 @@ if GetDepend('BSP_USING_WM8904'): if GetDepend('BSP_USING_SOFT_I2C'): src += ['drv_soft_i2c.c'] - + +if GetDepend('BSP_USING_SOFT_SPI'): + src += ['drv_soft_spi.c'] + path = [cwd,cwd + '/config'] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path) diff --git a/bsp/lpc55sxx/Libraries/drivers/drv_soft_i2c.h b/bsp/lpc55sxx/Libraries/drivers/drv_soft_i2c.h index ba15c2129d..f3c6677ae0 100644 --- a/bsp/lpc55sxx/Libraries/drivers/drv_soft_i2c.h +++ b/bsp/lpc55sxx/Libraries/drivers/drv_soft_i2c.h @@ -14,6 +14,17 @@ #include #include #include +#include + +/* Notice: PIO0_15(scl) --> 22; PIO1_8(sda) --> 24 */ + +#define BSP_SOFT_I2C1_SCL_PIN GET_PINS(0,15) +#define BSP_SOFT_I2C1_SCL_PIN GET_PINS(1,8) + +/* Notice: PIO0_18(scl) --> 56; PIO1_10(sda) --> 40 */ + +#define BSP_SOFT_I2C2_SCL_PIN GET_PINS(0,18) +#define BSP_SOFT_I2C2_SDA_PIN GET_PINS(1,10) /* lpc55s69 config class */ struct lpc55s69_soft_i2c_config @@ -33,7 +44,7 @@ struct lpc55s69_i2c #define SOFT_I2C1_BUS_CONFIG \ { \ .scl = BSP_SOFT_I2C1_SCL_PIN, \ - .sda = BSP_SOFT_I2C1_SCL_PIN, \ + .sda = BSP_SOFT_I2C1_SDA_PIN, \ .bus_name = "i2c1", \ } #endif @@ -42,7 +53,7 @@ struct lpc55s69_i2c #define SOFT_I2C2_BUS_CONFIG \ { \ .scl = BSP_SOFT_I2C2_SCL_PIN, \ - .sda = BSP_SOFT_I2C2_SCL_PIN, \ + .sda = BSP_SOFT_I2C2_SDA_PIN, \ .bus_name = "i2c2", \ } #endif /*BSP_USING_I2C2*/ diff --git a/bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.c b/bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.c new file mode 100644 index 0000000000..b8058a5517 --- /dev/null +++ b/bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-14 Wangyuqiang the first version + */ +#include +#include "drv_soft_spi.h" + +#if defined(RT_USING_PIN) && defined(RT_USING_SPI_BITOPS) && defined(RT_USING_SPI) + + +#define LOG_TAG "drv.soft_spi" +#include + +static struct lpc_soft_spi_config soft_spi_config[] = +{ +#ifdef BSP_USING_SOFT_SPI1 + SOFT_SPI1_BUS_CONFIG, +#endif +#ifdef BSP_USING_SOFT_SPI2 + SOFT_SPI2_BUS_CONFIG, +#endif +}; + +/** + * Attach the spi device to soft SPI bus, this function must be used after initialization. + */ +rt_err_t rt_hw_softspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin) +{ + + rt_err_t result; + struct rt_spi_device *spi_device; + + /* attach the device to soft spi bus*/ + spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); + RT_ASSERT(spi_device != RT_NULL); + + result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL); + return result; +} + +static void lpc_spi_gpio_init(struct lpc_soft_spi *spi) +{ + struct lpc_soft_spi_config *cfg = (struct lpc_soft_spi_config *)spi->cfg; + rt_pin_mode(cfg->sck, PIN_MODE_OUTPUT); + rt_pin_mode(cfg->miso, PIN_MODE_INPUT); + rt_pin_mode(cfg->mosi, PIN_MODE_OUTPUT); + + rt_pin_write(cfg->miso, PIN_HIGH); + rt_pin_write(cfg->sck, PIN_HIGH); + rt_pin_write(cfg->mosi, PIN_HIGH); +} + +void lpc_tog_sclk(void *data) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + if(rt_pin_read(cfg->sck) == PIN_HIGH) + { + rt_pin_write(cfg->sck, PIN_LOW); + } + else + { + rt_pin_write(cfg->sck, PIN_HIGH); + } +} + +void lpc_set_sclk(void *data, rt_int32_t state) +{ + + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + if (state) + { + rt_pin_write(cfg->sck, PIN_HIGH); + } + else + { + rt_pin_write(cfg->sck, PIN_LOW); + } +} + +void lpc_set_mosi(void *data, rt_int32_t state) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + if (state) + { + rt_pin_write(cfg->mosi, PIN_HIGH); + } + else + { + rt_pin_write(cfg->mosi, PIN_LOW); + } +} + +void lpc_set_miso(void *data, rt_int32_t state) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + if (state) + { + rt_pin_write(cfg->miso, PIN_HIGH); + } + else + { + rt_pin_write(cfg->miso, PIN_LOW); + } +} + +rt_int32_t lpc_get_sclk(void *data) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + return rt_pin_read(cfg->sck); +} + +rt_int32_t lpc_get_mosi(void *data) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + return rt_pin_read(cfg->mosi); +} + +rt_int32_t lpc_get_miso(void *data) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + return rt_pin_read(cfg->miso); +} + +void lpc_dir_mosi(void *data, rt_int32_t state) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + if (state) + { + rt_pin_mode(cfg->mosi, PIN_MODE_INPUT); + } + else + { + rt_pin_mode(cfg->mosi, PIN_MODE_OUTPUT); + } +} + +void lpc_dir_miso(void *data, rt_int32_t state) +{ + struct lpc_soft_spi_config* cfg = (struct lpc_soft_spi_config*)data; + if (state) + { + rt_pin_mode(cfg->miso, PIN_MODE_INPUT); + } + else + { + rt_pin_mode(cfg->miso, PIN_MODE_OUTPUT); + } +} + +static void lpc_udelay(rt_uint32_t us) +{ + rt_uint32_t ticks; + rt_uint32_t told, tnow, tcnt = 0; + rt_uint32_t reload = SysTick->LOAD; + + ticks = us * reload / (1000000UL / RT_TICK_PER_SECOND); + told = SysTick->VAL; + while (1) + { + tnow = SysTick->VAL; + if (tnow != told) + { + if (tnow < told) + { + tcnt += told - tnow; + } + else + { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) + { + break; + } + } + } +} + +static struct rt_spi_bit_ops lpc_soft_spi_ops = + { + .data = RT_NULL, + .tog_sclk = lpc_tog_sclk, + .set_sclk = lpc_set_sclk, + .set_mosi = lpc_set_mosi, + .set_miso = lpc_set_miso, + .get_sclk = lpc_get_sclk, + .get_mosi = lpc_get_mosi, + .get_miso = lpc_get_miso, + .dir_mosi = lpc_dir_mosi, + .dir_miso = lpc_dir_miso, + .udelay = lpc_udelay, + .delay_us = 1, +}; + +static struct lpc_soft_spi spi_obj[sizeof(soft_spi_config) / sizeof(soft_spi_config[0])]; + +/* Soft SPI initialization function */ +int rt_hw_softspi_init(void) +{ + rt_size_t obj_num = sizeof(spi_obj) / sizeof(struct lpc_soft_spi); + rt_err_t result; + + for (int i = 0; i < obj_num; i++) + { + lpc_soft_spi_ops.data = (void *)&soft_spi_config[i]; + spi_obj[i].spi.ops = &lpc_soft_spi_ops; + spi_obj[i].cfg = (void *)&soft_spi_config[i]; + lpc_spi_gpio_init(&spi_obj[i]); + result = rt_spi_bit_add_bus(&spi_obj[i].spi, soft_spi_config[i].bus_name, &lpc_soft_spi_ops); + RT_ASSERT(result == RT_EOK); + } + + return RT_EOK; +} +INIT_BOARD_EXPORT(rt_hw_softspi_init); + +#endif /* defined(RT_USING_SPI) && defined(RT_USING_SPI_BITOPS) && defined(RT_USING_PIN) */ diff --git a/bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.h b/bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.h new file mode 100644 index 0000000000..8727c337fe --- /dev/null +++ b/bsp/lpc55sxx/Libraries/drivers/drv_soft_spi.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-14 Wangyuqiang the first version + */ + +#ifndef DRV_SOFT_SPI_H_ +#define DRV_SOFT_SPI_H_ + +#include +#include +#include +#include + +/* Notice: PIO1_11(sck) --> 93; PIO0_15(miso) --> 22; PIO1_8(mosi) --> 24 */ + +#define BSP_S_SPI1_SCK_PIN GET_PINS(1,11) +#define BSP_S_SPI1_MISO_PIN GET_PINS(0,15) +#define BSP_S_SPI1_MOSI_PIN GET_PINS(1,8) + +/* Notice: PIO1_9(sck) --> 10; PIO0_18(miso) --> 56; PIO1_10(mosi) --> 40 */ + +#define BSP_S_SPI2_SCK_PIN GET_PINS(1,9) +#define BSP_S_SPI2_MISO_PIN GET_PINS(0,18) +#define BSP_S_SPI2_MOSI_PIN GET_PINS(1,10) + +/* lpc soft spi config */ +struct lpc_soft_spi_config +{ + rt_uint8_t sck; + rt_uint8_t mosi; + rt_uint8_t miso; + const char *bus_name; +}; + +/* lpc soft spi dirver */ +struct lpc_soft_spi +{ + struct rt_spi_bit_obj spi; + struct lpc_soft_spi_config *cfg; +}; + +#ifdef BSP_USING_SOFT_SPI1 +#define SOFT_SPI1_BUS_CONFIG \ + { \ + .sck = BSP_S_SPI1_SCK_PIN, \ + .mosi = BSP_S_SPI1_MOSI_PIN, \ + .miso = BSP_S_SPI1_MISO_PIN, \ + .bus_name = "sspi1", \ + } +#endif /* BSP_USING_SOFT_SPI1 */ +#ifdef BSP_USING_SOFT_SPI2 +#define SOFT_SPI2_BUS_CONFIG \ + { \ + .sck = BSP_S_SPI2_SCK_PIN, \ + .mosi = BSP_S_SPI2_MOSI_PIN, \ + .miso = BSP_S_SPI2_MISO_PIN, \ + .bus_name = "sspi2", \ + } +#endif /* BSP_USING_SOFT_SPI2 */ + +rt_err_t rt_hw_softspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin); +int rt_soft_spi_init(void); + +#endif /* __DRV_SOFT_SPI__ */ diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig index 4289e5eb33..9fde813000 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig @@ -129,34 +129,9 @@ menu "On-chip Peripheral Drivers" bool "Enable I2C1 Bus (software simulation)" default n - if BSP_USING_SOFT_I2C1 - comment "Notice: PB10 --> 26; PB11 --> 27" - - config BSP_SOFT_I2C1_SCL_PIN - int "i2c1 SCL pin number" - range 0 79 - default 26 - config BSP_SOFT_I2C1_SDA_PIN - int "i2c1 SDA pin number" - range 0 79 - default 27 - endif - config BSP_USING_SOFT_I2C2 bool "Enable I2C2 Bus (software simulation)" default n - - if BSP_USING_SOFT_I2C2 - comment "Notice: PC1 --> 33; PC0 --> 32" - config BSP_SOFT_I2C2_SCL_PIN - int "i2c2 SCL pin number" - range 0 79 - default 32 - config BSP_SOFT_I2C2_SDA_PIN - int "i2c2 SDA pin number" - range 0 79 - default 33 - endif endif menuconfig BSP_USING_SPI @@ -175,6 +150,22 @@ menu "On-chip Peripheral Drivers" default y endif + menuconfig BSP_USING_SOFT_SPI + bool "Enable soft SPI BUS" + default n + select RT_USING_PIN + select RT_USING_SPI_BITOPS + select RT_USING_SPI + if BSP_USING_SOFT_SPI + menuconfig BSP_USING_SOFT_SPI1 + bool "Enable soft SPI1 BUS (software simulation)" + default n + + menuconfig BSP_USING_SOFT_SPI2 + bool "Enable soft SPI2 BUS (software simulation)" + default n + endif + menuconfig BSP_USING_ADC config BSP_USING_ADC bool "Enable ADC Channel" diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c index 2e717ceecb..0091953179 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c @@ -17,6 +17,7 @@ processor_version: 6.0.0 /* clang-format on */ #include "fsl_common.h" +#include "fsl_gpio.h" #include "fsl_iocon.h" #include "pin_mux.h" @@ -60,6 +61,13 @@ BOARD_InitPins: - {pin_num: '3', peripheral: FLEXCOMM2, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_24/FC2_RXD_SDA_MOSI_DATA/SCT0_OUT1/SD1_D1/FC3_SSEL3/PLU_OUT6} - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2} - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3} + - {pin_num: '10', peripheral: GPIO, signal: 'PIO1, 9', pin_signal: PIO1_9/FC1_SCK/CT_INP4/SCT0_OUT2/FC4_CTS_SDA_SSEL0/ADC0_12} + - {pin_num: '40', peripheral: GPIO, signal: 'PIO1, 10', pin_signal: PIO1_10/FC1_RXD_SDA_MOSI_DATA/CTIMER1_MAT0/SCT0_OUT3} + - {pin_num: '56', peripheral: GPIO, signal: 'PIO0, 18', pin_signal: PIO0_18/FC4_CTS_SDA_SSEL0/SD0_WR_PRT/CTIMER1_MAT0/SCT0_OUT1/PLU_IN3/SECURE_GPIO0_18/ACMP0_C} + - {pin_num: '93', peripheral: GPIO, signal: 'PIO1, 11', pin_signal: PIO1_11/FC1_TXD_SCL_MISO_WS/CT_INP5/USB0_VBUS} + - {pin_num: '22', peripheral: GPIO, signal: 'PIO0, 15', pin_signal: PIO0_15/FC6_CTS_SDA_SSEL0/UTICK_CAP2/CT_INP16/SCT0_OUT2/SD0_WR_PRT/SECURE_GPIO0_15/ADC0_2} + - {pin_num: '24', peripheral: GPIO, signal: 'PIO1, 8', pin_signal: PIO1_8/FC0_CTS_SDA_SSEL0/SD0_CLK/SCT0_OUT1/FC4_SSEL2/ADC0_4} + - {pin_num: '31', peripheral: GPIO, signal: 'PIO1, 5', pin_signal: PIO1_5/FC0_RXD_SDA_MOSI_DATA/SD0_D2/CTIMER2_MAT0/SCT_GPI0} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ @@ -261,6 +269,32 @@ void BOARD_InitPins(void) * : Digital mode, digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO0_9_DIGIMODE_DIGITAL)); + IOCON->PIO[0][15] = ((IOCON->PIO[0][15] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT015 (pin 22) is configured as PIO0_15. */ + | IOCON_PIO_FUNC(PIO0_15_FUNC_ALT0) + + /* Select Digital mode. + * : Enable Digital mode. + * Digital input is enabled. */ + | IOCON_PIO_DIGIMODE(PIO0_15_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][18] = ((IOCON->PIO[0][18] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT018 (pin 56) is configured as PIO0_18. */ + | IOCON_PIO_FUNC(PIO0_18_FUNC_ALT0) + + /* Select Digital mode. + * : Enable Digital mode. + * Digital input is enabled. */ + | IOCON_PIO_DIGIMODE(PIO0_18_DIGIMODE_DIGITAL)); + IOCON->PIO[1][0] = ((IOCON->PIO[1][0] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) @@ -285,6 +319,71 @@ void BOARD_InitPins(void) * : Digital mode, digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_2_DIGIMODE_DIGITAL)); + IOCON->PIO[1][5] = ((IOCON->PIO[1][5] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT15 (pin 31) is configured as PIO1_5. */ + | IOCON_PIO_FUNC(PIO1_5_FUNC_ALT0) + + /* Select Digital mode. + * : Enable Digital mode. + * Digital input is enabled. */ + | IOCON_PIO_DIGIMODE(PIO1_5_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][8] = ((IOCON->PIO[1][8] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT18 (pin 24) is configured as PIO1_8. */ + | IOCON_PIO_FUNC(PIO1_8_FUNC_ALT0) + + /* Select Digital mode. + * : Enable Digital mode. + * Digital input is enabled. */ + | IOCON_PIO_DIGIMODE(PIO1_8_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][9] = ((IOCON->PIO[1][9] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT19 (pin 10) is configured as PIO1_9. */ + | IOCON_PIO_FUNC(PIO1_9_FUNC_ALT0) + + /* Select Digital mode. + * : Enable Digital mode. + * Digital input is enabled. */ + | IOCON_PIO_DIGIMODE(PIO1_9_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][10] = ((IOCON->PIO[1][10] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT110 (pin 40) is configured as PIO1_10. */ + | IOCON_PIO_FUNC(PIO1_10_FUNC_ALT0) + + /* Select Digital mode. + * : Enable Digital mode. + * Digital input is enabled. */ + | IOCON_PIO_DIGIMODE(PIO1_10_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][11] = ((IOCON->PIO[1][11] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT111 (pin 93) is configured as PIO1_11. */ + | IOCON_PIO_FUNC(PIO1_11_FUNC_ALT0) + + /* Select Digital mode. + * : Enable Digital mode. + * Digital input is enabled. */ + | IOCON_PIO_DIGIMODE(PIO1_11_DIGIMODE_DIGITAL)); + IOCON->PIO[1][24] = ((IOCON->PIO[1][24] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h index 39846c8c10..e0b9f74379 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h @@ -61,6 +61,9 @@ void BOARD_InitBootPins(void); /*! * @brief Selects pin function.: Alternative connection 2. */ #define PIO0_17_FUNC_ALT2 0x02u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO0_18_FUNC_ALT0 0x00u /*! * @brief Analog switch input control. Usable only if DIGIMODE = 0b0: Analog switch is closed. */ #define PIO0_23_ASW_ENABLE 0x01u @@ -76,7 +79,17 @@ void BOARD_InitBootPins(void); * : Inactive. * Inactive (no pull-down/pull-up resistor enabled). */ + #define PIO0_23_MODE_INACTIVE 0x00u +/*! + * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ +#define PIO0_15_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO0_15_FUNC_ALT0 0x00u +/*! + * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ +#define PIO0_18_DIGIMODE_DIGITAL 0x01u /*! * @brief Select Digital mode.: Digital mode, digital input is enabled. */ #define PIO0_24_DIGIMODE_DIGITAL 0x01u @@ -128,6 +141,30 @@ void BOARD_InitBootPins(void); /*! * @brief Selects pin function.: Alternative connection 2. */ #define PIO1_0_FUNC_ALT2 0x02u +/*! + * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ +#define PIO1_8_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO1_8_FUNC_ALT0 0x00u +/*! + * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ +#define PIO1_9_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO1_9_FUNC_ALT0 0x00u +/*! + * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ +#define PIO1_10_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO1_10_FUNC_ALT0 0x00u +/*! + * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ +#define PIO1_11_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO1_11_FUNC_ALT0 0x00u /*! * @brief Select Digital mode.: Digital mode, digital input is enabled. */ #define PIO1_20_DIGIMODE_DIGITAL 0x01u @@ -164,6 +201,12 @@ void BOARD_InitBootPins(void); /*! * @brief Selects pin function.: Alternative connection 3. */ #define PIO1_4_FUNC_ALT3 0x03u +/*! + * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ +#define PIO1_5_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO1_5_FUNC_ALT0 0x00u /*! * @brief Select Digital mode.: Digital mode, digital input is enabled. */ #define PIO1_6_DIGIMODE_DIGITAL 0x01u diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/easyflash/ef_fal_port.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/easyflash/ef_fal_port.c new file mode 100644 index 0000000000..cff5508a7e --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/easyflash/ef_fal_port.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-21 Wangyuqiang the first version + */ + +#include +#include +#include +#include +#include +#include +#include + +/* EasyFlash partition name on FAL partition table */ +#define FAL_EF_PART_NAME "easyflash" + +/* default ENV set for user */ +static const ef_env default_env_set[] = { + {"boot_times", "0"}, +}; + +static char log_buf[RT_CONSOLEBUF_SIZE]; +static struct rt_semaphore env_cache_lock; +static const struct fal_partition *part = NULL; + +/** + * Flash port for hardware initialize. + * + * @param default_env default ENV set for user + * @param default_env_size default ENV size + * + * @return result + */ +EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) { + EfErrCode result = EF_NO_ERR; + + *default_env = default_env_set; + *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]); + + rt_sem_init(&env_cache_lock, "env lock", 1, RT_IPC_FLAG_PRIO); + + part = fal_partition_find(FAL_EF_PART_NAME); + EF_ASSERT(part); + + return result; +} + +/** + * Read data from flash. + * @note This operation's units is word. + * + * @param addr flash address + * @param buf buffer to store read data + * @param size read bytes size + * + * @return result + */ +EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size) { + EfErrCode result = EF_NO_ERR; + + fal_partition_read(part, addr, (uint8_t *)buf, size); + + return result; +} + +/** + * Erase data on flash. + * @note This operation is irreversible. + * @note This operation's units is different which on many chips. + * + * @param addr flash address + * @param size erase bytes size + * + * @return result + */ +EfErrCode ef_port_erase(uint32_t addr, size_t size) { + EfErrCode result = EF_NO_ERR; + + /* make sure the start address is a multiple of FLASH_ERASE_MIN_SIZE */ + EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0); + + if (fal_partition_erase(part, addr, size) < 0) + { + result = EF_ERASE_ERR; + } + + return result; +} +/** + * Write data to flash. + * @note This operation's units is word. + * @note This operation must after erase. @see flash_erase. + * + * @param addr flash address + * @param buf the write data buffer + * @param size write bytes size + * + * @return result + */ +EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) { + EfErrCode result = EF_NO_ERR; + + if (fal_partition_write(part, addr, (uint8_t *)buf, size) < 0) + { + result = EF_WRITE_ERR; + } + + return result; +} + +/** + * lock the ENV ram cache + */ +void ef_port_env_lock(void) { + rt_sem_take(&env_cache_lock, RT_WAITING_FOREVER); +} + +/** + * unlock the ENV ram cache + */ +void ef_port_env_unlock(void) { + rt_sem_release(&env_cache_lock); +} + +/** + * This function is print flash debug info. + * + * @param file the file which has call this function + * @param line the line number which has call this function + * @param format output format + * @param ... args + * + */ +void ef_log_debug(const char *file, const long line, const char *format, ...) { + +#ifdef PRINT_DEBUG + + va_list args; + + /* args point to the first variable parameter */ + va_start(args, format); + ef_print("[Flash] (%s:%ld) ", file, line); + /* must use vprintf to print */ + rt_vsprintf(log_buf, format, args); + ef_print("%s", log_buf); + va_end(args); + +#endif + +} + +/** + * This function is print flash routine info. + * + * @param format output format + * @param ... args + */ +void ef_log_info(const char *format, ...) { + va_list args; + + /* args point to the first variable parameter */ + va_start(args, format); + ef_print("[Flash] "); + /* must use vprintf to print */ + rt_vsprintf(log_buf, format, args); + ef_print("%s", log_buf); + va_end(args); +} +/** + * This function is print flash non-package info. + * + * @param format output format + * @param ... args + */ +void ef_print(const char *format, ...) { + va_list args; + + /* args point to the first variable parameter */ + va_start(args, format); + /* must use vprintf to print */ + rt_vsprintf(log_buf, format, args); + rt_kprintf("%s", log_buf); + va_end(args); +} diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_cfg.h b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_cfg.h new file mode 100644 index 0000000000..7f22b7f54f --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_cfg.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-21 Wangyuqiang the first version + */ +#ifndef _FAL_CFG_H_ +#define _FAL_CFG_H_ + +#include +#include + +#ifndef FAL_USING_NOR_FLASH_DEV_NAME +#define NOR_FLASH_DEV_NAME "norflash0" +#else +#define NOR_FLASH_DEV_NAME FAL_USING_NOR_FLASH_DEV_NAME +#endif + +/* Flash device Configuration */ + +extern struct fal_flash_dev nor_flash0; + +/* flash device table */ + +#define FAL_FLASH_DEV_TABLE \ +{ \ + &nor_flash0, \ +} + +/* Partition Configuration */ + +#ifdef FAL_PART_HAS_TABLE_CFG + +/* partition table */ + +#define FAL_PART_TABLE \ +{ \ + {FAL_PART_MAGIC_WROD, "easyflash", NOR_FLASH_DEV_NAME, 0, 512 * 1024, 0}, \ + {FAL_PART_MAGIC_WROD, "download", NOR_FLASH_DEV_NAME, 512 * 1024, 1024 * 1024, 0}, \ + {FAL_PART_MAGIC_WROD, "wifi_image", NOR_FLASH_DEV_NAME, (512 + 1024) * 1024, 512 * 1024, 0}, \ + {FAL_PART_MAGIC_WROD, "font", NOR_FLASH_DEV_NAME, (512 + 1024 + 512) * 1024, 7 * 1024 * 1024, 0}, \ + {FAL_PART_MAGIC_WROD, "filesystem", NOR_FLASH_DEV_NAME, (512 + 1024 + 512 + 7 * 1024) * 1024, 7 * 1024 * 1024, 0}, \ +} +#endif /* FAL_PART_HAS_TABLE_CFG */ + +#endif /* _FAL_CFG_H_ */ diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_sample.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_sample.c new file mode 100644 index 0000000000..485d20d479 --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/fal/fal_sample.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-21 Wangyuqiang the first version + */ + +#include "rtthread.h" +#include "rtdevice.h" +#include "board.h" +#include "fal.h" + +#include + +#include "easyflash.h" +#include + +#define FS_PARTITION_NAME "filesystem" + +#define BUF_SIZE 1024 + +static int fal_test(const char *partiton_name) +{ + int ret; + int i, j, len; + uint8_t buf[BUF_SIZE]; + const struct fal_flash_dev *flash_dev = RT_NULL; + const struct fal_partition *partition = RT_NULL; + + if (!partiton_name) + { + rt_kprintf("Input param partition name is null!\n"); + return -1; + } + + partition = fal_partition_find(partiton_name); + if (partition == RT_NULL) + { + rt_kprintf("Find partition (%s) failed!\n", partiton_name); + ret = -1; + return ret; + } + + flash_dev = fal_flash_device_find(partition->flash_name); + if (flash_dev == RT_NULL) + { + rt_kprintf("Find flash device (%s) failed!\n", partition->flash_name); + ret = -1; + return ret; + } + + rt_kprintf("Flash device : %s " + "Flash size : %dK \n" + "Partition : %s " + "Partition size: %dK\n", + partition->flash_name, + flash_dev->len/1024, + partition->name, + partition->len/1024); + + /* erase all partition */ + ret = fal_partition_erase_all(partition); + if (ret < 0) + { + rt_kprintf("Partition (%s) erase failed!\n", partition->name); + ret = -1; + return ret; + } + rt_kprintf("Erase (%s) partition finish!\n", partiton_name); + + /* read the specified partition and check data */ + for (i = 0; i < partition->len;) + { + rt_memset(buf, 0x00, BUF_SIZE); + + len = (partition->len - i) > BUF_SIZE ? BUF_SIZE : (partition->len - i); + + ret = fal_partition_read(partition, i, buf, len); + if (ret < 0) + { + rt_kprintf("Partition (%s) read failed!\n", partition->name); + ret = -1; + return ret; + } + + for(j = 0; j < len; j++) + { + if (buf[j] != 0xFF) + { + rt_kprintf("The erase operation did not really succeed!\n"); + ret = -1; + return ret; + } + } + i += len; + } + + /* write 0x00 to the specified partition */ + for (i = 0; i < partition->len;) + { + rt_memset(buf, 0x00, BUF_SIZE); + + len = (partition->len - i) > BUF_SIZE ? BUF_SIZE : (partition->len - i); + + ret = fal_partition_write(partition, i, buf, len); + if (ret < 0) + { + rt_kprintf("Partition (%s) write failed!\n", partition->name); + ret = -1; + return ret; + } + + i += len; + } + rt_kprintf("Write (%s) partition finish! Write size %d(%dK).\n", partiton_name, i, i/1024); + + /* read the specified partition and check data */ + for (i = 0; i < partition->len;) + { + rt_memset(buf, 0xFF, BUF_SIZE); + + len = (partition->len - i) > BUF_SIZE ? BUF_SIZE : (partition->len - i); + + ret = fal_partition_read(partition, i, buf, len); + if (ret < 0) + { + rt_kprintf("Partition (%s) read failed!\n", partition->name); + ret = -1; + return ret; + } + + for(j = 0; j < len; j++) + { + if (buf[j] != 0x00) + { + rt_kprintf("The write operation did not really succeed!\n"); + ret = -1; + return ret; + } + } + + i += len; + } + + ret = 0; + return ret; +} + +static void fal_sample(void) +{ + /* 1- init */ + fal_init(); + + if (fal_test("font") == 0) + { + rt_kprintf("Fal partition (%s) test success!\n", "font"); + } + else + { + rt_kprintf("Fal partition (%s) test failed!\n", "font"); + } + + if (fal_test("download") == 0) + { + rt_kprintf("Fal partition (%s) test success!\n", "download"); + } + else + { + rt_kprintf("Fal partition (%s) test failed!\n", "download"); + } +} +MSH_CMD_EXPORT(fal_sample, fal sample); + +static void fal_elmfat_sample(void) +{ + int fd, size; + struct statfs elm_stat; + struct fal_blk_device *blk_dev; + char str[] = "elmfat mount to W25Q flash.", buf[80]; + + /* fal init */ + fal_init(); + + /* create block device */ + blk_dev = (struct fal_blk_device *)fal_blk_device_create(FS_PARTITION_NAME); + if(blk_dev == RT_NULL) + rt_kprintf("Can't create a block device on '%s' partition.\n", FS_PARTITION_NAME); + else + rt_kprintf("Create a block device on the %s partition of flash successful.\n", FS_PARTITION_NAME); + + /* make a elmfat format filesystem */ + if(dfs_mkfs("elm", FS_PARTITION_NAME) == 0) + rt_kprintf("make elmfat filesystem success.\n"); + + /* mount elmfat file system to FS_PARTITION_NAME */ + if(dfs_mount(FS_PARTITION_NAME, "/", "elm", 0, 0) == 0) + rt_kprintf("elmfat filesystem mount success.\n"); + + /* Get elmfat file system statistics */ + if(statfs("/", &elm_stat) == 0) + rt_kprintf("elmfat filesystem block size: %d, total blocks: %d, free blocks: %d.\n", + elm_stat.f_bsize, elm_stat.f_blocks, elm_stat.f_bfree); + + if(mkdir("/user", 0x777) == 0) + rt_kprintf("make a directory: '/user'.\n"); + + rt_kprintf("Write string '%s' to /user/test.txt.\n", str); + + /* Open the file in create and read-write mode, create the file if it does not exist*/ + fd = open("/user/test.txt", O_WRONLY | O_CREAT); + if (fd >= 0) + { + if(write(fd, str, sizeof(str)) == sizeof(str)) + rt_kprintf("Write data done.\n"); + + close(fd); + } + + /* Open file in read-only mode */ + fd = open("/user/test.txt", O_RDONLY); + if (fd >= 0) + { + size = read(fd, buf, sizeof(buf)); + + close(fd); + + if(size == sizeof(str)) + rt_kprintf("Read data from file test.txt(size: %d): %s \n", size, buf); + } +} +MSH_CMD_EXPORT_ALIAS(fal_elmfat_sample, fal_elmfat,fal elmfat sample); + +static void easyflash_sample(void) +{ + /* fal init */ + fal_init(); + + /* easyflash init */ + if(easyflash_init() == EF_NO_ERR) + { + uint32_t i_boot_times = NULL; + char *c_old_boot_times, c_new_boot_times[11] = {0}; + + /* get the boot count number from Env */ + c_old_boot_times = ef_get_env("boot_times"); + /* get the boot count number failed */ + if (c_old_boot_times == RT_NULL) + c_old_boot_times[0] = '0'; + + i_boot_times = atol(c_old_boot_times); + /* boot count +1 */ + i_boot_times ++; + rt_kprintf("===============================================\n"); + rt_kprintf("The system now boot %d times\n", i_boot_times); + rt_kprintf("===============================================\n"); + /* interger to string */ + sprintf(c_new_boot_times, "%d", i_boot_times); + /* set and store the boot count number to Env */ + ef_set_env("boot_times", c_new_boot_times); + ef_save_env(); + } +} +MSH_CMD_EXPORT(easyflash_sample, easyflash sample); diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/soft_spi_flash_init.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/soft_spi_flash_init.c new file mode 100644 index 0000000000..e74f9dc3aa --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/ports/soft_spi_flash_init.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-21 Wangyuqiang the first version + */ + +#include +#include "spi_flash.h" +#include "spi_flash_sfud.h" +#include "drv_soft_spi.h" +#include "drv_pin.h" + +#define cs_pin GET_PINS(1,5) + +static int rt_soft_spi_flash_init(void) +{ + int result = -1; + + result = rt_hw_softspi_device_attach("sspi1", "sspi10", cs_pin); + rt_kprintf("value is %d\n",result); + + if(result == RT_EOK) + { + rt_kprintf("rt_hw_softspi_device_attach successful!\n"); + } + + if (RT_NULL == rt_sfud_flash_probe("W25Q128", "sspi10")) + { + return -RT_ERROR; + } + + return RT_EOK; +} +INIT_COMPONENT_EXPORT(rt_soft_spi_flash_init);