예제 #1
0
void platform_init_external_devices( void )
{
    //wiced_bool_t button1_pressed;

    /* Initialise buttons to input by default */
    platform_gpio_init( &platform_gpio_pins[BTN1], INPUT_PULL_UP );
#if 0
    button1_pressed = wiced_gpio_input_get( BTN1 ) ? WICED_FALSE : WICED_TRUE;  /* The button has inverse logic */
    if ( button1_pressed != WICED_TRUE )
    {
        platform_gpio_init( &platform_gpio_pins[LED], OUTPUT_PUSH_PULL );
        platform_gpio_output_high( &platform_gpio_pins[LED] );
    }
#endif

    /* Initialise LEDs and turn off by default */
    platform_gpio_init( &platform_gpio_pins[LED_R], OUTPUT_PUSH_PULL );
    platform_gpio_init( &platform_gpio_pins[LED_G], OUTPUT_PUSH_PULL );
    platform_gpio_init( &platform_gpio_pins[LED_B], OUTPUT_PUSH_PULL );
    platform_gpio_output_high( &platform_gpio_pins[LED_R] );
    platform_gpio_output_high( &platform_gpio_pins[LED_G] );
    platform_gpio_output_high( &platform_gpio_pins[LED_B] );

#ifndef WICED_DISABLE_STDIO
    /* Initialise UART standard I/O */
    platform_stdio_init( &platform_uart_drivers[STDIO_UART], &platform_uart_peripherals[STDIO_UART], &stdio_config );
#endif
}
예제 #2
0
OSStatus host_platform_bus_deinit( void )
{
  platform_mcu_powersave_disable( );
  
  NVIC_DisableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] );
  pdc_disable_transfer( spi_get_pdc_base( wifi_spi.port ), PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );
  spi_disable(wifi_spi.port);
  
  /* Deinit the SPI lines */
  platform_gpio_peripheral_pin_init(  wifi_spi.mosi_pin,  INPUT_HIGH_IMPEDANCE );
  platform_gpio_peripheral_pin_init(  wifi_spi.miso_pin,  INPUT_HIGH_IMPEDANCE );
  platform_gpio_peripheral_pin_init(  wifi_spi.clock_pin, INPUT_HIGH_IMPEDANCE );
  
  /* Deinit the interrupt input for WLAN_IRQ */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
  platform_gpio_irq_disable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ] );
  
  /* Deinit SPI slave select GPIOs */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], INPUT_HIGH_IMPEDANCE );
  
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], INPUT_HIGH_IMPEDANCE );
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], INPUT_HIGH_IMPEDANCE );
#endif
  
  platform_mcu_powersave_enable( );
  
  return kNoErr;
}
예제 #3
0
wwd_result_t host_platform_bus_init( void )
{
    if ( sdio_bus_initted == WICED_FALSE )
    {
        uint8_t a = 0;

        platform_mcu_powersave_disable();

        /* SDIO bootstrapping: GPIO0 = 0 and GPIO1 = 0 */

#ifdef WICED_WIFI_USE_GPIO_FOR_BOOTSTRAP
        platform_gpio_init( &wifi_control_pins[WWD_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
        platform_gpio_output_low( &wifi_control_pins[WWD_PIN_BOOTSTRAP_0] );

        platform_gpio_init( &wifi_control_pins[WWD_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
        platform_gpio_output_low( &wifi_control_pins[WWD_PIN_BOOTSTRAP_1] );
#endif /* WICED_WIFI_USE_GPIO_FOR_BOOTSTRAP */
        /* Setup SDIO pins */
        for ( a = WWD_PIN_SDIO_CLK; a < WWD_PIN_SDIO_MAX; a++ )
        {
            if( a == WWD_PIN_SDIO_OOB_IRQ )
            {
                platform_gpio_peripheral_pin_init( &wifi_sdio_pins[a], 0 );
            }
            else
            {
                platform_gpio_peripheral_pin_init( &wifi_sdio_pins[a], ( IOPORT_MODE_MUX_C | IOPORT_MODE_PULLUP ));
            }
        }

        /* Enable the MCI peripheral */
        sysclk_enable_peripheral_clock( ID_HSMCI );

        HSMCI->HSMCI_CR = HSMCI_CR_SWRST;

        MCI_Disable( HSMCI );

        MCI_Init( &sdio_driver, HSMCI, ID_HSMCI, CPU_CLOCK_HZ );

        /* Enable SDIO interrupt */
        /* Priority must be set in platform.c file function platform_init_peripheral_irq_priorities */
        /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
        /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
//        NVIC_SetPriority( HSMCI_IRQn, SAM4S_SDIO_IRQ_PRIO );
        NVIC_EnableIRQ( HSMCI_IRQn );

//        host_rtos_init_semaphore( &sdio_transfer_done_semaphore );

//        enable_sdio_block_transfer_done_irq();

        platform_mcu_powersave_enable();

        sdio_bus_initted = WICED_TRUE;
    }
    return WICED_SUCCESS;
}
OSStatus host_platform_init( void )
{
    host_platform_deinit_wlan_powersave_clock( );

#if defined ( MICO_USE_WIFI_RESET_PIN )
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_RESET], OUTPUT_PUSH_PULL );
    host_platform_reset_wifi( true );  /* Start wifi chip in reset */
#endif
    
#if defined ( MICO_USE_WIFI_POWER_PIN )
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_POWER], OUTPUT_PUSH_PULL );
    host_platform_power_wifi( false ); /* Start wifi chip with regulators off */
#endif

    return kNoErr;
}
예제 #5
0
void platform_init_external_devices( void )
{
    /* Initialise LEDs and turn off by default */
    platform_gpio_init( &platform_gpio_pins[WICED_LED1], OUTPUT_PUSH_PULL );
    platform_gpio_init( &platform_gpio_pins[WICED_LED2], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED1] );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED2] );

    /* Initialise buttons to input by default */
    platform_gpio_init( &platform_gpio_pins[WICED_BUTTON1], INPUT_PULL_UP );
    platform_gpio_init( &platform_gpio_pins[WICED_BUTTON2], INPUT_PULL_UP );

