ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
ruuvi_nrf5_sdk15_spi.c
Go to the documentation of this file.
1 
41 #include "ruuvi_interface_spi.h"
42 #if RUUVI_NRF5_SDK15_SPI_ENABLED
43 
44 #include <stdint.h>
45 #include <string.h> //memcpy
46 
47 #include "ruuvi_driver_error.h"
48 #include "ruuvi_nrf5_sdk15_error.h"
49 #include "ruuvi_interface_gpio.h"
50 #include "ruuvi_interface_yield.h"
51 #include "ruuvi_nrf5_sdk15_gpio.h"
52 
53 #include "nrf_drv_spi.h"
54 #include "app_util_platform.h"
55 #include "nrf_gpio.h"
56 
57 
58 static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE (
59  SPI_INSTANCE);
60 static bool m_spi_init_done = false;
61 
62 static rd_status_t ruuvi_to_nrf_spi_mode (const ri_spi_mode_t
63  ruuvi_mode, nrf_drv_spi_mode_t * nrf_mode)
64 {
65  switch (ruuvi_mode)
66  {
67  case RI_SPI_MODE_0:
68  *nrf_mode = NRF_DRV_SPI_MODE_0;
69  return RD_SUCCESS;
70 
71  case RI_SPI_MODE_1:
72  *nrf_mode = NRF_DRV_SPI_MODE_1;
73  return RD_SUCCESS;
74 
75  case RI_SPI_MODE_2:
76  *nrf_mode = NRF_DRV_SPI_MODE_2;
77  return RD_SUCCESS;
78 
79  case RI_SPI_MODE_3:
80  *nrf_mode = NRF_DRV_SPI_MODE_3;
81  return RD_SUCCESS;
82 
83  default:
85  }
86 }
87 
88 static rd_status_t ruuvi_to_nrf_spi_freq (const ri_spi_mode_t
89  ruuvi_freq, nrf_drv_spi_frequency_t * nrf_freq)
90 {
91  switch (ruuvi_freq)
92  {
94  *nrf_freq = NRF_DRV_SPI_FREQ_1M;
95  return RD_SUCCESS;
96 
98  *nrf_freq = NRF_DRV_SPI_FREQ_2M;
99  return RD_SUCCESS;
100 
101  case RI_SPI_FREQUENCY_4M:
102  *nrf_freq = NRF_DRV_SPI_FREQ_4M;
103  return RD_SUCCESS;
104 
105  case RI_SPI_FREQUENCY_8M:
106  *nrf_freq = NRF_DRV_SPI_FREQ_8M;
107  return RD_SUCCESS;
108 
109  default:
110  return RD_ERROR_INVALID_PARAM;
111  }
112 }
113 
114 
116  config)
117 {
118  //Return error if SPI is already init
119  if (m_spi_init_done) { return NRF_ERROR_INVALID_STATE; }
120 
121  rd_status_t status = RD_SUCCESS;
122  nrf_drv_spi_mode_t mode = RI_SPI_MODE_0;
123  nrf_drv_spi_frequency_t frequency = NRF_DRV_SPI_FREQ_1M;
124  status |= ruuvi_to_nrf_spi_mode (config->mode, &mode);
125  status |= ruuvi_to_nrf_spi_freq (config->frequency, &frequency);
126  RD_ERROR_CHECK (status, RD_SUCCESS);
127  nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
128  spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
129  spi_config.miso_pin = ruuvi_to_nrf_pin_map (config->miso);
130  spi_config.mosi_pin = ruuvi_to_nrf_pin_map (config->mosi);
131  spi_config.sck_pin = ruuvi_to_nrf_pin_map (config->sclk);
132  spi_config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
133  spi_config.orc = 0xFF;
134  spi_config.frequency = frequency;
135  spi_config.mode = mode;
136  spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
137  // Use blocking mode by using NULL as event handler
138  ret_code_t err_code = NRF_SUCCESS;
139  err_code = nrf_drv_spi_init (&spi, &spi_config, NULL, NULL);
140 
141  for (size_t ii = 0; ii < config->ss_pins_number; ii++)
142  {
143  ri_gpio_configure (config->ss_pins[ii],
145  ri_gpio_write (config->ss_pins[ii], RI_GPIO_HIGH);
146  }
147 
148  m_spi_init_done = true;
149  return (status | ruuvi_nrf5_sdk15_to_ruuvi_error (err_code));
150 }
151 
152 bool ri_spi_is_init()
153 {
154  return m_spi_init_done;
155 }
156 
163 {
164  nrf_drv_spi_uninit (&spi);
165  m_spi_init_done = false;
166  return RD_SUCCESS;
167 }
168 
169 rd_status_t ri_spi_xfer_blocking (const uint8_t * tx,
170  const size_t tx_len, uint8_t * rx, const size_t rx_len)
171 {
172  //Return error if not init or if given null pointer
173  if (!m_spi_init_done) { return RD_ERROR_INVALID_STATE; }
174 
175  if ( (NULL == tx && 0 != tx_len) || (NULL == rx && 0 != rx_len)) { return RD_ERROR_NULL; }
176 
177  ret_code_t err_code = NRF_SUCCESS;
178  err_code |= nrf_drv_spi_transfer (&spi, tx, tx_len, rx, rx_len);
179  return ruuvi_nrf5_sdk15_to_ruuvi_error (err_code);
180 }
181 
182 #endif
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
rd_status_t ruuvi_nrf5_sdk15_to_ruuvi_error(const ret_code_t error)
convert nrf5 sdk15 error code into Ruuvi error code.
#define RD_ERROR_CHECK(error, mask)
Shorthand macro for calling the rd_error_check with current file & line.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
rd_status_t ri_gpio_configure(const ri_gpio_id_t pin, const ri_gpio_mode_t mode)
Configure a pin of a port into a mode. If there are several ports the platform driver must implement ...
rd_status_t ri_gpio_write(const ri_gpio_id_t pin, const ri_gpio_state_t state)
Write a pin of a port into given state If there are several ports the platform driver must implement ...
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
@ RI_GPIO_MODE_OUTPUT_STANDARD
Push-pull output, can be written.
@ RI_GPIO_HIGH
GPIO electrically high.
Interface for SPI operations.
rd_status_t ri_spi_uninit()
Uninitialize SPI driver.
ri_spi_mode_t
@ RI_SPI_MODE_1
CPOL = 0, CPHA = 1.
@ RI_SPI_MODE_0
CPOL = 0, CPHA = 0.
@ RI_SPI_MODE_3
CPOL = 1, CPHA = 1.
@ RI_SPI_MODE_2
CPOL = 1, CPHA = 0.
@ RI_SPI_FREQUENCY_4M
4 Mbps
@ RI_SPI_FREQUENCY_2M
2 Mbps
@ RI_SPI_FREQUENCY_1M
1 Mbps
@ RI_SPI_FREQUENCY_8M
8 Mbps
rd_status_t ri_spi_xfer_blocking(const uint8_t *const p_tx, const size_t tx_len, uint8_t *const p_rx, const size_t rx_len)
SPI transfer function.
bool ri_spi_is_init()
check if SPI interface is already initialized.
rd_status_t ri_spi_init(const ri_spi_init_config_t *const config)
Initialize SPI driver with given settings.
#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY
Definition: sdk_config.h:6339
ri_gpio_id_t * ss_pins
array of SPI pins, can be freed after function exits
ri_gpio_id_t sclk
pin number of SCLK
size_t ss_pins_number
sizeof ss_pins
ri_gpio_id_t miso
pin number of MISO
ri_spi_mode_t mode
Mode of SPI Bus, see ri_spi_mode_t.
ri_spi_frequency_t frequency
Frequency of SPI Bus, see ri_spi_frequency_t.
ri_gpio_id_t mosi
pin number of MOSI