MeshX 0.4
This repository provides an implementation for Bluetooth Low Energy (BLE) Mesh network nodes. The project allows you to create BLE mesh nodes that can communicate with each other, enabling the development of smart home solutions or other IoT-based applications.
Loading...
Searching...
No Matches
pwm_property_test.c File Reference

Property-based tests for MeshX PWM subsystem correctness. More...

Data Structures

struct  pwm_test_config_t
 Test configuration for PWM property tests. More...
struct  pwm_test_state_t
 Test state for tracking PWM operations. More...

Functions

void meshx_gpio_test_set_pin_count (uint8_t count)
void meshx_gpio_test_set_pin_mode (uint8_t pin, meshx_gpio_mode_t mode)
void meshx_pwm_test_set_pin_count (uint8_t count)
static void init_test_state (void)
 Initialize test state.
static meshx_err_t test_property_pwm_initialization (void)
 Property 4.1: PWM initialization based on configuration.
static meshx_err_t test_property_pwm_start_stop (void)
 Property 4.2: PWM start and stop operations.
static meshx_err_t test_property_duty_cycle_accuracy (void)
 Property 4.3: Duty cycle accuracy.
static meshx_err_t test_property_frequency_accuracy (void)
 Property 4.4: Frequency accuracy.
static meshx_err_t test_property_parameter_validation (void)
 Property 4.5: Parameter validation against hardware limits.
static meshx_err_t test_property_channel_allocation (void)
 Property 4.6: Hardware channel allocation and conflict handling.
static meshx_err_t test_property_state_maintenance (void)
 Property 4.7: PWM state maintenance.
static meshx_err_t test_property_deinit_cleanup (void)
 Property 4.8: Deinitialization and resource cleanup.
static meshx_err_t run_pwm_property_tests (void)
 Comprehensive property test for PWM subsystem correctness.
static meshx_err_t pwm_property_test_handler (int cmd_id, int argc, char **argv)
 PWM property test command handler.
meshx_err_t register_pwm_property_tests (void)
 Register PWM property tests with unit test framework.

Variables

static pwm_test_state_t test_state

Detailed Description

Property-based tests for MeshX PWM subsystem correctness.

This file implements property-based tests for the MeshX PWM subsystem, specifically validating Property 4: PWM Subsystem Correctness.

Validates: Requirements 4.1-4.10

Property 4: PWM Subsystem Correctness For any GPIO pin configured for PWM output (with frequency, duty cycle, resolution, and channel specifications), the PWM subsystem SHALL:

  1. Initialize based on YAML configuration
  2. Start and stop PWM output as requested
  3. Set and get duty cycle (0-100%) and frequency values accurately
  4. Validate parameters against hardware limits
  5. Handle hardware channel allocation and conflicts
  6. Maintain PWM state for runtime control and monitoring
  7. Deinitialize and free resources during shutdown
Author
MeshX Team
Date
2024

Function Documentation

◆ init_test_state()

void init_test_state ( void )
static

Initialize test state.

69{
76 memset(&test_state, 0, sizeof(test_state));
77}
static gpio_test_state_t test_state
Definition gpio_property_test.c:57
meshx_err_t meshx_gpio_init(void)
Initialize GPIO subsystem.
Definition meshx_gpio.c:95
meshx_err_t meshx_gpio_deinit(void)
Deinitialize GPIO subsystem.
Definition meshx_gpio.c:189
meshx_err_t meshx_pwm_deinit(void)
Deinitialize PWM subsystem.
Definition meshx_pwm.c:119
meshx_err_t meshx_pwm_init(void)
Initialize PWM subsystem.
Definition meshx_pwm.c:69
void meshx_gpio_test_set_pin_count(uint8_t count)
Definition meshx_gpio.c:72
void meshx_pwm_test_set_pin_count(uint8_t count)
Definition meshx_pwm.c:714

◆ meshx_gpio_test_set_pin_count()

