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:
Anthony Merlino 2017-10-11 08:15:57 +00:00 committed by Gregory Nutt
parent ed59867a16
commit dfb7ac4ed5
10 changed files with 1226 additions and 125 deletions

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View 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 */

View File

@ -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 */

View 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 */

View File

@ -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

View File

@ -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

View File

@ -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
****************************************************************************/