#ifndef WICED_DISABLE_STDIO
    /* Initialise UART standard I/O */
    platform_stdio_init( &platform_uart_drivers[STDIO_UART], &platform_uart_peripherals[STDIO_UART], &stdio_config );
#endif
}
예제 #6
0
void platform_init_external_devices( void )
{
    /*  This function initializes the external interfaces for the platform.
        You could use this to initialize the peripherals you use.
        Note however that if you initialize alternative functionality of 
        JTAG and UART pins, you could lock yourself out of being able to flash
        new firmware.
        Also, if WICED_BUTTON1 and WICED_BUTTON2 are not available, you are
        unable to use the bootloader patch to halt execution in the bootloader,
        a meathod to allow you to use JTAG for flashing even if you use those
        pins for other things.
    */

    /* Initialise LEDs and turn off by default */
    platform_gpio_init( &platform_gpio_pins[WICED_LED1], OUTPUT_PUSH_PULL );
    platform_gpio_init( &platform_gpio_pins[WICED_LED2], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED1] );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED2] );

    /* Initialise buttons to input by default */
    platform_gpio_init( &platform_gpio_pins[WICED_BUTTON1], INPUT_PULL_UP );
    platform_gpio_init( &platform_gpio_pins[WICED_BUTTON2], INPUT_PULL_UP );
    //platform_gpio_init( &platform_gpio_pins[WICED_SWITCH1], INPUT_PULL_UP );
    platform_gpio_init( &platform_gpio_pins[WICED_SWITCH2], INPUT_PULL_UP );
    platform_gpio_init( &platform_gpio_pins[WICED_SWITCH3], INPUT_PULL_UP );
    platform_gpio_init( &platform_gpio_pins[WICED_SWITCH4], INPUT_PULL_UP );


#ifndef WICED_DISABLE_STDIO
    /* Initialise UART standard I/O */
    platform_stdio_init( &platform_uart_drivers[STDIO_UART], &platform_uart_peripherals[STDIO_UART], &stdio_config );
#endif
}
예제 #7
0
wwd_result_t host_platform_bus_init( void )
{
    /* Setup the interrupt input for WLAN_IRQ */
    platform_gpio_init( &wifi_spi_pins[WWD_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
    //platform_gpio_irq_enable( &wifi_control_pins[WWD_PIN_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 );

#ifdef WICED_WIFI_USE_GPIO_FOR_BOOTSTRAP_0
    /* Set GPIO_B[1:0] to 01 to put WLAN module into gSPI mode */
    platform_gpio_init( &wifi_control_pins[WWD_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
    platform_gpio_output_high( &wifi_control_pins[WWD_PIN_BOOTSTRAP_0] );
#endif
#ifdef WICED_WIFI_USE_GPIO_FOR_BOOTSTRAP_1
    platform_gpio_init( &wifi_control_pins[WWD_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &wifi_control_pins[WWD_PIN_BOOTSTRAP_1] );
    #endif

    return WICED_SUCCESS;
}
예제 #8
0
void
initarm_gpio_init(void)
{

	/*
	 * Set initial values of GPIO output ports
	 */
	platform_gpio_init();
}
OSStatus host_platform_deinit_wlan_powersave_clock( void )
{
#ifndef MICO_USE_WIFI_32K_PIN
    return kNoErr;
#else
    /* Tie the pin to ground */
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_32K_CLK], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_32K_CLK] );
    return kNoErr;
#endif
}
예제 #10
0
void platform_init_external_devices( void )
{
    /* Initialise wake up pin */
    platform_gpio_init( &platform_gpio_pins[WICED_GPIO_11], INPUT_HIGH_IMPEDANCE );
    platform_wakeup_pin_enable( platform_gpio_pins[WICED_GPIO_11].pin, WAKEUP_PIN_ACTIVE_HIGH );

    /* Initialise LEDs and turn off by default */
    platform_gpio_init( &platform_gpio_pins[WICED_LED1], OUTPUT_PUSH_PULL );
    platform_gpio_init( &platform_gpio_pins[WICED_LED2], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED1] );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED2] );

    /* Initialise buttons to input by default */
    platform_gpio_init( &platform_gpio_pins[WICED_BUTTON1], INPUT_PULL_UP );
    platform_gpio_init( &platform_gpio_pins[WICED_BUTTON2], INPUT_PULL_UP );

#ifndef WICED_DISABLE_STDIO
    /* Initialise UART standard I/O */
    platform_stdio_init( &platform_uart_drivers[STDIO_UART], &platform_uart_peripherals[STDIO_UART], &stdio_config );