void meshx_gpio_test_set_pin_count ( uint8_t count)
extern
73{
74 if (count <= 128) {
75 gpio_runtime.pin_count = count;
76 return MESHX_SUCCESS;
77 }
78 return MESHX_FAIL;
79}
@ MESHX_FAIL
Definition meshx_err.h:45
static meshx_gpio_runtime_t gpio_runtime
Definition meshx_gpio.c:38
**This function is called by the parent element when a state change request *is received It validates the request and returns a result to the element not the model layer **return * MESHX_SUCCESS
Definition meshx_model_level.cpp:385

◆ meshx_gpio_test_set_pin_mode()

void meshx_gpio_test_set_pin_mode ( uint8_t pin,
meshx_gpio_mode_t mode )
extern

◆ meshx_pwm_test_set_pin_count()

void meshx_pwm_test_set_pin_count ( uint8_t count)
extern
715{
716 if (count > 128) count = 128;
717 pwm_runtime.pwm_pin_count = count;
718}
static meshx_pwm_runtime_t pwm_runtime
Definition meshx_pwm.c:54

◆ pwm_property_test_handler()

meshx_err_t pwm_property_test_handler ( int cmd_id,
int argc,
char ** argv )
static

PWM property test command handler.

This function is called by the unit test framework when PWM tests are requested.

685{
686 (void)argc;
687 (void)argv;
688
689 MESHX_LOGD(MODULE_ID_COMMON, "[DEBUG] PWM Property Test Handler - Command ID: %d", cmd_id);
690
691 switch (cmd_id) {
692 case 0:
693 // Run all property tests
694 return run_pwm_property_tests();
695
696 case 1:
697 // Property 4.1: PWM initialization
700
701 case 2:
702 // Property 4.2: PWM start/stop
705
706 case 3:
707 // Property 4.3: Duty cycle accuracy
710
711 case 4:
712 // Property 4.4: Frequency accuracy
715
716 case 5:
717 // Property 4.5: Parameter validation
720
721 case 6:
722 // Property 4.6: Channel allocation
725
726 case 7:
727 // Property 4.7: State maintenance
730
731 case 8:
732 // Property 4.8: Deinitialization cleanup
735
736 default:
737 MESHX_LOGE(MODULE_ID_COMMON, "Unknown PWM test command ID: %d", cmd_id);
738 return MESHX_INVALID_ARG;
739 }
740}
@ MESHX_INVALID_ARG
Definition meshx_err.h:46
#define MESHX_LOGE(module_id, format,...)
Definition meshx_log.h:114
#define MESHX_LOGD(module_id, format,...)
Definition meshx_log.h:132
@ MODULE_ID_COMMON
Definition module_id.h:36
static meshx_err_t run_pwm_property_tests(void)
Comprehensive property test for PWM subsystem correctness.
Definition pwm_property_test.c:616
static meshx_err_t test_property_parameter_validation(void)
Property 4.5: Parameter validation against hardware limits.
Definition pwm_property_test.c:306
static meshx_err_t test_property_channel_allocation(void)
Property 4.6: Hardware channel allocation and conflict handling.
Definition pwm_property_test.c:367
static meshx_err_t test_property_state_maintenance(void)
Property 4.7: PWM state maintenance.
Definition pwm_property_test.c:444
static meshx_err_t test_property_pwm_initialization(void)
Property 4.1: PWM initialization based on configuration.
Definition pwm_property_test.c:84
static meshx_err_t test_property_duty_cycle_accuracy(void)
Property 4.3: Duty cycle accuracy.
Definition pwm_property_test.c:161
static meshx_err_t test_property_frequency_accuracy(void)
Property 4.4: Frequency accuracy.
Definition pwm_property_test.c:236
static meshx_err_t test_property_pwm_start_stop(void)
Property 4.2: PWM start and stop operations.
Definition pwm_property_test.c:105
static meshx_err_t test_property_deinit_cleanup(void)
Property 4.8: Deinitialization and resource cleanup.
Definition pwm_property_test.c:554
static void init_test_state(void)
Initialize test state.
Definition pwm_property_test.c:68

