ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
ruuvi_interface_gpio_pwm_test.c
Go to the documentation of this file.
1 
11 #if RUUVI_RUN_TESTS
12 #include "ruuvi_driver_error.h"
13 #include "ruuvi_driver_test.h"
14 #include "ruuvi_interface_gpio.h"
20 #include "ruuvi_interface_yield.h"
21 #include <stdlib.h>
22 
23 static uint8_t num_int_trigs = 0;
24 static uint8_t stop_trigs = 0;
25 static void on_interrupt (ri_gpio_evt_t evt)
26 {
27  if (!stop_trigs)
28  { num_int_trigs ++; }
29 }
30 
31 static bool ri_gpio_pwm_test_init (void)
32 {
33  rd_status_t status = RD_SUCCESS;
34  bool failed = false;
35  // - Initialization must return @c RD_SUCCESS on first call.
36  status |= ri_gpio_pwm_init ();
37 
38  if (RD_SUCCESS == status)
39  {
40  // - Initialization must return @c RD_ERROR_INVALID_STATE on second call.
41  status = ri_gpio_pwm_init ();
42 
43  if (RD_ERROR_INVALID_STATE != status)
44  {
45  failed = true;
46  }
47 
48  // - Initialization must return @c RD_SUCCESS after uninitializtion.
49  status = ri_gpio_pwm_uninit ();
50  status |= ri_gpio_pwm_init ();
51 
52  if (RD_SUCCESS != status)
53  {
54  failed = true;
55  }
56  }
57  else
58  {
59  failed = true;
60  }
61 
62  // Cleanup
64  return failed;
65 }
66 
67 static rd_status_t ri_gpio_pwm_test_input (const rd_test_gpio_cfg_t cfg)
68 {
70  const float orig_freq = RI_GPIO_PWM_TEST_FREQ_HZ;
71  const float invalid_max_freq = RI_GPIO_PWM_TEST_FREQ_INVALID_MAX_HZ;
72  const float invalid_min_freq = RI_GPIO_PWM_TEST_FREQ_INVALID_MIN_HZ;
73  const float orig_dc = RI_GPIO_PWM_TEST_DC;
74  const float invalid_max_dc = RI_GPIO_PWM_TEST_DUTY_INVALID_MAX_HZ;
75  const float invalid_min_dc = RI_GPIO_PWM_TEST_DUTY_INVALID_MIN_HZ;
76  float cfg_freq = invalid_max_freq;
77  float cfg_dc = orig_dc;
78 
81  &cfg_freq, &cfg_dc))
82  {
83  status = RD_SUCCESS;
84  }
85 
86  cfg_freq = invalid_min_freq;
87 
90  &cfg_freq, &cfg_dc))
91  {
92  status = RD_SUCCESS;
93  }
94 
97  NULL, &cfg_dc))
98  {
99  status = RD_SUCCESS;
100  }
101 
102  cfg_freq = orig_freq;
103  cfg_dc = invalid_max_dc;
104 
107  &cfg_freq, &cfg_dc))
108  {
109  status = RD_SUCCESS;
110  }
111 
112  cfg_freq = orig_freq;
113  cfg_dc = invalid_min_dc;
114 
117  &cfg_freq, &cfg_dc))
118  {
119  status = RD_SUCCESS;
120  }
121 
124  &cfg_freq, NULL))
125  {
126  status = RD_SUCCESS;
127  }
128 
129  cfg_dc = orig_dc;
130 
133  &cfg_freq, &cfg_dc))
134  {
135  status = RD_SUCCESS;
136  }
137 
138  return status;
139 }
140 static bool ri_gpio_pwm_test_start (const rd_test_gpio_cfg_t cfg)
141 {
142  rd_status_t status = RD_SUCCESS;
143  bool failed = false;
144  const float orig_freq = RI_GPIO_PWM_TEST_FREQ_HZ;
145  float configured_freq = orig_freq;
146  const float orig_dc = RI_GPIO_PWM_TEST_DC;
147  float configured_dc = orig_dc;
148  status |= ri_gpio_pwm_init ();
150  &configured_freq, &configured_dc);
151  // Note: if timer-based low-power delay is enabled, this
152  // is grossly inaccurate.
154  stop_trigs = !stop_trigs;
155  status |= ri_gpio_pwm_stop (cfg.output);
156 
157  if ( (RI_GPIO_PWM_EXPECT_TRIGS != num_int_trigs) &&
158  (RI_GPIO_PWM_EXPECT_TRIGS != (num_int_trigs + 1)) &&
159  (RI_GPIO_PWM_EXPECT_TRIGS != (num_int_trigs - 1)))
160  {
161  failed = true;
162  }
163 
164  if (false == ri_gpio_pwm_is_init())
165  {
166  failed = true;
167  }
168 
169  if (RD_ERROR_INVALID_PARAM != ri_gpio_pwm_test_input (cfg))
170  {
171  failed = true;
172  }
173 
174  // Cleanup
176 
177  if (true == ri_gpio_pwm_is_init())
178  {
179  failed = true;
180  }
181 
182  return failed;
183 }
184 
186  const ri_gpio_id_t input, const ri_gpio_id_t output)
187 {
188  rd_status_t status;
189  bool failed = false;
190  rd_test_gpio_cfg_t cfg;
191  const uint8_t interrupt_table_size = RI_GPIO_INTERRUPT_TEST_TABLE_SIZE;
193  cfg.input = input;
194  cfg.output = output;
195  printfp ("\"gpio_pwm\":{\r\n");
196  printfp ("\"init\":");
197  status = ri_gpio_init();
198  status |= ri_gpio_interrupt_init (interrupt_table, interrupt_table_size);
199  status |= ri_gpio_interrupt_enable (cfg.input,
201  failed |= ri_gpio_pwm_test_init ();
202 
203  if (!failed)
204  {
205  printfp ("\"pass\",\r\n");
206  }
207  else
208  {
209  printfp ("\"fail\",\r\n");
210  }
211 
212  printfp ("\"start\":");
213  failed |= ri_gpio_pwm_test_start (cfg);
214 
215  if (!failed)
216  {
217  printfp ("\"pass\"\r\n");
218  }
219  else
220  {
221  printfp ("\"fail\"\r\n");
222  failed = true;
223  }
224 
225  // Cleanup.
229  ri_gpio_uninit();
230  printfp ("}\r\n");
231  return failed;
232 }
233 #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.
#define RI_GPIO_PWM_TEST_DUTY_INVALID_MAX_HZ
Invalid duty cycle.
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_interrupt_enable(const ri_gpio_id_t pin, const ri_gpio_slope_t slope, const ri_gpio_mode_t mode, const ri_gpio_interrupt_fp_t handler)
Enable interrupt on a pin.
#define RI_GPIO_INTERRUPT_TEST_TABLE_SIZE
Fixed 64 interrupt table size, adjust this if some device has more than 2 ports with 32 gpios each.
rd_status_t ri_gpio_pwm_stop(const ri_gpio_id_t pin)
Stop PWM on given pin.
#define RI_GPIO_PWM_TEST_FREQ_INVALID_MAX_HZ
Invalid frequency.
rd_status_t ri_gpio_interrupt_init(ri_gpio_interrupt_fp_t *const interrupt_table, const uint16_t max_interrupts)
Initialize interrupt functionality to GPIO. Takes address of interrupt table as a pointer to avoid ty...
#define RI_GPIO_PWM_TEST_DC
Duty cycle in test.
void(* ri_gpio_interrupt_fp_t)(const ri_gpio_evt_t)
#define RI_GPIO_PWM_TEST_DUTY_INVALID_MIN_HZ
Invalid duty cycle.
bool ri_gpio_pwm_is_init(void)
Check if PWM is initialized.
#define RI_GPIO_PWM_TEST_FREQ_INVALID_MIN_HZ
Invalid frequency.
#define RI_GPIO_PWM_TEST_TIME_MS
Milliseconds to test.
rd_status_t ri_gpio_interrupt_uninit(void)
Uninitialize interrupt functionality of GPIO.
rd_status_t ri_gpio_interrupt_disable(const ri_gpio_id_t pin)
Disable interrupt on a pin.
rd_status_t ri_gpio_pwm_init(void)
Run any necessary initialization for PWM.
rd_status_t ri_gpio_init(void)
Initializes GPIO module. Call this before other GPIO functions. After initialization all GPIO pins sh...
#define RI_GPIO_PWM_EXPECT_TRIGS
rd_status_t ri_gpio_pwm_start(const ri_gpio_id_t pin, const ri_gpio_mode_t mode, float *const frequency, float *const duty_cycle)
Start PWM on given pin at given frequency and duty cycle.
rd_status_t ri_gpio_pwm_uninit(void)
Uninitialize PWM.
#define RI_GPIO_PWM_TEST_FREQ_HZ
Frequency of test.
bool ri_gpio_pwm_run_integration_test(const rd_test_print_fp printfp, const ri_gpio_id_t input, const ri_gpio_id_t output)
Run all GPIO interrupt integration tests.
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_HIGHDRIVE
Push-pull output, can be written. Higher current drive than standard.
@ 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.
rd_status_t ri_delay_ms(uint32_t time)
Delay a given number of milliseconds.
structure to configure GPIO test with input and output. These GPIOs must be physically connected on b...
ri_gpio_id_t input
Input pin used in test. Must be interrupt-capable.
ri_gpio_id_t output
Output pin used in test. Must be PWM-capable.