From 2bfb32699491281cd3cb457fa08ac833ceee5395 Mon Sep 17 00:00:00 2001 From: ziggurat29 Date: Wed, 27 Apr 2016 19:36:43 -0500 Subject: [PATCH] add board ioctls for allowing user application to cause qspi memory mapped mode to be engaged and disengaged. Also partitioned qspi flash for filesystem and other purposes (eventually xip). --- configs/stm32l476vg-disco/include/boardctl.h | 52 +++++++ configs/stm32l476vg-disco/src/stm32_appinit.c | 139 +++++++++++------- .../stm32l476vg-disco/src/stm32l476vg-disco.h | 7 - 3 files changed, 141 insertions(+), 57 deletions(-) create mode 100644 configs/stm32l476vg-disco/include/boardctl.h diff --git a/configs/stm32l476vg-disco/include/boardctl.h b/configs/stm32l476vg-disco/include/boardctl.h new file mode 100644 index 0000000000..a5c7b5bf7b --- /dev/null +++ b/configs/stm32l476vg-disco/include/boardctl.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * configs/stm32l476vg-disco/include/boardctl.h + * + * Copyright (C) 2016 dev@ziggurat29.com. All rights reserved. + * Author: dev@ziggurat29.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __CONFIGS_STM32L476VG_DISCO_INCLUDE_BOARDCTL_H +#define __CONFIGS_STM32L476VG_DISCO_INCLUDE_BOARDCTL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BIOC_ENTER_MEMMAP BOARDIOC_USER+1 +#define BIOC_EXIT_MEMMAP BOARDIOC_USER+2 + +#endif /* __CONFIGS_STM32L476VG_DISCO_INCLUDE_BOARDCTL_H */ diff --git a/configs/stm32l476vg-disco/src/stm32_appinit.c b/configs/stm32l476vg-disco/src/stm32_appinit.c index 5e277507ec..0f1d37e4d2 100644 --- a/configs/stm32l476vg-disco/src/stm32_appinit.c +++ b/configs/stm32l476vg-disco/src/stm32_appinit.c @@ -55,6 +55,7 @@ #include #include +#include #include #include @@ -75,7 +76,7 @@ # include "stm32l4_rtc.h" #endif -#if defined(HAVE_N25QXXX) || defined(HAVE_PROGMEM_CHARDEV) +#if defined(HAVE_N25QXXX) # include #endif @@ -96,6 +97,23 @@ # define SYSLOG dbg #endif +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + + /**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef HAVE_N25QXXX +FAR struct qspi_dev_s *g_qspi; +FAR struct mtd_dev_s *g_mtd_fs; +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -112,15 +130,12 @@ int board_app_initialize(void) { #ifdef HAVE_RTC_DRIVER - FAR struct rtc_lowerhalf_s *lower; + FAR struct rtc_lowerhalf_s *rtclower; #endif -#ifdef HAVE_N25QXXX - FAR struct qspi_dev_s *qspi; +#if defined(HAVE_N25QXXX) +FAR struct mtd_dev_s *mtd_temp; #endif -#if defined(HAVE_N25QXXX) || defined(HAVE_PROGMEM_CHARDEV) - FAR struct mtd_dev_s *mtd; -#endif -#if defined(HAVE_N25QXXX_CHARDEV) || defined(HAVE_PROGMEM_CHARDEV) +#if defined(HAVE_N25QXXX_CHARDEV) char blockdev[18]; char chardev[12]; #endif @@ -152,8 +167,8 @@ int board_app_initialize(void) #ifdef HAVE_RTC_DRIVER /* Instantiate the STM32 lower-half RTC driver */ - lower = stm32l4_rtc_lowerhalf(); - if (!lower) + rtclower = stm32l4_rtc_lowerhalf(); + if (!rtclower) { sdbg("ERROR: Failed to instantiate the RTC lower-half driver\n"); return -ENOMEM; @@ -164,7 +179,7 @@ int board_app_initialize(void) * as /dev/rtc0 */ - ret = rtc_initialize(0, lower); + ret = rtc_initialize(0, rtclower); if (ret < 0) { sdbg("ERROR: Failed to bind/register the RTC driver: %d\n", ret); @@ -176,10 +191,11 @@ int board_app_initialize(void) #ifdef HAVE_N25QXXX /* Create an instance of the STM32L4 QSPI device driver */ - qspi = stm32l4_qspi_initialize(0); - if (!qspi) + g_qspi = stm32l4_qspi_initialize(0); + if (!g_qspi) { - SYSLOG("ERROR: sam_qspi_initialize failed\n"); + SYSLOG("ERROR: stm32l4_qspi_initialize failed\n"); + return ret; } else { @@ -187,45 +203,34 @@ int board_app_initialize(void) * N25QXXX device. */ - mtd = n25qxxx_initialize(qspi, true); - if (!mtd) + mtd_temp = n25qxxx_initialize(g_qspi, true); + if (!mtd_temp) { SYSLOG("ERROR: n25qxxx_initialize failed\n"); - } - -#ifdef HAVE_N25QXXX_SMARTFS - /* Configure the device with no partition support */ - - SYSLOG("doing smart_initialize()\n"); - ret = smart_initialize(N25QXXX_SMART_MINOR, mtd, NULL); - if (ret != OK) - { - SYSLOG("ERROR: Failed to initialize SmartFS: %d\n", ret); - } - -#elif defined(HAVE_N25QXXX_NXFFS) - /* Initialize to provide NXFFS on the N25QXXX MTD interface */ - - SYSLOG("doing nxffs_initialize()\n"); - ret = nxffs_initialize(mtd); - if (ret < 0) - { - SYSLOG("ERROR: NXFFS initialization failed: %d\n", ret); - } - - /* Mount the file system at /mnt/n25qxxx */ - - ret = mount(NULL, "/mnt/n25qxxx", "nxffs", 0, NULL); - if (ret < 0) - { - SYSLOG("ERROR: Failed to mount the NXFFS volume: %d\n", errno); return ret; } + g_mtd_fs = mtd_temp; + +#ifdef CONFIG_MTD_PARTITION + /* Setup a partition of 256KiB for our file system. + * + */ +#if defined(CONFIG_N25QXXX_SECTOR512) + mtd_temp = mtd_partition(g_mtd_fs, 0, 512); +#else + mtd_temp = mtd_partition(g_mtd_fs, 0, 64); +#endif + if (!g_mtd_fs) + { + SYSLOG("ERROR: mtd_partition failed\n"); + return ret; + } + g_mtd_fs = mtd_temp; +#endif -#else /* if defined(HAVE_N25QXXX_CHARDEV) */ /* Use the FTL layer to wrap the MTD driver as a block driver */ - ret = ftl_initialize(N25QXXX_MTD_MINOR, mtd); + ret = ftl_initialize(N25QXXX_MTD_MINOR, g_mtd_fs); if (ret < 0) { SYSLOG("ERROR: Failed to initialize the FTL layer: %d\n", ret); @@ -244,9 +249,7 @@ int board_app_initialize(void) * visible setting, but you can make it set by selecting an * arbitrary writable file system (you don't have to actually * use it, just select it so that the block device created via - * ftl_initialize() will be writable). Personally, I chose FAT, - * because SMARTFS and NXFFS will cause the other code branches - * above to become active. + * ftl_initialize() will be writable). */ ret = bchdev_register(blockdev, chardev, false); @@ -255,7 +258,6 @@ int board_app_initialize(void) SYSLOG("ERROR: bchdev_register %s failed: %d\n", chardev, ret); return ret; } -#endif } #endif @@ -268,6 +270,43 @@ int board_app_initialize(void) #ifdef CONFIG_BOARDCTL_IOCTL int board_ioctl(unsigned int cmd, uintptr_t arg) { + switch(cmd) + { +#ifdef HAVE_N25QXXX + case BIOC_ENTER_MEMMAP: + { + struct qspi_meminfo_s meminfo; + + /* set up the meminfo like a regular memory transaction, many of the fields + * are not used, the others are to set up for the 'read' command that will + * automatically be issued by the controller as needed. + * 6 = CONFIG_N25QXXX_DUMMIES; + * 0xeb = N25QXXX_FAST_READ_QUADIO; + */ + + meminfo.flags = QSPIMEM_READ | QSPIMEM_QUADIO; + meminfo.addrlen = 3; + meminfo.dummies = 6; //CONFIG_N25QXXX_DUMMIES; + meminfo.cmd = 0xeb;//N25QXXX_FAST_READ_QUADIO; + meminfo.addr = 0; + meminfo.buflen = 0; + meminfo.buffer = NULL; + + stm32l4_qspi_enter_memorymapped(g_qspi, &meminfo, 80000000); + } + break; + + case BIOC_EXIT_MEMMAP: + stm32l4_qspi_exit_memorymapped(g_qspi); + break; + +#endif + + default: + return -EINVAL; + break; + } + return OK; } #endif diff --git a/configs/stm32l476vg-disco/src/stm32l476vg-disco.h b/configs/stm32l476vg-disco/src/stm32l476vg-disco.h index 03c63bc3ea..4331d064d5 100644 --- a/configs/stm32l476vg-disco/src/stm32l476vg-disco.h +++ b/configs/stm32l476vg-disco/src/stm32l476vg-disco.h @@ -59,7 +59,6 @@ #define HAVE_N25QXXX_NXFFS 1 #define HAVE_N25QXXX_SMARTFS 1 #define HAVE_N25QXXX_CHARDEV 1 -#define HAVE_PROGMEM_CHARDEV 1 #if !defined(CONFIG_FS_PROCFS) # undef HAVE_PROC @@ -108,12 +107,6 @@ # undef HAVE_N25QXXX_CHARDEV #endif -/* On-chip Programming Memory */ - -#if !defined(CONFIG_STM32L4_PROGMEM) || !defined(CONFIG_MTD_PROGMEM) -# undef HAVE_PROGMEM_CHARDEV -#endif - /* If both the N25QXXX FLASH and SmartFS, then this is the minor device * number of the Smart block driver (/dev/smartN) */