◆ register_pwm_property_tests()

meshx_err_t register_pwm_property_tests ( void )

Register PWM property tests with unit test framework.

Returns
meshx_err_t Registration result
746{
747 MESHX_LOGD(MODULE_ID_PWM_PROPERTY_TEST, "Registering PWM property tests");
749}
@ MODULE_ID_PWM_PROPERTY_TEST
Definition module_id.h:48
static meshx_err_t pwm_property_test_handler(int cmd_id, int argc, char **argv)
PWM property test command handler.
Definition pwm_property_test.c:684
meshx_err_t register_unit_test(module_id_t module_id, module_callback_t callback)
Register a unit test for a specific module.
Definition unit_test.c:137

◆ run_pwm_property_tests()

meshx_err_t run_pwm_property_tests ( void )
static

Comprehensive property test for PWM subsystem correctness.

Runs all property tests for Property 4: PWM Subsystem Correctness.

617{
618 MESHX_LOGD(MODULE_ID_COMMON, "Starting PWM Property Tests");
619 MESHX_LOGD(MODULE_ID_COMMON, "Property 4: PWM Subsystem Correctness");
620 MESHX_LOGD(MODULE_ID_COMMON, "Validates: Requirements 4.1-4.10");
621
623
624 // Run all property tests
625 meshx_err_t result;
626
628 if (result != MESHX_SUCCESS) {
629 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.1 FAILED");
630 return result;
631 }
632
634 if (result != MESHX_SUCCESS) {
635 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.2 FAILED");
636 return result;
637 }
638
640 if (result != MESHX_SUCCESS) {
641 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.3 FAILED");
642 return result;
643 }
644
646 if (result != MESHX_SUCCESS) {
647 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.4 FAILED");
648 return result;
649 }
650
652 if (result != MESHX_SUCCESS) {
653 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.5 FAILED");
654 return result;
655 }
656
658 if (result != MESHX_SUCCESS) {
659 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.6 FAILED");
660 return result;
661 }
662
664 if (result != MESHX_SUCCESS) {
665 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.7 FAILED");
666 return result;
667 }
668
670 if (result != MESHX_SUCCESS) {
671 MESHX_LOGE(MODULE_ID_COMMON, "Property 4.8 FAILED");
672 return result;
673 }
674
675 MESHX_LOGI(MODULE_ID_COMMON, "All PWM Property Tests PASSED");
676 return MESHX_SUCCESS;
677}
meshx_err_t
MeshX Error Codes.
Definition meshx_err.h:43
#define MESHX_LOGI(module_id, format,...)
Definition meshx_log.h:126

◆ test_property_channel_allocation()

meshx_err_t test_property_channel_allocation ( void )
static

Property 4.6: Hardware channel allocation and conflict handling.

Tests that hardware channel allocation and conflicts are handled properly.