#endif
}
OSStatus host_platform_bus_deinit( void )
{
    uint32_t         a;

    platform_mcu_powersave_disable();

    /* Disable SPI and SPI DMA */
    SPI_Cmd( wifi_spi.port, DISABLE );
    SPI_I2S_DeInit( wifi_spi.port );
    SPI_I2S_DMACmd( wifi_spi.port, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE );
    DMA_DeInit( wifi_spi.tx_dma.stream );
    DMA_DeInit( wifi_spi.rx_dma.stream );

#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
    /* Clear GPIO_B[1:0] */
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], INPUT_HIGH_IMPEDANCE );
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], INPUT_HIGH_IMPEDANCE );
#endif

    /* Clear SPI slave select GPIOs */
    platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], INPUT_HIGH_IMPEDANCE );

    /* Clear the SPI lines */
    for ( a = WIFI_PIN_SPI_CLK; a < WIFI_PIN_SPI_MAX; a++ )
    {
        platform_gpio_init( &wifi_spi_pins[ a ], INPUT_HIGH_IMPEDANCE );
    }

    platform_gpio_irq_disable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ] );
    platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );

    /* Disable SPI_SLAVE Periph clock and DMA1 clock */
    (wifi_spi.peripheral_clock_func)( wifi_spi.peripheral_clock_reg, DISABLE );
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, DISABLE );

    platform_mcu_powersave_enable();

    return kNoErr;
}
예제 #12
0
void platform_init_external_devices( void )
{
    /*  This function initializes the external interfaces for the platform.
        You could use this to initialize the peripherals you use.
        Note however that if you initialize alternative functionality of 
        JTAG and UART pins, you could lock yourself out of being able to flash
        new firmware.
    */

    //patch added to resolve the microseconds delay hang issue.
    do
    {
        // enable DWT hardware and cycle counting
        CoreDebug->DEMCR = CoreDebug->DEMCR | CoreDebug_DEMCR_TRCENA_Msk;
        // reset a counter
        DWT->CYCCNT = 0;
        // enable the counter
        DWT->CTRL = (DWT->CTRL | DWT_CTRL_CYCCNTENA_Msk) ;
    }
    while(0);

    /* Initialise button to input by default */
    platform_gpio_init( &platform_gpio_pins[WICED_BUTTON1], INPUT_PULL_UP );

#ifndef GPIO_LED_NOT_SUPPORTED
    /* Initialise LEDs and turn off by default */
    platform_gpio_init( &platform_gpio_pins[WICED_LED1], OUTPUT_PUSH_PULL );
    platform_gpio_init( &platform_gpio_pins[WICED_LED2], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED1] );
    platform_gpio_output_low( &platform_gpio_pins[WICED_LED2] );
#endif

#ifndef WICED_DISABLE_STDIO
    /* Initialise UART standard I/O */
    platform_stdio_init( &platform_uart_drivers[STDIO_UART], &platform_uart_peripherals[STDIO_UART], &stdio_config );
