ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
ruuvi_interface_gpio_test.c
Go to the documentation of this file.
2 #if RUUVI_RUN_TESTS
3 #include "ruuvi_driver_error.h"
4 #include "ruuvi_driver_test.h"
5 #include "ruuvi_interface_gpio.h"
7 #include <stdbool.h>
8 
9 #define PULL_DELAY_MS (1U)
10 
12 {
13  rd_status_t err_code = RD_SUCCESS;
14  // - Interface must return RD_SUCCESS after first call.
15  err_code = ri_gpio_init();
16 
17  if (RD_SUCCESS != err_code)
18  {
19  RD_ERROR_CHECK (err_code, ~RD_ERROR_FATAL);
20  return RD_ERROR_SELFTEST;
21  }
22 
23  // - Interface must return RD_ERROR_INVALID_STATE when called while already initialized.
24  err_code = ri_gpio_init();
25 
26  if (RD_SUCCESS == err_code)
27  {
28  RD_ERROR_CHECK (err_code, ~RD_ERROR_FATAL);
29  return RD_ERROR_SELFTEST;
30  }
31 
32  // - Interface must return RD_SUCCESS when called after uninitialization.
33  err_code = ri_gpio_uninit();
34 
35  if (RD_SUCCESS != err_code)
36  {
37  RD_ERROR_CHECK (err_code, ~RD_ERROR_FATAL);
38  return RD_ERROR_SELFTEST;
39  }
40 
41  err_code = ri_gpio_uninit();
42 
43  if (RD_SUCCESS != err_code)
44  {
45  RD_ERROR_CHECK (err_code, ~RD_ERROR_FATAL);
46  return RD_ERROR_SELFTEST;
47  }
48 
49  return RD_SUCCESS;
50 }
51 
53  const ri_gpio_id_t output)
54 {
55  rd_status_t status = RD_SUCCESS;
56  // * - When Input is in High-Z mode, and output mode is INPUT_PULLUP, input must read as HIGH
57  ri_gpio_state_t state;
58  status |= ri_gpio_init();
60  status |= ri_gpio_configure (output, RI_GPIO_MODE_INPUT_PULLUP);
61  status |= ri_delay_ms (PULL_DELAY_MS);
62  status |= ri_gpio_read (input, &state);
63 
64  if (RD_SUCCESS != status || RI_GPIO_HIGH != state)
65  {
67  status = RD_ERROR_SELFTEST;
68  }
69  else
70  {
71  // - When Input is in High-Z mode, and output mode is INPUT_PULLDOWN, input must read as LOW
73  status |= ri_gpio_configure (output,
75  status |= ri_delay_ms (PULL_DELAY_MS);
76  status |= ri_gpio_read (input, &state);
77 
78  if (RD_SUCCESS != status || RI_GPIO_LOW != state)
79  {
81  status = RD_ERROR_SELFTEST;
82  }
83 
84  // - When Input is in INPUT_PULLUP mode, and output is in OUTPUT_LOW mode, input must read as LOW
86  status |= ri_gpio_configure (output,
88  status |= ri_gpio_write (output, RI_GPIO_LOW);
89  status |= ri_gpio_read (input, &state);
90 
91  if (RD_SUCCESS != status || RI_GPIO_LOW != state)
92  {
94  status = RD_ERROR_SELFTEST;
95  }
96 
97  // - When Input is in INPUT_PULLDOWN mode, and output is in OUTPUT_HIGH mode, input must read as HIGH
100  status |= ri_gpio_write (output, RI_GPIO_HIGH);
101  status |= ri_gpio_read (input, &state);
102 
103  if (RD_SUCCESS != status || RI_GPIO_HIGH != state)
104  {
106  status = RD_ERROR_SELFTEST;
107  }
108  }
109 
110  status |= ri_gpio_uninit();
111  return status;
112 }
113 
115  const ri_gpio_id_t output)
116 {
117  rd_status_t status = RD_SUCCESS;
118  // * - When Input is in High-Z mode, and output mode is INPUT_PULLUP, input must read as HIGH
119  ri_gpio_state_t state;
120  status |= ri_gpio_init();
121  status |= ri_gpio_configure (input, RI_GPIO_MODE_INPUT_NOPULL);
123  status |= ri_gpio_write (output, RI_GPIO_LOW);
124  status |= ri_gpio_read (input, &state);
125 
126  // Verify our start state
127  if (RD_SUCCESS != status || RI_GPIO_LOW != state)
128  {
130  status = RD_ERROR_SELFTEST;
131  }
132  else
133  {
134  // Verify low-to-high
135  status |= ri_gpio_toggle (output);
136  status |= ri_gpio_read (input, &state);
137 
138  if (RD_SUCCESS != status || RI_GPIO_HIGH != state)
139  {
141  status = RD_ERROR_SELFTEST;
142  }
143 
144  // Verify high-to-low
145  status |= ri_gpio_toggle (output);
146  status |= ri_gpio_read (input, &state);
147 
148  if (RD_SUCCESS != status || RI_GPIO_LOW != state)
149  {
151  status = RD_ERROR_SELFTEST;
152  }
153 
154  // Verify second low-to-high (after toggle, not static set)
155  status |= ri_gpio_toggle (output);
156  status |= ri_gpio_read (input, &state);
157 
158  if (RD_SUCCESS != status || RI_GPIO_HIGH != state)
159  {
161  status = RD_ERROR_SELFTEST;
162  }
163  }
164 
165  status |= ri_gpio_uninit();
166  return status;
167 }
168 
170  const ri_gpio_id_t input, const ri_gpio_id_t output)
171 {
172  rd_status_t status;
173  printfp ("\"gpio\":{\r\n");
174  printfp ("\"init\":");
175  status = ri_gpio_test_init();
176 
177  if (RD_SUCCESS == status)
178  {
179  printfp ("\"pass\",\r\n");
180  }
181  else
182  {
183  printfp ("\"fail\",\r\n");
184  }
185 
186  printfp ("\"configure\":");
187  status = ri_gpio_test_configure (input, output);
188 
189  if (RD_SUCCESS == status)
190  {
191  printfp ("\"pass\",\r\n");
192  }
193  else
194  {
195  printfp ("\"fail\",\r\n");
196  }
197 
198  printfp ("\"toggle\":");
199  status = ri_gpio_test_toggle (input, output);
200 
201  if (RD_SUCCESS == status)
202  {
203  printfp ("\"pass\"\r\n");
204  }
205  else
206  {
207  printfp ("\"fail\"\r\n");
208  }
209 
210  printfp ("},\r\n");
211  return status;
212 }
213 
214 #endif
#define RD_ERROR_FATAL
Program should always reset after this.
uint32_t rd_status_t
bitfield for representing errors
#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_SELFTEST
Self-test fail.
rd_status_t ri_gpio_uninit(void)
Uninitializes GPIO module. Call this to reset GPIO to High-Z mode. After uninitialization all GPIO pi...
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_test_configure(const ri_gpio_id_t input, const ri_gpio_id_t output)
Test configuring a pin of a port into a mode.
bool ri_gpio_run_integration_test(const rd_test_print_fp printfp, const ri_gpio_id_t input, const ri_gpio_id_t output)
Run all GPIO integration tests.
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_test_init(void)
Test GPIO module initialization.
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 p_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 ...
rd_status_t ri_gpio_test_toggle(const ri_gpio_id_t input, const ri_gpio_id_t output)
Test toggling the state of a pin of a port.
void(* rd_test_print_fp)(const char *const msg)
function pointer to print test information
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Functions for testing drivers.
uint16_t ri_gpio_id_t
port<<8 + pin
@ RI_GPIO_MODE_OUTPUT_STANDARD
Push-pull output, can be written.
@ RI_GPIO_MODE_INPUT_PULLUP
Input, can be read. Pulled up by internal resistor, value depends on IC.
@ RI_GPIO_MODE_INPUT_NOPULL
Input, can be read. No pull resistors.
@ 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.
rd_status_t ri_delay_ms(uint32_t time)
Delay a given number of milliseconds.