368{
369 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.6: Hardware channel allocation and conflict handling");
370
371 if (!test_state.pwm_initialized) {
372 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM not initialized");
374 }
375
376 // Test multiple pins can be configured (implementation may handle channel allocation)
377 const uint8_t test_pins[] = {3, 4, 5};
378
379 for (size_t i = 0; i < sizeof(test_pins) / sizeof(test_pins[0]); i++) {
380 meshx_err_t result = meshx_pwm_start(test_pins[i]);
381 if (result != MESHX_SUCCESS) {
383 "FAIL: Starting PWM on pin %u failed: %d", test_pins[i], result);
384 return result;
385 }
386
387 test_state.pwm_started[test_pins[i]] = true;
388 test_state.pwm_channels[test_pins[i]] = i; // Assume sequential channel allocation
389
390 // Set different parameters for each pin
391 result = meshx_pwm_set_frequency(test_pins[i], 1000 + (i * 1000));
392 if (result != MESHX_SUCCESS) {
394 "FAIL: Setting frequency on pin %u failed: %d", test_pins[i], result);
395 return result;
396 }
397
398 result = meshx_pwm_set_duty_cycle(test_pins[i], 25 * (i + 1));
399 if (result != MESHX_SUCCESS) {
401 "FAIL: Setting duty cycle on pin %u failed: %d", test_pins[i], result);
402 return result;
403 }
404 }
405
406 // Verify each pin maintains its own state
407 for (size_t i = 0; i < sizeof(test_pins) / sizeof(test_pins[0]); i++) {
408 uint32_t read_frequency;
409 meshx_err_t result = meshx_pwm_get_frequency(test_pins[i], &read_frequency);
410 if (result != MESHX_SUCCESS) {
412 "FAIL: Getting frequency from pin %u failed: %d", test_pins[i], result);
413 return result;
414 }
415
416 uint8_t read_duty_cycle;
417 result = meshx_pwm_get_duty_cycle(test_pins[i], &read_duty_cycle);
418 if (result != MESHX_SUCCESS) {
420 "FAIL: Getting duty cycle from pin %u failed: %d", test_pins[i], result);
421 return result;
422 }
423
424 // Clean up
425 result = meshx_pwm_stop(test_pins[i]);
426 if (result != MESHX_SUCCESS) {
428 "FAIL: Stopping PWM on pin %u failed: %d", test_pins[i], result);
429 return result;
430 }
431
432 test_state.pwm_started[test_pins[i]] = false;
433 }
434
435 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.6 - Hardware channel allocation and conflict handling");
436 return MESHX_SUCCESS;
437}
@ MESHX_ERR_GPIO_NOT_INITIALIZED
Definition meshx_err.h:70
meshx_err_t meshx_pwm_get_frequency(uint8_t logical_pin, uint32_t *frequency)
Get PWM frequency.
Definition meshx_pwm.c:562
meshx_err_t meshx_pwm_set_duty_cycle(uint8_t logical_pin, uint8_t duty_cycle)
Set PWM duty cycle.
Definition meshx_pwm.c:433
meshx_err_t meshx_pwm_stop(uint8_t logical_pin)
Stop PWM output on pin.
Definition meshx_pwm.c:373
meshx_err_t meshx_pwm_start(uint8_t logical_pin)
Start PWM output on pin.
Definition meshx_pwm.c:295
meshx_err_t meshx_pwm_get_duty_cycle(uint8_t logical_pin, uint8_t *duty_cycle)
Get PWM duty cycle.
Definition meshx_pwm.c:480
meshx_err_t meshx_pwm_set_frequency(uint8_t logical_pin, uint32_t frequency)
Set PWM frequency.
Definition meshx_pwm.c:515

◆ test_property_deinit_cleanup()

meshx_err_t test_property_deinit_cleanup ( void )
static

Property 4.8: Deinitialization and resource cleanup.

Tests that PWM subsystem deinitializes and cleans up resources during shutdown.

555{
556 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.8: Deinitialization and resource cleanup");
557
558 if (!test_state.pwm_initialized) {
559 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM not initialized");
561 }
562
563 // Test deinitialization
564 meshx_err_t result = meshx_pwm_deinit();
565 if (result != MESHX_SUCCESS) {
566 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM deinitialization failed: %d", result);
567 return MESHX_FAIL;
568 }
569
570 test_state.pwm_initialized = false;
571
572 // Verify PWM operations fail after deinitialization
573 // (This depends on implementation - may return MESHX_ERR_GPIO_NOT_INITIALIZED
574 // or may re-initialize automatically)
575 result = meshx_pwm_start(200); // Definitely invalid (> 128)
576 if (result != MESHX_SUCCESS && result != MESHX_ERR_GPIO_NOT_INITIALIZED) {
578 "FAIL: Unexpected error after deinitialization: %d", result);
579 return MESHX_FAIL;
580 }
581
582 // Test re-initialization
583 result = meshx_pwm_init();
584 if (result != MESHX_SUCCESS) {
585 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM re-initialization failed: %d", result);
586 return MESHX_FAIL;
587 }
588
589 test_state.pwm_initialized = true;
590
591 // Verify PWM can be used again after re-initialization
593 result = meshx_pwm_start(7);
594 if (result != MESHX_SUCCESS) {
596 "FAIL: Cannot use PWM after re-initialization: %d", result);
597 return MESHX_FAIL;
598 }
599
600 // Clean up
601 result = meshx_pwm_stop(7);
602 if (result != MESHX_SUCCESS) {
603 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Failed to stop PWM after test: %d", result);
604 return result;
605 }
606
607 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.8 - Deinitialization and resource cleanup");
608 return MESHX_SUCCESS;
609}
@ MESHX_GPIO_MODE_PWM_OUTPUT
Definition meshx_gpio.h:34
void meshx_gpio_test_set_pin_mode(uint8_t pin, meshx_gpio_mode_t mode)

