WIFI_API_20150524e
Diff: WIFI_Driver/nordic/spi_master.c
- Revision:
- 0:a2de37bf5f3d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WIFI_Driver/nordic/spi_master.c Tue Jun 09 06:04:13 2015 +0000 @@ -0,0 +1,183 @@ +/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Nordic Semiconductor ASA. + * Terms and conditions of usage are described in detail in NORDIC + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + */ + +#include <spi_master.h> +//#include "nrf_delay.h" +#include "nrf_gpio.h" +//#include "common.h" +#include "spi_master_config.h" // This file must be in the application folder + +uint32_t* spi_master_init(SPIModuleNumber module_number, SPIMode mode, bool lsb_first) +{ + uint32_t config_mode; + + NRF_SPI_Type *spi_base_address = (SPI0 == module_number)? NRF_SPI0 : (NRF_SPI_Type *)NRF_SPI1; + + if(SPI0 == module_number) + { + /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI0 */ + nrf_gpio_cfg_output(SPI_PSELSCK0); + nrf_gpio_cfg_output(SPI_PSELMOSI0); + nrf_gpio_cfg_input(SPI_PSELMISO0, NRF_GPIO_PIN_PULLUP); + nrf_gpio_cfg_output(SPI_PSELSS0); + nrf_gpio_cfg_output(SPI_PSELSS1_flash); //added by Tsungta + + /* Configure pins, frequency and mode */ + spi_base_address->PSELSCK = SPI_PSELSCK0; + spi_base_address->PSELMOSI = SPI_PSELMOSI0; + spi_base_address->PSELMISO = SPI_PSELMISO0; + nrf_gpio_pin_set(SPI_PSELSS0); /* disable Set slave select (inactive high) */ + nrf_gpio_pin_set(SPI_PSELSS1_flash); //added by Tsungta + } + else + { + /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI1*/ + nrf_gpio_cfg_output(SPI_PSELSCK1); + nrf_gpio_cfg_output(SPI_PSELMOSI1); + nrf_gpio_cfg_input(SPI_PSELMISO1, NRF_GPIO_PIN_PULLUP); + nrf_gpio_cfg_output(SPI_PSELSS1); + nrf_gpio_cfg_output(SPI_PSELSS1_flash); //added by Tsungta + + /* Configure pins, frequency and mode */ + spi_base_address->PSELSCK = SPI_PSELSCK1; + spi_base_address->PSELMOSI = SPI_PSELMOSI1; + spi_base_address->PSELMISO = SPI_PSELMISO1; + nrf_gpio_pin_set(SPI_PSELSS1); /* disable Set slave select (inactive high) */ + nrf_gpio_pin_set(SPI_PSELSS1_flash); //added by Tsungta + } + spi_base_address->FREQUENCY = (uint32_t) SPI_OPERATING_FREQUENCY_4M; //modified by Tsungta, 4MHz is max. speed for 1.8V + + /*lint -e845 -save // A zero has been given as right argument to operator '!'" */ + /** @snippet [SPI Select mode] */ + switch (mode ) + { + + case SPI_MODE0: + config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos); + break; + case SPI_MODE1: + config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos); + break; + case SPI_MODE2: + config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos); + break; + case SPI_MODE3: + config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos); + break; + default: + config_mode = 0; + break; + + } + /** @snippet [SPI Select mode] */ + /*lint -restore */ + + /*lint -e845 -save // A zero has been given as right argument to operator '!'" */ + /** @snippet [SPI Select endianess] */ + if (lsb_first) + { + spi_base_address->CONFIG = (config_mode | (SPI_CONFIG_ORDER_LsbFirst << SPI_CONFIG_ORDER_Pos)); + } + else + { + spi_base_address->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos)); + } + /** @snippet [SPI Select endianess] */ + /*lint -restore */ + + spi_base_address->EVENTS_READY = 0U; +#if 1 + + /* Enable */ + if(SPI0 == module_number) + spi_base_address->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); +#endif + return (uint32_t *)spi_base_address; +} + +//bool spi_master_tx_rx(uint32_t *spi_base_address, uint16_t transfer_size, const uint8_t *tx_data, uint8_t *rx_data) +bool spi_master_tx_rx(SPIModuleNumber module_number, uint16_t transfer_size, const uint8_t *tx_data, uint8_t *rx_data) +{ + uint32_t counter = 0; + uint16_t number_of_txd_bytes = 0; + uint32_t SEL_SS_PINOUT; + /*lint -e{826} //Are too small pointer conversion */ +// NRF_SPI_Type *spi_base = (NRF_SPI_Type *)spi_base_address; + NRF_SPI_Type *spi_base = (SPI0 == module_number)? NRF_SPI0 : (NRF_SPI_Type *)NRF_SPI1; + volatile uint32_t dummyread; + + if(NRF_SPI0 == spi_base) + spi_base->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); +// nrf_delay_ms(10); + +// if( (uint32_t *)NRF_SPI0 == spi_base_address) + if(NRF_SPI0 == spi_base) + { + SEL_SS_PINOUT = SPI_PSELSS0; + } + else + { + SEL_SS_PINOUT = SPI_PSELSS1; + } + + /* enable slave (slave select active low) */ + if (SEL_SS_PINOUT == SPI_PSELSS0) + nrf_gpio_pin_clear(SEL_SS_PINOUT); + + while(number_of_txd_bytes < transfer_size) + { + counter = 0;//Tsungta; FIXED for 4MHz issue + if(tx_data == 0) + { + spi_base->TXD = 0x0;//0xFF; + } + else + spi_base->TXD = (uint32_t)(tx_data[number_of_txd_bytes]); + + /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */ + while ((spi_base->EVENTS_READY == 0U) && (counter < TIMEOUT_COUNTER)) + { + counter++; + } + + if (counter == TIMEOUT_COUNTER) + { + /* timed out, disable slave (slave select active low) and return with error */ + if (SEL_SS_PINOUT == SPI_PSELSS0) + nrf_gpio_pin_set(SEL_SS_PINOUT); + return false; + } + else + { /* clear the event to be ready to receive next messages */ + spi_base->EVENTS_READY = 0U; + } + + if(rx_data == 0) + { + dummyread = spi_base->RXD; + } + else + rx_data[number_of_txd_bytes] = (uint8_t)spi_base->RXD; + number_of_txd_bytes++; + }; + + /* disable slave (slave select active low) */ + if (SEL_SS_PINOUT == SPI_PSELSS0) + nrf_gpio_pin_set(SEL_SS_PINOUT); + + if(NRF_SPI0 == spi_base) + spi_base->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); +// nrf_delay_ms(10); + + return true; +} +