diff --git a/configs/clicker2-stm32/Kconfig b/configs/clicker2-stm32/Kconfig index cd52c627d0f..d0d991ddb2e 100644 --- a/configs/clicker2-stm32/Kconfig +++ b/configs/clicker2-stm32/Kconfig @@ -6,63 +6,164 @@ if ARCH_BOARD_CLICKER2_STM32 config CLICKER2_STM32_MB1_SPI - bool "mikroBUS1 SPI" - default n - select STM32_SPI3 - ---help--- - Enable SPI support on mikroBUS1 (STM32 SPI3) + bool "mikroBUS1 SPI" + default n + select STM32_SPI3 + ---help--- + Enable SPI support on mikroBUS1 (STM32 SPI3) config CLICKER2_STM32_MB2_SPI - bool "mikroBUS2 SPI" - default n - select STM32_SPI2 - ---help--- - Enable SPI support on mikroBUS1 (STM32 SPI2) + bool "mikroBUS2 SPI" + default n + select STM32_SPI2 + ---help--- + Enable SPI support on mikroBUS1 (STM32 SPI2) config CLICKER2_STM32_MB1_BEE - bool "mikroBUS1 MRF24J40 BEE" - default y - depends on IEEE802154_MRF24J40 - select CLICKER2_STM32_MB1_SPI - ---help--- - Enable support for MRF24J40 BEE on mikroBUS1 + bool "mikroBUS1 MRF24J40 BEE" + default y + depends on IEEE802154_MRF24J40 + select CLICKER2_STM32_MB1_SPI + ---help--- + Enable support for MRF24J40 BEE on mikroBUS1 config CLICKER2_STM32_MB2_BEE - bool "mikroBUS2 MRF24J40 BEE" - default n - depends on IEEE802154_MRF24J40 - select CLICKER2_STM32_MB2_SPI - ---help--- - Enable support for MRF24J40 BEE on mikroBUS2 + bool "mikroBUS2 MRF24J40 BEE" + default n + depends on IEEE802154_MRF24J40 + select CLICKER2_STM32_MB2_SPI + ---help--- + Enable support for MRF24J40 BEE on mikroBUS2 config CLICKER2_STM32_MRF24J40LH_VERBOSE - bool "Verbose MRF24J40 lowerhalf" - default n - depends on IEEE802154_MRF24J40 && DEBUG_WIRELESS_INFO - ---help--- - Enable verbose syslog for MRF24J40 lowerhalf + bool "Verbose MRF24J40 lowerhalf" + default n + depends on IEEE802154_MRF24J40 && DEBUG_WIRELESS_INFO + ---help--- + Enable verbose syslog for MRF24J40 lowerhalf config CLICKER2_STM32_MB1_XBEE - bool "mikroBUS1 XBee radio" - default n - depends on IEEE802154_XBEE - select CLICKER2_STM32_MB1_SPI - ---help--- - Enable support for XBee radio on mikroBUS1 + bool "mikroBUS1 XBee radio" + default n + depends on IEEE802154_XBEE + select CLICKER2_STM32_MB1_SPI + ---help--- + Enable support for XBee radio on mikroBUS1 config CLICKER2_STM32_MB2_XBEE - bool "mikroBUS2 XBee radio" - default n - depends on IEEE802154_XBEE - select CLICKER2_STM32_MB2_SPI - ---help--- - Enable support for XBee on mikroBUS2 + bool "mikroBUS2 XBee radio" + default n + depends on IEEE802154_XBEE + select CLICKER2_STM32_MB2_SPI + ---help--- + Enable support for XBee on mikroBUS2 config CLICKER2_STM32_XBEELH_VERBOSE - bool "Verbose XBee lowerhalf" - default n - depends on IEEE802154_XBEE && DEBUG_WIRELESS_INFO - ---help--- - Enable verbose syslog for XBee lowerhalf + bool "Verbose XBee lowerhalf" + default n + depends on IEEE802154_XBEE && DEBUG_WIRELESS_INFO + ---help--- + Enable verbose syslog for XBee lowerhalf + +config CLICKER2_STM32_MB1_MMCSD + bool "mikroBUS1 uSD Card Click board" + default n + select CLICKER2_STM32_MB1_SPI + ---help--- + Enable support for uSD click on mikroBUS1 + +config CLICKER2_STM32_MB2_MMCSD + bool "mikroBUS2 uSD Card Click board" + default n + select CLICKER2_STM32_MB2_SPI + ---help--- + Enable support for uSD click on mikroBUS2 + +if FS_AUTOMOUNTER +if CLICKER2_STM32_MB1_MMCSD + +config CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT + bool "MB1 MMCSD automounter" + default n + +if CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT + +config CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_FSTYPE + string "MB1 MMCSD file system type" + default "vfat" + +config CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_BLKDEV + string "MB1 MMCSD block device" + default "/dev/mmcsd0" + +config CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_MOUNTPOINT + string "MB1 MMCSD mount point" + default "/mnt/sdcard0" + +config CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_DDELAY + int "MB1 MMCSD debounce delay (milliseconds)" + default 1000 + +config CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_UDELAY + int "MB1 MMCSD unmount retry delay (milliseconds)" + default 2000 + +endif # CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT +endif # CLICKER2_STM32_MB1_MMCSD + +if CLICKER2_STM32_MB2_MMCSD + +config CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT + bool "MB2 MMCSD automounter" + default n + +if CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT + +config CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_FSTYPE + string "MB2 MMCSD file system type" + default "vfat" + +config CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_BLKDEV + string "MB2 MMCSD block device" + default "/dev/mmcsd0" + +config CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_MOUNTPOINT + string "MB2 MMCSD mount point" + default "/mnt/sdcard0" + +config CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_DDELAY + int "MB2 MMCSD debounce delay (milliseconds)" + default 1000 + +config CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_UDELAY + int "MB2 MMCSD unmount retry delay (milliseconds)" + default 2000 + +endif # CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT +endif # CLICKER2_STM32_MB2_MMCSD + +endif # FS_AUTOMOUNTER + +config CLICKER2_STM32_SYSLOG_FILE + bool "Enable file syslog" + default n + depends on SYSLOG_FILE + +if CLICKER2_STM32_SYSLOG_FILE + +config CLICKER2_STM32_SYSLOG_FILE_PATH + string "Path to syslog file" + default "/mnt/sdcard0/nuttx.log" + +config CLICKER2_STM32_SYSLOG_FILE_DELAY + int "Delay time(ms) for syslog file" + default 2500 + ---help--- + If the file used for syslog is on an SD card, the device may need time + to finish mounting the file system. This option selects the amount of + time in milliseconds for the system to wait before attempting to setup + the syslog file + +endif # CLICKER2_STM32_SYSLOG_FILE endif # ARCH_BOARD_CLICKER2_STM32 diff --git a/configs/clicker2-stm32/src/Makefile b/configs/clicker2-stm32/src/Makefile index f8fe3115733..e49b27f94dc 100644 --- a/configs/clicker2-stm32/src/Makefile +++ b/configs/clicker2-stm32/src/Makefile @@ -64,6 +64,14 @@ ifeq ($(CONFIG_IEEE802154_XBEE),y) CSRCS += stm32_xbee.c endif +ifeq ($(CONFIG_MMCSD_SPI),y) +CSRCS += stm32_mmcsd.c +endif + +ifeq ($(CONFIG_FS_AUTOMOUNTER),y) +CSRCS += stm32_automount.c +endif + ifeq ($(CONFIG_ADC),y) CSRCS += stm32_adc.c endif diff --git a/configs/clicker2-stm32/src/clicker2-stm32.h b/configs/clicker2-stm32/src/clicker2-stm32.h index 6251a50e30e..e39f06d44a3 100644 --- a/configs/clicker2-stm32/src/clicker2-stm32.h +++ b/configs/clicker2-stm32/src/clicker2-stm32.h @@ -52,43 +52,70 @@ /* Assume that we support everything until convinced otherwise */ -#define HAVE_MMCSD 1 -#define HAVE_USBDEV 1 -#define HAVE_USBMONITOR 1 +#define HAVE_USBDEV 1 +#define HAVE_USBMONITOR 1 +#define HAVE_MMCSD 1 +#define HAVE_AUTOMOUNTER 1 -/* Can't support MMC/SD features if mountpoints are disabled or if SDIO support - * is not enabled. - */ +/* MMCSD */ +/* Only support uSD click board */ -#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_STM32_SDIO) || \ - !defined(CONFIG_MMCSD_SDIO) +#if !defined(CONFIG_CLICKER2_STM32_MB1_MMCSD) && \ + !defined(CONFIG_CLICKER2_STM32_MB2_MMCSD) # undef HAVE_MMCSD #endif -/* Default MMC/SD minor number */ +/* Can't support MMC/SD features if mountpoints are disabled */ + +#if defined(HAVE_MMCSD) && defined(CONFIG_DISABLE_MOUNTPOINT) +# warning Mountpoints disabled. No MMC/SD support +# undef HAVE_MMCSD +#endif #ifdef HAVE_MMCSD -/* Default MMC/SD SLOT number */ +/* Default slot number */ -# if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != 0 -# error Only one MMC/SD slot -# undef CONFIG_NSH_MMCSDSLOTNO -# endif - -# ifdef CONFIG_NSH_MMCSDSLOTNO -# define MMCSD_SLOTNO CONFIG_NSH_MMCSDSLOTNO -# else -# define MMCSD_SLOTNO 0 +# ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD +# ifdef CONFIG_NSH_MMCSDSLOTNO +# define MB1_MMCSD_SLOTNO CONFIG_NSH_MMCSDSLOTNO +# else +# define MB1_MMCSD_SLOTNO 0 +# endif +# ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD +# define MB2_MMCSD_SLOTNO MB1_MMCSD_SLOTNO+1 +# endif +# elif defined(CONFIG_CLICKER2_STM32_MB2_MMCSD) +# ifdef CONFIG_NSH_MMCSDSLOTNO +# define MB2_MMCSD_SLOTNO CONFIG_NSH_MMCSDSLOTNO +# else +# define MB2_MMCSD_SLOTNO 0 +# endif # endif /* Default minor device number */ -# ifdef CONFIG_NSH_MMCSDMINOR -# define MMCSD_MINOR CONFIG_NSH_MMCSDMINOR -# else -# define MMCSD_MINOR 0 +# ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD +# ifdef CONFIG_NSH_MMCSDMINOR +# define MB1_MMCSD_MINOR CONFIG_NSH_MMCSDMINOR +# else +# define MB1_MMCSD_MINOR 0 +# endif +# ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD +# define MB2_MMCSD_MINOR MB1_MMCSD_MINOR+1 +# endif +# elif defined(CONFIG_CLICKER2_STM32_MB2_MMCSD) +# ifdef CONFIG_NSH_MMCSDMINOR +# define MB2_MMCSD_MINOR CONFIG_NSH_MMCSDMINOR +# else +# define MB2_MMCSD_MINOR 0 +# endif # endif + +#endif /* HAVE_MMCSD */ + +#ifndef CONFIG_FS_AUTOMOUNTER +# undef HAVE_AUTOMOUNTER #endif /* Can't support USB device feature if USB OTG FS is not enabled */ @@ -111,7 +138,6 @@ # undef HAVE_USBMONITOR #endif - /* Mickroe Clicker2 STM32 GPIOs *********************************************/ /* LEDs * @@ -203,11 +229,8 @@ /* Reset * - * mikroBUS1 Interrupt: PE7-MB1_RST - * mikroBUS2 Interrupt: PE13-MB2_RST - * - * I assume that the interrupt lines are active low. The initial state holds the - * device in reset. + * mikroBUS1 Reset: PE7-MB1_RST + * mikroBUS2 Reset: PE13-MB2_RST */ #define GPIO_MB1_RST (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ @@ -215,12 +238,6 @@ #define GPIO_MB2_RST (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN13) -#define GPIO_MB1_XBEE_RST (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|\ - GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN7) - -#define GPIO_MB2_XBEE_RST (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|\ - GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN13) - /* Interrupts * * mikroBUS1 Interrupt: PE10-MB1_INT @@ -233,9 +250,6 @@ #define GPIO_MB1_INT (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTE|GPIO_PIN10) #define GPIO_MB2_INT (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTE|GPIO_PIN14) -#define GPIO_MB1_XBEE_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN10) -#define GPIO_MB2_XBEE_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN14) - #ifndef __ASSEMBLY__ /************************************************************************************ @@ -338,5 +352,79 @@ int stm32_mrf24j40_initialize(void); int stm32_xbee_initialize(void); #endif +/**************************************************************************** + * Name: stm32_mmcsd_initialize + * + * Description: + * Initialize the MMCSD device. + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef HAVE_MMCSD +int stm32_mmcsd_initialize(void); +#endif + +/**************************************************************************** + * Name: stm32_cardinserted + * + * Description: + * Check if SD card is inserted in slotno + * + * Returned Value: + * true if card is inserted, false if not + * + ****************************************************************************/ + +#ifdef HAVE_MMCSD +bool stm32_cardinserted(int slotno); +#endif + +/************************************************************************************ + * Name: stm32_automount_initialize + * + * Description: + * Configure auto-mounters for each enabled MikroBus MMCSD + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef HAVE_AUTOMOUNTER +int stm32_automount_initialize(void); +#endif + +/************************************************************************************ + * Name: stm32_automount_event + * + * Description: + * The MMCSD card detection logic has detected an insertion or removal event. It + * has already scheduled the MMC/SD block driver operations. Now we need to + * schedule the auto-mount event which will occur with a substantial delay to make + * sure that everything has settle down. + * + * Input Parameters: + * slotno - Identifies the MB slot: MB1_MMCSD_SLOTNO or MB2_MMCSD_SLOTNO. + * inserted - True if the card is inserted in the slot. False otherwise. + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled. + * + ************************************************************************************/ + +#ifdef HAVE_AUTOMOUNTER +void stm32_automount_event(int slotno, bool inserted); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_CLICKER2_STM32_SRC_CLICKER2_H */ diff --git a/configs/clicker2-stm32/src/stm32_appinit.c b/configs/clicker2-stm32/src/stm32_appinit.c index cd197295038..18840ceeab7 100644 --- a/configs/clicker2-stm32/src/stm32_appinit.c +++ b/configs/clicker2-stm32/src/stm32_appinit.c @@ -41,7 +41,10 @@ #include #include +#include +#include +#include #include #include "clicker2-stm32.h" @@ -86,13 +89,37 @@ int board_app_initialize(uintptr_t arg) { + int ret; + /* Did we already initialize via board_initialize()? */ #ifndef CONFIG_BOARD_INITIALIZE - return stm32_bringup(); -#else - return OK; + ret = stm32_bringup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_bringup() failed: %d\n", ret); + return ret + } #endif + +#ifdef CONFIG_CLICKER2_STM32_SYSLOG_FILE + + /* Delay some time for the automounter to finish mounting before bringing up + * file syslog. + */ + + usleep(CONFIG_CLICKER2_STM32_SYSLOG_FILE_DELAY * 1000); + + ret = syslog_file_channel(CONFIG_CLICKER2_STM32_SYSLOG_FILE_PATH); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: syslog_file_channel() failed: %d\n", ret); + return ret; + } +#endif + + UNUSED(ret); + return OK; } #endif /* CONFIG_LIB_BOARDCTL */ diff --git a/configs/clicker2-stm32/src/stm32_automount.c b/configs/clicker2-stm32/src/stm32_automount.c new file mode 100644 index 00000000000..0ad5eab86da --- /dev/null +++ b/configs/clicker2-stm32/src/stm32_automount.c @@ -0,0 +1,391 @@ +/************************************************************************************ + * configs/clicker2-stm32/src/stm32_automount.c + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Author: Anthony Merlino + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_FS_AUTOMOUNTER_DEBUG) && !defined(CONFIG_DEBUG_FS) +# define CONFIG_DEBUG_FS 1 +#endif + +#include + +#include +#include +#include + +#include "clicker2-stm32.h" + +#ifdef HAVE_AUTOMOUNTER + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* This structure represents the changeable state of the automounter */ + +struct stm32_automount_state_s +{ + volatile automount_handler_t handler; /* Upper half handler */ + FAR void *arg; /* Handler argument */ + bool enable; /* Fake interrupt enable */ + bool pending; /* Set if there an event while disabled */ +}; + +/* This structure represents the static configuration of an automounter */ + +struct stm32_automount_config_s +{ + /* This must be first thing in structure so that we can simply cast from struct + * automount_lower_s to struct stm32_automount_config_s + */ + + struct automount_lower_s lower; /* Publicly visible part */ + uint8_t mmcsd; /* MB1_MMCSD_SLOTNO or MB2_MMCSD_SLOTNO */ + FAR struct stm32_automount_state_s *state; /* Changeable state */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +static int stm32_attach(FAR const struct automount_lower_s *lower, + automount_handler_t isr, FAR void *arg); +static void stm32_enable(FAR const struct automount_lower_s *lower, bool enable); +static bool stm32_inserted(FAR const struct automount_lower_s *lower); + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT +static struct stm32_automount_state_s g_mb1_mmcsdstate; +static const struct stm32_automount_config_s g_mb1_mmcsdconfig = +{ + .lower = + { + .fstype = CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_FSTYPE, + .blockdev = CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_BLKDEV, + .mountpoint = CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_MOUNTPOINT, + .ddelay = MSEC2TICK(CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_DDELAY), + .udelay = MSEC2TICK(CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT_UDELAY), + .attach = stm32_attach, + .enable = stm32_enable, + .inserted = stm32_inserted + }, + .mmcsd = MB1_MMCSD_SLOTNO, + .state = &g_mb1_mmcsdstate +}; +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT +static struct stm32_automount_state_s g_mb2_mmcsdstate; +static const struct stm32_automount_config_s g_mb2_mmcsdconfig = +{ + .lower = + { + .fstype = CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_FSTYPE, + .blockdev = CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_BLKDEV, + .mountpoint = CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_MOUNTPOINT, + .ddelay = MSEC2TICK(CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_DDELAY), + .udelay = MSEC2TICK(CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT_UDELAY), + .attach = stm32_attach, + .enable = stm32_enable, + .inserted = stm32_inserted + }, + .mmcsd = MB2_MMCSD_SLOTNO, + .state = &g_mb2_mmcsdstate +}; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_attach + * + * Description: + * Attach a new MMCSD event handler + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * isr - The new event handler to be attach + * arg - Client data to be provided when the event handler is invoked. + * + * Returned Value: + * Always returns OK + * + ************************************************************************************/ + +static int stm32_attach(FAR const struct automount_lower_s *lower, + automount_handler_t isr, FAR void *arg) +{ + FAR const struct stm32_automount_config_s *config; + FAR struct stm32_automount_state_s *state; + + /* Recover references to our structure */ + + config = (FAR struct stm32_automount_config_s *)lower; + DEBUGASSERT(config && config->state); + + state = config->state; + + /* Save the new handler info (clearing the handler first to eliminate race + * conditions). + */ + + state->handler = NULL; + state->pending = false; + state->arg = arg; + state->handler = isr; + return OK; +} + +/************************************************************************************ + * Name: stm32_enable + * + * Description: + * Enable card insertion/removal event detection + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * enable - True: enable event detection; False: disable + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void stm32_enable(FAR const struct automount_lower_s *lower, bool enable) +{ + FAR const struct stm32_automount_config_s *config; + FAR struct stm32_automount_state_s *state; + irqstate_t flags; + + /* Recover references to our structure */ + + config = (FAR struct stm32_automount_config_s *)lower; + DEBUGASSERT(config && config->state); + + state = config->state; + + /* Save the fake enable setting */ + + flags = enter_critical_section(); + state->enable = enable; + + /* Did an interrupt occur while interrupts were disabled? */ + + if (enable && state->pending) + { + /* Yes.. perform the fake interrupt if the interrutp is attached */ + + if (state->handler) + { + bool inserted = stm32_cardinserted(config->mmcsd); + (void)state->handler(&config->lower, state->arg, inserted); + } + + state->pending = false; + } + + leave_critical_section(flags); +} + +/************************************************************************************ + * Name: stm32_inserted + * + * Description: + * Check if a card is inserted into the slot. + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * + * Returned Value: + * True if the card is inserted; False otherwise + * + ************************************************************************************/ + +static bool stm32_inserted(FAR const struct automount_lower_s *lower) +{ + FAR const struct stm32_automount_config_s *config; + + config = (FAR struct stm32_automount_config_s *)lower; + DEBUGASSERT(config && config->state); + + return stm32_cardinserted(config->mmcsd); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_automount_initialize + * + * Description: + * Configure auto-mounters for each enabled MMCSD MikroBus slot + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +int stm32_automount_initialize(void) +{ + FAR void *handle; + + finfo("Initializing automounter(s)\n"); + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT + /* Initialize the MB1 MMCSD auto-mounter */ + + handle = automount_initialize(&g_mb1_mmcsdconfig.lower); + if (!handle) + { + ferr("ERROR: Failed to initialize auto-mounter for MB1 MMCSD\n"); + return ERROR; + } +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT + /* Initialize the MB2 MMCSD auto-mounter */ + + handle = automount_initialize(&g_mb2_mmcsdconfig.lower); + if (!handle) + { + ferr("ERROR: Failed to initialize auto-mounter for MB2 MMCSD\n"); + return ERROR; + } +#endif + + return OK; +} + +/************************************************************************************ + * Name: stm32_automount_event + * + * Description: + * The HSMCI card detection logic has detected an insertion or removal event. It + * has already scheduled the MMC/SD block driver operations. Now we need to + * schedule the auto-mount event which will occur with a substantial delay to make + * sure that everything has settle down. + * + * Input Parameters: + * slotno - Identifies the MB slot: MB1_MMCSD_SLOTNO or MB2_MMCSD_SLOTNO. There is a + * terminology problem here: Each HSMCI supports two slots, slot A and slot B. + * Only slot A is used. So this is not a really a slot, but an HSCMI peripheral + * number. + * inserted - True if the card is inserted in the slot. False otherwise. + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled. + * + ************************************************************************************/ + +void stm32_automount_event(int slotno, bool inserted) +{ + FAR const struct stm32_automount_config_s *config; + FAR struct stm32_automount_state_s *state; + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT + /* Is this a change in the MB1 MMCSD slot insertion state? */ + + if (slotno == MB1_MMCSD_SLOTNO) + { + /* Yes.. Select the MB1 MMCSD automounter */ + + config = &g_mb1_mmcsdconfig; + state = &g_mb1_mmcsdstate; + } + else +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT + /* Is this a change in the MB2 MMCSD slot insertion state? */ + + if (slotno == MB2_MMCSD_SLOTNO) + { + /* Yes.. Select the MB2 MMCSD automounter */ + + config = &g_mb2_mmcsdconfig; + state = &g_mb2_mmcsdstate; + } + else +#endif + { + ferr("ERROR: Unsupported MMCSD%d\n", slotno); + return; + } + + /* Is the auto-mounter interrupt attached? */ + + if (state->handler) + { + /* Yes.. Have we been asked to hold off interrupts? */ + + if (!state->enable) + { + /* Yes.. just remember that there is a pending interrupt. We will + * deliver the interrupt when interrupts are "re-enabled." + */ + + state->pending = true; + } + else + { + /* No.. forward the event to the handler */ + + (void)state->handler(&config->lower, state->arg, inserted); + } + } +} + +#endif /* HAVE_AUTOMOUNTER */ diff --git a/configs/clicker2-stm32/src/stm32_bringup.c b/configs/clicker2-stm32/src/stm32_bringup.c index ce2cb4a6015..ec3abe242c0 100644 --- a/configs/clicker2-stm32/src/stm32_bringup.c +++ b/configs/clicker2-stm32/src/stm32_bringup.c @@ -46,7 +46,6 @@ #include #include -#include #include #ifdef CONFIG_USBMONITOR @@ -76,9 +75,6 @@ int stm32_bringup(void) { -#ifdef HAVE_MMCSD - FAR struct sdio_dev_s *sdio; -#endif int ret; #ifdef CONFIG_FS_PROCFS @@ -91,38 +87,6 @@ int stm32_bringup(void) } #endif -#ifdef HAVE_MMCSD - /* Mount the SDIO-based MMC/SD block driver */ - /* First, get an instance of the SDIO interface */ - - sdio = sdio_initialize(MMCSD_SLOTNO); - if (!sdio) - { - syslog(LOG_ERR, - "ERROR: Failed to initialize SDIO slot %d\n", - MMCSD_SLOTNO); - return -ENODEV; - } - - /* Now bind the SDIO interface to the MMC/SD driver */ - - ret = mmcsd_slotinitialize(MMCSD_MINOR, sdio); - if (ret != OK) - { - syslog(LOG_ERR, - "ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", - ret); - return ret; - } - - /* Then let's guess and say that there is a card in the slot. The Olimex - * STM32 P407 does not support a GPIO to detect if there is a card in - * the slot so we are reduced to guessing. - */ - - sdio_mediachange(sdio, true); -#endif - #ifdef CONFIG_CAN /* Initialize CAN and register the CAN driver. */ @@ -173,6 +137,27 @@ int stm32_bringup(void) } #endif +#if defined(CONFIG_CLICKER2_STM32_MB1_MMCSD_AUTOMOUNT) || \ + defined(CONFIG_CLICKER2_STM32_MB2_MMCSD_AUTOMOUNT) + /* Configure uSD automounter */ + + ret = stm32_automount_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_automount_initialize() failed: %d\n", ret); + } +#endif + +#if defined(CONFIG_CLICKER2_STM32_MB1_MMCSD) || defined(CONFIG_CLICKER2_STM32_MB2_MMCSD) + /* Configure uSD card slot */ + + ret = stm32_mmcsd_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_mmcsd_initialize() failed: %d\n", ret); + } +#endif + #ifdef CONFIG_BUTTONS /* Register the BUTTON driver */ diff --git a/configs/clicker2-stm32/src/stm32_mmcsd.c b/configs/clicker2-stm32/src/stm32_mmcsd.c new file mode 100644 index 00000000000..22dc2cda274 --- /dev/null +++ b/configs/clicker2-stm32/src/stm32_mmcsd.c @@ -0,0 +1,428 @@ +/**************************************************************************** + * configs/clicker2-stm32/src/stm32_mmcsd.c + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Author: Anthony Merlino + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "stm32_spi.h" + +#include "clicker2-stm32.h" + +#ifdef CONFIG_MMCSD_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if !defined(CONFIG_CLICKER2_STM32_MB1_MMCSD) && \ + !defined(CONFIG_CLICKER2_STM32_MB2_MMCSD) +# error Only the Mikroe uSD click boards are supported +#endif + +/* Can't support MMC/SD features if mountpoints are disabled or if SDIO support + * is not enabled. + */ + +#if defined(CONFIG_DISABLE_MOUNTPOINT) +# error Mountpoints are required for MMCSD support +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD +# ifndef CONFIG_STM32_SPI3 +# error MMCSD on mikroBUS1 requires CONFIG_STM32_SPI3 +# endif +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD +# ifndef CONFIG_STM32_SPI2 +# error MMCSD on mikroBUS1 requires CONFIG_STM32_SPI2 +# endif +#endif + +#ifdef CONFIG_SCHED_LPWORK +# define MMCSDWORK LPWORK +#elif defined (CONFIG_SCHED_HPWORK) +# define MMCSDWORK HPWORK +#else +# error High or low priority work queue required for MMCSD support +#endif + +/* Card Detect + * + * mikroBUS1 Card Detect (AN pin): PE10-MB1_INT + * mikroBUS2 Card Detect (AN pin: PE14-MB2_INT + * + * There is a pull-up on the uSD click board` + */ + +#define GPIO_MB1_CD (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTA|GPIO_PIN2) +#define GPIO_MB2_CD (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTA|GPIO_PIN3) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure holds static information unique to one MMCSD slot */ + +struct stm32_mmcsd_state_s +{ + uint8_t spidev; /* SPI bus used for MMCSD */ + uint8_t slotno; /* Slot number */ + int minor; /* The MMC/SD minor device number */ + uint32_t cdcfg; /* Card detect PIO pin configuration */ + xcpt_t handler; /* Interrupt handler */ + bool cd; /* TRUE: card is inserted */ + spi_mediachange_t callback; /* SPI media change callback */ + FAR void *cbarg; /* Argument to pass to media change callback */ + struct work_s work; /* For deferring card detect interrupt work */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static bool stm32_cardinserted_internal(struct stm32_mmcsd_state_s *state); +static void stm32_mmcsd_carddetect(FAR void *arg); +static int stm32_mmcsd_setup(FAR struct stm32_mmcsd_state_s *); + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD +static int stm32_mb1_mmcsd_carddetect(int irq, FAR void *regs, FAR void *arg); +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD +static int stm32_mb2_mmcsd_carddetect(int irq, FAR void *regs, FAR void *arg); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* MMCSD device state */ + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD +static int stm32_mb1_mmcsd_carddetect(int irq, void *regs, FAR void *arg); + +static struct stm32_mmcsd_state_s g_mb1_mmcsd = +{ + .spidev = 3, + .slotno = MB1_MMCSD_SLOTNO, + .minor = MB1_MMCSD_MINOR, + .cdcfg = GPIO_MB1_CD, + .handler = stm32_mb1_mmcsd_carddetect, + .callback = NULL, + .cbarg = NULL, +}; +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD +static int stm32_mb2_mmcsd_carddetect(int irq, void *regs, FAR void *arg); + +static struct stm32_mmcsd_state_s g_mb2_mmcsd = +{ + .spidev = 2, + .slotno = MB2_MMCSD_SLOTNO, + .minor = MB2_MMCSD_MINOR, + .cdcfg = GPIO_MB2_CD, + .handler = stm32_mb2_mmcsd_carddetect, + .callback = NULL, + .cbarg = NULL, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_cardinserted_internal + * + * Description: + * Check if a card is inserted into the selected MMCSD slot + * + ****************************************************************************/ + +static bool stm32_cardinserted_internal(struct stm32_mmcsd_state_s *state) +{ + bool inserted; + + /* Get the state of the PIO pin */ + + inserted = stm32_gpioread(state->cdcfg); + finfo("Slot %d inserted: %s\n", state->slotno, inserted ? "NO" : "YES"); + return !inserted; +} + +/**************************************************************************** + * Name: stm32_mmcsd_carddetect, stm32_mb1_mmcsd_carddetect, and + * stm32_mb2_mmcsd_carddetect + * + * Description: + * Card detect interrupt handlers + * + ****************************************************************************/ + +static void stm32_mmcsd_carddetect(FAR void *arg) +{ + bool cd; + FAR struct stm32_mmcsd_state_s *state = (FAR struct stm32_mmcsd_state_s *)arg; + + /* Get the current card insertion state */ + + cd = stm32_cardinserted_internal(state); + + /* Has the card detect state changed? */ + + if (cd != state->cd) + { + /* Yes... remember that new state and inform the HSMCI driver */ + + state->cd = cd; + + /* Report the new state to the SPI driver */ + + if (state->callback) + { + state->callback(state->cbarg); + } + } + +#ifdef HAVE_AUTOMOUNTER + /* Let the automounter know about the insertion event */ + + stm32_automount_event(state->slotno, stm32_cardinserted(state->slotno)); +#endif +} + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD +static int stm32_mb1_mmcsd_carddetect(int irq, FAR void *regs, FAR void *arg) +{ + if (work_available(&g_mb1_mmcsd.work)) + { + return work_queue(MMCSDWORK, &g_mb1_mmcsd.work, stm32_mmcsd_carddetect, + &g_mb1_mmcsd, 0); + } + + return OK; +} +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD +static int stm32_mb2_mmcsd_carddetect(int irq, FAR void *regs, FAR void *arg) +{ + if (work_available(&g_mb2_mmcsd.work)) + { + return work_queue(MMCSDWORK, &g_mb2_mmcsd.work, stm32_mmcsd_carddetect, + &g_mb2_mmcsd, 0); + } + + return OK; +} +#endif + +static int stm32_mmcsd_setup(struct stm32_mmcsd_state_s *state) +{ + struct spi_dev_s *spi; + int ret; + /* Initialize the SPI bus and get an instance of the SPI interface */ + + spi = stm32_spibus_initialize(state->spidev); + if (spi == NULL) + { + spierr("ERROR: Failed to initialize SPI bus %d\n", state->spidev); + return -ENODEV; + } + + ret = mmcsd_spislotinitialize(state->minor, state->slotno, spi); + if (ret < 0) + { + mcerr("ERROR: Failed to bind SPI port %d to SD slot %d\n", + state->spidev, state->slotno); + return ret; + } + + /* Initialize Card Detect pin and enable interrupt on edges */ + + stm32_configgpio(state->cdcfg); + stm32_gpiosetevent(state->cdcfg, true, true, true, state->handler, NULL); + + state->cd = stm32_cardinserted_internal(state); + if (state->callback) + { + state->callback(state->cbarg); + } + +#ifdef HAVE_AUTOMOUNTER + /* Let the automounter know about the insertion event */ + + stm32_automount_event(state->slotno, stm32_cardinserted(state->slotno)); +#endif + + mcinfo("INFO: mmcsd%d card has been initialized successfully\n", state->minor); + return OK; +} + +/**************************************************************************** + * Public Function + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mmcsd_initialize + * + * Description: + * Initialize the MMCSD device. + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int stm32_mmcsd_initialize(void) +{ + int ret; + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD + finfo("Configuring MMCSD on mikroBUS1\n"); + + ret = stm32_mmcsd_setup(&g_mb1_mmcsd); + if (ret < 0) + { + mcerr("ERROR: Failed to initialize MMCSD on mikroBus1: %d\n", ret); + } +#endif + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD + finfo("Configuring MMCSD on mikroBUS2\n"); + ret = stm32_mmcsd_setup(&g_mb2_mmcsd); + if (ret < 0) + { + mcerr("ERROR: Failed to initialize MMCSD on mikroBus2: %d\n", ret); + } +#endif + + UNUSED(ret); + return OK; +} + +/**************************************************************************** + * Name: stm32_cardinserted + * + * Description: + * Check if a card is inserted into the selected MMCSD slot + * + ****************************************************************************/ + +bool stm32_cardinserted(int slotno) +{ + struct stm32_mmcsd_state_s *state; + + /* Get the MMCSD description */ + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD + if (slotno == g_mb1_mmcsd.slotno) + { + state = &g_mb1_mmcsd; + } +#endif +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD + if (slotno == g_mb2_mmcsd.slotno) + { + state = &g_mb2_mmcsd; + } +#endif + + if (!state) + { + ferr("ERROR: No state for slotno %d\n", slotno); + return false; + } + + /* Return the state of the CD pin */ + + return stm32_cardinserted_internal(state); +} + +/***************************************************************************** + * Name: stm32_spi2register + * + * Description: + * Registers media change callback + ****************************************************************************/ + +int stm32_spi2register(struct spi_dev_s *dev, spi_mediachange_t callback, + void *arg) +{ + spiinfo("INFO: Registering spi2 device\n"); +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD + g_mb2_mmcsd.callback = callback; + g_mb2_mmcsd.cbarg = arg; +#endif + return OK; +} + +/***************************************************************************** + * Name: stm32_spi3register + * + * Description: + * Registers media change callback + ****************************************************************************/ + +int stm32_spi3register(struct spi_dev_s *dev, spi_mediachange_t callback, + void *arg) +{ + spiinfo("INFO: Registering spi3 device\n"); +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD + g_mb1_mmcsd.callback = callback; + g_mb1_mmcsd.cbarg = arg; +#endif + return OK; +} + +#endif /* CONFIG_MMCSD_SPI */ diff --git a/configs/clicker2-stm32/src/stm32_mrf24j40.c b/configs/clicker2-stm32/src/stm32_mrf24j40.c index 04737b9941f..bab336cafa1 100644 --- a/configs/clicker2-stm32/src/stm32_mrf24j40.c +++ b/configs/clicker2-stm32/src/stm32_mrf24j40.c @@ -201,7 +201,7 @@ static void stm32_enable_irq(FAR const struct mrf24j40_lower_s *lower, if (state) { - (void)stm32_gpiosetevent(priv->intcfg, true, true, true, + (void)stm32_gpiosetevent(priv->intcfg, false, true, true, priv->handler, priv->arg); } else diff --git a/configs/clicker2-stm32/src/stm32_spi.c b/configs/clicker2-stm32/src/stm32_spi.c index 319a2ae7ac9..826563e2a82 100644 --- a/configs/clicker2-stm32/src/stm32_spi.c +++ b/configs/clicker2-stm32/src/stm32_spi.c @@ -122,12 +122,47 @@ uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, uint32_t devid) void stm32_spi2select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) { spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); - /* To be provided */ + + switch (devid) + { +#ifdef CONFIG_IEEE802154_MRF24J40 + case SPIDEV_IEEE802154(0): + /* Set the GPIO low to select and high to de-select */ + + stm32_gpiowrite(GPIO_MB2_CS, !selected); + break; +#endif +#ifdef CONFIG_IEEE802154_XBEE + case SPIDEV_IEEE802154(0): + /* Set the GPIO low to select and high to de-select */ + + stm32_gpiowrite(GPIO_MB2_CS, !selected); + break; +#endif +#ifdef CONFIG_MMCSD_SPI + case SPIDEV_MMCSD(0): + /* Set the GPIO low to select and high to de-select */ + + stm32_gpiowrite(GPIO_MB2_CS, !selected); + break; +#endif + default: + break; + } } uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, uint32_t devid) { - return 0; + uint8_t status = 0; + +#ifdef CONFIG_CLICKER2_STM32_MB2_MMCSD + if (devid == SPIDEV_MMCSD(0)) + { + status = stm32_cardinserted(MB2_MMCSD_SLOTNO); + } +#endif + + return status; } #endif @@ -152,6 +187,13 @@ void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) stm32_gpiowrite(GPIO_MB1_CS, !selected); break; #endif +#ifdef CONFIG_MMCSD_SPI + case SPIDEV_MMCSD(0): + /* Set the GPIO low to select and high to de-select */ + + stm32_gpiowrite(GPIO_MB1_CS, !selected); + break; +#endif default: break; } @@ -159,7 +201,16 @@ void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, uint32_t devid) { - return 0; + uint8_t status = 0; + +#ifdef CONFIG_CLICKER2_STM32_MB1_MMCSD + if (devid == SPIDEV_MMCSD(0)) + { + status |= stm32_cardinserted(MB1_MMCSD_SLOTNO); + } +#endif + + return status; } #endif diff --git a/configs/clicker2-stm32/src/stm32_xbee.c b/configs/clicker2-stm32/src/stm32_xbee.c index 2b868a71311..1f746c9437c 100644 --- a/configs/clicker2-stm32/src/stm32_xbee.c +++ b/configs/clicker2-stm32/src/stm32_xbee.c @@ -83,6 +83,28 @@ # endif #endif +/* Reset + * + * mikroBUS1 Reset: PE7-MB1_RST + * mikroBUS2 Reset: PE13-MB2_RST + * + * Reset line must be configured for opendrain + */ + +#define GPIO_MB1_XBEE_RST (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|\ + GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN7) +#define GPIO_MB2_XBEE_RST (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|\ + GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN13) + +/* Interrupts + * + * mikroBUS1 Interrupt: PE10-MB1_INT + * mikroBUS2 Interrupt: PE14-MB2_INT + */ + +#define GPIO_MB1_XBEE_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN10) +#define GPIO_MB2_XBEE_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN14) + /**************************************************************************** * Private Types ****************************************************************************/