text: /****************************************************************************
   * config/stm3220g_eval/src/stm32_appinit.c
   *
   *   Copyright (C) 2012, 2016 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>
  
  #include <stdbool.h>
  #include <stdio.h>
  #include <syslog.h>
  #include <errno.h>
  
  #include <nuttx/board.h>
  #include <nuttx/i2c/i2c_master.h>
  
  #ifdef CONFIG_STM32_SPI1
  #  include <nuttx/spi/spi.h>
  #  include <nuttx/mtd/mtd.h>
  #endif
  
  #ifdef CONFIG_STM32_SDIO
  #  include <nuttx/sdio.h>
  #  include <nuttx/mmcsd.h>
  #endif
  
  #ifdef CONFIG_STM32_OTGFS
  #  include "stm32_usbhost.h"
  #endif
  
  #include "stm32.h"
  #include "stm32_i2c.h"
  #include "stm3220g-eval.h"
  
  /****************************************************************************
   * Pre-processor Definitions
   ****************************************************************************/
  
  /* Configuration ************************************************************/
  
  /* For now, don't build in any SPI1 support -- NSH is not using it */
  
  #undef CONFIG_STM32_SPI1
  
  /* MMCSD PORT and SLOT number probably depend on the board configuration */
  
  #define HAVE_USBDEV   1
  #define HAVE_MMCSD    1
  #define HAVE_USBHOST  1
  
  #if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != 0
  #  error "Only one MMC/SD slot"
  #  undef CONFIG_NSH_MMCSDSLOTNO
  #endif
  
  #ifndef CONFIG_NSH_MMCSDSLOTNO
  #  define CONFIG_NSH_MMCSDSLOTNO 0
  #endif
  
  /* Can't support MMC/SD features if mountpoints are disabled or if SDIO support
   * is not enabled.
   */
  
  #if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_STM32_SDIO)
  #  undef HAVE_MMCSD
  #endif
  
  #ifndef CONFIG_NSH_MMCSDMINOR
  #  define CONFIG_NSH_MMCSDMINOR 0
  #endif
  
  /* Can't support USB host or device features if USB OTG FS is not enabled */
  
  #ifndef CONFIG_STM32_OTGFS
  #  undef HAVE_USBDEV
  #  undef HAVE_USBHOST
  #endif
  
  /* Can't support USB device is USB device is not enabled */
  
  #ifndef CONFIG_USBDEV
  #  undef HAVE_USBDEV
  #endif
  
  /* Can't support USB host is USB host is not enabled */
  
  #ifndef CONFIG_USBHOST
  #  undef HAVE_USBHOST
  #endif
  
  /****************************************************************************
   * Private Functions
   ****************************************************************************/
  
  /****************************************************************************
   * Name: stm32_i2c_register
   *
   * Description:
   *   Register one I2C drivers for the I2C tool.
   *
   ****************************************************************************/
  
  #ifdef HAVE_I2CTOOL
  static void stm32_i2c_register(int bus)
  {
    FAR struct i2c_master_s *i2c;
    int ret;
  
    i2c = stm32_i2cbus_initialize(bus);
    if (i2c == NULL)
      {
        _err("ERROR: Failed to get I2C%d interface\n", bus);
      }
    else
      {
        ret = i2c_register(i2c, bus);
        if (ret < 0)
          {
            _err("ERROR: Failed to register I2C%d driver: %d\n", bus, ret);
            stm32_i2cbus_uninitialize(i2c);
          }
      }
  }
  #endif
  
  /****************************************************************************
   * Name: stm32_i2ctool
   *
   * Description:
   *   Register I2C drivers for the I2C tool.
   *
   ****************************************************************************/
  
  #ifdef HAVE_I2CTOOL
  static void stm32_i2ctool(void)
  {
  #ifdef CONFIG_STM32_I2C1
    stm32_i2c_register(1);
  #endif
  #ifdef CONFIG_STM32_I2C2
    stm32_i2c_register(2);
  #endif
  #ifdef CONFIG_STM32_I2C3
    stm32_i2c_register(3);
  #endif
  }
  #else
  #  define stm32_i2ctool()
  #endif
  
  /****************************************************************************
   * Public Functions
   ****************************************************************************/
  
  /****************************************************************************
   * Name: board_app_initialize
   *
   * Description:
   *   Perform application specific initialization.  This function is never
   *   called directly from application code, but only indirectly via the
   *   (non-standard) boardctl() interface using the command BOARDIOC_INIT.
   *
   * Input Parameters:
   *   arg - The boardctl() argument is passed to the board_app_initialize()
   *         implementation without modification.  The argument has no
   *         meaning to NuttX; the meaning of the argument is a contract
   *         between the board-specific initalization logic and the
   *         matching application logic.  The value cold be such things as a
   *         mode enumeration value, a set of DIP switch switch settings, a
   *         pointer to configuration data read from a file or serial FLASH,
   *         or whatever you would like to do with it.  Every implementation
   *         should accept zero/NULL as a default configuration.
   *
   * Returned Value:
   *   Zero (OK) is returned on success; a negated errno value is returned on
   *   any failure to indicate the nature of the failure.
   *
   ****************************************************************************/
  
  int board_app_initialize(uintptr_t arg)
  {
  #ifdef CONFIG_STM32_SPI1
    FAR struct spi_dev_s *spi;
    FAR struct mtd_dev_s *mtd;
  #endif
  #ifdef HAVE_MMCSD
    FAR struct sdio_dev_s *sdio;
  #endif
    int ret;
  
    /* Register I2C drivers on behalf of the I2C tool */
  
    stm32_i2ctool();
  
    /* Configure SPI-based devices */
  
  #ifdef CONFIG_STM32_SPI1
    /* Get the SPI port */
  
    spi = stm32_spibus_initialize(1);
    if (!spi)
      {
        syslog(LOG_ERR, "ERROR: Failed to initialize SPI port 0\n");
        return -ENODEV;
      }
  
    /* Now bind the SPI interface to the M25P64/128 SPI FLASH driver */
  
    mtd = m25p_initialize(spi);
    if (!mtd)
      {
        syslog(LOG_ERR, "ERROR: Failed to bind SPI port 0 to the SPI FLASH driver\n");
        return -ENODEV;
      }
  
  #warning "Now what are we going to do with this SPI FLASH driver?"
  #endif
  
    /* Mount the SDIO-based MMC/SD block driver */
  
  #ifdef HAVE_MMCSD
    /* First, get an instance of the SDIO interface */
  
    sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO);
    if (!sdio)
      {
        syslog(LOG_ERR, "ERROR: Failed to initialize SDIO slot %d\n",
               CONFIG_NSH_MMCSDSLOTNO);
        return -ENODEV;
      }
  
    /* Now bind the SDIO interface to the MMC/SD driver */
  
    ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, 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.  I need to check to
     * see if the STM3220G-EVAL board supports a GPIO to detect if there is a card in
     * the slot.
     */
  
     sdio_mediachange(sdio, true);
  #endif
  
    /* Initialize USB host operation.  stm32_usbhost_initialize() starts a thread
     * will monitor for USB connection and disconnection events.
     */
  
  #ifdef HAVE_USBHOST
    ret = stm32_usbhost_initialize();
    if (ret != OK)
      {
        syslog(LOG_ERR, "ERROR: Failed to initialize USB host: %d\n", ret);
        return ret;
      }
  #endif
  
  #ifdef CONFIG_PWM
    /* Initialize PWM and register the PWM device. */
  
    ret = stm32_pwm_setup();
    if (ret < 0)
      {
        syslog(LOG_ERR, "ERROR: stm32_pwm_setup() failed: %d\n", ret);
      }
  #endif
  
  #ifdef CONFIG_ADC
    /* Initialize ADC and register the ADC driver. */
  
    ret = stm32_adc_setup();
    if (ret < 0)
      {
        syslog(LOG_ERR, "ERROR: stm32_adc_setup failed: %d\n", ret);
      }
  #endif
  
  #ifdef CONFIG_CAN
    /* Initialize CAN and register the CAN driver. */
  
    ret = stm32_can_setup();
    if (ret < 0)
      {
        syslog(LOG_ERR, "ERROR: stm32_can_setup failed: %d\n", ret);
      }
  #endif
  
    UNUSED(ret);
    return OK;
  }
  