◆ test_property_duty_cycle_accuracy()

meshx_err_t test_property_duty_cycle_accuracy ( void )
static

Property 4.3: Duty cycle accuracy.

Tests that duty cycle can be set and get accurately (0-100%).

162{
163 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.3: Duty cycle accuracy");
164
165 if (!test_state.pwm_initialized) {
166 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM not initialized");
168 }
169
170 uint8_t test_pin = 6;
171 meshx_pwm_start(test_pin);
172 test_state.pwm_started[test_pin] = true;
173
174 // Test valid duty cycle values
175 const uint8_t test_duty_cycles[] = {0, 25, 50, 75, 100};
176
177 for (size_t i = 0; i < sizeof(test_duty_cycles) / sizeof(test_duty_cycles[0]); i++) {
178 // Set duty cycle
179 meshx_err_t result = meshx_pwm_set_duty_cycle(test_pin, test_duty_cycles[i]);
180 if (result != MESHX_SUCCESS) {
182 "FAIL: Setting duty cycle %u%% failed: %d", test_duty_cycles[i], result);
183 return result;
184 }
185
186 test_state.pwm_duty_cycles[test_pin] = test_duty_cycles[i];
187
188 // Get duty cycle and verify
189 uint8_t read_duty_cycle;
190 result = meshx_pwm_get_duty_cycle(test_pin, &read_duty_cycle);
191 if (result != MESHX_SUCCESS) {
193 "FAIL: Getting duty cycle failed: %d", result);
194 return result;
195 }
196
197 if (read_duty_cycle != test_duty_cycles[i]) {
199 "FAIL: Duty cycle mismatch: set %u%%, got %u%%",
200 test_duty_cycles[i], read_duty_cycle);
201 return MESHX_FAIL;
202 }
203
204 // Verify test state matches
205 if (test_state.pwm_duty_cycles[test_pin] != read_duty_cycle) {
207 "FAIL: Test state mismatch: test_state=%u%%, read=%u%%",
208 test_state.pwm_duty_cycles[test_pin], read_duty_cycle);
209 return MESHX_FAIL;
210 }
211 }
212
213 // Test invalid duty cycle values (should fail)
214 const uint8_t invalid_duty_cycles[] = {101, 255};
215
216 for (size_t i = 0; i < sizeof(invalid_duty_cycles) / sizeof(invalid_duty_cycles[0]); i++) {
217 meshx_err_t result = meshx_pwm_set_duty_cycle(test_pin, invalid_duty_cycles[i]);
218 if (result != MESHX_ERR_GPIO_PWM_INVALID_PARAM) {
220 "FAIL: Invalid duty cycle %u should return MESHX_ERR_GPIO_PWM_INVALID_PARAM, got: %d",
221 invalid_duty_cycles[i], result);
222 return MESHX_FAIL;
223 }
224 }
225
226 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.3 - Duty cycle accuracy");
227 meshx_pwm_stop(test_pin);
228 return MESHX_SUCCESS;
229}
@ MESHX_ERR_GPIO_PWM_INVALID_PARAM
Definition meshx_err.h:69

◆ test_property_frequency_accuracy()

meshx_err_t test_property_frequency_accuracy ( void )
static

Property 4.4: Frequency accuracy.