#endif
}
예제 #13
0
uint32_t  platform_get_factory_reset_button_time ( uint32_t max_time )
{
    uint32_t button_press_timer = 0;
    int led_state = 0;

    /* Initialise input */
     platform_gpio_init( &platform_gpio_pins[ PLATFORM_FACTORY_RESET_BUTTON_GPIO ], INPUT_PULL_UP );

     while ( (PLATFORM_FACTORY_RESET_PRESSED_STATE == platform_gpio_input_get(&platform_gpio_pins[ PLATFORM_FACTORY_RESET_BUTTON_GPIO ])) )
    {
         /* How long is the "Factory Reset" button being pressed. */
         host_rtos_delay_milliseconds( PLATFORM_FACTORY_RESET_CHECK_PERIOD );

         /* Toggle LED every PLATFORM_FACTORY_RESET_CHECK_PERIOD  */
        if ( led_state == 0 )
        {
            platform_gpio_output_high( &platform_gpio_pins[ PLATFORM_FACTORY_RESET_LED_GPIO ] );
            led_state = 1;
        }
        else
        {
            platform_gpio_output_low( &platform_gpio_pins[ PLATFORM_FACTORY_RESET_LED_GPIO ] );
            led_state = 0;
        }

        button_press_timer += PLATFORM_FACTORY_RESET_CHECK_PERIOD;
        if ((max_time > 0) && (button_press_timer >= max_time))
        {
            break;
        }
    }

     /* turn off the LED */
     if (PLATFORM_FACTORY_RESET_LED_ON_STATE == 1)
     {
         platform_gpio_output_low( &platform_gpio_pins[ PLATFORM_FACTORY_RESET_LED_GPIO ] );
     }
     else
     {
         platform_gpio_output_high( &platform_gpio_pins[ PLATFORM_FACTORY_RESET_LED_GPIO ] );
     }

    return button_press_timer;
}
예제 #14
0
platform_result_t platform_spi_init( const platform_spi_t* spi, const platform_spi_config_t* config )
{
    UNUSED_PARAMETER(spi);
    UNUSED_PARAMETER(config);

    platform_mcu_powersave_disable( );

    Pdc* spi_pdc = spi_get_pdc_base( spi->peripheral );

    /* Setup chip select pin */
    platform_gpio_init( config->chip_select, OUTPUT_PUSH_PULL );
    platform_gpio_output_high( config->chip_select );

    /* Setup other pins */
    platform_gpio_peripheral_pin_init( spi->mosi_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) );
    platform_gpio_peripheral_pin_init( spi->miso_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) );
    platform_gpio_peripheral_pin_init( spi->clk_pin,  ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP )  );

    /* Configure an SPI peripheral. */
    pmc_enable_periph_clk( spi->peripheral_id );
    spi_disable( spi->peripheral );
    spi_reset( spi->peripheral );
    spi_set_lastxfer( spi->peripheral );
    spi_set_master_mode( spi->peripheral );
    spi_disable_mode_fault_detect( spi->peripheral );
    spi_set_peripheral_chip_select_value( spi->peripheral, 0 );

    spi_set_clock_polarity( spi->peripheral, 0, ( ( config->mode && SPI_CLOCK_IDLE_HIGH )   ? (1) : (0) ) );
    spi_set_clock_phase( spi->peripheral, 0,    ( ( config->mode && SPI_CLOCK_RISING_EDGE ) ? (1) : (0) ) );

    spi_set_bits_per_transfer( spi->peripheral, 0, SPI_CSR_BITS_8_BIT );
    spi_set_baudrate_div( spi->peripheral, 0, (uint8_t)( CPU_CLOCK_HZ / config->speed ) );
    spi_set_transfer_delay( spi->peripheral, 0, 0, 0 );
    spi_enable( spi->peripheral );
    pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );

    platform_mcu_powersave_enable( );

    return PLATFORM_SUCCESS;
}
예제 #15
0
static int
mv_gpio_attach(device_t dev)
{
	int error, i;
	struct mv_gpio_softc *sc;
	uint32_t dev_id, rev_id;

	sc = (struct mv_gpio_softc *)device_get_softc(dev);
	if (sc == NULL)
		return (ENXIO);

	mv_gpio_softc = sc;

	/* Get chip id and revision */
	soc_id(&dev_id, &rev_id);

	if (dev_id == MV_DEV_88F5182 ||
	    dev_id == MV_DEV_88F5281 ||
	    dev_id == MV_DEV_MV78100 ||
	    dev_id == MV_DEV_MV78100_Z0 ) {
		sc->pin_num = 32;
		sc->irq_num = 4;

	} else if (dev_id == MV_DEV_88F6281 ||
	    dev_id == MV_DEV_88F6282) {
		sc->pin_num = 50;
		sc->irq_num = 7;

	} else {
		device_printf(dev, "unknown chip id=0x%x\n", dev_id);
		return (ENXIO);
	}

	error = bus_alloc_resources(dev, mv_gpio_res, sc->res);
	if (error) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	sc->bst = rman_get_bustag(sc->res[0]);
	sc->bsh = rman_get_bushandle(sc->res[0]);

	/* Disable and clear all interrupts */
	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_EDGE_MASK, 0);
	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_LEV_MASK, 0);
	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_CAUSE, 0);

	if (sc->pin_num > GPIO_PINS_PER_REG) {
		bus_space_write_4(sc->bst, sc->bsh,
		    GPIO_HI_INT_EDGE_MASK, 0);
		bus_space_write_4(sc->bst, sc->bsh,
		    GPIO_HI_INT_LEV_MASK, 0);
		bus_space_write_4(sc->bst, sc->bsh,
		    GPIO_HI_INT_CAUSE, 0);
	}

	for (i = 0; i < sc->irq_num; i++) {
		if (bus_setup_intr(dev, sc->res[1 + i],
		    INTR_TYPE_MISC, mv_gpio_intr, NULL,
		    sc, &sc->ih_cookie[i]) != 0) {
			bus_release_resources(dev, mv_gpio_res, sc->res);
			device_printf(dev, "could not set up intr %d\n", i);
			return (ENXIO);
		}
	}

	return (platform_gpio_init());
}
예제 #16
0
wiced_result_t bluetooth_wiced_init_platform( void )
{
    if ( wiced_bt_control_pins[ WICED_BT_PIN_HOST_WAKE ] != NULL )
    {
        RETURN_IF_FAILURE( platform_gpio_init( wiced_bt_control_pins[WICED_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE ) );
    }

    if ( wiced_bt_control_pins[ WICED_BT_PIN_DEVICE_WAKE ] != NULL )
    {
        RETURN_IF_FAILURE( platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_DEVICE_WAKE ], OUTPUT_PUSH_PULL ) );
        RETURN_IF_FAILURE( platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_DEVICE_WAKE ] ) );
        wiced_rtos_delay_milliseconds( 100 );
    }

    /* Configure Reg Enable pin to output. Set to HIGH */
    if ( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] != NULL )
    {
        RETURN_IF_FAILURE( platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_POWER ], OUTPUT_OPEN_DRAIN_PULL_UP ) );
        RETURN_IF_FAILURE( platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ) );
    }

    if ( wiced_bt_uart_config.flow_control == FLOW_CONTROL_DISABLED )
    {
        /* Configure RTS pin to output. Set to HIGH */
        RETURN_IF_FAILURE( platform_gpio_init( wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_OPEN_DRAIN_PULL_UP ) );
        RETURN_IF_FAILURE( platform_gpio_output_high( wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS] ) );

        /* Configure CTS pin to input pull-up */
        RETURN_IF_FAILURE( platform_gpio_init( wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS], INPUT_PULL_UP ) );
    }

    if ( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] != NULL )
    {
        RETURN_IF_FAILURE( platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_RESET ], OUTPUT_PUSH_PULL ) );
        RETURN_IF_FAILURE( platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ) );

        /* Configure USART comms */
        RETURN_IF_FAILURE( bluetooth_wiced_init_config_uart( &wiced_bt_uart_config ) );

        /* Reset bluetooth chip */
        RETURN_IF_FAILURE( platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ) );
        wiced_rtos_delay_milliseconds( 10 );
        RETURN_IF_FAILURE( platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ) );
    }
    else
    {
        /* Configure USART comms */
        RETURN_IF_FAILURE( bluetooth_wiced_init_config_uart( &wiced_bt_uart_config ) );
    }

    wiced_rtos_delay_milliseconds( BLUETOOTH_CHIP_STABILIZATION_DELAY );

    if ( wiced_bt_uart_config.flow_control == FLOW_CONTROL_DISABLED )
    {
        /* Bluetooth chip is ready. Pull host's RTS low */
        RETURN_IF_FAILURE( platform_gpio_output_low( wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS] ) );
    }

    /* Wait for Bluetooth chip to pull its RTS (host's CTS) low. From observation using CRO, it takes the bluetooth chip > 170ms to pull its RTS low after CTS low */
    while ( platform_gpio_input_get( wiced_bt_uart_pins[ WICED_BT_PIN_UART_CTS ] ) == WICED_TRUE )
    {
        wiced_rtos_delay_milliseconds( 10 );
    }
    return WICED_SUCCESS;
}
예제 #17
0
OSStatus platform_spi_init( platform_spi_driver_t* driver, const platform_spi_t* peripheral, const platform_spi_config_t* config )
{
  SPI_InitTypeDef   spi_init;
  OSStatus          err;
  
  platform_mcu_powersave_disable();
  
  require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);

