ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
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"
52
53#include "nrf_drv_spi.h"
54#include "app_util_platform.h"
55#include "nrf_gpio.h"
56
57
58static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE (
59 SPI_INSTANCE);
60static bool m_spi_init_done = false;
61
62static 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
88static 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
102 *nrf_freq = NRF_DRV_SPI_FREQ_4M;
103 return RD_SUCCESS;
104
106 *nrf_freq = NRF_DRV_SPI_FREQ_8M;
107 return RD_SUCCESS;
108
109 default:
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
152bool 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
169rd_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_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
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