Tests that frequency can be set and get accurately.

237{
238 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.4: Frequency accuracy");
239
240 if (!test_state.pwm_initialized) {
241 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM not initialized");
243 }
244
245 uint8_t test_pin = 6;
246 meshx_pwm_start(test_pin);
247 test_state.pwm_started[test_pin] = true;
248
249 // Test valid frequency values (typical PWM frequencies)
250 const uint32_t test_frequencies[] = {100, 500, 1000, 5000, 10000, 20000};
251
252 for (size_t i = 0; i < sizeof(test_frequencies) / sizeof(test_frequencies[0]); i++) {
253 // Set frequency
254 meshx_err_t result = meshx_pwm_set_frequency(test_pin, test_frequencies[i]);
255 if (result != MESHX_SUCCESS) {
257 "FAIL: Setting frequency %u Hz failed: %d", test_frequencies[i], result);
258 return result;
259 }
260
261 test_state.pwm_frequencies[test_pin] = test_frequencies[i];
262
263 // Get frequency and verify
264 uint32_t read_frequency;
265 result = meshx_pwm_get_frequency(test_pin, &read_frequency);
266 if (result != MESHX_SUCCESS) {
268 "FAIL: Getting frequency failed: %d", result);
269 return result;
270 }
271
272 if (read_frequency != test_frequencies[i]) {
274 "FAIL: Frequency mismatch: set %u Hz, got %u Hz",
275 test_frequencies[i], read_frequency);
276 return MESHX_FAIL;
277 }
278
279 // Verify test state matches
280 if (test_state.pwm_frequencies[test_pin] != read_frequency) {
282 "FAIL: Test state mismatch: test_state=%u Hz, read=%u Hz",
283 test_state.pwm_frequencies[test_pin], read_frequency);
284 return MESHX_FAIL;
285 }
286 }
287
288 // Test zero frequency (should fail)
289 meshx_err_t result = meshx_pwm_set_frequency(test_pin, 0);
290 if (result != MESHX_ERR_GPIO_PWM_INVALID_PARAM) {
292 "FAIL: Zero frequency should return MESHX_ERR_GPIO_PWM_INVALID_PARAM, got: %d", result);
293 return MESHX_FAIL;
294 }
295
296 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.4 - Frequency accuracy");
297 meshx_pwm_stop(test_pin);
298 return MESHX_SUCCESS;
299}

◆ test_property_parameter_validation()

meshx_err_t test_property_parameter_validation ( void )
static

Property 4.5: Parameter validation against hardware limits.

Tests that PWM parameters are validated against hardware limits.

307{
308 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.5: Parameter validation against hardware limits");
309
310 if (!test_state.pwm_initialized) {
311 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM not initialized");
313 }
314
315 uint8_t test_pin = 6;
316 meshx_pwm_start(test_pin);
317 test_state.pwm_started[test_pin] = true;
318
319 // Test resolution parameter validation
320 const uint8_t test_resolutions[] = {8, 10, 12, 16};
321
322 for (size_t i = 0; i < sizeof(test_resolutions) / sizeof(test_resolutions[0]); i++) {
323 meshx_err_t result = meshx_pwm_set_resolution(test_pin, test_resolutions[i]);
324 if (result != MESHX_SUCCESS) {
326 "FAIL: Setting resolution %u bits failed: %d", test_resolutions[i], result);
327 return result;
328 }
329
330 test_state.pwm_resolutions[test_pin] = test_resolutions[i];
331
332 // Get resolution and verify
333 uint8_t read_resolution;
334 result = meshx_pwm_get_resolution(test_pin, &read_resolution);
335 if (result != MESHX_SUCCESS) {
337 "FAIL: Getting resolution failed: %d", result);
338 return result;
339 }
340
341 if (read_resolution != test_resolutions[i]) {
343 "FAIL: Resolution mismatch: set %u bits, got %u bits",
344 test_resolutions[i], read_resolution);
345 return MESHX_FAIL;
346 }
347 }
348
349 // Test invalid resolution (should fail)
350 meshx_err_t result = meshx_pwm_set_resolution(test_pin, 0); // 0-bit resolution invalid
351 if (result != MESHX_ERR_GPIO_PWM_INVALID_PARAM) {
353 "FAIL: Invalid resolution should return MESHX_ERR_GPIO_PWM_INVALID_PARAM, got: %d", result);
354 return MESHX_FAIL;
355 }
356
357 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.5 - Parameter validation against hardware limits");
358 meshx_pwm_stop(test_pin);
359 return MESHX_SUCCESS;
360}
meshx_err_t meshx_pwm_set_resolution(uint8_t logical_pin, uint8_t resolution)
Set PWM resolution.
Definition meshx_pwm.c:597
meshx_err_t meshx_pwm_get_resolution(uint8_t logical_pin, uint8_t *resolution)
Get PWM resolution.
Definition meshx_pwm.c:634