/* Calculate prescaler */
  err = calculate_prescaler( config->speed, &spi_init.SPI_BaudRatePrescaler );
  require_noerr(err, exit);
      
  /* Configure data-width */
  if ( config->bits == 8 )
  {
    spi_init.SPI_DataSize = SPI_DataSize_8b;
  }
  else if ( config->bits == 16 )
  {
    require_action( !(config->mode & SPI_USE_DMA), exit, err = kUnsupportedErr);
    spi_init.SPI_DataSize = SPI_DataSize_16b;
  }
  else
  {
    err = kUnsupportedErr;
    goto exit;
  }
  
  /* Configure MSB or LSB */
  if ( config->mode & SPI_MSB_FIRST )
  {
    spi_init.SPI_FirstBit = SPI_FirstBit_MSB;
  }
  else
  {
    spi_init.SPI_FirstBit = SPI_FirstBit_LSB;
  }
  
  /* Configure mode CPHA and CPOL */
  if ( config->mode & SPI_CLOCK_IDLE_HIGH )
  {
    spi_init.SPI_CPOL = SPI_CPOL_High;
  }
  else
  {
    spi_init.SPI_CPOL = SPI_CPOL_Low;
  }
  
  if ( config->mode & SPI_CLOCK_RISING_EDGE )
  {
    spi_init.SPI_CPHA = ( config->mode & SPI_CLOCK_IDLE_HIGH ) ? SPI_CPHA_2Edge : SPI_CPHA_1Edge;
  }
  else
  {
    spi_init.SPI_CPHA = ( config->mode & SPI_CLOCK_IDLE_HIGH ) ? SPI_CPHA_1Edge : SPI_CPHA_2Edge;
  }

  driver->peripheral = (platform_spi_t *)peripheral;
    
  /* Init SPI GPIOs */
  platform_gpio_set_alternate_function( peripheral->pin_clock->port, peripheral->pin_clock->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, peripheral->gpio_af );
  platform_gpio_set_alternate_function( peripheral->pin_mosi->port,  peripheral->pin_mosi->pin_number,  GPIO_OType_PP, GPIO_PuPd_NOPULL, peripheral->gpio_af );
  platform_gpio_set_alternate_function( peripheral->pin_miso->port,  peripheral->pin_miso->pin_number,  GPIO_OType_PP, GPIO_PuPd_UP, peripheral->gpio_af );
  
  /* Init the chip select GPIO */
  platform_gpio_init( config->chip_select, OUTPUT_PUSH_PULL );
  platform_gpio_output_high( config->chip_select );
  
  
  /* Enable SPI peripheral clock */
  (peripheral->peripheral_clock_func)( peripheral->peripheral_clock_reg, ENABLE );
  (peripheral->peripheral_clock_func)( peripheral->peripheral_clock_reg, ENABLE );
  
  SPI_I2S_DeInit( peripheral->port );
  
  spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  spi_init.SPI_Mode      = SPI_Mode_Master;
  spi_init.SPI_NSS       = SPI_NSS_Soft;
  spi_init.SPI_CRCPolynomial = 0x7; /* reset value */
  SPI_CalculateCRC( peripheral->port, DISABLE );
  
  /* Init and enable SPI */
  SPI_Init( peripheral->port, &spi_init );
  
  SPI_I2S_DMACmd( peripheral->port, SPI_I2S_DMAReq_Rx, DISABLE );
  SPI_I2S_DMACmd( peripheral->port, SPI_I2S_DMAReq_Tx, DISABLE );
  
  SPI_Cmd ( peripheral->port, ENABLE );
  
  if ( config->mode & SPI_USE_DMA ){
    DMA_DeInit( peripheral->rx_dma.stream );
    DMA_DeInit( peripheral->tx_dma.stream );
    
    if ( peripheral->tx_dma.controller == DMA1 )
    {
      RCC->AHB1ENR |= RCC_AHB1Periph_DMA1;
    }
    else
    {
      RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
    }
    
     if ( peripheral->rx_dma.controller == DMA1 )
    {
      RCC->AHB1ENR |= RCC_AHB1Periph_DMA1;
    }
    else
    {
      RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
    }
    SPI_I2S_DMACmd( peripheral->port, SPI_I2S_DMAReq_Rx, ENABLE );
    SPI_I2S_DMACmd( peripheral->port, SPI_I2S_DMAReq_Tx, ENABLE );
  }

exit:
  platform_mcu_powersave_enable();
  return err;
}
예제 #18
0
OSStatus host_enable_oob_interrupt( void )
{
    platform_gpio_init( &wifi_sdio_pins[WIFI_PIN_SDIO_OOB_IRQ], INPUT_HIGH_IMPEDANCE );
    platform_gpio_irq_enable( &wifi_sdio_pins[WIFI_PIN_SDIO_OOB_IRQ], IRQ_TRIGGER_RISING_EDGE, sdio_oob_irq_handler, 0 );
    return kNoErr;
}
예제 #19
0
OSStatus host_platform_bus_init( void )
{
    SDIO_InitTypeDef sdio_init_structure;
    OSStatus         result;
    uint8_t          a;

    platform_mcu_powersave_disable();

    result = mico_rtos_init_semaphore( &sdio_transfer_finished_semaphore, 1 );
    if ( result != kNoErr )
    {
        return result;
    }

    /* Turn on SDIO IRQ */
    SDIO->ICR = (uint32_t) 0xffffffff;

    /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
    /* otherwise FreeRTOS will not be able to mask the interrupt */
    /* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */
    /* is the lowest priority */
    NVIC_EnableIRQ( SDIO_IRQ_CHANNEL );
    NVIC_EnableIRQ( DMA2_3_IRQ_CHANNEL );
    
    /* Set GPIO_B[1:0] to 00 to put WLAN module into SDIO mode */
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] );
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] );
#endif

    /* Setup GPIO pins for SDIO data & clock */
    for ( a = WIFI_PIN_SDIO_CLK; a < WIFI_PIN_SDIO_MAX; a++ )
    {
        platform_gpio_set_alternate_function( wifi_sdio_pins[ a ].port, wifi_sdio_pins[ a ].pin_number, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SDIO );
    }

