Marco Hsu / WIFI_API_32kRAM
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spi_master.c Source File

spi_master.c

00001 /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is property of Nordic Semiconductor ASA.
00004  * Terms and conditions of usage are described in detail in NORDIC
00005  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  */
00012 
00013 #include <spi_master.h>
00014 //#include "nrf_delay.h"
00015 #include "nrf_gpio.h"
00016 //#include "common.h"
00017 #include "spi_master_config.h" // This file must be in the application folder
00018 
00019 uint32_t* spi_master_init(SPIModuleNumber module_number, SPIMode mode, bool lsb_first)
00020 {
00021     uint32_t config_mode;
00022 
00023     NRF_SPI_Type *spi_base_address = (SPI0 == module_number)? NRF_SPI0 : (NRF_SPI_Type *)NRF_SPI1;
00024 
00025     if(SPI0 == module_number)
00026     {
00027         /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI0 */
00028         nrf_gpio_cfg_output(SPI_PSELSCK0);
00029         nrf_gpio_cfg_output(SPI_PSELMOSI0);
00030         nrf_gpio_cfg_input(SPI_PSELMISO0, NRF_GPIO_PIN_PULLUP);
00031         nrf_gpio_cfg_output(SPI_PSELSS0);
00032                 nrf_gpio_cfg_output(SPI_PSELSS1_flash); //added by Tsungta
00033                 
00034         /* Configure pins, frequency and mode */
00035         spi_base_address->PSELSCK  = SPI_PSELSCK0;
00036         spi_base_address->PSELMOSI = SPI_PSELMOSI0;
00037         spi_base_address->PSELMISO = SPI_PSELMISO0;
00038         nrf_gpio_pin_set(SPI_PSELSS0); /* disable Set slave select (inactive high) */
00039               nrf_gpio_pin_set(SPI_PSELSS1_flash);  //added by Tsungta        
00040     }
00041     else
00042     {
00043         /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI1*/
00044         nrf_gpio_cfg_output(SPI_PSELSCK1);
00045         nrf_gpio_cfg_output(SPI_PSELMOSI1);
00046         nrf_gpio_cfg_input(SPI_PSELMISO1, NRF_GPIO_PIN_PULLUP);
00047         nrf_gpio_cfg_output(SPI_PSELSS1);
00048                 nrf_gpio_cfg_output(SPI_PSELSS1_flash); //added by Tsungta
00049             
00050         /* Configure pins, frequency and mode */
00051         spi_base_address->PSELSCK  = SPI_PSELSCK1;
00052         spi_base_address->PSELMOSI = SPI_PSELMOSI1;
00053         spi_base_address->PSELMISO = SPI_PSELMISO1;
00054         nrf_gpio_pin_set(SPI_PSELSS1);         /* disable Set slave select (inactive high) */
00055               nrf_gpio_pin_set(SPI_PSELSS1_flash);  //added by Tsungta
00056     }
00057     spi_base_address->FREQUENCY = (uint32_t) SPI_OPERATING_FREQUENCY_4M;    //modified by Tsungta, 4MHz is max. speed for 1.8V
00058 
00059     /*lint -e845 -save // A zero has been given as right argument to operator '!'" */
00060     /** @snippet [SPI Select mode] */
00061     switch (mode )
00062     {
00063        
00064         case SPI_MODE0:
00065             config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
00066             break;
00067         case SPI_MODE1:
00068             config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
00069             break;
00070         case SPI_MODE2:
00071             config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
00072             break;
00073         case SPI_MODE3:
00074             config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
00075             break;
00076         default:
00077             config_mode = 0;
00078             break;
00079     
00080     }
00081     /** @snippet [SPI Select mode] */
00082     /*lint -restore */
00083 
00084     /*lint -e845 -save // A zero has been given as right argument to operator '!'" */
00085     /** @snippet [SPI Select endianess] */
00086     if (lsb_first)
00087     {
00088         spi_base_address->CONFIG = (config_mode | (SPI_CONFIG_ORDER_LsbFirst << SPI_CONFIG_ORDER_Pos));
00089     }
00090     else
00091     {
00092         spi_base_address->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos));
00093     }
00094     /** @snippet [SPI Select endianess] */
00095     /*lint -restore */
00096 
00097     spi_base_address->EVENTS_READY = 0U;
00098 #if 1
00099 
00100     /* Enable */
00101     if(SPI0 == module_number)
00102     spi_base_address->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
00103 #endif
00104     return (uint32_t *)spi_base_address;
00105 }
00106 
00107 //bool spi_master_tx_rx(uint32_t *spi_base_address, uint16_t transfer_size, const uint8_t *tx_data, uint8_t *rx_data)
00108 bool spi_master_tx_rx(SPIModuleNumber module_number, uint16_t transfer_size, const uint8_t *tx_data, uint8_t *rx_data)
00109 {
00110     uint32_t counter = 0;
00111     uint16_t number_of_txd_bytes = 0;
00112     uint32_t SEL_SS_PINOUT;
00113     /*lint -e{826} //Are too small pointer conversion */
00114 //    NRF_SPI_Type *spi_base = (NRF_SPI_Type *)spi_base_address;
00115     NRF_SPI_Type *spi_base = (SPI0 == module_number)? NRF_SPI0 : (NRF_SPI_Type *)NRF_SPI1;
00116     volatile uint32_t dummyread;
00117 
00118     if(NRF_SPI0 == spi_base)
00119     spi_base->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
00120 //    nrf_delay_ms(10);
00121 
00122 //    if( (uint32_t *)NRF_SPI0 == spi_base_address)
00123     if(NRF_SPI0 == spi_base)
00124     {
00125         SEL_SS_PINOUT = SPI_PSELSS0;
00126     }
00127     else
00128     {
00129         SEL_SS_PINOUT = SPI_PSELSS1;
00130     }
00131 
00132     /* enable slave (slave select active low) */
00133     if (SEL_SS_PINOUT == SPI_PSELSS0)
00134     nrf_gpio_pin_clear(SEL_SS_PINOUT);
00135 
00136     while(number_of_txd_bytes < transfer_size)
00137     {
00138             counter = 0;//Tsungta; FIXED for 4MHz issue
00139         if(tx_data == 0)
00140         {
00141             spi_base->TXD = 0x0;//0xFF;
00142         }
00143         else
00144         spi_base->TXD = (uint32_t)(tx_data[number_of_txd_bytes]);
00145 
00146         /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */
00147         while ((spi_base->EVENTS_READY == 0U) && (counter < TIMEOUT_COUNTER))
00148         {
00149             counter++;
00150         }
00151 
00152         if (counter == TIMEOUT_COUNTER)
00153         {
00154             /* timed out, disable slave (slave select active low) and return with error */
00155     if (SEL_SS_PINOUT == SPI_PSELSS0)
00156             nrf_gpio_pin_set(SEL_SS_PINOUT);
00157             return false;
00158         }
00159         else
00160         {   /* clear the event to be ready to receive next messages */
00161             spi_base->EVENTS_READY = 0U;
00162         }
00163 
00164         if(rx_data == 0)
00165         {
00166             dummyread = spi_base->RXD;
00167         }
00168         else
00169         rx_data[number_of_txd_bytes] = (uint8_t)spi_base->RXD;
00170         number_of_txd_bytes++;
00171     };
00172 
00173     /* disable slave (slave select active low) */
00174     if (SEL_SS_PINOUT == SPI_PSELSS0)
00175     nrf_gpio_pin_set(SEL_SS_PINOUT);
00176 
00177     if(NRF_SPI0 == spi_base)
00178     spi_base->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
00179 //    nrf_delay_ms(10);
00180 
00181     return true;
00182 }
00183