From 887ff945a901fac1fe18d6be7367b7f405a99e1a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 4 Oct 2018 14:36:34 +0000 Subject: Flash infrastructure rework based on WSPI, not complete. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12320 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/include/hal_wspi.h | 28 +- .../serial_nor/devices/micron_n25q/flash_device.c | 567 ++++++++++++++++ .../serial_nor/devices/micron_n25q/flash_device.h | 148 +++++ .../serial_nor/devices/micron_n25q/flash_device.mk | 14 + .../serial_nor/devices/micron_n25q/micron_n25q.c | 544 ---------------- .../serial_nor/devices/micron_n25q/micron_n25q.h | 149 ----- .../serial_nor/devices/micron_n25q/micron_n25q.mk | 14 - os/hal/lib/complex/serial_nor/hal_jesd216_flash.c | 402 ++++++++++++ os/hal/lib/complex/serial_nor/hal_jesd216_flash.h | 223 +++++++ os/hal/lib/complex/serial_nor/serial_nor.c | 165 ++--- os/hal/lib/complex/serial_nor/serial_nor.h | 64 +- os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk | 4 + os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c | 65 +- os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h | 106 +-- testex/STM32/STM32L4xx/QSPI-N25Q128/halconf.h | 4 +- testex/STM32/STM32L4xx/QSPI-N25Q128/mcuconf.h | 2 +- testhal/STM32/STM32L4xx/WSPI-N25Q128/.cproject | 50 ++ testhal/STM32/STM32L4xx/WSPI-N25Q128/.project | 90 +++ testhal/STM32/STM32L4xx/WSPI-N25Q128/Makefile | 215 +++++++ testhal/STM32/STM32L4xx/WSPI-N25Q128/chconf.h | 714 +++++++++++++++++++++ .../WSPI-N25Q128 (OpenOCD, Flash and Run).launch | 52 ++ testhal/STM32/STM32L4xx/WSPI-N25Q128/halconf.h | 559 ++++++++++++++++ testhal/STM32/STM32L4xx/WSPI-N25Q128/main.c | 170 +++++ testhal/STM32/STM32L4xx/WSPI-N25Q128/mcuconf.h | 333 ++++++++++ testhal/STM32/STM32L4xx/WSPI-N25Q128/readme.txt | 26 + 25 files changed, 3788 insertions(+), 920 deletions(-) create mode 100644 os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.c create mode 100644 os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.h create mode 100644 os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.mk delete mode 100644 os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.c delete mode 100644 os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.h delete mode 100644 os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.mk create mode 100644 os/hal/lib/complex/serial_nor/hal_jesd216_flash.c create mode 100644 os/hal/lib/complex/serial_nor/hal_jesd216_flash.h create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/.cproject create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/.project create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/Makefile create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/chconf.h create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/debug/WSPI-N25Q128 (OpenOCD, Flash and Run).launch create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/halconf.h create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/main.c create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/mcuconf.h create mode 100644 testhal/STM32/STM32L4xx/WSPI-N25Q128/readme.txt diff --git a/os/hal/include/hal_wspi.h b/os/hal/include/hal_wspi.h index 65f1fe9b0..69d2e2371 100644 --- a/os/hal/include/hal_wspi.h +++ b/os/hal/include/hal_wspi.h @@ -143,20 +143,20 @@ typedef struct { * ensured. * @{ */ -#define WSPI_CFG_INSTRUCTION_MODE_MASK (7LU << 0LU) -#define WSPI_CFG_INSTRUCTION_MODE_NONE (0LU << 0LU) -#define WSPI_CFG_INSTRUCTION_MODE_ONE_LINES (1LU << 0LU) -#define WSPI_CFG_INSTRUCTION_MODE_TWO_LINES (2LU << 0LU) -#define WSPI_CFG_INSTRUCTION_MODE_FOUR_LINES (3LU << 0LU) -#define WSPI_CFG_INSTRUCTION_MODE_EIGHT_LINES (4LU << 0LU) - -#define WSPI_CFG_INSTRUCTION_DDR (1LU << 3LU) - -#define WSPI_CFG_INSTRUCTION_SIZE_MASK (3LU << 4LU) -#define WSPI_CFG_INSTRUCTION_SIZE_8 (0LU << 4LU) -#define WSPI_CFG_INSTRUCTION_SIZE_16 (1LU << 4LU) -#define WSPI_CFG_INSTRUCTION_SIZE_24 (2LU << 4LU) -#define WSPI_CFG_INSTRUCTION_SIZE_32 (3LU << 4LU) +#define WSPI_CFG_CMD_MODE_MASK (7LU << 0LU) +#define WSPI_CFG_CMD_MODE_NONE (0LU << 0LU) +#define WSPI_CFG_CMD_MODE_ONE_LINE (1LU << 0LU) +#define WSPI_CFG_CMD_MODE_TWO_LINES (2LU << 0LU) +#define WSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 0LU) +#define WSPI_CFG_CMD_MODE_EIGHT_LINES (4LU << 0LU) + +#define WSPI_CFG_CMD_DDR (1LU << 3LU) + +#define WSPI_CFG_CMD_SIZE_MASK (3LU << 4LU) +#define WSPI_CFG_CMD_SIZE_8 (0LU << 4LU) +#define WSPI_CFG_CMD_SIZE_16 (1LU << 4LU) +#define WSPI_CFG_CMD_SIZE_24 (2LU << 4LU) +#define WSPI_CFG_CMD_SIZE_32 (3LU << 4LU) #define WSPI_CFG_ADDR_MODE_MASK (7LU << 8LU) #define WSPI_CFG_ADDR_MODE_NONE (0LU << 8LU) diff --git a/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.c b/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.c new file mode 100644 index 000000000..032e6d0cc --- /dev/null +++ b/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.c @@ -0,0 +1,567 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file flash_device.c + * @brief Micron N25Q serial flash driver code. + * + * @addtogroup MICRON_N25Q + * @ingroup MICRON_N25Q + * @{ + */ + +#include + +#include "hal.h" +#include "serial_nor.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define PAGE_SIZE 256U +#define PAGE_MASK (PAGE_SIZE - 1U) + +#if SNOR_USE_SUB_SECTORS == TRUE +#define SECTOR_SIZE 0x00001000U +#define CMD_SECTOR_ERASE N25Q_CMD_SUBSECTOR_ERASE +#else +#define SECTOR_SIZE 0x00010000U +#define CMD_SECTOR_ERASE N25Q_CMD_SECTOR_ERASE +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief N25Q128 descriptor. + */ +flash_descriptor_t snor_descriptor = { + .attributes = FLASH_ATTR_ERASED_IS_ONE | FLASH_ATTR_REWRITABLE | + FLASH_ATTR_SUSPEND_ERASE_CAPABLE, + .page_size = 256U, + .sectors_count = 0U, /* It is overwritten.*/ + .sectors = NULL, + .sectors_size = SECTOR_SIZE, + .address = 0U +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI +/* Initial N25Q_CMD_READ_ID command.*/ +static const wspi_command_t n25q_cmd_read_id = { + .cmd = N25Q_CMD_READ_ID, + .cfg = 0U | +#if SNOR_SWITCH_WIDTH == TRUE + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE, +#else +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE, +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES, +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES, +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES, +#endif +#endif + .addr = 0, + .alt = 0, + .dummy = 0 +}; + +/* Initial N25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER command.*/ +static const wspi_command_t n25q_cmd_write_evconf = { + .cmd = N25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER, + .cfg = 0U | +#if SNOR_SWITCH_WIDTH == TRUE + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE, +#else +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE, +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES, +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES, +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES, +#endif +#endif + .addr = 0, + .alt = 0, + .dummy = 0 +}; + +/* Initial N25Q_CMD_WRITE_ENABLE command.*/ +static const wspi_command_t n25q_cmd_write_enable = { + .cmd = N25Q_CMD_WRITE_ENABLE, + .cfg = 0U | +#if SNOR_SWITCH_WIDTH == TRUE + WSPI_CFG_CMD_MODE_ONE_LINE, +#else +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE, +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES, +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES, +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES, +#endif +#endif + .addr = 0, + .alt = 0, + .dummy = 0 +}; + +/* Bus width initialization.*/ +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L +static const uint8_t n25q_evconf_value[1] = {0xCF}; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L +static const uint8_t n25q_evconf_value[1] = {0x8F}; +#else +static const uint8_t n25q_evconf_value[1] = {0x4F}; +#endif +#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static bool n25q_find_id(const uint8_t *set, size_t size, uint8_t element) { + size_t i; + + for (i = 0; i < size; i++) { + if (set[i] == element) { + return true; + } + } + return false; +} + +static flash_error_t n25q_poll_status(SNORDriver *devp) { + uint8_t sts; + + do { +#if SNOR_NICE_WAITING == TRUE + osalThreadSleepMilliseconds(1); +#endif + /* Read status command.*/ + jesd216_cmd_receive(devp->config->busp, N25Q_CMD_READ_FLAG_STATUS_REGISTER, + 1, &sts); + } while ((sts & N25Q_FLAGS_PROGRAM_ERASE) == 0U); + + /* Checking for errors.*/ + if ((sts & N25Q_FLAGS_ALL_ERRORS) != 0U) { + /* Clearing status register.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_CLEAR_FLAG_STATUS_REGISTER); + + /* Program operation failed.*/ + return FLASH_ERROR_PROGRAM; + } + + return FLASH_NO_ERROR; +} + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) +static void n25q_reset_memory(SNORDriver *devp) { + + /* 1x N25Q_CMD_RESET_ENABLE command.*/ + static const wspi_command_t cmd_reset_enable_1 = { + .cmd = N25Q_CMD_RESET_ENABLE, + .cfg = WSPI_CFG_CMD_MODE_ONE_LINE, + .addr = 0, + .alt = 0, + .dummy = 0 + }; + + /* 1x N25Q_CMD_RESET_MEMORY command.*/ + static const wspi_command_t cmd_reset_memory_1 = { + .cmd = N25Q_CMD_RESET_MEMORY, + .cfg = WSPI_CFG_CMD_MODE_ONE_LINE, + .addr = 0, + .alt = 0, + .dummy = 0 + }; + + /* If the device is in one bit mode then the following commands are + rejected because shorter than 8 bits. If the device is in multiple + bits mode then the commands are accepted and the device is reset to + one bit mode.*/ +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + /* 4x N25Q_CMD_RESET_ENABLE command.*/ + static const wspi_command_t cmd_reset_enable_4 = { + .cmd = N25Q_CMD_RESET_ENABLE, + .cfg = WSPI_CFG_CMD_MODE_FOUR_LINES, + .addr = 0, + .alt = 0, + .dummy = 0 + }; + + /* 4x N25Q_CMD_RESET_MEMORY command.*/ + static const wspi_command_t cmd_reset_memory_4 = { + .cmd = N25Q_CMD_RESET_MEMORY, + .cfg = WSPI_CFG_CMD_MODE_FOUR_LINES, + .addr = 0, + .alt = 0, + .dummy = 0 + }; + + wspiCommand(devp->config->busp, &cmd_reset_enable_4); + wspiCommand(devp->config->busp, &cmd_reset_memory_4); +#else + /* 2x N25Q_CMD_RESET_ENABLE command.*/ + static const wspi_command_t cmd_reset_enable_2 = { + .cfg = WSPI_CFG_CMD(N25Q_CMD_RESET_ENABLE) | + WSPI_CFG_CMD_MODE_TWO_LINES, + .addr = 0, + .alt = 0, + .dummy = 0 + }; + + /* 2x N25Q_CMD_RESET_MEMORY command.*/ + static const wspi_command_t cmd_reset_memory_2 = { + .cfg = WSPI_CFG_CMD(N25Q_CMD_RESET_MEMORY) | + WSPI_CFG_CMD_MODE_TWO_LINES, + .addr = 0, + .alt = 0, + .dummy = 0 + }; + + wspiCommand(devp->config->busp, &cmd_reset_enable_2); + wspiCommand(devp->config->busp, &cmd_reset_memory_2); +#endif + + /* Now the device should be in one bit mode for sure and we perform a + device reset.*/ + wspiCommand(devp->config->busp, &cmd_reset_enable_1); + wspiCommand(devp->config->busp, &cmd_reset_memory_1); +} +#endif /* #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ + +static const uint8_t n25q_manufacturer_ids[] = N25Q_SUPPORTED_MANUFACTURE_IDS; +static const uint8_t n25q_memory_type_ids[] = N25Q_SUPPORTED_MEMORY_TYPE_IDS; + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +void snor_device_init(SNORDriver *devp) { + +#if JESD216_BUS_MODE == JESD216_BUS_MODE_SPI + /* Reading device ID.*/ + jesd216_cmd_receive(devp->config->busp, N25Q_CMD_READ_ID, + sizeof devp->device_id, devp->device_id); + +#else /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ + /* Attempting a reset of the XIP mode, it could be in an unexpected state + because a CPU reset does not reset the memory too.*/ + snor_reset_xip(devp); + + /* Attempting a eeset of the device, it could be in an unexpected state + because a CPU reset does not reset the memory too.*/ + n25q_reset_memory(devp); + + /* Reading device ID and unique ID.*/ + wspiReceive(devp->config->busp, &n25q_cmd_read_id, + sizeof devp->device_id, devp->device_id); +#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ + + /* Checking if the device is white listed.*/ + osalDbgAssert(n25q_find_id(n25q_manufacturer_ids, + sizeof n25q_manufacturer_ids, + devp->device_id[0]), + "invalid manufacturer id"); + osalDbgAssert(n25q_find_id(n25q_memory_type_ids, + sizeof n25q_memory_type_ids, + devp->device_id[1]), + "invalid memory type id"); + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && (SNOR_SWITCH_WIDTH == TRUE) + /* Setting up final bus width.*/ + wspiCommand(devp->config->busp, &n25q_cmd_write_enable); + wspiSend(devp->config->busp, &n25q_cmd_write_evconf, 1, n25q_evconf_value); + + { + uint8_t id[3]; + + /* Reading ID again for confirmation.*/ + jesd216_cmd_receive(devp->config->busp, N25Q_CMD_MULTIPLE_IO_READ_ID, + 3, id); + + /* Checking if the device is white listed.*/ + osalDbgAssert(memcmp(id, devp->device_id, 3) == 0, + "id confirmation failed"); + } +#endif + + /* Setting up the device size.*/ + snor_descriptor.sectors_count = (1U << (size_t)devp->device_id[2]) / + SECTOR_SIZE; + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) + { + static const uint8_t flash_conf[1] = { + (SNOR_READ_DUMMY_CYCLES << 4U) | 0x0FU + }; + + /* Setting up the dummy cycles to be used for fast read operations.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_WRITE_ENABLE); + jesd216_cmd_send(devp->config->busp, N25Q_CMD_WRITE_V_CONF_REGISTER, + 1, flash_conf); + } +#endif +} + +const flash_descriptor_t *snor_get_descriptor(void *instance) { + SNORDriver *devp = (SNORDriver *)instance; + + osalDbgCheck(instance != NULL); + osalDbgAssert((devp->state != FLASH_UNINIT) && (devp->state != FLASH_STOP), + "invalid state"); + + return &snor_descriptor; +} + +flash_error_t snor_device_read(SNORDriver *devp, flash_offset_t offset, + size_t n, uint8_t *rp) { + +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + /* Fast read command in WSPI mode.*/ + jesd216_cmd_addr_dummy_receive(devp->config->busp, N25Q_CMD_FAST_READ, + offset, SNOR_READ_DUMMY_CYCLES, n, rp); +#else + /* Normal read command in SPI mode.*/ + jesd216_cmd_addr_receive(devp->config->busp, N25Q_CMD_READ, + offset, n, rp); +#endif + + return FLASH_NO_ERROR; +} + +flash_error_t snor_device_program(SNORDriver *devp, flash_offset_t offset, + size_t n, const uint8_t *pp) { + + /* Data is programmed page by page.*/ + while (n > 0U) { + flash_error_t err; + + /* Data size that can be written in a single program page operation.*/ + size_t chunk = (size_t)(((offset | PAGE_MASK) + 1U) - offset); + if (chunk > n) { + chunk = n; + } + + /* Enabling write operation.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_WRITE_ENABLE); + + /* Page program command.*/ + jesd216_cmd_addr_send(devp->config->busp, N25Q_CMD_PAGE_PROGRAM, offset, + chunk, pp); + + /* Wait for status and check errors.*/ + err = n25q_poll_status(devp); + if (err != FLASH_NO_ERROR) { + + /* Bus released.*/ + jesd216_bus_release(devp->config->busp); + + return err; + } + + /* Next page.*/ + offset += chunk; + pp += chunk; + n -= chunk; + } + + return FLASH_NO_ERROR; +} + +flash_error_t snor_device_start_erase_all(SNORDriver *devp) { + + /* Enabling write operation.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_WRITE_ENABLE); + + /* Bulk erase command.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_BULK_ERASE); + + return FLASH_NO_ERROR; +} + +flash_error_t snor_device_start_erase_sector(SNORDriver *devp, + flash_sector_t sector) { + flash_offset_t offset = (flash_offset_t)(sector * SECTOR_SIZE); + + /* Enabling write operation.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_WRITE_ENABLE); + + /* Sector erase command.*/ + jesd216_cmd_addr(devp->config->busp, N25Q_CMD_SECTOR_ERASE, offset); + + return FLASH_NO_ERROR; +} + +flash_error_t snor_device_verify_erase(SNORDriver *devp, + flash_sector_t sector) { + uint8_t cmpbuf[SNOR_COMPARE_BUFFER_SIZE]; + flash_offset_t offset; + size_t n; + + /* Read command.*/ + offset = (flash_offset_t)(sector * SECTOR_SIZE); + n = SECTOR_SIZE; + while (n > 0U) { + uint8_t *p; + +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + jesd216_cmd_addr_dummy_receive(devp->config->busp, N25Q_CMD_FAST_READ, + offset, SNOR_READ_DUMMY_CYCLES, + sizeof cmpbuf, cmpbuf); +#else + /* Normal read command in SPI mode.*/ + jesd216_cmd_addr_receive(devp->config->busp, N25Q_CMD_READ, + offset, sizeof cmpbuf, cmpbuf); +#endif + + /* Checking for erased state of current buffer.*/ + for (p = cmpbuf; p < &cmpbuf[SNOR_COMPARE_BUFFER_SIZE]; p++) { + if (*p != 0xFFU) { + /* Ready state again.*/ + devp->state = FLASH_READY; + + return FLASH_ERROR_VERIFY; + } + } + + offset += sizeof cmpbuf; + n -= sizeof cmpbuf; + } + + return FLASH_NO_ERROR; +} + +flash_error_t snor_device_query_erase(SNORDriver *devp, uint32_t *msec) { + uint8_t sts; + + /* Read status command.*/ + jesd216_cmd_receive(devp->config->busp, N25Q_CMD_READ_FLAG_STATUS_REGISTER, + 1, &sts); + + /* If the P/E bit is zero (busy) or the flash in a suspended state then + report that the operation is still in progress.*/ + if (((sts & N25Q_FLAGS_PROGRAM_ERASE) == 0U) || + ((sts & N25Q_FLAGS_ERASE_SUSPEND) != 0U)) { + + /* Recommended time before polling again, this is a simplified + implementation.*/ + if (msec != NULL) { + *msec = 1U; + } + + return FLASH_BUSY_ERASING; + } + + /* Checking for errors.*/ + if ((sts & N25Q_FLAGS_ALL_ERRORS) != 0U) { + + /* Clearing status register.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_CLEAR_FLAG_STATUS_REGISTER); + + /* Erase operation failed.*/ + return FLASH_ERROR_ERASE; + } + + return FLASH_NO_ERROR; +} + +flash_error_t snor_device_read_sfdp(SNORDriver *devp, flash_offset_t offset, + size_t n, uint8_t *rp) { + + (void)devp; + (void)rp; + (void)offset; + (void)n; + + return FLASH_NO_ERROR; +} + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) +void snor_activate_xip(SNORDriver *devp) { + static const uint8_t flash_status_xip[1] = { + (SNOR_READ_DUMMY_CYCLES << 4U) | 0x07U + }; + + /* Activating XIP mode in the device.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_WRITE_ENABLE); + jesd216_cmd_send(devp->config->busp, N25Q_CMD_WRITE_V_CONF_REGISTER, + 1, flash_status_xip); +} + +void snor_reset_xip(SNORDriver *devp) { + static const uint8_t flash_conf[1] = { + (SNOR_READ_DUMMY_CYCLES << 4U) | 0x0FU + }; + wspi_command_t cmd; + uint8_t buf[1]; + + /* Resetting XIP mode by reading one byte without XIP confirmation bit.*/ + cmd.alt = 0xFF; + cmd.addr = 0; + cmd.dummy = SNOR_READ_DUMMY_CYCLES - 2; + cmd.cfg = WSPI_CFG_CMD_MODE_NONE | + WSPI_CFG_ADDR_SIZE_24 | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_ADDR_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE | +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_ADDR_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES | +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_ADDR_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES | +#else + WSPI_CFG_ADDR_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES | +#endif + WSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/ + WSPI_CFG_ALT_SIZE_8; + wspiReceive(devp->config->busp, &cmd, 1, buf); + + /* Enabling write operation.*/ + jesd216_cmd(devp->config->busp, N25Q_CMD_WRITE_ENABLE); + + /* Rewriting volatile configuration register.*/ + jesd216_cmd_send(devp->config->busp, N25Q_CMD_WRITE_V_CONF_REGISTER, + 1, flash_conf); +} +#endif /* #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ + +/** @} */ diff --git a/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.h b/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.h new file mode 100644 index 000000000..59db2c30d --- /dev/null +++ b/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.h @@ -0,0 +1,148 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file flash_device.h + * @brief Micron N25Q serial flash driver header. + * + * @addtogroup MICRON_N25Q + * @ingroup MICRON_N25Q + * @{ + */ + +#ifndef FLASH_DEVICE_H +#define FLASH_DEVICE_H + +#include "hal_jesd216_flash.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Device identification + * @{ + */ +#define N25Q_SUPPORTED_MANUFACTURE_IDS {0x20} +#define N25Q_SUPPORTED_MEMORY_TYPE_IDS {0xBA, 0xBB} +/** @} */ + +/** + * @name Command codes + * @{ + */ +#define N25Q_CMD_RESET_ENABLE 0x66 +#define N25Q_CMD_RESET_MEMORY 0x99 +#define N25Q_CMD_READ_ID 0x9F +#define N25Q_CMD_MULTIPLE_IO_READ_ID 0xAF +#define N25Q_CMD_READ_DISCOVERY_PARAMETER 0x5A +#define N25Q_CMD_READ 0x03 +#define N25Q_CMD_FAST_READ 0x0B +#define N25Q_CMD_WRITE_ENABLE 0x06 +#define N25Q_CMD_WRITE_DISABLE 0x04 +#define N25Q_CMD_READ_STATUS_REGISTER 0x05 +#define N25Q_CMD_WRITE_STATUS_REGISTER 0x01 +#define N25Q_CMD_READ_LOCK_REGISTER 0xE8 +#define N25Q_CMD_WRITE_LOCK_REGISTER 0xE5 +#define N25Q_CMD_READ_FLAG_STATUS_REGISTER 0x70 +#define N25Q_CMD_CLEAR_FLAG_STATUS_REGISTER 0x50 +#define N25Q_CMD_READ_NV_CONFIGURATION_REGISTER 0xB5 +#define N25Q_CMD_WRITE_NV_CONFIGURATION_REGISTER 0xB1 +#define N25Q_CMD_READ_V_CONF_REGISTER 0x85 +#define N25Q_CMD_WRITE_V_CONF_REGISTER 0x81 +#define N25Q_CMD_READ_ENHANCED_V_CONF_REGISTER 0x65 +#define N25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER 0x61 +#define N25Q_CMD_PAGE_PROGRAM 0x02 +#define N25Q_CMD_SUBSECTOR_ERASE 0x20 +#define N25Q_CMD_SECTOR_ERASE 0xD8 +#define N25Q_CMD_BULK_ERASE 0xC7 +#define N25Q_CMD_PROGRAM_ERASE_RESUME 0x7A +#define N25Q_CMD_PROGRAM_ERASE_SUSPEND 0x75 +#define N25Q_CMD_READ_OTP_ARRAY 0x4B +#define N25Q_CMD_PROGRAM_OTP_ARRAY 0x42 +/** @} */ + +/** + * @name Flags status register bits + * @{ + */ +#define N25Q_FLAGS_PROGRAM_ERASE 0x80U +#define N25Q_FLAGS_ERASE_SUSPEND 0x40U +#define N25Q_FLAGS_ERASE_ERROR 0x20U +#define N25Q_FLAGS_PROGRAM_ERROR 0x10U +#define N25Q_FLAGS_VPP_ERROR 0x08U +#define N25Q_FLAGS_PROGRAM_SUSPEND 0x04U +#define N25Q_FLAGS_PROTECTION_ERROR 0x02U +#define N25Q_FLAGS_RESERVED 0x01U +#define N25Q_FLAGS_ALL_ERRORS (N25Q_FLAGS_ERASE_ERROR | \ + N25Q_FLAGS_PROGRAM_ERROR | \ + N25Q_FLAGS_VPP_ERROR | \ + N25Q_FLAGS_PROTECTION_ERROR) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern flash_descriptor_t snor_descriptor; +#endif + +#ifdef __cplusplus +extern "C" { +#endif +void snor_device_init(SNORDriver *devp); +const flash_descriptor_t *snor_get_descriptor(void *instance); +flash_error_t snor_device_read(SNORDriver *devp, flash_offset_t offset, + size_t n, uint8_t *rp); +flash_error_t snor_device_program(SNORDriver *devp, flash_offset_t offset, + size_t n, const uint8_t *pp); +flash_error_t snor_device_start_erase_all(SNORDriver *devp); +flash_error_t snor_device_start_erase_sector(SNORDriver *devp, + flash_sector_t sector); +flash_error_t snor_device_verify_erase(SNORDriver *devp, + flash_sector_t sector); +flash_error_t snor_device_query_erase(SNORDriver *devp, uint32_t *msec); +flash_error_t snor_device_read_sfdp(SNORDriver *devp, flash_offset_t offset, + size_t n, uint8_t *rp); +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + void snor_activate_xip(SNORDriver *devp); + void snor_reset_xip(SNORDriver *devp); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* FLASH_DEVICE_H */ + +/** @} */ + diff --git a/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.mk b/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.mk new file mode 100644 index 000000000..802a8388d --- /dev/null +++ b/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.mk @@ -0,0 +1,14 @@ +# List of all the Micron N25Q device files. +N25QSRC := $(CHIBIOS)/os/hal/lib/peripherals/flash/hal_flash.c \ + $(CHIBIOS)/os/hal/lib/complex/serial_nor/hal_jesd216_flash.c \ + $(CHIBIOS)/os/hal/lib/complex/serial_nor/serial_nor.c \ + $(CHIBIOS)/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.c + +# Required include directories +N25QINC := $(CHIBIOS)/os/hal/lib/peripherals/flash \ + $(CHIBIOS)/os/hal/lib/complex/serial_nor \ + $(CHIBIOS)/os/hal/lib/complex/serial_nor/devices/micron_n25q + +# Shared variables +ALLCSRC += $(N25QSRC) +ALLINC += $(N25QINC) diff --git a/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.c b/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.c deleted file mode 100644 index 4240192fb..000000000 --- a/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file m25q_flash.c - * @brief Micron N25Q serial flash driver code. - * - * @addtogroup MICRON_N25Q - * @ingroup M25Q - * @{ - */ - -#include - -#include "hal.h" -#include "m25q.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define PAGE_SIZE 256U -#define PAGE_MASK (PAGE_SIZE - 1U) - -#if M25Q_USE_SUB_SECTORS == TRUE -#define SECTOR_SIZE 0x00001000U -#define CMD_SECTOR_ERASE M25Q_CMD_SUBSECTOR_ERASE -#else -#define SECTOR_SIZE 0x00010000U -#define CMD_SECTOR_ERASE M25Q_CMD_SECTOR_ERASE -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief N25Q128 descriptor. - */ -flash_descriptor_t m25q_descriptor = { - .attributes = FLASH_ATTR_ERASED_IS_ONE | FLASH_ATTR_REWRITABLE | - FLASH_ATTR_SUSPEND_ERASE_CAPABLE, - .page_size = 256U, - .sectors_count = 0U, /* It is overwritten.*/ - .sectors = NULL, - .sectors_size = SECTOR_SIZE, - .address = 0U -}; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI -/* Initial M25Q_CMD_READ_ID command.*/ -static const qspi_command_t m25q_cmd_read_id = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_READ_ID) | -#if M25Q_SWITCH_WIDTH == TRUE - QSPI_CFG_CMD_MODE_ONE_LINE | - QSPI_CFG_DATA_MODE_ONE_LINE, -#else -#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L - QSPI_CFG_CMD_MODE_ONE_LINE | - QSPI_CFG_DATA_MODE_ONE_LINE, -#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L - QSPI_CFG_CMD_MODE_TWO_LINES | - QSPI_CFG_DATA_MODE_TWO_LINES, -#else - QSPI_CFG_CMD_MODE_FOUR_LINES | - QSPI_CFG_DATA_MODE_FOUR_LINES, -#endif -#endif - .addr = 0, - .alt = 0 -}; - -/* Initial M25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER command.*/ -static const qspi_command_t m25q_cmd_write_evconf = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER) | -#if M25Q_SWITCH_WIDTH == TRUE - QSPI_CFG_CMD_MODE_ONE_LINE | - QSPI_CFG_DATA_MODE_ONE_LINE, -#else -#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L - QSPI_CFG_CMD_MODE_ONE_LINE | - QSPI_CFG_DATA_MODE_ONE_LINE, -#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L - QSPI_CFG_CMD_MODE_TWO_LINES | - QSPI_CFG_DATA_MODE_TWO_LINES, -#else - QSPI_CFG_CMD_MODE_FOUR_LINES | - QSPI_CFG_DATA_MODE_FOUR_LINES, -#endif -#endif - .addr = 0, - .alt = 0 -}; - -/* Initial M25Q_CMD_WRITE_ENABLE command.*/ -static const qspi_command_t m25q_cmd_write_enable = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_WRITE_ENABLE) | -#if M25Q_SWITCH_WIDTH == TRUE - QSPI_CFG_CMD_MODE_ONE_LINE, -#else -#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L - QSPI_CFG_CMD_MODE_ONE_LINE, -#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L - QSPI_CFG_CMD_MODE_TWO_LINES, -#else - QSPI_CFG_CMD_MODE_FOUR_LINES, -#endif -#endif - .addr = 0, - .alt = 0 -}; - -/* Bus width initialization.*/ -#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L -static const uint8_t m25q_evconf_value[1] = {0xCF}; -#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L -static const uint8_t m25q_evconf_value[1] = {0x8F}; -#else -static const uint8_t m25q_evconf_value[1] = {0x4F}; -#endif -#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -static bool m25q_find_id(const uint8_t *set, size_t size, uint8_t element) { - size_t i; - - for (i = 0; i < size; i++) { - if (set[i] == element) { - return true; - } - } - return false; -} - -static flash_error_t m25q_poll_status(M25QDriver *devp) { - uint8_t sts; - - do { -#if M25Q_NICE_WAITING == TRUE - osalThreadSleepMilliseconds(1); -#endif - /* Read status command.*/ - jesd216_cmd_receive(devp->config->busp, M25Q_CMD_READ_FLAG_STATUS_REGISTER, - 1, &sts); - } while ((sts & M25Q_FLAGS_PROGRAM_ERASE) == 0U); - - /* Checking for errors.*/ - if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) { - /* Clearing status register.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER); - - /* Program operation failed.*/ - return FLASH_ERROR_PROGRAM; - } - - return FLASH_NO_ERROR; -} - -#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) -static void m25q_reset_memory(M25QDriver *devp) { - - /* 1x M25Q_CMD_RESET_ENABLE command.*/ - static const qspi_command_t cmd_reset_enable_1 = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) | - QSPI_CFG_CMD_MODE_ONE_LINE, - .addr = 0, - .alt = 0 - }; - - /* 1x M25Q_CMD_RESET_MEMORY command.*/ - static const qspi_command_t cmd_reset_memory_1 = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) | - QSPI_CFG_CMD_MODE_ONE_LINE, - .addr = 0, - .alt = 0 - }; - - /* If the device is in one bit mode then the following commands are - rejected because shorter than 8 bits. If the device is in multiple - bits mode then the commands are accepted and the device is reset to - one bit mode.*/ -#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI4L - /* 4x M25Q_CMD_RESET_ENABLE command.*/ - static const qspi_command_t cmd_reset_enable_4 = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) | - QSPI_CFG_CMD_MODE_FOUR_LINES, - .addr = 0, - .alt = 0 - }; - - /* 4x M25Q_CMD_RESET_MEMORY command.*/ - static const qspi_command_t cmd_reset_memory_4 = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) | - QSPI_CFG_CMD_MODE_FOUR_LINES, - .addr = 0, - .alt = 0 - }; - - qspiCommand(devp->config->busp, &cmd_reset_enable_4); - qspiCommand(devp->config->busp, &cmd_reset_memory_4); -#else - /* 2x M25Q_CMD_RESET_ENABLE command.*/ - static const qspi_command_t cmd_reset_enable_2 = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) | - QSPI_CFG_CMD_MODE_TWO_LINES, - .addr = 0, - .alt = 0 - }; - - /* 2x M25Q_CMD_RESET_MEMORY command.*/ - static const qspi_command_t cmd_reset_memory_2 = { - .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) | - QSPI_CFG_CMD_MODE_TWO_LINES, - .addr = 0, - .alt = 0 - }; - - qspiCommand(devp->config->busp, &cmd_reset_enable_2); - qspiCommand(devp->config->busp, &cmd_reset_memory_2); -#endif - - /* Now the device should be in one bit mode for sure and we perform a - device reset.*/ - qspiCommand(devp->config->busp, &cmd_reset_enable_1); - qspiCommand(devp->config->busp, &cmd_reset_memory_1); -} -#endif /* #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ - -static const uint8_t m25q_manufacturer_ids[] = M25Q_SUPPORTED_MANUFACTURE_IDS; -static const uint8_t m25q_memory_type_ids[] = M25Q_SUPPORTED_MEMORY_TYPE_IDS; - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -void m25q_device_init(M25QDriver *devp) { - -#if JESD216_BUS_MODE == JESD216_BUS_MODE_SPI - /* Reading device ID.*/ - jesd216_cmd_receive(devp->config->busp, M25Q_CMD_READ_ID, - sizeof devp->device_id, devp->device_id); - -#else /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ - /* Attempting a reset of the XIP mode, it could be in an unexpected state - because a CPU reset does not reset the memory too.*/ - m25q_reset_xip(devp); - - /* Attempting a eeset of the device, it could be in an unexpected state - because a CPU reset does not reset the memory too.*/ - m25q_reset_memory(devp); - - /* Reading device ID and unique ID.*/ - qspiReceive(devp->config->busp, &m25q_cmd_read_id, - sizeof devp->device_id, devp->device_id); -#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ - - /* Checking if the device is white listed.*/ - osalDbgAssert(m25q_find_id(m25q_manufacturer_ids, - sizeof m25q_manufacturer_ids, - devp->device_id[0]), - "invalid manufacturer id"); - osalDbgAssert(m25q_find_id(m25q_memory_type_ids, - sizeof m25q_memory_type_ids, - devp->device_id[1]), - "invalid memory type id"); - -#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && (M25Q_SWITCH_WIDTH == TRUE) - /* Setting up final bus width.*/ - qspiCommand(devp->config->busp, &m25q_cmd_write_enable); - qspiSend(devp->config->busp, &m25q_cmd_write_evconf, 1, m25q_evconf_value); - - { - uint8_t id[3]; - - /* Reading ID again for confirmation.*/ - jesd216_cmd_receive(devp->config->busp, M25Q_CMD_MULTIPLE_IO_READ_ID, - 3, id); - - /* Checking if the device is white listed.*/ - osalDbgAssert(memcmp(id, devp->device_id, 3) == 0, - "id confirmation failed"); - } -#endif - - /* Setting up the device size.*/ - m25q_descriptor.sectors_count = (1U << (size_t)devp->device_id[2]) / - SECTOR_SIZE; - -#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) - { - static const uint8_t flash_conf[1] = { - (M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU - }; - - /* Setting up the dummy cycles to be used for fast read operations.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); - jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER, - 1, flash_conf); - } -#endif -} - -const flash_descriptor_t *m25q_get_descriptor(void *instance) { - M25QDriver *devp = (M25QDriver *)instance; - - osalDbgCheck(instance != NULL); - osalDbgAssert((devp->state != FLASH_UNINIT) && (devp->state != FLASH_STOP), - "invalid state"); - - return &m25q_descriptor; -} - -flash_error_t m25q_device_read(M25QDriver *devp, flash_offset_t offset, - size_t n, uint8_t *rp) { - -#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI - /* Fast read command in QSPI mode.*/ - jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ, - offset, M25Q_READ_DUMMY_CYCLES, n, rp); -#else - /* Normal read command in SPI mode.*/ - jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ, - offset, n, rp); -#endif - - return FLASH_NO_ERROR; -} - -flash_error_t m25q_device_program(M25QDriver *devp, flash_offset_t offset, - size_t n, const uint8_t *pp) { - - /* Data is programmed page by page.*/ - while (n > 0U) { - flash_error_t err; - - /* Data size that can be written in a single program page operation.*/ - size_t chunk = (size_t)(((offset | PAGE_MASK) + 1U) - offset); - if (chunk > n) { - chunk = n; - } - - /* Enabling write operation.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); - - /* Page program command.*/ - jesd216_cmd_addr_send(devp->config->busp, M25Q_CMD_PAGE_PROGRAM, offset, - chunk, pp); - - /* Wait for status and check errors.*/ - err = m25q_poll_status(devp); - if (err != FLASH_NO_ERROR) { - - /* Bus released.*/ - jesd216_bus_release(devp->config->busp); - - return err; - } - - /* Next page.*/ - offset += chunk; - pp += chunk; - n -= chunk; - } - - return FLASH_NO_ERROR; -} - -flash_error_t m25q_device_start_erase_all(M25QDriver *devp) { - - /* Enabling write operation.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); - - /* Bulk erase command.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_BULK_ERASE); - - return FLASH_NO_ERROR; -} - -flash_error_t m25q_device_start_erase_sector(M25QDriver *devp, - flash_sector_t sector) { - flash_offset_t offset = (flash_offset_t)(sector * SECTOR_SIZE); - - /* Enabling write operation.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); - - /* Sector erase command.*/ - jesd216_cmd_addr(devp->config->busp, M25Q_CMD_SECTOR_ERASE, offset); - - return FLASH_NO_ERROR; -} - -flash_error_t m25q_device_verify_erase(M25QDriver *devp, - flash_sector_t sector) { - uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE]; - flash_offset_t offset; - size_t n; - - /* Read command.*/ - offset = (flash_offset_t)(sector * SECTOR_SIZE); - n = SECTOR_SIZE; - while (n > 0U) { - uint8_t *p; - -#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI - jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ, - offset, M25Q_READ_DUMMY_CYCLES, - sizeof cmpbuf, cmpbuf); -#else - /* Normal read command in SPI mode.*/ - jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ, - offset, sizeof cmpbuf, cmpbuf); -#endif - - /* Checking for erased state of current buffer.*/ - for (p = cmpbuf; p < &cmpbuf[M25Q_COMPARE_BUFFER_SIZE]; p++) { - if (*p != 0xFFU) { - /* Ready state again.*/ - devp->state = FLASH_READY; - - return FLASH_ERROR_VERIFY; - } - } - - offset += sizeof cmpbuf; - n -= sizeof cmpbuf; - } - - return FLASH_NO_ERROR; -} - -flash_error_t m25q_device_query_erase(M25QDriver *devp, uint32_t *msec) { - uint8_t sts; - - /* Read status command.*/ - jesd216_cmd_receive(devp->config->busp, M25Q_CMD_READ_FLAG_STATUS_REGISTER, - 1, &sts); - - /* If the P/E bit is zero (busy) or the flash in a suspended state then - report that the operation is still in progress.*/ - if (((sts & M25Q_FLAGS_PROGRAM_ERASE) == 0U) || - ((sts & M25Q_FLAGS_ERASE_SUSPEND) != 0U)) { - - /* Recommended time before polling again, this is a simplified - implementation.*/ - if (msec != NULL) { - *msec = 1U; - } - - return FLASH_BUSY_ERASING; - } - - /* Checking for errors.*/ - if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) { - - /* Clearing status register.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER); - - /* Erase operation failed.*/ - return FLASH_ERROR_ERASE; - } - - return FLASH_NO_ERROR; -} - -flash_error_t m25q_device_read_sfdp(M25QDriver *devp, flash_offset_t offset, - size_t n, uint8_t *rp) { - - (void)devp; - (void)rp; - (void)offset; - (void)n; - - return FLASH_NO_ERROR; -} - -#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) -void m25q_activate_xip(M25QDriver *devp) { - static const uint8_t flash_status_xip[1] = { - (M25Q_READ_DUMMY_CYCLES << 4U) | 0x07U - }; - - /* Activating XIP mode in the device.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); - jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER, - 1, flash_status_xip); -} - -void m25q_reset_xip(M25QDriver *devp) { - static const uint8_t flash_conf[1] = { - (M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU - }; - qspi_command_t cmd; - uint8_t buf[1]; - - /* Resetting XIP mode by reading one byte without XIP confirmation bit.*/ - cmd.alt = 0xFF; - cmd.addr = 0; - cmd.cfg = QSPI_CFG_CMD_MODE_NONE | - QSPI_CFG_ADDR_SIZE_24 | -#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L - QSPI_CFG_ADDR_MODE_ONE_LINE | - QSPI_CFG_DATA_MODE_ONE_LINE | -#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L - QSPI_CFG_ADDR_MODE_TWO_LINES | - QSPI_CFG_DATA_MODE_TWO_LINES | -#else - QSPI_CFG_ADDR_MODE_FOUR_LINES | - QSPI_CFG_DATA_MODE_FOUR_LINES | -#endif - QSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/ - QSPI_CFG_ALT_SIZE_8 | - QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2); - qspiReceive(devp->config->busp, &cmd, 1, buf); - - /* Enabling write operation.*/ - jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); - - /* Rewriting volatile configuration register.*/ - jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER, - 1, flash_conf); -} -#endif /* #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ - -/** @} */ diff --git a/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.h b/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.h deleted file mode 100644 index d29f9439c..000000000 --- a/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file n25q_flash.h - * @brief Micron N25Q serial flash driver header. - * - * @addtogroup MICRON_N25Q - * @ingroup M25Q - * @{ - */ - -#ifndef MICRON_N25Q_H -#define MICRON_N25Q_H - -#include "hal_jesd216_flash.h" -#include "m25q_flash.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Device identification - * @{ - */ -#define M25Q_SUPPORTED_MANUFACTURE_IDS {0x20} -#define M25Q_SUPPORTED_MEMORY_TYPE_IDS {0xBA, 0xBB} -/** @} */ - -/** - * @name Command codes - * @{ - */ -#define M25Q_CMD_RESET_ENABLE 0x66 -#define M25Q_CMD_RESET_MEMORY 0x99 -#define M25Q_CMD_READ_ID 0x9F -#define M25Q_CMD_MULTIPLE_IO_READ_ID 0xAF -#define M25Q_CMD_READ_DISCOVERY_PARAMETER 0x5A -#define M25Q_CMD_READ 0x03 -#define M25Q_CMD_FAST_READ 0x0B -#define M25Q_CMD_WRITE_ENABLE 0x06 -#define M25Q_CMD_WRITE_DISABLE 0x04 -#define M25Q_CMD_READ_STATUS_REGISTER 0x05 -#define M25Q_CMD_WRITE_STATUS_REGISTER 0x01 -#define M25Q_CMD_READ_LOCK_REGISTER 0xE8 -#define M25Q_CMD_WRITE_LOCK_REGISTER 0xE5 -#define M25Q_CMD_READ_FLAG_STATUS_REGISTER 0x70 -#define M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER 0x50 -#define M25Q_CMD_READ_NV_CONFIGURATION_REGISTER 0xB5 -#define M25Q_CMD_WRITE_NV_CONFIGURATION_REGISTER 0xB1 -#define M25Q_CMD_READ_V_CONF_REGISTER 0x85 -#define M25Q_CMD_WRITE_V_CONF_REGISTER 0x81 -#define M25Q_CMD_READ_ENHANCED_V_CONF_REGISTER 0x65 -#define M25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER 0x61 -#define M25Q_CMD_PAGE_PROGRAM 0x02 -#define M25Q_CMD_SUBSECTOR_ERASE 0x20 -#define M25Q_CMD_SECTOR_ERASE 0xD8 -#define M25Q_CMD_BULK_ERASE 0xC7 -#define M25Q_CMD_PROGRAM_ERASE_RESUME 0x7A -#define M25Q_CMD_PROGRAM_ERASE_SUSPEND 0x75 -#define M25Q_CMD_READ_OTP_ARRAY 0x4B -#define M25Q_CMD_PROGRAM_OTP_ARRAY 0x42 -/** @} */ - -/** - * @name Flags status register bits - * @{ - */ -#define M25Q_FLAGS_PROGRAM_ERASE 0x80U -#define M25Q_FLAGS_ERASE_SUSPEND 0x40U -#define M25Q_FLAGS_ERASE_ERROR 0x20U -#define M25Q_FLAGS_PROGRAM_ERROR 0x10U -#define M25Q_FLAGS_VPP_ERROR 0x08U -#define M25Q_FLAGS_PROGRAM_SUSPEND 0x04U -#define M25Q_FLAGS_PROTECTION_ERROR 0x02U -#define M25Q_FLAGS_RESERVED 0x01U -#define M25Q_FLAGS_ALL_ERRORS (M25Q_FLAGS_ERASE_ERROR | \ - M25Q_FLAGS_PROGRAM_ERROR | \ - M25Q_FLAGS_VPP_ERROR | \ - M25Q_FLAGS_PROTECTION_ERROR) -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern flash_descriptor_t m25q_descriptor; -#endif - -#ifdef __cplusplus -extern "C" { -#endif -void m25q_device_init(M25QDriver *devp); -const flash_descriptor_t *m25q_get_descriptor(void *instance); -flash_error_t m25q_device_read(M25QDriver *devp, flash_offset_t offset, - size_t n, uint8_t *rp); -flash_error_t m25q_device_program(M25QDriver *devp, flash_offset_t offset, - size_t n, const uint8_t *pp); -flash_error_t m25q_device_start_erase_all(M25QDriver *devp); -flash_error_t m25q_device_start_erase_sector(M25QDriver *devp, - flash_sector_t sector); -flash_error_t m25q_device_verify_erase(M25QDriver *devp, - flash_sector_t sector); -flash_error_t m25q_device_query_erase(M25QDriver *devp, uint32_t *msec); -flash_error_t m25q_device_read_sfdp(M25QDriver *devp, flash_offset_t offset, - size_t n, uint8_t *rp); -#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI - void m25q_activate_xip(M25QDriver *devp); - void m25q_reset_xip(M25QDriver *devp); -#endif -#ifdef __cplusplus -} -#endif - -#endif /* MICRON_N25Q_H */ - -/** @} */ - diff --git a/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.mk b/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.mk deleted file mode 100644 index 143fec675..000000000 --- a/os/hal/lib/complex/serial_nor/devices/micron_n25q/micron_n25q.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of all the Micron N25Q device files. -M25QSRC := $(CHIBIOS)/os/hal/lib/peripherals/flash/hal_flash.c \ - $(CHIBIOS)/os/hal/lib/peripherals/flash/hal_jesd216_flash.c \ - $(CHIBIOS)/os/hal/lib/complex/m25q/serial_nor.c \ - $(CHIBIOS)/os/hal/lib/complex/m25q/devices/micron_n25q/micron_n25q.c - -# Required include directories -M25QINC := $(CHIBIOS)/os/hal/lib/peripherals/flash \ - $(CHIBIOS)/os/hal/lib/complex/m25q \ - $(CHIBIOS)/os/hal/lib/complex/m25q/devices/micron_n25q - -# Shared variables -ALLCSRC += $(M25QSRC) -ALLINC += $(M25QINC) diff --git a/os/hal/lib/complex/serial_nor/hal_jesd216_flash.c b/os/hal/lib/complex/serial_nor/hal_jesd216_flash.c new file mode 100644 index 000000000..6b81d1bec --- /dev/null +++ b/os/hal/lib/complex/serial_nor/hal_jesd216_flash.c @@ -0,0 +1,402 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file hal_jesd216_flash.c + * @brief JESD216 compliant flash driver class code. + * + * @addtogroup HAL_JESD216_FLASH + * @{ + */ + +#include "hal.h" + +#include "hal_jesd216_flash.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +void jesd216_start(BUSDriver *busp, const BUSConfig *config) { + +#if JESD216_BUS_MODE == JESD216_BUS_MODE_SPI + spiStart(busp, config); +#else + wspiStart(busp, config); +#endif +} + +void jesd216_stop(BUSDriver *busp) { + +#if JESD216_BUS_MODE == JESD216_BUS_MODE_SPI + spiStop(busp); +#else + wspiStop(busp); +#endif +} + +void jesd216_cmd(BUSDriver *busp, uint32_t cmd) { +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + wspi_command_t mode; + + mode.cmd = cmd; + mode.dummy = 0U; + mode.cfg = 0U | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES; +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES; +#endif + mode.addr = 0U; + mode.alt = 0U; + wspiCommand(busp, &mode); +#else + uint8_t buf[1]; + + spiSelect(busp); + buf[0] = cmd; + spiSend(busp, 1, buf); + spiUnselect(busp); +#endif +} + +void jesd216_cmd_receive(BUSDriver *busp, + uint32_t cmd, + size_t n, + uint8_t *p) { +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + wspi_command_t mode; + + mode.cmd = cmd; + mode.dummy = 0U; + mode.cfg = 0U | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES; +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES; +#endif + mode.addr = 0U; + mode.alt = 0U; + wspiReceive(busp, &mode, n, p); +#else + uint8_t buf[1]; + + spiSelect(busp); + buf[0] = cmd; + spiSend(busp, 1, buf); + spiReceive(busp, n, p); + spiUnselect(busp); +#endif +} + +void jesd216_cmd_send(BUSDriver *busp, + uint32_t cmd, + size_t n, + const uint8_t *p) { +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + wspi_command_t mode; + + mode.cmd = cmd; + mode.dummy = 0U; + mode.cfg = 0U | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES; +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES; +#endif + mode.addr = 0U; + mode.alt = 0U; + wspiSend(busp, &mode, n, p); +#else + uint8_t buf[1]; + + spiSelect(busp); + buf[0] = cmd; + spiSend(busp, 1, buf); + spiSend(busp, n, p); + spiUnselect(busp); +#endif +} + +void jesd216_cmd_addr(BUSDriver *busp, + uint32_t cmd, + flash_offset_t offset) { +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + wspi_command_t mode; + + mode.cmd = cmd; + mode.dummy = 0U; + mode.cfg = 0U | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_ADDR_MODE_ONE_LINE | + WSPI_CFG_ADDR_SIZE_24; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_ADDR_MODE_TWO_LINES | + WSPI_CFG_ADDR_SIZE_24; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_ADDR_MODE_FOUR_LINES | + WSPI_CFG_ADDR_SIZE_24; +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_ADDR_MODE_EIGHT_LINES | + WSPI_CFG_ADDR_SIZE_24; +#endif + mode.addr = offset; + mode.alt = 0U; + wspiCommand(busp, &mode); +#else + uint8_t buf[4]; + + spiSelect(busp); + buf[0] = cmd; + buf[1] = (uint8_t)(offset >> 16); + buf[2] = (uint8_t)(offset >> 8); + buf[3] = (uint8_t)(offset >> 0); + spiSend(busp, 4, buf); + spiUnselect(busp); +#endif +} + +void jesd216_cmd_addr_send(BUSDriver *busp, + uint32_t cmd, + flash_offset_t offset, + size_t n, + const uint8_t *p) { +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + wspi_command_t mode; + + mode.cmd = cmd; + mode.dummy = 0U; + mode.cfg = 0U | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_ADDR_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_ADDR_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_ADDR_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES; +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_ADDR_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES; +#endif + + /* Handling 32 bits addressing. + TODO: Address size should come from upper levels.*/ + if ((cmd & JESD216_CMD_EXTENDED_ADDRESSING) == 0) { + mode.cfg |= WSPI_CFG_ADDR_SIZE_24; + } + else { + mode.cfg |= WSPI_CFG_ADDR_SIZE_32; + } + + mode.addr = offset; + mode.alt = 0U; + wspiSend(busp, &mode, n, p); +#else + uint8_t buf[4]; + + spiSelect(busp); + buf[0] = cmd; + buf[1] = (uint8_t)(offset >> 16); + buf[2] = (uint8_t)(offset >> 8); + buf[3] = (uint8_t)(offset >> 0); + spiSend(busp, 4, buf); + spiSend(busp, n, p); + spiUnselect(busp); +#endif +} + +void jesd216_cmd_addr_receive(BUSDriver *busp, + uint32_t cmd, + flash_offset_t offset, + size_t n, + uint8_t *p) { +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + wspi_command_t mode; + + mode.cmd = cmd; + mode.dummy = 0U; + mode.cfg = 0U | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_ADDR_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_ADDR_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_ADDR_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES; +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_ADDR_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES; +#endif + + /* Handling 32 bits addressing. + TODO: Address size should come from upper levels.*/ + if ((cmd & JESD216_CMD_EXTENDED_ADDRESSING) == 0) { + mode .cfg |= WSPI_CFG_ADDR_SIZE_24; + } + else { + mode .cfg |= WSPI_CFG_ADDR_SIZE_32; + } + + mode.addr = offset; + mode.alt = 0U; + wspiReceive(busp, &mode, n, p); +#else + uint8_t buf[4]; + + spiSelect(busp); + buf[0] = cmd; + buf[1] = (uint8_t)(offset >> 16); + buf[2] = (uint8_t)(offset >> 8); + buf[3] = (uint8_t)(offset >> 0); + spiSend(busp, 4, buf); + spiReceive(busp, n, p); + spiUnselect(busp); +#endif +} + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) +void jesd216_cmd_addr_dummy_receive(BUSDriver *busp, + uint32_t cmd, + flash_offset_t offset, + uint32_t dummy, + size_t n, + uint8_t *p) { + wspi_command_t mode; + + mode.cmd = cmd; + mode.dummy = dummy; + mode.cfg = 0U | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_ADDR_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_ADDR_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI4L + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_ADDR_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES; +#else + WSPI_CFG_CMD_MODE_EIGHT_LINES | + WSPI_CFG_ADDR_MODE_EIGHT_LINES | + WSPI_CFG_DATA_MODE_EIGHT_LINES; +#endif + + /* Handling 32 bits addressing. + TODO: Address size should come from upper levels.*/ + if ((cmd & JESD216_CMD_EXTENDED_ADDRESSING) == 0) { + mode .cfg |= WSPI_CFG_ADDR_SIZE_24; + } + else { + mode .cfg |= WSPI_CFG_ADDR_SIZE_32; + } + + mode.addr = offset; + mode.alt = 0U; + wspiReceive(busp, &mode, n, p); +} +#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ + +#if ((JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && \ + (JESD216_SHARED_BUS == TRUE)) || defined(__DOXYGEN__) +void jesd216_bus_acquire(BUSDriver *busp, const BUSConfig *config) { + + (void)config; + + wspiAcquireBus(busp); + if (busp->config != config) { + wspiStart(busp, config); + } +} + +void jesd216_bus_release(BUSDriver *busp) { + + wspiReleaseBus(busp); +} +#elif (JESD216_BUS_MODE == JESD216_BUS_MODE_SPI) && \ + (JESD216_SHARED_BUS == TRUE) +void jesd216_bus_acquire(BUSDriver *busp, const BUSConfig *config) { + + spiAcquireBus(busp); + if (busp->config != config) { + spiStart(busp, config); + } +} + +void jesd216_bus_release(BUSDriver *busp) { + + spiReleaseBus(busp); +} +#else +#define jesd216_bus_acquire(busp) +#define jesd216_bus_release(busp) +#endif + +/** @} */ diff --git a/os/hal/lib/complex/serial_nor/hal_jesd216_flash.h b/os/hal/lib/complex/serial_nor/hal_jesd216_flash.h new file mode 100644 index 000000000..63ad44e71 --- /dev/null +++ b/os/hal/lib/complex/serial_nor/hal_jesd216_flash.h @@ -0,0 +1,223 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file hal_jesd216_flash.h + * @brief JESD216 compliant flash driver class header. + * + * @addtogroup HAL_JESD216_FLASH + * @{ + */ + +#ifndef HAL_JESD216_FLASH_H +#define HAL_JESD216_FLASH_H + +#include "hal_flash.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Common command codes + * @{ + */ +#define JESD216_CMD_READ_ID 0x9FU +#define JESD216_CMD_READ 0x03U +#define JESD216_CMD_WRITE_ENABLE 0x06U +#define JESD216_CMD_WRITE_DISABLE 0x04U +#define JESD216_CMD_READ_STATUS_REGISTER 0x05U +#define JESD216_CMD_WRITE_STATUS_REGISTER 0x01U +#define JESD216_CMD_PAGE_PROGRAM 0x02U +#define JESD216_CMD_ERASE_4K 0x20U +#define JESD216_CMD_ERASE_BULK 0xC7U +#define JESD216_CMD_PROGRAM_ERASE_RESUME 0x7AU +#define JESD216_CMD_PROGRAM_ERASE_SUSPEND 0x75U +#define JESD216_CMD_READ_OTP_ARRAY 0x4BU +#define JESD216_CMD_PROGRAM_OTP_ARRAY 0x42U +/** @} */ + +/** + * @name Command options + * @{ + */ +#define JESD216_CMD_EXTENDED_ADDRESSING 0x80000000U +/** @} */ + +/** + * @name Bus interface. + * @{ + */ +#define JESD216_BUS_MODE_SPI 0U +#define JESD216_BUS_MODE_WSPI1L 1U +#define JESD216_BUS_MODE_WSPI2L 2U +#define JESD216_BUS_MODE_WSPI4L 4U +#define JESD216_BUS_MODE_WSPI8L 8U +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Physical transport interface. + */ +#if !defined(JESD216_BUS_MODE) || defined(__DOXYGEN__) +#define JESD216_BUS_MODE JESD216_BUS_MODE_WSPI4L +#endif + +/** + * @brief Shared bus switch. + * @details If set to @p TRUE the device acquires bus ownership + * on each transaction. + * @note Requires @p SPI_USE_MUTUAL_EXCLUSION or + * @p SPI_USE_MUTUAL_EXCLUSION. + */ +#if !defined(JESD216_SHARED_BUS) || defined(__DOXYGEN__) +#define JESD216_SHARED_BUS TRUE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if (JESD216_BUS_MODE == JESD216_BUS_MODE_SPI) && (HAL_USE_SPI == FALSE) +#error "JESD216_BUS_MODE_SPI requires HAL_USE_SPI" +#endif + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && (HAL_USE_WSPI == FALSE) +#error "JESD216_BUS_MODE_WSPIxL requires HAL_USE_WSPI" +#endif + +#if (JESD216_BUS_MODE == JESD216_BUS_MODE_SPI) && \ + (JESD216_SHARED_BUS == TRUE) && \ + (SPI_USE_MUTUAL_EXCLUSION == FALSE) +#error "JESD216_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION" +#endif + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && \ + (JESD216_BUS_MODE != JESD216_BUS_MODE_WSPI1L) && \ + (JESD216_BUS_MODE != JESD216_BUS_MODE_WSPI2L) && \ + (JESD216_BUS_MODE != JESD216_BUS_MODE_WSPI4L) && \ + (JESD216_BUS_MODE != JESD216_BUS_MODE_WSPI8L) +#error "invalid JESD216_BUS_MODE selected" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) +#define BUSConfig WSPIConfig +#define BUSDriver WSPIDriver +#else +#define BUSConfig SPIConfig +#define BUSDriver SPIDriver +#endif + +#define _jesd216_config \ + BUSDriver *busp; \ + const BUSConfig *buscfg; + +/** + * @brief @p JESD215Flash specific methods. + */ +#define _jesd216_flash_methods_alone \ + /* Read SFDP.*/ \ + flash_error_t (*read_sfdp)(void *instance, \ + flash_offset_t offset, \ + size_t n, \ + uint8_t *rp); + +/** + * @brief @p JESD215Flash specific methods with inherited ones. + */ +#define _jesd216_flash_methods \ + _base_flash_methods \ + _jesd216_flash_methods_alone + +/** + * @brief @p JESD215Flash virtual methods table. + */ +struct JESD215FlashVMT { + _jesd216_flash_methods +}; + +/** + * @brief @p JESD215Flash specific data. + */ +#define _jesd216_flash_data \ + _base_flash_data + +/** + * @brief Base flash class. + */ +typedef struct { + /** @brief Virtual Methods Table.*/ + const struct JESD215FlashVMT *vmt; + _jesd216_flash_data +} JESD215Flash; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Macro Functions (BaseFlash) + * @{ + */ +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void jesd216_start(BUSDriver *busp, const BUSConfig *config); + void jesd216_stop(BUSDriver *busp); + void jesd216_cmd(BUSDriver *busp, uint32_t cmd); + void jesd216_cmd_receive(BUSDriver *busp, uint32_t cmd, + size_t n, uint8_t *p); + void jesd216_cmd_send(BUSDriver *busp, uint32_t cmd, + size_t n, const uint8_t *p); + void jesd216_cmd_addr(BUSDriver *busp, uint32_t cmd, flash_offset_t offset); + void jesd216_cmd_addr_send(BUSDriver *busp, uint32_t cmd, + flash_offset_t offset, size_t n, const uint8_t *p); + void jesd216_cmd_addr_receive(BUSDriver *busp, uint32_t cmd, + flash_offset_t offset, size_t n, uint8_t *p); +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + void jesd216_cmd_addr_dummy_receive(BUSDriver *busp, uint32_t cmd, + flash_offset_t offset, uint32_t dummy, + size_t n, uint8_t *p); +#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ +#if JESD216_SHARED_BUS == TRUE + void jesd216_bus_acquire(BUSDriver *busp, const BUSConfig *config); + void jesd216_bus_release(BUSDriver *busp); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* HAL_JESD216_FLASH_H */ + +/** @} */ diff --git a/os/hal/lib/complex/serial_nor/serial_nor.c b/os/hal/lib/complex/serial_nor/serial_nor.c index b4c0970b7..3c0b2cd28 100644 --- a/os/hal/lib/complex/serial_nor/serial_nor.c +++ b/os/hal/lib/complex/serial_nor/serial_nor.c @@ -24,7 +24,7 @@ */ #include "hal.h" -#include "m25q.h" +#include "serial_nor.h" /*===========================================================================*/ /* Driver local definitions. */ @@ -38,42 +38,42 @@ /* Driver local variables and types. */ /*===========================================================================*/ -static flash_error_t m25q_read(void *instance, flash_offset_t offset, +static flash_error_t snor_read(void *instance, flash_offset_t offset, size_t n, uint8_t *rp); -static flash_error_t m25q_program(void *instance, flash_offset_t offset, +static flash_error_t snor_program(void *instance, flash_offset_t offset, size_t n, const uint8_t *pp); -static flash_error_t m25q_start_erase_all(void *instance); -static flash_error_t m25q_start_erase_sector(void *instance, +static flash_error_t snor_start_erase_all(void *instance); +static flash_error_t snor_start_erase_sector(void *instance, flash_sector_t sector); -static flash_error_t m25q_verify_erase(void *instance, +static flash_error_t snor_verify_erase(void *instance, flash_sector_t sector); -static flash_error_t m25q_query_erase(void *instance, uint32_t *msec); -static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, +static flash_error_t snor_query_erase(void *instance, uint32_t *msec); +static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset, size_t n, uint8_t *rp); /** * @brief Virtual methods table. */ -static const struct M25QDriverVMT m25q_vmt = { +static const struct SNORDriverVMT snor_vmt = { (size_t)0, - m25q_get_descriptor, m25q_read, m25q_program, - m25q_start_erase_all, m25q_start_erase_sector, - m25q_query_erase, m25q_verify_erase, - m25q_read_sfdp + snor_get_descriptor, snor_read, snor_program, + snor_start_erase_all, snor_start_erase_sector, + snor_query_erase, snor_verify_erase, + snor_read_sfdp }; /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ -static flash_error_t m25q_read(void *instance, flash_offset_t offset, +static flash_error_t snor_read(void *instance, flash_offset_t offset, size_t n, uint8_t *rp) { - M25QDriver *devp = (M25QDriver *)instance; + SNORDriver *devp = (SNORDriver *)instance; flash_error_t err; osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); - osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count * - (size_t)m25q_descriptor.sectors_size); + osalDbgCheck((size_t)offset + n <= (size_t)snor_descriptor.sectors_count * + (size_t)snor_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -88,7 +88,7 @@ static flash_error_t m25q_read(void *instance, flash_offset_t offset, devp->state = FLASH_READ; /* Actual read implementation.*/ - err = m25q_device_read(devp, offset, n, rp); + err = snor_device_read(devp, offset, n, rp); /* Ready state again.*/ devp->state = FLASH_READY; @@ -99,14 +99,14 @@ static flash_error_t m25q_read(void *instance, flash_offset_t offset, return err; } -static flash_error_t m25q_program(void *instance, flash_offset_t offset, +static flash_error_t snor_program(void *instance, flash_offset_t offset, size_t n, const uint8_t *pp) { - M25QDriver *devp = (M25QDriver *)instance; + SNORDriver *devp = (SNORDriver *)instance; flash_error_t err; osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); - osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count * - (size_t)m25q_descriptor.sectors_size); + osalDbgCheck((size_t)offset + n <= (size_t)snor_descriptor.sectors_count * + (size_t)snor_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -121,7 +121,7 @@ static flash_error_t m25q_program(void *instance, flash_offset_t offset, devp->state = FLASH_PGM; /* Actual program implementation.*/ - err = m25q_device_program(devp, offset, n, pp); + err = snor_device_program(devp, offset, n, pp); /* Ready state again.*/ devp->state = FLASH_READY; @@ -132,8 +132,8 @@ static flash_error_t m25q_program(void *instance, flash_offset_t offset, return err; } -static flash_error_t m25q_start_erase_all(void *instance) { - M25QDriver *devp = (M25QDriver *)instance; +static flash_error_t snor_start_erase_all(void *instance) { + SNORDriver *devp = (SNORDriver *)instance; flash_error_t err; osalDbgCheck(instance != NULL); @@ -151,7 +151,7 @@ static flash_error_t m25q_start_erase_all(void *instance) { devp->state = FLASH_ERASE; /* Actual erase implementation.*/ - err = m25q_device_start_erase_all(devp); + err = snor_device_start_erase_all(devp); /* Ready state again.*/ devp->state = FLASH_READY; @@ -162,13 +162,13 @@ static flash_error_t m25q_start_erase_all(void *instance) { return err; } -static flash_error_t m25q_start_erase_sector(void *instance, +static flash_error_t snor_start_erase_sector(void *instance, flash_sector_t sector) { - M25QDriver *devp = (M25QDriver *)instance; + SNORDriver *devp = (SNORDriver *)instance; flash_error_t err; osalDbgCheck(instance != NULL); - osalDbgCheck(sector < m25q_descriptor.sectors_count); + osalDbgCheck(sector < snor_descriptor.sectors_count); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -183,7 +183,7 @@ static flash_error_t m25q_start_erase_sector(void *instance, devp->state = FLASH_ERASE; /* Actual erase implementation.*/ - err = m25q_device_start_erase_sector(devp, sector); + err = snor_device_start_erase_sector(devp, sector); /* Bus released.*/ jesd216_bus_release(devp->config->busp); @@ -191,13 +191,13 @@ static flash_error_t m25q_start_erase_sector(void *instance, return err; } -static flash_error_t m25q_verify_erase(void *instance, +static flash_error_t snor_verify_erase(void *instance, flash_sector_t sector) { - M25QDriver *devp = (M25QDriver *)instance; + SNORDriver *devp = (SNORDriver *)instance; flash_error_t err; osalDbgCheck(instance != NULL); - osalDbgCheck(sector < m25q_descriptor.sectors_count); + osalDbgCheck(sector < snor_descriptor.sectors_count); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -212,7 +212,7 @@ static flash_error_t m25q_verify_erase(void *instance, devp->state = FLASH_READ; /* Actual verify erase implementation.*/ - err = m25q_device_verify_erase(devp, sector); + err = snor_device_verify_erase(devp, sector); /* Ready state again.*/ devp->state = FLASH_READY; @@ -223,8 +223,8 @@ static flash_error_t m25q_verify_erase(void *instance, return err; } -static flash_error_t m25q_query_erase(void *instance, uint32_t *msec) { - M25QDriver *devp = (M25QDriver *)instance; +static flash_error_t snor_query_erase(void *instance, uint32_t *msec) { + SNORDriver *devp = (SNORDriver *)instance; flash_error_t err; osalDbgCheck(instance != NULL); @@ -238,7 +238,7 @@ static flash_error_t m25q_query_erase(void *instance, uint32_t *msec) { jesd216_bus_acquire(devp->config->busp, devp->config->buscfg); /* Actual query erase implementation.*/ - err = m25q_device_query_erase(devp, msec); + err = snor_device_query_erase(devp, msec); /* The device is ready to accept commands.*/ if (err == FLASH_NO_ERROR) { @@ -255,9 +255,9 @@ static flash_error_t m25q_query_erase(void *instance, uint32_t *msec) { return err; } -static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, +static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset, size_t n, uint8_t *rp) { - M25QDriver *devp = (M25QDriver *)instance; + SNORDriver *devp = (SNORDriver *)instance; flash_error_t err; osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); @@ -272,7 +272,7 @@ static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, jesd216_bus_acquire(devp->config->busp, devp->config->buscfg); /* Actual read SFDP implementation.*/ - err = m25q_device_read_sfdp(devp, offset, n, rp); + err = snor_device_read_sfdp(devp, offset, n, rp); /* The device is ready to accept commands.*/ if (err == FLASH_NO_ERROR) { @@ -292,15 +292,15 @@ static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, /** * @brief Initializes an instance. * - * @param[out] devp pointer to the @p M25QDriver object + * @param[out] devp pointer to the @p SNORDriver object * * @init */ -void m25qObjectInit(M25QDriver *devp) { +void m25qObjectInit(SNORDriver *devp) { osalDbgCheck(devp != NULL); - devp->vmt = &m25q_vmt; + devp->vmt = &snor_vmt; devp->state = FLASH_STOP; devp->config = NULL; } @@ -308,12 +308,12 @@ void m25qObjectInit(M25QDriver *devp) { /** * @brief Configures and activates N25Q128 driver. * - * @param[in] devp pointer to the @p M25QDriver object + * @param[in] devp pointer to the @p SNORDriver object * @param[in] config pointer to the configuration * * @api */ -void m25qStart(M25QDriver *devp, const M25QConfig *config) { +void m25qStart(SNORDriver *devp, const SNORConfig *config) { osalDbgCheck((devp != NULL) && (config != NULL)); osalDbgAssert(devp->state != FLASH_UNINIT, "invalid state"); @@ -326,7 +326,7 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) { jesd216_bus_acquire(devp->config->busp, devp->config->buscfg); /* Device identification and initialization.*/ - m25q_device_init(devp); + snor_device_init(devp); /* Driver in ready state.*/ devp->state = FLASH_READY; @@ -339,11 +339,11 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) { /** * @brief Deactivates the N25Q128 driver. * - * @param[in] devp pointer to the @p M25QDriver object + * @param[in] devp pointer to the @p SNORDriver object * * @api */ -void m25qStop(M25QDriver *devp) { +void m25qStop(SNORDriver *devp) { osalDbgCheck(devp != NULL); osalDbgAssert(devp->state != FLASH_UNINIT, "invalid state"); @@ -368,51 +368,52 @@ void m25qStop(M25QDriver *devp) { } #if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) -#if (QSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__) +#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__) /** * @brief Enters the memory Mapping mode. - * @details The memory mapping mode is only available when the QSPI mode - * is selected and the underlying QSPI controller supports the + * @details The memory mapping mode is only available when the WSPI mode + * is selected and the underlying WSPI controller supports the * feature. * - * @param[in] devp pointer to the @p M25QDriver object + * @param[in] devp pointer to the @p SNORDriver object * @param[out] addrp pointer to the memory start address of the mapped * flash or @p NULL * * @api */ -void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) { - qspi_command_t cmd; +void m25qMemoryMap(SNORDriver *devp, uint8_t **addrp) { + wspi_command_t cmd; /* Bus acquisition.*/ jesd216_bus_acquire(devp->config->busp, devp->config->buscfg); /* Activating XIP mode in the device.*/ - m25q_activate_xip(devp); - - /* Putting the QSPI driver in memory mapped mode.*/ - cmd.cfg = QSPI_CFG_CMD(M25Q_CMD_FAST_READ) | - QSPI_CFG_ADDR_SIZE_24 | -#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L - QSPI_CFG_CMD_MODE_ONE_LINE | - QSPI_CFG_ADDR_MODE_ONE_LINE | - QSPI_CFG_DATA_MODE_ONE_LINE | -#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L - QSPI_CFG_CMD_MODE_TWO_LINES | - QSPI_CFG_ADDR_MODE_TWO_LINES | - QSPI_CFG_DATA_MODE_TWO_LINES | + snor_activate_xip(devp); + + /* Putting the WSPI driver in memory mapped mode. + TODO: Put this in the device code.*/ + cmd.cmd = N25Q_CMD_FAST_READ; + cmd.dummy = SNOR_READ_DUMMY_CYCLES - 2; + cmd.cfg = WSPI_CFG_ADDR_SIZE_24 | +#if JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI1L + WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_ADDR_MODE_ONE_LINE | + WSPI_CFG_DATA_MODE_ONE_LINE | +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_WSPI2L + WSPI_CFG_CMD_MODE_TWO_LINES | + WSPI_CFG_ADDR_MODE_TWO_LINES | + WSPI_CFG_DATA_MODE_TWO_LINES | #else - QSPI_CFG_CMD_MODE_FOUR_LINES | - QSPI_CFG_ADDR_MODE_FOUR_LINES | - QSPI_CFG_DATA_MODE_FOUR_LINES | + WSPI_CFG_CMD_MODE_FOUR_LINES | + WSPI_CFG_ADDR_MODE_FOUR_LINES | + WSPI_CFG_DATA_MODE_FOUR_LINES | #endif - QSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/ - QSPI_CFG_ALT_SIZE_8 | - QSPI_CFG_SIOO | - QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2); + WSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/ + WSPI_CFG_ALT_SIZE_8 | + WSPI_CFG_SIOO; - /* Starting QSPI memory mapped mode.*/ - qspiMapFlash(devp->config->busp, &cmd, addrp); + /* Starting WSPI memory mapped mode.*/ + wspiMapFlash(devp->config->busp, &cmd, addrp); /* Bus release.*/ jesd216_bus_release(devp->config->busp); @@ -421,24 +422,24 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) { /** * @brief Leaves the memory Mapping mode. * - * @param[in] devp pointer to the @p M25QDriver object + * @param[in] devp pointer to the @p SNORDriver object * * @api */ -void m25qMemoryUnmap(M25QDriver *devp) { +void m25qMemoryUnmap(SNORDriver *devp) { /* Bus acquisition.*/ jesd216_bus_acquire(devp->config->busp, devp->config->buscfg); - /* Stopping QSPI memory mapped mode.*/ - qspiUnmapFlash(devp->config->busp); + /* Stopping WSPI memory mapped mode.*/ + wspiUnmapFlash(devp->config->busp); - m25q_reset_xip(devp); + snor_reset_xip(devp); /* Bus release.*/ jesd216_bus_release(devp->config->busp); } -#endif /* QSPI_SUPPORTS_MEMMAP == TRUE */ +#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */ #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ /** @} */ diff --git a/os/hal/lib/complex/serial_nor/serial_nor.h b/os/hal/lib/complex/serial_nor/serial_nor.h index d33dd9f48..9882c9d54 100644 --- a/os/hal/lib/complex/serial_nor/serial_nor.h +++ b/os/hal/lib/complex/serial_nor/serial_nor.h @@ -45,8 +45,8 @@ * @details This is the number of dummy cycles to be used for fast read * operations. */ -#if !defined(M25Q_READ_DUMMY_CYCLES) || defined(__DOXYGEN__) -#define M25Q_READ_DUMMY_CYCLES 8 +#if !defined(SNOR_READ_DUMMY_CYCLES) || defined(__DOXYGEN__) +#define SNOR_READ_DUMMY_CYCLES 8 #endif /** @@ -57,8 +57,8 @@ * Register then this option is not required. * @note This option is only valid in QSPI bus modes. */ -#if !defined(M25Q_SWITCH_WIDTH) || defined(__DOXYGEN__) -#define M25Q_SWITCH_WIDTH TRUE +#if !defined(SNOR_SWITCH_WIDTH) || defined(__DOXYGEN__) +#define SNOR_SWITCH_WIDTH TRUE #endif /** @@ -67,15 +67,15 @@ * routines releasing some extra CPU time for threads with lower * priority, this may slow down the driver a bit however. */ -#if !defined(M25Q_NICE_WAITING) || defined(__DOXYGEN__) -#define M25Q_NICE_WAITING TRUE +#if !defined(SNOR_NICE_WAITING) || defined(__DOXYGEN__) +#define SNOR_NICE_WAITING TRUE #endif /** * @brief Uses 4kB sub-sectors rather than 64kB sectors. */ -#if !defined(M25Q_USE_SUB_SECTORS) || defined(__DOXYGEN__) -#define M25Q_USE_SUB_SECTORS FALSE +#if !defined(SNOR_USE_SUB_SECTORS) || defined(__DOXYGEN__) +#define SNOR_USE_SUB_SECTORS FALSE #endif /** @@ -85,8 +85,8 @@ * Larger buffers lead to better verify performance but increase * stack usage for that function. */ -#if !defined(M25Q_COMPARE_BUFFER_SIZE) || defined(__DOXYGEN__) -#define M25Q_COMPARE_BUFFER_SIZE 32 +#if !defined(SNOR_COMPARE_BUFFER_SIZE) || defined(__DOXYGEN__) +#define SNOR_COMPARE_BUFFER_SIZE 32 #endif /** @} */ @@ -94,12 +94,12 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -#if (M25Q_READ_DUMMY_CYCLES < 1) || (M25Q_READ_DUMMY_CYCLES > 15) -#error "invalid M25Q_READ_DUMMY_CYCLES value (1..15)" +#if (SNOR_READ_DUMMY_CYCLES < 1) || (SNOR_READ_DUMMY_CYCLES > 15) +#error "invalid SNOR_READ_DUMMY_CYCLES value (1..15)" #endif -#if (M25Q_COMPARE_BUFFER_SIZE & (M25Q_COMPARE_BUFFER_SIZE - 1)) != 0 -#error "invalid M25Q_COMPARE_BUFFER_SIZE value" +#if (SNOR_COMPARE_BUFFER_SIZE & (SNOR_COMPARE_BUFFER_SIZE - 1)) != 0 +#error "invalid SNOR_COMPARE_BUFFER_SIZE value" #endif /*===========================================================================*/ @@ -111,43 +111,43 @@ */ typedef struct { _jesd216_config -} M25QConfig; +} SNORConfig; /** - * @brief @p M25Q specific methods. + * @brief @p SNOR specific methods. */ -#define _m25q_methods \ +#define _snor_methods \ _jesd216_flash_methods /** * @extends JESD216FlashVMT * - * @brief @p M25Q virtual methods table. + * @brief @p SNOR virtual methods table. */ -struct M25QDriverVMT { - _m25q_methods +struct SNORDriverVMT { + _snor_methods }; /** * @extends JESD216Flash * - * @brief Type of M25Q flash class. + * @brief Type of SNOR flash class. */ typedef struct { /** - * @brief M25QDriver Virtual Methods Table. + * @brief SNORDriver Virtual Methods Table. */ - const struct M25QDriverVMT *vmt; + const struct SNORDriverVMT *vmt; _jesd216_flash_data /** * @brief Current configuration data. */ - const M25QConfig *config; + const SNORConfig *config; /** * @brief Device ID and unique ID. */ uint8_t device_id[20]; -} M25QDriver; +} SNORDriver; /*===========================================================================*/ /* Driver macros. */ @@ -160,13 +160,13 @@ typedef struct { #ifdef __cplusplus extern "C" { #endif - void m25qObjectInit(M25QDriver *devp); - void m25qStart(M25QDriver *devp, const M25QConfig *config); - void m25qStop(M25QDriver *devp); + void m25qObjectInit(SNORDriver *devp); + void m25qStart(SNORDriver *devp, const SNORConfig *config); + void m25qStop(SNORDriver *devp); #if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) -#if (QSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__) - void m25qMemoryMap(M25QDriver *devp, uint8_t ** addrp); - void m25qMemoryUnmap(M25QDriver *devp); +#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__) + void m25qMemoryMap(SNORDriver *devp, uint8_t ** addrp); + void m25qMemoryUnmap(SNORDriver *devp); #endif /* QSPI_SUPPORTS_MEMMAP == TRUE */ #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ #ifdef __cplusplus @@ -174,7 +174,7 @@ extern "C" { #endif /* Device-specific implementations.*/ -#include "m25q_flash.h" +#include "flash_device.h" #endif /* M25Q_H */ diff --git a/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk b/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk index a4e4b610a..6d58d6bae 100644 --- a/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk +++ b/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk @@ -2,8 +2,12 @@ ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_QSPI TRUE,$(HALCONF)),) PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_qspi_lld.c endif +ifneq ($(findstring HAL_USE_WSPI TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c +endif else PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_qspi_lld.c +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c endif PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1 diff --git a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c index f83a6acf6..3d6561ff6 100644 --- a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c +++ b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c @@ -129,7 +129,7 @@ void wspi_lld_init(void) { #if STM32_WSPI_USE_QUADSPI1 wspiObjectInit(&WSPID1); - WSPID1.wspi = QUADSPI; + WSPID1.qspi = QUADSPI; WSPID1.dma = STM32_DMA_STREAM(STM32_WSPI_QUADSPI1_DMA_STREAM); WSPID1.dmamode = STM32_DMA_CR_CHSEL(QUADSPI1_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_WSPI_QUADSPI1_DMA_PRIORITY) | @@ -165,14 +165,14 @@ void wspi_lld_start(WSPIDriver *wspip) { #endif /* Common initializations.*/ - dmaStreamSetPeripheral(wspip->dma, &wspip->wspi->DR); + dmaStreamSetPeripheral(wspip->dma, &wspip->qspi->DR); } /* WSPI setup and enable.*/ - wspip->wspi->DCR = wspip->config->dcr; - wspip->wspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) | + wspip->qspi->DCR = wspip->config->dcr; + wspip->qspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) | QUADSPI_CR_TCIE | QUADSPI_CR_DMAEN | QUADSPI_CR_EN; - wspip->wspi->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF | + wspip->qspi->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF | QUADSPI_FCR_CSMF | QUADSPI_FCR_CTOF; } @@ -189,7 +189,7 @@ void wspi_lld_stop(WSPIDriver *wspip) { if (wspip->state == WSPI_READY) { /* WSPI disable.*/ - wspip->wspi->CR = 0U; + wspip->qspi->CR = 0U; /* Releasing the DMA.*/ dmaStreamRelease(wspip->dma); @@ -218,23 +218,19 @@ void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp) { /* If it is a command without address and alternate phases then the command is sent as an alternate byte, the command phase is suppressed.*/ if ((cmdp->cfg & (WSPI_CFG_ADDR_MODE_MASK | WSPI_CFG_ALT_MODE_MASK)) == 0U) { - uint32_t cfg; - /* The command mode field is copied in the alternate mode field. All other fields are not used in this scenario.*/ - cfg = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U; - - wspip->wspi->DLR = 0U; - wspip->wspi->ABR = cmdp->cfg & WSPI_CFG_CMD_MASK; - wspip->wspi->CCR = cfg; + wspip->qspi->DLR = 0U; + wspip->qspi->ABR = cmdp->cmd; + wspip->qspi->CCR = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U; return; } #endif - wspip->wspi->DLR = 0U; - wspip->wspi->ABR = cmdp->alt; - wspip->wspi->CCR = cmdp->cfg; + wspip->qspi->DLR = 0U; + wspip->qspi->ABR = cmdp->alt; + wspip->qspi->CCR = cmdp->cmd | cmdp->cfg; if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) { - wspip->wspi->AR = cmdp->addr; + wspip->qspi->AR = cmdp->addr; } } @@ -256,11 +252,11 @@ void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp, dmaStreamSetTransactionSize(wspip->dma, n); dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_M2P); - wspip->wspi->DLR = n - 1; - wspip->wspi->ABR = cmdp->alt; - wspip->wspi->CCR = cmdp->cfg; + wspip->qspi->DLR = n - 1; + wspip->qspi->ABR = cmdp->alt; + wspip->qspi->CCR = cmdp->cmd | cmdp->cfg; if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) { - wspip->wspi->AR = cmdp->addr; + wspip->qspi->AR = cmdp->addr; } dmaStreamEnable(wspip->dma); @@ -284,11 +280,13 @@ void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp, dmaStreamSetTransactionSize(wspip->dma, n); dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_P2M); - wspip->wspi->DLR = n - 1; - wspip->wspi->ABR = cmdp->alt; - wspip->wspi->CCR = cmdp->cfg | QUADSPI_CCR_FMODE_0; + wspip->qspi->DLR = n - 1; + wspip->qspi->ABR = cmdp->alt; + wspip->qspi->CCR = cmdp->cmd | cmdp->cfg | + QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) | + QUADSPI_CCR_FMODE_0; if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) { - wspip->wspi->AR = cmdp->addr; + wspip->qspi->AR = cmdp->addr; } dmaStreamEnable(wspip->dma); @@ -312,13 +310,14 @@ void wspi_lld_map_flash(WSPIDriver *wspip, uint8_t **addrp) { /* Disabling the DMA request while in memory mapped mode.*/ - wspip->wspi->CR &= ~QUADSPI_CR_DMAEN; + wspip->qspi->CR &= ~QUADSPI_CR_DMAEN; /* Starting memory mapped mode using the passed parameters.*/ - wspip->wspi->DLR = 0; - wspip->wspi->ABR = 0; - wspip->wspi->AR = 0; - wspip->wspi->CCR = cmdp->cfg | QUADSPI_CCR_FMODE_1 | QUADSPI_CCR_FMODE_0; + wspip->qspi->DLR = 0; + wspip->qspi->ABR = 0; + wspip->qspi->AR = 0; + wspip->qspi->CCR = cmdp->cmd | cmdp->cfg | + QUADSPI_CCR_FMODE_1 | QUADSPI_CCR_FMODE_0; /* Mapped flash absolute base address.*/ if (addrp != NULL) { @@ -338,12 +337,12 @@ void wspi_lld_map_flash(WSPIDriver *wspip, void wspi_lld_unmap_flash(WSPIDriver *wspip) { /* Aborting memory mapped mode.*/ - wspip->wspi->CR |= QUADSPI_CR_ABORT; - while ((wspip->wspi->CR & QUADSPI_CR_ABORT) != 0U) { + wspip->qspi->CR |= QUADSPI_CR_ABORT; + while ((wspip->qspi->CR & QUADSPI_CR_ABORT) != 0U) { } /* Re-enabling DMA request, we are going back to indirect mode.*/ - wspip->wspi->CR |= QUADSPI_CR_DMAEN; + wspip->qspi->CR |= QUADSPI_CR_DMAEN; } #endif /* WSPI_SUPPORTS_MEMMAP == TRUE */ diff --git a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h index 456b0308d..ce58a6945 100644 --- a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h +++ b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h @@ -53,54 +53,62 @@ * . * @{ */ -#define WSPI_CFG_INSTRUCTION_MODE_MASK (3LU << 8LU) -#define WSPI_CFG_INSTRUCTION_MODE_NONE (0LU << 8LU) -#define WSPI_CFG_INSTRUCTION_MODE_ONE_LINES (1LU << 8LU) -#define WSPI_CFG_INSTRUCTION_MODE_TWO_LINES (2LU << 8LU) -#define WSPI_CFG_INSTRUCTION_MODE_FOUR_LINES (3LU << 8LU) - -#define WSPI_CFG_INSTRUCTION_DDR (1LU << 31LU) - -#define WSPI_CFG_INSTRUCTION_SIZE_MASK 0LU -#define WSPI_CFG_INSTRUCTION_SIZE_8 0LU - -#define WSPI_CFG_ADDR_MODE_MASK (3LU << 10LU) -#define WSPI_CFG_ADDR_MODE_NONE (0LU << 10LU) -#define WSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 10LU) -#define WSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 10LU) -#define WSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 10LU) - -#define WSPI_CFG_ADDR_DDR (1LU << 31LU) - -#define WSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU) -#define WSPI_CFG_ADDR_SIZE_8 (0LU << 12LU) -#define WSPI_CFG_ADDR_SIZE_16 (1LU << 12LU) -#define WSPI_CFG_ADDR_SIZE_24 (2LU << 12LU) -#define WSPI_CFG_ADDR_SIZE_32 (3LU << 12LU) - -#define WSPI_CFG_ALT_MODE_MASK (3LU << 14LU) -#define WSPI_CFG_ALT_MODE_NONE (0LU << 14LU) -#define WSPI_CFG_ALT_MODE_ONE_LINE (1LU << 14LU) -#define WSPI_CFG_ALT_MODE_TWO_LINES (2LU << 14LU) -#define WSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 14LU) - -#define WSPI_CFG_ALT_DDR (1LU << 31LU) - -#define WSPI_CFG_ALT_SIZE_MASK (3LU << 16LU) -#define WSPI_CFG_ALT_SIZE_8 (0LU << 16LU) -#define WSPI_CFG_ALT_SIZE_16 (1LU << 16LU) -#define WSPI_CFG_ALT_SIZE_24 (2LU << 16LU) -#define WSPI_CFG_ALT_SIZE_32 (3LU << 16LU) - -#define WSPI_CFG_DATA_MODE_MASK (3LU << 24LU) -#define WSPI_CFG_DATA_MODE_NONE (0LU << 24LU) -#define WSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU) -#define WSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU) -#define WSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU) - -#define WSPI_CFG_DATA_DDR (1LU << 31LU) - -#define WSPI_CFG_SIOO (1LU << 28LU) +#define WSPI_CFG_CMD_MODE_MASK (3LU << 8LU) +#define WSPI_CFG_CMD_MODE_NONE (0LU << 8LU) +#define WSPI_CFG_CMD_MODE_ONE_LINE (1LU << 8LU) +#define WSPI_CFG_CMD_MODE_TWO_LINES (2LU << 8LU) +#define WSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 8LU) + +#define WSPI_CFG_CMD_DDR (1LU << 31LU) + +#define WSPI_CFG_CMD_SIZE_MASK 0LU +#define WSPI_CFG_CMD_SIZE_8 0LU + +#define WSPI_CFG_ADDR_MODE_MASK (3LU << 10LU) +#define WSPI_CFG_ADDR_MODE_NONE (0LU << 10LU) +#define WSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 10LU) +#define WSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 10LU) +#define WSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 10LU) + +#define WSPI_CFG_ADDR_DDR (1LU << 31LU) + +#define WSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU) +#define WSPI_CFG_ADDR_SIZE_8 (0LU << 12LU) +#define WSPI_CFG_ADDR_SIZE_16 (1LU << 12LU) +#define WSPI_CFG_ADDR_SIZE_24 (2LU << 12LU) +#define WSPI_CFG_ADDR_SIZE_32 (3LU << 12LU) + +#define WSPI_CFG_ALT_MODE_MASK (3LU << 14LU) +#define WSPI_CFG_ALT_MODE_NONE (0LU << 14LU) +#define WSPI_CFG_ALT_MODE_ONE_LINE (1LU << 14LU) +#define WSPI_CFG_ALT_MODE_TWO_LINES (2LU << 14LU) +#define WSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 14LU) + +#define WSPI_CFG_ALT_DDR (1LU << 31LU) + +#define WSPI_CFG_ALT_SIZE_MASK (3LU << 16LU) +#define WSPI_CFG_ALT_SIZE_8 (0LU << 16LU) +#define WSPI_CFG_ALT_SIZE_16 (1LU << 16LU) +#define WSPI_CFG_ALT_SIZE_24 (2LU << 16LU) +#define WSPI_CFG_ALT_SIZE_32 (3LU << 16LU) + +#define WSPI_CFG_DATA_MODE_MASK (3LU << 24LU) +#define WSPI_CFG_DATA_MODE_NONE (0LU << 24LU) +#define WSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU) +#define WSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU) +#define WSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU) + +#define WSPI_CFG_DATA_DDR (1LU << 31LU) + +#define WSPI_CFG_SIOO (1LU << 28LU) +/** @} */ + +/** + * @name Helpers for CCR register. + * @{ + */ +#define QUADSPI_CCR_DUMMY_CYCLES_MASK (0x1FLU << 18LU) +#define QUADSPI_CCR_DUMMY_CYCLES(n) ((n) << 18LU) /** @} */ /** @@ -239,7 +247,7 @@ struct hal_wspi_config { /** * @brief Operation complete callback or @p NULL. */ - wspicallback_t end_cb; + wspicallback_t end_cb; /* End of the mandatory fields.*/ /** * @brief DCR register initialization data. diff --git a/testex/STM32/STM32L4xx/QSPI-N25Q128/halconf.h b/testex/STM32/STM32L4xx/QSPI-N25Q128/halconf.h index 6f608316a..93c9a9a6d 100644 --- a/testex/STM32/STM32L4xx/QSPI-N25Q128/halconf.h +++ b/testex/STM32/STM32L4xx/QSPI-N25Q128/halconf.h @@ -128,7 +128,7 @@ * @brief Enables the QSPI subsystem. */ #if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__) -#define HAL_USE_QSPI FALSE +#define HAL_USE_QSPI TRUE #endif /** @@ -205,7 +205,7 @@ * @brief Enables the WSPI subsystem. */ #if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__) -#define HAL_USE_WSPI TRUE +#define HAL_USE_WSPI FALSE #endif /*===========================================================================*/ diff --git a/testex/STM32/STM32L4xx/QSPI-N25Q128/mcuconf.h b/testex/STM32/STM32L4xx/QSPI-N25Q128/mcuconf.h index d4eda14a7..c64e33b58 100644 --- a/testex/STM32/STM32L4xx/QSPI-N25Q128/mcuconf.h +++ b/testex/STM32/STM32L4xx/QSPI-N25Q128/mcuconf.h @@ -327,7 +327,7 @@ /* * WSPI driver system settings. */ -#define STM32_WSPI_USE_QUADSPI1 TRUE +#define STM32_WSPI_USE_QUADSPI1 FALSE #define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) #endif /* MCUCONF_H */ diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/.cproject b/testhal/STM32/STM32L4xx/WSPI-N25Q128/.cproject new file mode 100644 index 000000000..8a79aa591 --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/.cproject @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/.project b/testhal/STM32/STM32L4xx/WSPI-N25Q128/.project new file mode 100644 index 000000000..05b9a6795 --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/.project @@ -0,0 +1,90 @@ + + + STM32L4xx-WSPI-N25Q128 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + -j1 + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + board + 2 + CHIBIOS/os/hal/boards/ST_STM32L476_DISCOVERY + + + os + 2 + CHIBIOS/os + + + diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/Makefile b/testhal/STM32/STM32L4xx/WSPI-N25Q128/Makefile new file mode 100644 index 000000000..6e6eb3cc8 --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/Makefile @@ -0,0 +1,215 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# Linker extra options here. +ifeq ($(USE_LDOPT),) + USE_LDOPT = +endif + +# Enable this if you want link time optimizations (LTO) +ifeq ($(USE_LTO),) + USE_LTO = yes +endif + +# If enabled, this option allows to compile the application in THUMB mode. +ifeq ($(USE_THUMB),) + USE_THUMB = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# If enabled, this option makes the build process faster by not compiling +# modules not used in the current configuration. +ifeq ($(USE_SMART_BUILD),) + USE_SMART_BUILD = yes +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x400 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x400 +endif + +# Enables the use of FPU (no, softfp, hard). +ifeq ($(USE_FPU),) + USE_FPU = no +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Define project name here +PROJECT = ch + +# Imported source files and paths +CHIBIOS = ../../../.. + +# Licensing files. +include $(CHIBIOS)/os/license/license.mk +# Startup files. +include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l4xx.mk +# HAL-OSAL files (optional). +include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/platform.mk +include $(CHIBIOS)/os/hal/boards/ST_STM32L476_DISCOVERY/board.mk +include $(CHIBIOS)/os/hal/osal/rt/osal.mk +# RTOS files (optional). +include $(CHIBIOS)/os/rt/rt.mk +include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk +# EX files (optional). +# Other files (optional). +include $(CHIBIOS)/os/hal/lib/complex/serial_nor/devices/micron_n25q/flash_device.mk +#include $(CHIBIOS)/os/hal/lib/complex/mfs/mfs.mk +include $(CHIBIOS)/os/hal/lib/streams/streams.mk + +# Define linker script file here +LDSCRIPT= $(STARTUPLD)/STM32L476xG.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(ALLCSRC) \ + $(TESTSRC) \ + main.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = $(ALLCPPSRC) + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACSRC = + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACPPSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCPPSRC = + +# List ASM source files here +ASMSRC = $(ALLASMSRC) +ASMXSRC = $(ALLXASMSRC) + +INCDIR = $(ALLINC) $(TESTINC) + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +MCU = cortex-m4 + +#TRGT = arm-elf- +TRGT = arm-none-eabi- +CC = $(TRGT)gcc +CPPC = $(TRGT)g++ +# Enable loading with g++ only if you need C++ runtime support. +# NOTE: You can use C++ even without C++ support if you are careful. C++ +# runtime support makes code size explode. +LD = $(TRGT)gcc +#LD = $(TRGT)g++ +CP = $(TRGT)objcopy +AS = $(TRGT)gcc -x assembler-with-cpp +AR = $(TRGT)ar +OD = $(TRGT)objdump +SZ = $(TRGT)size +HEX = $(CP) -O ihex +BIN = $(CP) -O binary + +# ARM-specific options here +AOPT = + +# THUMB-specific options here +TOPT = -mthumb -DTHUMB + +# Define C warning options here +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes + +# Define C++ warning options here +CPPWARN = -Wall -Wextra -Wundef + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = -DCHPRINTF_USE_FLOAT=1 + +# Define ASM defines here +UADEFS = + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# +# End of user defines +############################################################################## + +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk +include $(RULESPATH)/rules.mk diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/chconf.h b/testhal/STM32/STM32L4xx/WSPI-N25Q128/chconf.h new file mode 100644 index 000000000..33701dbc2 --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/chconf.h @@ -0,0 +1,714 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_6_0_ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16 or 32 bits. + */ +#if !defined(CH_CFG_ST_RESOLUTION) +#define CH_CFG_ST_RESOLUTION 32 +#endif + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#if !defined(CH_CFG_ST_FREQUENCY) +#define CH_CFG_ST_FREQUENCY 10000 +#endif + +/** + * @brief Time intervals data size. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_INTERVALS_SIZE) +#define CH_CFG_INTERVALS_SIZE 32 +#endif + +/** + * @brief Time types data size. + * @note Allowed values are 16 or 32 bits. + */ +#if !defined(CH_CFG_TIME_TYPES_SIZE) +#define CH_CFG_TIME_TYPES_SIZE 32 +#endif + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#if !defined(CH_CFG_ST_TIMEDELTA) +#define CH_CFG_ST_TIMEDELTA 2 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#if !defined(CH_CFG_TIME_QUANTUM) +#define CH_CFG_TIME_QUANTUM 0 +#endif + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#if !defined(CH_CFG_MEMCORE_SIZE) +#define CH_CFG_MEMCORE_SIZE 0 +#endif + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#if !defined(CH_CFG_NO_IDLE_THREAD) +#define CH_CFG_NO_IDLE_THREAD FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_OPTIMIZE_SPEED) +#define CH_CFG_OPTIMIZE_SPEED TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TM) +#define CH_CFG_USE_TM TRUE +#endif + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_REGISTRY) +#define CH_CFG_USE_REGISTRY TRUE +#endif + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_WAITEXIT) +#define CH_CFG_USE_WAITEXIT TRUE +#endif + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_SEMAPHORES) +#define CH_CFG_USE_SEMAPHORES TRUE +#endif + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#endif + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MUTEXES) +#define CH_CFG_USE_MUTEXES TRUE +#endif + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#endif + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_CONDVARS) +#define CH_CFG_USE_CONDVARS TRUE +#endif + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#endif + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_EVENTS) +#define CH_CFG_USE_EVENTS TRUE +#endif + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#if !defined(CH_CFG_USE_EVENTS_TIMEOUT) +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#endif + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MESSAGES) +#define CH_CFG_USE_MESSAGES TRUE +#endif + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#if !defined(CH_CFG_USE_MESSAGES_PRIORITY) +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#endif + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_MAILBOXES) +#define CH_CFG_USE_MAILBOXES TRUE +#endif + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCORE) +#define CH_CFG_USE_MEMCORE TRUE +#endif + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#if !defined(CH_CFG_USE_HEAP) +#define CH_CFG_USE_HEAP TRUE +#endif + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMPOOLS) +#define CH_CFG_USE_MEMPOOLS TRUE +#endif + +/** + * @brief Objects FIFOs APIs. + * @details If enabled then the objects FIFOs APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_FIFOS) +#define CH_CFG_USE_OBJ_FIFOS TRUE +#endif + +/** + * @brief Pipes APIs. + * @details If enabled then the pipes APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_PIPES) +#define CH_CFG_USE_PIPES TRUE +#endif + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#if !defined(CH_CFG_USE_DYNAMIC) +#define CH_CFG_USE_DYNAMIC TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Objects factory options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Objects Factory APIs. + * @details If enabled then the objects factory APIs are included in the + * kernel. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_CFG_USE_FACTORY) +#define CH_CFG_USE_FACTORY TRUE +#endif + +/** + * @brief Maximum length for object names. + * @details If the specified length is zero then the name is stored by + * pointer but this could have unintended side effects. + */ +#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#endif + +/** + * @brief Enables the registry of generic objects. + */ +#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#endif + +/** + * @brief Enables factory for generic buffers. + */ +#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#endif + +/** + * @brief Enables factory for semaphores. + */ +#if !defined(CH_CFG_FACTORY_SEMAPHORES) +#define CH_CFG_FACTORY_SEMAPHORES TRUE +#endif + +/** + * @brief Enables factory for mailboxes. + */ +#if !defined(CH_CFG_FACTORY_MAILBOXES) +#define CH_CFG_FACTORY_MAILBOXES TRUE +#endif + +/** + * @brief Enables factory for objects FIFOs. + */ +#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#endif + +/** + * @brief Enables factory for Pipes. + */ +#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_PIPES TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_STATISTICS) +#define CH_DBG_STATISTICS FALSE +#endif + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) +#define CH_DBG_SYSTEM_STATE_CHECK TRUE +#endif + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_CHECKS) +#define CH_DBG_ENABLE_CHECKS TRUE +#endif + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_ASSERTS) +#define CH_DBG_ENABLE_ASSERTS TRUE +#endif + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_MASK) +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#endif + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) +#define CH_DBG_TRACE_BUFFER_SIZE 128 +#endif + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#if !defined(CH_DBG_ENABLE_STACK_CHECK) +#define CH_DBG_ENABLE_STACK_CHECK FALSE +#endif + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_FILL_THREADS) +#define CH_DBG_FILL_THREADS FALSE +#endif + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#if !defined(CH_DBG_THREADS_PROFILING) +#define CH_DBG_THREADS_PROFILING FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System structure extension. + * @details User fields added to the end of the @p ch_system_t structure. + */ +#define CH_CFG_SYSTEM_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief System initialization hook. + * @details User initialization code added to the @p chSysInit() function + * just before interrupts are enabled globally. + */ +#define CH_CFG_SYSTEM_INIT_HOOK() { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p _thread_init() function. + * + * @note It is invoked from within @p _thread_init() and implicitly from all + * the threads creation APIs. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/debug/WSPI-N25Q128 (OpenOCD, Flash and Run).launch b/testhal/STM32/STM32L4xx/WSPI-N25Q128/debug/WSPI-N25Q128 (OpenOCD, Flash and Run).launch new file mode 100644 index 000000000..54cc23b6e --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/debug/WSPI-N25Q128 (OpenOCD, Flash and Run).launch @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/halconf.h b/testhal/STM32/STM32L4xx/WSPI-N25Q128/halconf.h new file mode 100644 index 000000000..6f608316a --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/halconf.h @@ -0,0 +1,559 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef HALCONF_H +#define HALCONF_H + +#define _CHIBIOS_HAL_CONF_ +#define _CHIBIOS_HAL_CONF_VER_6_0_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the cryptographic subsystem. + */ +#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__) +#define HAL_USE_CRY FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the QSPI subsystem. + */ +#if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__) +#define HAL_USE_QSPI FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL TRUE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SIO subsystem. + */ +#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) +#define HAL_USE_SIO FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the TRNG subsystem. + */ +#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__) +#define HAL_USE_TRNG FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB FALSE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/** + * @brief Enables the WSPI subsystem. + */ +#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__) +#define HAL_USE_WSPI TRUE +#endif + +/*===========================================================================*/ +/* PAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) +#define PAL_USE_CALLBACKS FALSE +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__) +#define PAL_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/** + * @brief Enforces the driver to use direct callbacks rather than OSAL events. + */ +#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__) +#define CAN_ENFORCE_USE_CALLBACKS FALSE +#endif + +/*===========================================================================*/ +/* CRY driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the SW fall-back of the cryptographic driver. + * @details When enabled, this option, activates a fall-back software + * implementation for algorithms not supported by the underlying + * hardware. + * @note Fall-back implementations may not be present for all algorithms. + */ +#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_USE_FALLBACK FALSE +#endif + +/** + * @brief Makes the driver forcibly use the fall-back implementations. + */ +#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_ENFORCE_FALLBACK FALSE +#endif + +/*===========================================================================*/ +/* DAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__) +#define DAC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DAC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the zero-copy API. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* QSPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(QSPI_USE_WAIT) || defined(__DOXYGEN__) +#define QSPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p qspiAcquireBus() and @p qspiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(QSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define QSPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/** + * @brief OCR initialization constant for V20 cards. + */ +#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__) +#define SDC_INIT_OCR_V20 0x50FF8000U +#endif + +/** + * @brief OCR initialization constant for non-V20 cards. + */ +#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__) +#define SDC_INIT_OCR 0x80100000U +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 16 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 256 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/** + * @brief Serial over USB number of buffers. + * @note The default is 2 buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_NUMBER 2 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables circular transfers APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__) +#define SPI_USE_CIRCULAR FALSE +#endif + + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief Handling method for SPI CS line. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__) +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD +#endif + +/*===========================================================================*/ +/* UART driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) +#define UART_USE_WAIT FALSE +#endif + +/** + * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define UART_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* WSPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__) +#define WSPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define WSPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#endif /* HALCONF_H */ + +/** @} */ diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/main.c b/testhal/STM32/STM32L4xx/WSPI-N25Q128/main.c new file mode 100644 index 000000000..6e8a35436 --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/main.c @@ -0,0 +1,170 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +#include + +#include "ch.h" +#include "hal.h" + +#include "serial_nor.h" + +/* 16MB device, 2 cycles delay after NCS.*/ +const WSPIConfig wspicfg1 = { + NULL, + STM32_DCR_FSIZE(24) | STM32_DCR_CSHT(1) +}; + +wspi_command_t cmd_read_id = { + .cmd = 0x9E, + .cfg = WSPI_CFG_CMD_MODE_ONE_LINE | + WSPI_CFG_ADDR_MODE_NONE | + WSPI_CFG_ALT_MODE_NONE | + WSPI_CFG_DATA_MODE_ONE_LINE, + .addr = 0, + .alt = 0, + .dummy = 0 +}; + +/* + * Generic buffer. + */ +uint8_t buffer[2048]; + +const uint8_t pattern[128] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +SNORDriver m25q; + +const SNORConfig m25qcfg1 = { + &WSPID1, + &wspicfg1 +}; + +/* + * LED blinker thread, times are in milliseconds. + */ +static THD_WORKING_AREA(waThread1, 128); +static THD_FUNCTION(Thread1, arg) { + + (void)arg; + chRegSetThreadName("blinker"); + while (true) { + palToggleLine(LINE_LED_GREEN); + chThdSleepMilliseconds(500); + palToggleLine(LINE_LED_GREEN); + chThdSleepMilliseconds(500); + } +} + +/* + * Application entry point. + */ +int main(void) { + flash_error_t err; + uint8_t *addr; + + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + + /* + * LED line as output. + */ + palSetLineMode(LINE_LED_GREEN, PAL_MODE_OUTPUT_PUSHPULL); + + /* + * Creates the blinker thread. + */ + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL); + + /* + * Initializing and starting SNOR driver. + */ + m25qObjectInit(&m25q); + m25qStart(&m25q, &m25qcfg1); + + /* Reading.*/ + err = flashRead(&m25q, 0, 128, buffer); + if (err != FLASH_NO_ERROR) + chSysHalt("read error"); + + /* Erasing the first sector and waiting for completion.*/ + (void) flashStartEraseSector(&m25q, 0); + err = flashWaitErase((BaseFlash *)&m25q); + if (err != FLASH_NO_ERROR) + chSysHalt("erase error"); + + /* Verifying the erase operation.*/ + err = flashVerifyErase(&m25q, 0); + if (err != FLASH_NO_ERROR) + chSysHalt("verify erase error"); + + /* Programming a pattern.*/ + err = flashProgram(&m25q, 0, 128, pattern); + if (err != FLASH_NO_ERROR) + chSysHalt("program error"); + + /* Verifying the erase operation.*/ + err = flashVerifyErase(&m25q, 0); + if (err != FLASH_ERROR_VERIFY) + chSysHalt("verify non-erase error"); + + /* Memory mapping the device.*/ + m25qMemoryMap(&m25q, &addr); + + /* Unmapping the device.*/ + m25qMemoryUnmap(&m25q); + + /* Reading it back.*/ + memset(buffer, 0, 128); + err = flashRead(&m25q, 16, 128, buffer); + if (err != FLASH_NO_ERROR) + chSysHalt("read error"); + + /* Reading it back.*/ + memset(buffer, 0, 128); + err = flashRead(&m25q, 0, 128, buffer); + if (err != FLASH_NO_ERROR) + chSysHalt("read error"); + + /* Erasing again.*/ + (void) flashStartEraseSector(&m25q, 0); + err = flashWaitErase((BaseFlash *)&m25q); + if (err != FLASH_NO_ERROR) + chSysHalt("erase error"); + + /* + * Normal main() thread activity, in this demo it does nothing. + */ + while (true) { + chThdSleepMilliseconds(500); + } + return 0; +} diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/mcuconf.h b/testhal/STM32/STM32L4xx/WSPI-N25Q128/mcuconf.h new file mode 100644 index 000000000..d4eda14a7 --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/mcuconf.h @@ -0,0 +1,333 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/* + * STM32L4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#ifndef MCUCONF_H +#define MCUCONF_H + +#define STM32L4xx_MCUCONF +#define STM32L476_MCUCONF + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_VOS STM32_VOS_RANGE1 +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_HSI16_ENABLED FALSE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED FALSE +#define STM32_LSE_ENABLED TRUE +#define STM32_MSIPLL_ENABLED TRUE +#define STM32_MSIRANGE STM32_MSIRANGE_4M +#define STM32_MSISRANGE STM32_MSISRANGE_4M +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_MSI +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 80 +#define STM32_PLLP_VALUE 7 +#define STM32_PLLQ_VALUE 6 +#define STM32_PLLR_VALUE 4 +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#define STM32_STOPWUCK STM32_STOPWUCK_MSI +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#define STM32_PLLSAI1N_VALUE 72 +#define STM32_PLLSAI1P_VALUE 7 +#define STM32_PLLSAI1Q_VALUE 6 +#define STM32_PLLSAI1R_VALUE 6 +#define STM32_PLLSAI2N_VALUE 72 +#define STM32_PLLSAI2P_VALUE 7 +#define STM32_PLLSAI2R_VALUE 6 + +/* + * Peripherals clock sources. + */ +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#define STM32_USART3SEL STM32_USART3SEL_SYSCLK +#define STM32_UART4SEL STM32_UART4SEL_SYSCLK +#define STM32_UART5SEL STM32_UART5SEL_SYSCLK +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK +#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK +#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#define STM32_SAI2SEL STM32_SAI2SEL_OFF +#define STM32_CLK48SEL STM32_CLK48SEL_PLLSAI1 +#define STM32_ADCSEL STM32_ADCSEL_SYSCLK +#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 +#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 +#define STM32_RTCSEL STM32_RTCSEL_LSI + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI1635_38_PRIORITY 6 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_22_PRIORITY 6 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_DUAL_MODE FALSE +#define STM32_ADC_COMPACT_SAMPLES FALSE +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_USE_ADC2 FALSE +#define STM32_ADC_USE_ADC3 FALSE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC2_DMA_PRIORITY 2 +#define STM32_ADC_ADC3_DMA_PRIORITY 2 +#define STM32_ADC_ADC12_IRQ_PRIORITY 5 +#define STM32_ADC_ADC3_IRQ_PRIORITY 5 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM3 FALSE +#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM5 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM8 FALSE +#define STM32_GPT_TIM1_IRQ_PRIORITY 7 +#define STM32_GPT_TIM2_IRQ_PRIORITY 7 +#define STM32_GPT_TIM3_IRQ_PRIORITY 7 +#define STM32_GPT_TIM4_IRQ_PRIORITY 7 +#define STM32_GPT_TIM5_IRQ_PRIORITY 7 +#define STM32_GPT_TIM6_IRQ_PRIORITY 7 +#define STM32_GPT_TIM7_IRQ_PRIORITY 7 +#define STM32_GPT_TIM8_IRQ_PRIORITY 7 + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C2_IRQ_PRIORITY 5 +#define STM32_I2C_I2C3_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C2_DMA_PRIORITY 3 +#define STM32_I2C_I2C3_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM3 FALSE +#define STM32_ICU_USE_TIM4 FALSE +#define STM32_ICU_USE_TIM5 FALSE +#define STM32_ICU_USE_TIM8 FALSE +#define STM32_ICU_TIM1_IRQ_PRIORITY 7 +#define STM32_ICU_TIM2_IRQ_PRIORITY 7 +#define STM32_ICU_TIM3_IRQ_PRIORITY 7 +#define STM32_ICU_TIM4_IRQ_PRIORITY 7 +#define STM32_ICU_TIM5_IRQ_PRIORITY 7 +#define STM32_ICU_TIM8_IRQ_PRIORITY 7 + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_ADVANCED FALSE +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM4 FALSE +#define STM32_PWM_USE_TIM5 FALSE +#define STM32_PWM_USE_TIM8 FALSE +#define STM32_PWM_TIM1_IRQ_PRIORITY 7 +#define STM32_PWM_TIM2_IRQ_PRIORITY 7 +#define STM32_PWM_TIM3_IRQ_PRIORITY 7 +#define STM32_PWM_TIM4_IRQ_PRIORITY 7 +#define STM32_PWM_TIM5_IRQ_PRIORITY 7 +#define STM32_PWM_TIM8_IRQ_PRIORITY 7 + +/* + * QSPI driver system settings. + */ +#define STM32_QSPI_USE_QUADSPI1 TRUE +#define STM32_QSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) + +/* + * SDC driver system settings. + */ +#define STM32_SDC_USE_SDMMC1 FALSE +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 1000 +#define STM32_SDC_SDMMC_READ_TIMEOUT 1000 +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 +#define STM32_SDC_SDMMC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 TRUE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USE_UART4 FALSE +#define STM32_SERIAL_USE_UART5 FALSE +#define STM32_SERIAL_USE_LPUART1 FALSE +#define STM32_SERIAL_USART1_PRIORITY 12 +#define STM32_SERIAL_USART2_PRIORITY 12 +#define STM32_SERIAL_USART3_PRIORITY 12 +#define STM32_SERIAL_UART4_PRIORITY 12 +#define STM32_SERIAL_UART5_PRIORITY 12 +#define STM32_SERIAL_LPUART1_PRIORITY 12 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USE_UART4 FALSE +#define STM32_UART_USE_UART5 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_UART_USART1_IRQ_PRIORITY 12 +#define STM32_UART_USART2_IRQ_PRIORITY 12 +#define STM32_UART_USART3_IRQ_PRIORITY 12 +#define STM32_UART_UART4_IRQ_PRIORITY 12 +#define STM32_UART_UART5_IRQ_PRIORITY 12 +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_UART4_DMA_PRIORITY 0 +#define STM32_UART_UART5_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_OTG1 FALSE +#define STM32_USB_OTG1_IRQ_PRIORITY 14 +#define STM32_USB_OTG1_RX_FIFO_SIZE 512 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +/* + * WSPI driver system settings. + */ +#define STM32_WSPI_USE_QUADSPI1 TRUE +#define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) + +#endif /* MCUCONF_H */ diff --git a/testhal/STM32/STM32L4xx/WSPI-N25Q128/readme.txt b/testhal/STM32/STM32L4xx/WSPI-N25Q128/readme.txt new file mode 100644 index 000000000..a604d6fd4 --- /dev/null +++ b/testhal/STM32/STM32L4xx/WSPI-N25Q128/readme.txt @@ -0,0 +1,26 @@ +***************************************************************************** +** ChibiOS/HAL - CAN driver demo for STM32. ** +***************************************************************************** + +** TARGET ** + +The demo runs on an STM32 Nucleo64-L476RG board. + +** The Demo ** + +The application demonstrates the use of the STM32 CAN driver. + +** Build Procedure ** + +The demo has been tested using the free Codesourcery GCC-based toolchain +and YAGARTO. +Just modify the TRGT line in the makefile in order to use different GCC ports. + +** Notes ** + +Some files used by the demo are not part of ChibiOS/RT but are copyright of +ST Microelectronics and are licensed under a different license. +Also note that not all the files present in the ST library are distributed +with ChibiOS/RT, you can find the whole library on the ST web site: + + http://www.st.com -- cgit v1.2.3