#ifdef SDIO_1_BIT
    platform_gpio_init( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ], INPUT_PULL_UP );
    platform_gpio_irq_enable( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ], IRQ_TRIGGER_FALLING_EDGE, sdio_int_pin_irq_handler, 0 );
#endif

    /*!< Enable the SDIO AHB Clock and the DMA2 Clock */
    RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA2, ENABLE );
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_SDIO, ENABLE );

    SDIO_DeInit( );
    sdio_init_structure.SDIO_ClockDiv            = (uint8_t) 120; /* 0x78, clock is taken from the high speed APB bus ; */ /* About 400KHz */
    sdio_init_structure.SDIO_ClockEdge           = SDIO_ClockEdge_Rising;
    sdio_init_structure.SDIO_ClockBypass         = SDIO_ClockBypass_Disable;
    sdio_init_structure.SDIO_ClockPowerSave      = SDIO_ClockPowerSave_Enable;
    sdio_init_structure.SDIO_BusWide             = SDIO_BusWide_1b;
    sdio_init_structure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
    SDIO_Init( &sdio_init_structure );
    SDIO_SetPowerState( SDIO_PowerState_ON );
    SDIO_SetSDIOReadWaitMode( SDIO_ReadWaitMode_CLK );
    SDIO_ClockCmd( ENABLE );

    platform_mcu_powersave_enable();

    return kNoErr;
}
예제 #20
0
platform_result_t platform_spi_init( const platform_spi_t* spi, const platform_spi_config_t* config )
{
    SPI_InitTypeDef   spi_init;
    platform_result_t result;
    uint8_t           spi_number;

    wiced_assert( "bad argument", ( spi != NULL ) && ( config != NULL ) );

    platform_mcu_powersave_disable();

    spi_number = platform_spi_get_port_number( spi->port );

    /* Init SPI GPIOs */
    platform_gpio_set_alternate_function( spi->pin_clock->port, spi->pin_clock->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, spi->gpio_af );
    platform_gpio_set_alternate_function( spi->pin_mosi->port,  spi->pin_mosi->pin_number,  GPIO_OType_PP, GPIO_PuPd_NOPULL, spi->gpio_af );
    platform_gpio_set_alternate_function( spi->pin_miso->port,  spi->pin_miso->pin_number,  GPIO_OType_PP, GPIO_PuPd_NOPULL, spi->gpio_af );

    /* Init the chip select GPIO */
    platform_gpio_init( config->chip_select, OUTPUT_PUSH_PULL );
    platform_gpio_output_high( config->chip_select );

    /* Calculate prescaler */
    result = calculate_prescaler( config->speed, &spi_init.SPI_BaudRatePrescaler );
    if ( result != PLATFORM_SUCCESS )
    {
        platform_mcu_powersave_enable();
        return result;
    }

    /* Configure data-width */
    if ( config->bits == 8 )
    {
        spi_init.SPI_DataSize = SPI_DataSize_8b;
    }
    else if ( config->bits == 16 )
    {
        if ( config->mode & SPI_USE_DMA )
        {
            platform_mcu_powersave_enable();

            /* 16 bit mode is not supported for a DMA */
            return PLATFORM_UNSUPPORTED;
        }

        spi_init.SPI_DataSize = SPI_DataSize_16b;
    }
    else
    {
        platform_mcu_powersave_enable();

        /* Requested mode is not supported */
        return PLATFORM_UNSUPPORTED;
    }

    /* Configure MSB or LSB */
    if ( config->mode & SPI_MSB_FIRST )
    {
        spi_init.SPI_FirstBit = SPI_FirstBit_MSB;
    }
    else
    {
        spi_init.SPI_FirstBit = SPI_FirstBit_LSB;
    }

    /* Configure mode CPHA and CPOL */
    if ( config->mode & SPI_CLOCK_IDLE_HIGH )
    {
        spi_init.SPI_CPOL = SPI_CPOL_High;
    }
    else
    {
        spi_init.SPI_CPOL = SPI_CPOL_Low;
    }

    if ( config->mode & SPI_CLOCK_RISING_EDGE )
    {
        spi_init.SPI_CPHA = ( config->mode & SPI_CLOCK_IDLE_HIGH ) ? SPI_CPHA_2Edge : SPI_CPHA_1Edge;
    }
    else
    {
        spi_init.SPI_CPHA = ( config->mode & SPI_CLOCK_IDLE_HIGH ) ? SPI_CPHA_1Edge : SPI_CPHA_2Edge;
    }

    /* Enable SPI peripheral clock */
    spi_peripheral_clock_functions[ spi_number ]( spi_peripheral_clocks[ spi_number ], ENABLE );

    spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    spi_init.SPI_Mode      = SPI_Mode_Master;
    spi_init.SPI_NSS       = SPI_NSS_Soft;
    spi_init.SPI_CRCPolynomial = 0x7; /* reset value */
    SPI_CalculateCRC( spi->port, DISABLE );

    /* Init and enable SPI */
    SPI_Init( spi->port, &spi_init );
    SPI_Cmd ( spi->port, ENABLE );

    platform_mcu_powersave_enable();

    return WICED_SUCCESS;
}
// Magicoe OSStatus platform_spi_init( const platform_spi_t* spi, const platform_spi_config_t* config )
OSStatus platform_spi_init( platform_spi_driver_t* driver, const platform_spi_t* peripheral, const platform_spi_config_t* config )
{
//  SPI_InitTypeDef   spi_init;
  OSStatus          err = kNoErr;
  platform_mcu_powersave_disable();
	uint32_t t1;	//general var
  require_action_quiet( ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);

  require_action_quiet( ( peripheral->port == LPC_SPI0 ), exit, err = kParamErr);


	driver->isRxDone = driver->isTxDone = 0;
	#ifndef NO_MICO_RTOS
	if (driver->sem_xfer_done == 0)
		mico_rtos_init_semaphore(&driver->sem_xfer_done, 1);
	#endif

   // >>> Init Pin mux
  	t1 = IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF;

	if (peripheral->port == LPC_SPI0)
	{
	  	if (config->speed >= 24000000)
	  		t1 |= 1UL<<9;	// enable fast slew
		g_pIO->PIO[0][11] = IOCON_FUNC1 | t1;/* SPI0_SCK */
		g_pIO->PIO[0][12] = IOCON_FUNC1 | t1;	/* SPI0_MOSI */
		g_pIO->PIO[0][13] = IOCON_FUNC1 | t1;	/* SPI0_MISO */
		// config CS pin as GPIO
		g_pIO->PIO[config->chip_select->port][config->chip_select->pin_number] = IOCON_FUNC0  | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF;
		platform_gpio_output_high(config->chip_select);
		platform_gpio_init(config->chip_select, OUTPUT_PUSH_PULL);
	}
	// <<<

	// >>>
	// initialize SPI peripheral
	{
		uint32_t bv;
		LPC_SPI_T *pSPI = peripheral->port;

		// >>>
		bv = pSPI == LPC_SPI0 ? 1UL << 9 : 1UL<<10;

		g_pASys->ASYNCAPBCLKCTRLSET = bv;	// enable clock to SPI

		g_pASys->ASYNCPRESETCTRLSET = bv;
		g_pASys->ASYNCPRESETCTRLCLR = bv;
		// <<<

		//			predly | postDly| fraDly | xferDly
		pSPI->DLY = 1UL<<0 | 1UL<<4 | 1UL<<8 | 1UL<<12;
        pSPI->DLY = 0;

		t1 = Chip_Clock_GetAsyncSyscon_ClockRate();
		t1 = (t1 + config->speed - 1) / config->speed;
		pSPI->DIV = t1 - 1;	// proper division

		pSPI->TXCTRL = (config->bits - 1) << 24;	// 8 bits per frame

		//   Enable | master | no loopback
		t1 = 1UL<<0 | 1UL<<2 | 0UL<<7;
		// determine SPI mode
		if (config->mode & SPI_CLOCK_IDLE_HIGH) {
			t1 |= 1UL<<5;	// CPOL = 1
			if (t1 & SPI_CLOCK_RISING_EDGE)
				t1 |= 1UL<<4;	// CPHA = 1
		} else {
			if (!(t1 & SPI_CLOCK_RISING_EDGE))
				t1 |= 1UL<<4;
		}
		pSPI->CFG = t1;
	}
	// <<<

	g_pDMA->DMACOMMON[0].ENABLESET = (1UL<<peripheral->dmaRxChnNdx) | (1UL<<peripheral->dmaTxChnNdx);
	g_pDMA->DMACOMMON[0].INTENSET = (1UL<<peripheral->dmaRxChnNdx) | (1UL<<peripheral->dmaTxChnNdx);

	g_pDMA->DMACH[peripheral->dmaRxChnNdx].CFG = DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_SNGL | DMA_CFG_CHPRIORITY(1);
	g_pDMA->DMACH[peripheral->dmaTxChnNdx].CFG = DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_SNGL | DMA_CFG_CHPRIORITY(1);

exit:
  platform_mcu_powersave_enable();
  return err;
}
예제 #22
0
OSStatus host_platform_bus_init( void )
{
  pdc_packet_t  pdc_spi_packet;
  Pdc*          spi_pdc  = spi_get_pdc_base( wifi_spi.port );
  
  platform_mcu_powersave_disable( );
  
  mico_rtos_init_semaphore( &spi_transfer_finished_semaphore, 1 );
  
  /* Setup the SPI lines */
  platform_gpio_peripheral_pin_init(  wifi_spi.mosi_pin,  ( wifi_spi.mosi_pin_mux_mode | IOPORT_MODE_PULLUP ) );
  platform_gpio_peripheral_pin_init(  wifi_spi.miso_pin,  ( wifi_spi.miso_pin_mux_mode | IOPORT_MODE_PULLUP ) );
  platform_gpio_peripheral_pin_init(  wifi_spi.clock_pin, ( wifi_spi.clock_pin_mux_mode | IOPORT_MODE_PULLUP ) );
  
  /* Setup the interrupt input for WLAN_IRQ */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
  platform_gpio_irq_enable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 );
  
  /* Setup SPI slave select GPIOs */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], OUTPUT_PUSH_PULL );
  platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] );
  
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
  /* Set GPIO_B[1:0] to 01 to put WLAN module into gSPI mode */
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
  platform_gpio_output_high( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] );
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
  platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] );