◆ test_property_pwm_initialization()

meshx_err_t test_property_pwm_initialization ( void )
static

Property 4.1: PWM initialization based on configuration.

Tests that PWM subsystem initializes correctly based on YAML configuration.

85{
86 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.1: PWM initialization based on configuration");
87
88 // Test PWM subsystem initialization
89 meshx_err_t result = meshx_pwm_init();
90 if (result != MESHX_SUCCESS) {
91 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM initialization failed: %d", result);
92 return MESHX_FAIL;
93 }
94
95 test_state.pwm_initialized = true;
96 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.1 - PWM initialization based on configuration");
97 return MESHX_SUCCESS;
98}

◆ test_property_pwm_start_stop()

meshx_err_t test_property_pwm_start_stop ( void )
static

Property 4.2: PWM start and stop operations.

Tests that PWM can be started and stopped as requested.

106{
107 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.2: PWM start and stop operations");
108
109 if (!test_state.pwm_initialized) {
110 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM not initialized");
112 }
113
114 uint8_t test_pin = 6; // Use safe Xiao C3 pin
115 uint32_t test_frequency = 1000; // 1kHz
116 uint8_t test_duty_cycle = 50; // 50%
117 uint8_t test_resolution = 10; // 10-bit resolution
118
119 // Test starting PWM
121 meshx_err_t result = meshx_pwm_start(test_pin);
122 if (result != MESHX_SUCCESS) {
123 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM start failed: %d", result);
124 return result;
125 }
126
127 test_state.pwm_started[test_pin] = true;
128 test_state.pwm_frequencies[test_pin] = test_frequency;
129 test_state.pwm_duty_cycles[test_pin] = test_duty_cycle;
130 test_state.pwm_resolutions[test_pin] = test_resolution;
131
132 // Verify PWM is running (implementation dependent)
133 // For now, just verify no error on subsequent operations
134
135 // Test stopping PWM
136 result = meshx_pwm_stop(test_pin);
137 if (result != MESHX_SUCCESS) {
138 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM stop failed: %d", result);
139 return result;
140 }
141
142 test_state.pwm_started[test_pin] = false;
143
144 // Test stopping already stopped PWM (should succeed or return appropriate error)
145 result = meshx_pwm_stop(test_pin);
146 if (result != MESHX_SUCCESS && result != MESHX_ERR_GPIO_PWM_NOT_SUPPORTED) {
148 "FAIL: Stopping already stopped PWM returned unexpected error: %d", result);
149 return MESHX_FAIL;
150 }
151
152 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.2 - PWM start and stop operations");
153 return MESHX_SUCCESS;
154}
@ MESHX_ERR_GPIO_PWM_NOT_SUPPORTED
Definition meshx_err.h:68

◆ test_property_state_maintenance()

meshx_err_t test_property_state_maintenance ( void )
static

Property 4.7: PWM state maintenance.

Tests that PWM state is maintained for runtime control and monitoring.

