diff options
Diffstat (limited to 'src/drivers/spi_master_fast.cpp')
-rw-r--r-- | src/drivers/spi_master_fast.cpp | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/drivers/spi_master_fast.cpp b/src/drivers/spi_master_fast.cpp new file mode 100644 index 00000000..7ef2b360 --- /dev/null +++ b/src/drivers/spi_master_fast.cpp @@ -0,0 +1,176 @@ + /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. + * + * The information contained herein is confidential 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_fast.h" +#include <string.h> +#include "nrf_gpio.h" +#include "nrf_delay.h" + +static SPI_config_t spi_config_table[2]; +static NRF_SPI_Type *spi_base[2] = {NRF_SPI0, NRF_SPI1}; +static NRF_SPI_Type *SPI; + +uint32_t* spi_master_init(SPI_module_number_t spi_num, SPI_config_t *spi_config) +{ + if(spi_num > 1) + { + return 0; + } + memcpy(&spi_config_table[spi_num], spi_config, sizeof(SPI_config_t)); + + /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI0 */ + nrf_gpio_cfg_output(spi_config->pin_SCK); + nrf_gpio_cfg_output(spi_config->pin_MOSI); + nrf_gpio_cfg_input(spi_config->pin_MISO, NRF_GPIO_PIN_NOPULL); + nrf_gpio_cfg_output(spi_config->pin_CSN); + + /* Configure pins, frequency and mode */ + spi_base[spi_num]->PSELSCK = spi_config->pin_SCK; + spi_base[spi_num]->PSELMOSI = spi_config->pin_MOSI; + spi_base[spi_num]->PSELMISO = spi_config->pin_MISO; + nrf_gpio_pin_set(spi_config->pin_CSN); /* disable Set slave select (inactive high) */ + + spi_base[spi_num]->FREQUENCY = (uint32_t)spi_config->frequency << 24; + + spi_base[spi_num]->CONFIG = spi_config->config.SPI_cfg; + + spi_base[spi_num]->EVENTS_READY = 0; + /* Enable */ + spi_base[spi_num]->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); + + return (uint32_t *)spi_base[spi_num]; +} + +bool spi_master_tx_rx(SPI_module_number_t spi_num, uint16_t transfer_size, const uint8_t *tx_data, uint8_t *rx_data) +{ + volatile uint32_t *SPI_DATA_READY; + uint32_t tmp; + if(tx_data == 0 || rx_data == 0) + { + return false; + } + + SPI = spi_base[spi_num]; + SPI_DATA_READY = &SPI->EVENTS_READY; + /* enable slave (slave select active low) */ + nrf_gpio_pin_clear(spi_config_table[spi_num].pin_CSN); + + *SPI_DATA_READY = 0; + + SPI->TXD = (uint32_t)*tx_data++; + tmp = (uint32_t)*tx_data++; + while(--transfer_size) + { + SPI->TXD = tmp; + tmp = (uint32_t)*tx_data++; + + /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */ + while (*SPI_DATA_READY == 0); + + /* clear the event to be ready to receive next messages */ + *SPI_DATA_READY = 0; + + *rx_data++ = SPI->RXD; + } + + /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */ + while (*SPI_DATA_READY == 0); + + *rx_data = SPI->RXD; + + /* disable slave (slave select active low) */ + nrf_gpio_pin_set(spi_config_table[spi_num].pin_CSN); + + return true; +} + +bool spi_master_tx(SPI_module_number_t spi_num, uint16_t transfer_size, const uint8_t *tx_data) +{ + volatile uint32_t dummyread; + + if(tx_data == 0) + { + return false; + } + + SPI = spi_base[spi_num]; + + /* enable slave (slave select active low) */ + nrf_gpio_pin_clear(spi_config_table[spi_num].pin_CSN); + + SPI->EVENTS_READY = 0; + + SPI->TXD = (uint32_t)*tx_data++; + + while(--transfer_size) + { + SPI->TXD = (uint32_t)*tx_data++; + + /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */ + while (SPI->EVENTS_READY == 0); + + /* clear the event to be ready to receive next messages */ + SPI->EVENTS_READY = 0; + + dummyread = SPI->RXD; + } + + /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */ + while (SPI->EVENTS_READY == 0); + + dummyread = SPI->RXD; + + /* disable slave (slave select active low) */ + nrf_gpio_pin_set(spi_config_table[spi_num].pin_CSN); + + return true; +} + +bool spi_master_rx(SPI_module_number_t spi_num, uint16_t transfer_size, uint8_t *rx_data) +{ + if(rx_data == 0) + { + return false; + } + + SPI = spi_base[spi_num]; + + /* enable slave (slave select active low) */ + nrf_gpio_pin_clear(spi_config_table[spi_num].pin_CSN); + + SPI->EVENTS_READY = 0; + + SPI->TXD = 0; + + while(--transfer_size) + { + SPI->TXD = 0; + + /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */ + while (SPI->EVENTS_READY == 0); + + /* clear the event to be ready to receive next messages */ + SPI->EVENTS_READY = 0; + + *rx_data++ = SPI->RXD; + } + + /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */ + while (SPI->EVENTS_READY == 0); + + *rx_data = SPI->RXD; + + /* disable slave (slave select active low) */ + nrf_gpio_pin_set(spi_config_table[spi_num].pin_CSN); + + return true; +} |