#endif
  
  /* Enable the peripheral and set SPI mode. */
  flexcom_enable( flexcom_base[ wifi_spi.spi_id ] );
  flexcom_set_opmode( flexcom_base[ wifi_spi.spi_id ], FLEXCOM_SPI );
  
  /* Init pdc, and clear RX TX. */
  pdc_spi_packet.ul_addr = 0;
  pdc_spi_packet.ul_size = 1;
  pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
  pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
  
  spi_disable_interrupt(wifi_spi.port, 0xffffffff );
  spi_disable( wifi_spi.port );
  spi_reset( wifi_spi.port );
  spi_set_lastxfer( wifi_spi.port );
  spi_set_master_mode( wifi_spi.port );
  spi_disable_mode_fault_detect( wifi_spi.port );
  
  spi_set_clock_polarity( wifi_spi.port, 0, SPI_CLK_POLARITY );
  spi_set_clock_phase( wifi_spi.port, 0, SPI_CLK_PHASE );
  spi_set_bits_per_transfer( wifi_spi.port, 0, SPI_CSR_BITS_8_BIT );
  spi_set_baudrate_div( wifi_spi.port, 0, (sysclk_get_cpu_hz() / SPI_BAUD_RATE) );
  spi_set_transfer_delay( wifi_spi.port, 0, 0, 0 );
  
  /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
  /* otherwise FreeRTOS will not be able to mask the interrupt */
  /* keep in mind that ARMCM4 interrupt priority logic is inverted, the highest value */
  /* is the lowest priority */
  /* Configure SPI interrupts . */
  
  NVIC_EnableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] );
  
  spi_enable(wifi_spi.port);
  
  platform_mcu_powersave_enable( );
  
  return kNoErr;
}
예제 #23
0
OSStatus MicoGpioInitialize( mico_gpio_t gpio, mico_gpio_config_t configuration )
{
  if ( gpio >= MICO_GPIO_NONE )
    return kUnsupportedErr;
  return (OSStatus) platform_gpio_init( &platform_gpio_pins[gpio], configuration );
}
OSStatus host_platform_bus_init( void )
{
    SPI_InitTypeDef  spi_init;
    DMA_InitTypeDef  dma_init_structure;
    uint32_t         a;

    platform_mcu_powersave_disable();

    mico_rtos_init_semaphore(&spi_transfer_finished_semaphore, 1);

    /* Enable SPI_SLAVE DMA clock */
    if ( wifi_spi.tx_dma.controller == DMA1 )
    {
        RCC->AHB1ENR |= RCC_AHB1Periph_DMA1;
    }
    else
    {
        RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
    }


    if ( wifi_spi.rx_dma.controller == DMA1 )
    {
        RCC->AHB1ENR |= RCC_AHB1Periph_DMA1;
    }
    else
    {
        RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
    }


    /* Enable SPI_SLAVE Periph clock */
    (wifi_spi.peripheral_clock_func)( wifi_spi.peripheral_clock_reg, ENABLE );

    /* Enable SYSCFG. Needed for selecting EXTI interrupt line */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, ENABLE );


    /* Setup the interrupt input for WLAN_IRQ */
    platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
    platform_gpio_irq_enable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 );

    /* Setup SPI slave select GPIOs */
    platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], OUTPUT_PUSH_PULL );
    platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] );

    /* Setup the SPI lines */
    for ( a = WIFI_PIN_SPI_CLK; a < WIFI_PIN_SPI_MAX; a++ )
    {
        platform_gpio_set_alternate_function( wifi_spi_pins[ a ].port, wifi_spi_pins[ a ].pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, wifi_spi.gpio_af );
    }