445{
446 MESHX_LOGD(MODULE_ID_COMMON, "Testing Property 4.7: PWM state maintenance");
447
448 if (!test_state.pwm_initialized) {
449 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: PWM not initialized");
451 }
452
453 uint8_t test_pin = 6;
454 meshx_pwm_start(test_pin);
455 test_state.pwm_started[test_pin] = true;
456
457 // Test state persistence across multiple operations
458 const struct {
459 uint32_t frequency;
460 uint8_t duty_cycle;
461 uint8_t resolution;
462 const char* description;
463 } state_changes[] = {
464 {1000, 25, 8, "Initial state"},
465 {2000, 50, 10, "Increased frequency and duty"},
466 {500, 75, 12, "Decreased frequency, increased duty"},
467 {1500, 10, 16, "Medium frequency, low duty"},
468 };
469
470 for (size_t i = 0; i < sizeof(state_changes) / sizeof(state_changes[0]); i++) {
471 // Set all parameters
472 meshx_err_t result = meshx_pwm_set_frequency(test_pin, state_changes[i].frequency);
473 if (result != MESHX_SUCCESS) {
474 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Setting frequency for %s failed: %d",
475 state_changes[i].description, result);
476 return result;
477 }
478
479 result = meshx_pwm_set_duty_cycle(test_pin, state_changes[i].duty_cycle);
480 if (result != MESHX_SUCCESS) {
481 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Setting duty cycle for %s failed: %d",
482 state_changes[i].description, result);
483 return result;
484 }
485
486 result = meshx_pwm_set_resolution(test_pin, state_changes[i].resolution);
487 if (result != MESHX_SUCCESS) {
488 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Setting resolution for %s failed: %d",
489 state_changes[i].description, result);
490 return result;
491 }
492
493 // Update test state
494 test_state.pwm_frequencies[test_pin] = state_changes[i].frequency;
495 test_state.pwm_duty_cycles[test_pin] = state_changes[i].duty_cycle;
496 test_state.pwm_resolutions[test_pin] = state_changes[i].resolution;
497
498 // Verify all parameters can be retrieved
499 uint32_t read_frequency;
500 result = meshx_pwm_get_frequency(test_pin, &read_frequency);
501 if (result != MESHX_SUCCESS) {
502 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Getting frequency for %s failed: %d",
503 state_changes[i].description, result);
504 return result;
505 }
506
507 uint8_t read_duty_cycle;
508 result = meshx_pwm_get_duty_cycle(test_pin, &read_duty_cycle);
509 if (result != MESHX_SUCCESS) {
510 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Getting duty cycle for %s failed: %d",
511 state_changes[i].description, result);
512 return result;
513 }
514
515 uint8_t read_resolution;
516 result = meshx_pwm_get_resolution(test_pin, &read_resolution);
517 if (result != MESHX_SUCCESS) {
518 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Getting resolution for %s failed: %d",
519 state_changes[i].description, result);
520 return result;
521 }
522
523 // Verify state consistency
524 if (read_frequency != state_changes[i].frequency ||
525 read_duty_cycle != state_changes[i].duty_cycle ||
526 read_resolution != state_changes[i].resolution) {
528 "FAIL: State inconsistency for %s: expected %u Hz, %u%%, %u bits; got %u Hz, %u%%, %u bits",
529 state_changes[i].description,
530 state_changes[i].frequency, state_changes[i].duty_cycle, state_changes[i].resolution,
531 read_frequency, read_duty_cycle, read_resolution);
532 return MESHX_FAIL;
533 }
534 }
535
536 // Clean up
537 meshx_err_t result = meshx_pwm_stop(test_pin);
538 if (result != MESHX_SUCCESS) {
539 MESHX_LOGE(MODULE_ID_COMMON, "FAIL: Stopping PWM failed: %d", result);
540 return result;
541 }
542
543 test_state.pwm_started[test_pin] = false;
544
545 MESHX_LOGD(MODULE_ID_COMMON, "PASS: Property 4.7 - PWM state maintenance");
546 return MESHX_SUCCESS;
547}

Variable Documentation

◆ test_state

pwm_test_state_t test_state
static