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; }
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; }