#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
    /* Set GPIO_B[1:0] to 01 to put WLAN module into gSPI mode */
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
    platform_gpio_output_high( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] );
    platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
    platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] );
#endif

    /* Setup DMA for SPIX RX */
    DMA_DeInit( wifi_spi.rx_dma.stream );
    dma_init_structure.DMA_Channel = wifi_spi.rx_dma.channel;
    dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t) &(wifi_spi.port->DR);
    dma_init_structure.DMA_Memory0BaseAddr = 0;
    dma_init_structure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    dma_init_structure.DMA_BufferSize = 0;
    dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    dma_init_structure.DMA_Mode = DMA_Mode_Normal;
    dma_init_structure.DMA_Priority = DMA_Priority_VeryHigh;
    dma_init_structure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    dma_init_structure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    dma_init_structure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    dma_init_structure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init( wifi_spi.rx_dma.stream, &dma_init_structure );

    /* Setup DMA for SPIX TX */
    DMA_DeInit( wifi_spi.tx_dma.stream );
    dma_init_structure.DMA_Channel =  wifi_spi.tx_dma.channel;
    dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t) &(wifi_spi.port->DR);
    dma_init_structure.DMA_Memory0BaseAddr = 0;
    dma_init_structure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
    dma_init_structure.DMA_BufferSize = 0;
    dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    dma_init_structure.DMA_Mode = DMA_Mode_Normal;
    dma_init_structure.DMA_Priority = DMA_Priority_VeryHigh;
    dma_init_structure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    dma_init_structure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    dma_init_structure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    dma_init_structure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init( wifi_spi.tx_dma.stream, &dma_init_structure );

    /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
    /* otherwise FreeRTOS will not be able to mask the interrupt */
    /* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */
    /* is the lowest priority */
    NVIC_EnableIRQ( wifi_spi.rx_dma.irq_vector );

    /* Enable DMA for TX */
    SPI_I2S_DMACmd( wifi_spi.port, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE );

    /* Setup SPI */
    spi_init.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
    spi_init.SPI_Mode              = SPI_Mode_Master;
    spi_init.SPI_DataSize          = SPI_DataSize_8b;
    spi_init.SPI_CPOL              = SPI_CPOL_High;
    spi_init.SPI_CPHA              = SPI_CPHA_2Edge;
    spi_init.SPI_NSS               = SPI_NSS_Soft;
    spi_init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
    spi_init.SPI_FirstBit          = SPI_FirstBit_MSB;
    spi_init.SPI_CRCPolynomial     = (uint16_t) 7;

    /* Init SPI and enable it */
    SPI_Init( wifi_spi.port, &spi_init );
    SPI_Cmd( wifi_spi.port, ENABLE );

    platform_mcu_powersave_enable();

    return kNoErr;
}