Esempio n. 1
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;
}
Esempio n. 2
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;
}