ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
ruuvi_nrf5_sdk15_gpio.c
Go to the documentation of this file.
2 #include "ruuvi_interface_gpio.h"
3 #if (RUUVI_NRF5_SDK15_GPIO_ENABLED || DOXYGEN || CEEDLING)
4 
5 #include "ruuvi_interface_gpio.h"
6 #include "ruuvi_driver_error.h"
7 #include "nrf_gpio.h"
8 #include "nrf_drv_gpiote.h"
9 #include <stdbool.h>
10 
26 static bool m_gpio_is_init = false;
27 
31 static inline uint8_t ruuvi_to_nrf_pin_map (const ri_gpio_id_t pin)
32 {
33  return ( (pin >> 3U) & 0xE0U) + (pin & 0x1FU);
34 }
35 
39 static inline ri_gpio_id_t nrf_to_ruuvi_pin (nrf_drv_gpiote_pin_t pin)
40 {
41  return ( (pin >> 5) << 8) + (pin & 0x1F);
42 }
43 
45 {
46  if (m_gpio_is_init) { return RD_ERROR_INVALID_STATE; }
47 
48  m_gpio_is_init = true;
49  return RD_SUCCESS;
50 }
51 
53 {
54  rd_status_t status = RD_SUCCESS;
55 
56  if (false == m_gpio_is_init)
57  {
58  return RD_SUCCESS;
59  }
60 
61  // Number of pins is defined by nrf_gpio.h
62  for (uint8_t iii = 0; iii < NUMBER_OF_PINS; iii++)
63  {
64  ri_gpio_id_t pin = nrf_to_ruuvi_pin (iii);
65  status |= ri_gpio_configure (pin, RI_GPIO_MODE_HIGH_Z);
66  }
67 
68  m_gpio_is_init = false;
69  return status;
70 }
71 
72 bool ri_gpio_is_init (void)
73 {
74  return m_gpio_is_init;
75 }
76 
78  const ri_gpio_mode_t mode)
79 {
80  rd_status_t err_code = RD_SUCCESS;
81 
82  if (RI_GPIO_ID_UNUSED != pin)
83  {
84  const uint8_t nrf_pin = ruuvi_to_nrf_pin_map (pin);
85 
86  switch (mode)
87  {
89  nrf_gpio_cfg_default (nrf_pin);
90  break;
91 
93  nrf_gpio_cfg_input (nrf_pin, NRF_GPIO_PIN_NOPULL);
94  break;
95 
97  nrf_gpio_cfg_input (nrf_pin, NRF_GPIO_PIN_PULLUP);
98  break;
99 
101  nrf_gpio_cfg_input (nrf_pin, NRF_GPIO_PIN_PULLDOWN);
102  break;
103 
105  nrf_gpio_cfg_output (nrf_pin);
106  break;
107 
109  nrf_gpio_cfg (nrf_pin,
110  NRF_GPIO_PIN_DIR_OUTPUT,
111  NRF_GPIO_PIN_INPUT_DISCONNECT,
112  NRF_GPIO_PIN_NOPULL,
113  NRF_GPIO_PIN_H0H1,
114  NRF_GPIO_PIN_NOSENSE);
115  break;
116 
118  nrf_gpio_cfg (nrf_pin,
119  NRF_GPIO_PIN_DIR_OUTPUT,
120  NRF_GPIO_PIN_INPUT_CONNECT,
121  NRF_GPIO_PIN_PULLUP,
122  NRF_GPIO_PIN_S0D1,
123  NRF_GPIO_PIN_NOSENSE);
124  break;
125 
127  nrf_gpio_cfg (nrf_pin,
128  NRF_GPIO_PIN_DIR_OUTPUT,
129  NRF_GPIO_PIN_INPUT_CONNECT,
130  NRF_GPIO_PIN_NOPULL,
131  NRF_GPIO_PIN_S0D1,
132  NRF_GPIO_PIN_NOSENSE);
133  break;
134 
136  nrf_gpio_cfg (nrf_pin,
137  NRF_GPIO_PIN_DIR_OUTPUT,
138  NRF_GPIO_PIN_INPUT_CONNECT,
139  NRF_GPIO_PIN_PULLUP,
140  NRF_GPIO_PIN_H0D1,
141  NRF_GPIO_PIN_NOSENSE);
142  break;
143 
145  nrf_gpio_cfg (nrf_pin,
146  NRF_GPIO_PIN_DIR_OUTPUT,
147  NRF_GPIO_PIN_INPUT_CONNECT,
148  NRF_GPIO_PIN_NOPULL,
149  NRF_GPIO_PIN_S0D1,
150  NRF_GPIO_PIN_NOSENSE);
151  break;
152 
153  default:
154  err_code |= RD_ERROR_INVALID_PARAM;
155  }
156  }
157 
158  return err_code;
159 }
160 
162 {
163  if (RI_GPIO_ID_UNUSED != pin)
164  {
165  const uint8_t nrf_pin = ruuvi_to_nrf_pin_map (pin);
166  nrf_gpio_pin_toggle (nrf_pin);
167  }
168 
169  return RD_SUCCESS;
170 }
171 
173  const ri_gpio_state_t state)
174 {
175  rd_status_t err_code = RD_SUCCESS;
176 
177  if (RI_GPIO_ID_UNUSED != pin)
178  {
179  const uint8_t nrf_pin = ruuvi_to_nrf_pin_map (pin);
180 
181  if (RI_GPIO_HIGH == state)
182  {
183  nrf_gpio_pin_set (nrf_pin);
184  }
185  else if (RI_GPIO_LOW == state)
186  {
187  nrf_gpio_pin_clear (nrf_pin);
188  }
189  else
190  {
191  err_code |= RD_ERROR_INVALID_PARAM;
192  }
193  }
194 
195  return err_code;
196 }
197 
199  ri_gpio_state_t * const state)
200 {
201  rd_status_t err_code = RD_SUCCESS;
202 
203  if (NULL == state)
204  {
205  err_code |= RD_ERROR_NULL;
206  }
207  else if (RI_GPIO_ID_UNUSED != pin)
208  {
209  const uint8_t nrf_pin = ruuvi_to_nrf_pin_map (pin);
210  bool high = nrf_gpio_pin_read (nrf_pin);
211 
212  if (true == high)
213  {
214  *state = RI_GPIO_HIGH;
215  }
216 
217  if (false == high)
218  {
219  *state = RI_GPIO_LOW;
220  }
221  }
222 
223  return err_code;
224 }
226 #endif
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
rd_status_t ri_gpio_uninit(void)
Uninitializes GPIO module. Call this to reset GPIO to High-Z mode. After uninitialization all GPIO pi...
bool ri_gpio_is_init(void)
return true if GPIO is init, false otherwise.
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_toggle(const ri_gpio_id_t pin)
Toggle the state of a pin of a port. If there are several ports the platform driver must implement a ...
rd_status_t ri_gpio_init(void)
Initializes GPIO module. Call this before other GPIO functions. After initialization all GPIO pins sh...
rd_status_t ri_gpio_read(const ri_gpio_id_t pin, ri_gpio_state_t *const state)
Read state of a pin of a port into bool high If there are several ports the platform driver must impl...
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.
uint16_t ri_gpio_id_t
port<<8 + pin
#define RI_GPIO_ID_UNUSED
Enable implementation selected by application.
ri_gpio_mode_t
@ RI_GPIO_MODE_OUTPUT_STANDARD
Push-pull output, can be written.
@ RI_GPIO_MODE_SINK_PULLUP_STANDARD
Sink only, pull-up, standard drive. I2C without external resistors.
@ RI_GPIO_MODE_INPUT_PULLUP
Input, can be read. Pulled up by internal resistor, value depends on IC.
@ RI_GPIO_MODE_OUTPUT_HIGHDRIVE
Push-pull output, can be written. Higher current drive than standard.
@ RI_GPIO_MODE_SINK_NOPULL_HIGHDRIVE
Sink only, nopull,, high-drive. I2C with strong external resistors.
@ RI_GPIO_MODE_INPUT_NOPULL
Input, can be read. No pull resistors.
@ RI_GPIO_MODE_SINK_NOPULL_STANDARD
Sink only, nopull, standard drive. I2C with weak external resistors.
@ RI_GPIO_MODE_SINK_PULLUP_HIGHDRIVE
Sink only, pull-up, high-drive. I2C with optional external resistors.
@ RI_GPIO_MODE_HIGH_Z
High-impedance mode, electrically disconnected.
@ RI_GPIO_MODE_INPUT_PULLDOWN
Input, can be read. Pulled dpwn by internal resistor, value depends on IC.
ri_gpio_state_t
States of GPIO pins.
@ RI_GPIO_LOW
GPIO electrically low.
@ RI_GPIO_HIGH
GPIO electrically high.