Merged in antmerlino/nuttx/clicker2 (pull request #507)
clicker2-stm32: Adds SD card, automount, and syslog file support and fixes a few minor issues * configs/clicker2-stm32: Moves defines for xbee from clicker2-stm32.h to stm32_xbee.h * configs/clicker2-stm32: Adds support for uSD click boards and automount support * configs/clicker2-stm32: Fixes minor guard clause * clicker2-stm32: Bring-up automounter before MMCSD * clicker2-stm32: MRF24J40 interrupt should only fire on falling edge. * clicker2-stm32: Adds file syslog support for logging to file on SD card Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
parent
ed59867a16
commit
dfb7ac4ed5
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -41,7 +41,10 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <nuttx/syslog/syslog.h>
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#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 */
|
||||
|
391
configs/clicker2-stm32/src/stm32_automount.c
Normal file
391
configs/clicker2-stm32/src/stm32_automount.c
Normal file
@ -0,0 +1,391 @@
|
||||
/************************************************************************************
|
||||
* configs/clicker2-stm32/src/stm32_automount.c
|
||||
*
|
||||
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||
* Author: Anthony Merlino <anthony@vergeaero.com>
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* 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 <nuttx/config.h>
|
||||
|
||||
#if defined(CONFIG_FS_AUTOMOUNTER_DEBUG) && !defined(CONFIG_DEBUG_FS)
|
||||
# define CONFIG_DEBUG_FS 1
|
||||
#endif
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/fs/automount.h>
|
||||
|
||||
#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 */
|
@ -46,7 +46,6 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
#include <nuttx/input/buttons.h>
|
||||
|
||||
#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 */
|
||||
|
||||
|
428
configs/clicker2-stm32/src/stm32_mmcsd.c
Normal file
428
configs/clicker2-stm32/src/stm32_mmcsd.c
Normal file
@ -0,0 +1,428 @@
|
||||
/****************************************************************************
|
||||
* configs/clicker2-stm32/src/stm32_mmcsd.c
|
||||
*
|
||||
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||
* Author: Anthony Merlino <anthony@vergeaero.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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
#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 */
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user