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
meshx_pwm.h File Reference

MeshX PWM Interface. More...

#include <stdint.h>
#include "../../inc/meshx_err.h"

Go to the source code of this file.

Functions

meshx_err_t meshx_pwm_init (void)
 Initialize PWM subsystem.
meshx_err_t meshx_pwm_deinit (void)
 Deinitialize PWM subsystem.
meshx_err_t meshx_pwm_start (uint8_t logical_pin)
 Start PWM output on pin.
meshx_err_t meshx_pwm_stop (uint8_t logical_pin)
 Stop PWM output on pin.
meshx_err_t meshx_pwm_set_duty_cycle (uint8_t logical_pin, uint8_t duty_cycle)
 Set PWM duty cycle.
meshx_err_t meshx_pwm_get_duty_cycle (uint8_t logical_pin, uint8_t *duty_cycle)
 Get PWM duty cycle.
meshx_err_t meshx_pwm_set_frequency (uint8_t logical_pin, uint32_t frequency)
 Set PWM frequency.
meshx_err_t meshx_pwm_get_frequency (uint8_t logical_pin, uint32_t *frequency)
 Get PWM frequency.
meshx_err_t meshx_pwm_set_resolution (uint8_t logical_pin, uint8_t resolution)
 Set PWM resolution.
meshx_err_t meshx_pwm_get_resolution (uint8_t logical_pin, uint8_t *resolution)
 Get PWM resolution.

Detailed Description

MeshX PWM Interface.

This file defines the MeshX PWM interface for platform-abstracted PWM operations.

Author
MeshX Team
Date
2024

Function Documentation

◆ meshx_pwm_deinit()

meshx_err_t meshx_pwm_deinit ( void )

Deinitialize PWM subsystem.

This function deinitializes the PWM subsystem and releases all resources.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure

This function deinitializes the PWM subsystem and releases all resources. It stops all PWM outputs, deconfigures channels, and cleans up platform resources.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
120{
121 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Deinitializing PWM subsystem");
122
123 if (!pwm_runtime.initialized) {
124 MESHX_LOGW(MODULE_ID_COMPONENT_MESHX_GPIO, "PWM not initialized");
125 return MESHX_SUCCESS;
126 }
127
128 // Stop all active PWM outputs
129 for (uint8_t i = 0; i < pwm_runtime.pwm_pin_count; i++) {
130 if (pwm_runtime.pwm_states != NULL && pwm_runtime.pwm_states[i].started) {
132 }
133 }
134
135 // Deinitialize platform-specific PWM
137 if (err != MESHX_SUCCESS) {
138 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Platform PWM deinit failed: %d", err);
139 return err;
140 }
141
142 // Free allocated resources
143 // Note: In actual implementation, these would be freed if dynamically allocated
144 // For now, just reset pointers since they're statically allocated or NULL
145 pwm_runtime.pwm_configs = NULL;
146 pwm_runtime.pwm_states = NULL;
147 memset(pwm_runtime.channel_allocation, 0xFF, sizeof(pwm_runtime.channel_allocation));
148 pwm_runtime.allocated_channels = 0;
149
150 pwm_runtime.initialized = false;
151 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "PWM subsystem deinitialized");
152 return MESHX_SUCCESS;
153}
meshx_err_t
MeshX Error Codes.
Definition meshx_err.h:43
meshx_err_t meshx_pwm_platform_deinit(void)
Platform-specific PWM deinitialization.
#define MESHX_LOGW(module_id, format,...)
Definition meshx_log.h:120
#define MESHX_LOGE(module_id, format,...)
Definition meshx_log.h:114
#define MESHX_LOGD(module_id, format,...)
Definition meshx_log.h:132
**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_err_t meshx_pwm_stop(uint8_t logical_pin)
Stop PWM output on pin.
Definition meshx_pwm.c:373
static meshx_pwm_runtime_t pwm_runtime
Definition meshx_pwm.c:54
@ MODULE_ID_COMPONENT_MESHX_GPIO
Definition module_id.h:44

◆ meshx_pwm_get_duty_cycle()

meshx_err_t meshx_pwm_get_duty_cycle ( uint8_t logical_pin,
uint8_t * duty_cycle )

Get PWM duty cycle.

Parameters
logical_pinLogical pin number (0-255)
[out]duty_cyclePointer to store duty cycle
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
481{
482 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Getting PWM duty cycle from pin %u", logical_pin);
483
484 if (duty_cycle == NULL) {
485 return MESHX_INVALID_ARG;
486 }
487
488 // Validate pin
489 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
490 if (err != MESHX_SUCCESS) {
491 return err;
492 }
493
494 // Check if PWM is started
495 if (pwm_runtime.pwm_states == NULL || !pwm_runtime.pwm_states[logical_pin].started) {
497 }
498
499 // TODO: Get from platform-specific implementation
500 // For now, return from runtime state
501 *duty_cycle = pwm_runtime.pwm_states[logical_pin].duty_cycle;
502
504 "PWM duty cycle on pin %u is %u%%", logical_pin, *duty_cycle);
505 return MESHX_SUCCESS;
506}
@ MESHX_INVALID_ARG
Definition meshx_err.h:46
@ MESHX_ERR_GPIO_PWM_NOT_SUPPORTED
Definition meshx_err.h:68
static meshx_err_t validate_pwm_logical_pin(uint8_t logical_pin)
Validate logical pin number for PWM.
Definition meshx_pwm.c:161

◆ meshx_pwm_get_frequency()

meshx_err_t meshx_pwm_get_frequency ( uint8_t logical_pin,
uint32_t * frequency )

Get PWM frequency.

Parameters
logical_pinLogical pin number (0-255)
[out]frequencyPointer to store frequency
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
563{
564 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Getting PWM frequency from pin %u", logical_pin);
565
566 if (frequency == NULL) {
567 return MESHX_INVALID_ARG;
568 }
569
570 // Validate pin
571 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
572 if (err != MESHX_SUCCESS) {
573 return err;
574 }
575
576 // Check if PWM is started
577 if (pwm_runtime.pwm_states == NULL || !pwm_runtime.pwm_states[logical_pin].started) {
579 }
580
581 // TODO: Get from platform-specific implementation
582 // For now, return from runtime state
583 *frequency = pwm_runtime.pwm_states[logical_pin].frequency;
584
586 "PWM frequency on pin %u is %u Hz", logical_pin, *frequency);
587 return MESHX_SUCCESS;
588}

◆ meshx_pwm_get_resolution()

meshx_err_t meshx_pwm_get_resolution ( uint8_t logical_pin,
uint8_t * resolution )

Get PWM resolution.

Parameters
logical_pinLogical pin number (0-255)
[out]resolutionPointer to store resolution
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
635{
636 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Getting PWM resolution from pin %u", logical_pin);
637
638 if (resolution == NULL) {
639 return MESHX_INVALID_ARG;
640 }
641
642 // Validate pin
643 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
644 if (err != MESHX_SUCCESS) {
645 return err;
646 }
647
648 // Check if PWM is started
649 if (pwm_runtime.pwm_states == NULL || !pwm_runtime.pwm_states[logical_pin].started) {
651 }
652
653 // TODO: Get from platform-specific implementation
654 // For now, return from runtime state
655 *resolution = pwm_runtime.pwm_states[logical_pin].resolution;
656
658 "PWM resolution on pin %u is %u bits", logical_pin, *resolution);
659 return MESHX_SUCCESS;
660}

◆ meshx_pwm_init()

meshx_err_t meshx_pwm_init ( void )

Initialize PWM subsystem.

This function initializes the PWM subsystem based on YAML configuration.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure

This function initializes the PWM subsystem based on compiled configuration. It sets up hardware PWM channels and configures all PWM pins according to their YAML configuration.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
70{
71 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Initializing PWM subsystem");
72
73 if (pwm_runtime.initialized) {
74 MESHX_LOGW(MODULE_ID_COMPONENT_MESHX_GPIO, "PWM already initialized");
75 return MESHX_SUCCESS;
76 }
77
78 // Initialize platform-specific PWM
80 if (err != MESHX_SUCCESS) {
81 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Platform PWM init failed: %d", err);
82 return err;
83 }
84
85 // TODO: Load configuration from generated headers
86 // For now, initialize with empty configuration
87 pwm_runtime.pwm_pin_count = 0;
88 pwm_runtime.pwm_configs = NULL;
89 pwm_runtime.pwm_states = NULL;
90 memset(pwm_runtime.channel_allocation, 0xFF, sizeof(pwm_runtime.channel_allocation));
91 pwm_runtime.allocated_channels = 0;
92
93 pwm_runtime.initialized = true;
94#if CONFIG_ENABLE_UNIT_TEST
95 pwm_runtime.pwm_pin_count = 128;
96 pwm_runtime.pwm_configs = test_pwm_configs;
97 pwm_runtime.pwm_states = test_pwm_states;
98 memset(test_pwm_configs, 0, sizeof(test_pwm_configs));
99 memset(test_pwm_states, 0, sizeof(test_pwm_states));
100 for (int i = 0; i < 128; i++) {
101 test_pwm_configs[i].logical_pin = i;
102 test_pwm_configs[i].channel = 0xFF;
103 test_pwm_configs[i].frequency = 1000;
104 test_pwm_configs[i].resolution = 10;
105 }
106#endif
107 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "PWM subsystem initialized");
108 return MESHX_SUCCESS;
109}
meshx_err_t meshx_pwm_platform_init(void)
Platform-specific PWM initialization.
static meshx_pwm_config_t test_pwm_configs[128]
Definition meshx_pwm.c:56
static meshx_pwm_state_t test_pwm_states[128]
Definition meshx_pwm.c:57

◆ meshx_pwm_set_duty_cycle()

meshx_err_t meshx_pwm_set_duty_cycle ( uint8_t logical_pin,
uint8_t duty_cycle )

Set PWM duty cycle.

Parameters
logical_pinLogical pin number (0-255)
duty_cycleDuty cycle (0-100%)
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
434{
436 "Setting PWM duty cycle on pin %u to %u%%", logical_pin, duty_cycle);
437
438 // Validate pin
439 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
440 if (err != MESHX_SUCCESS) {
441 return err;
442 }
443
444 // Validate duty cycle
445 err = validate_pwm_duty_cycle(duty_cycle);
446 if (err != MESHX_SUCCESS) {
447 return err;
448 }
449
450 // Check if PWM is started
451 if (pwm_runtime.pwm_states == NULL || !pwm_runtime.pwm_states[logical_pin].started) {
453 }
454
455 // TODO: Get physical pin from logical pin mapping
456 // For now, use logical pin as physical pin (simplified)
457 uint8_t physical_pin = logical_pin;
458
459 // Set platform-specific PWM duty cycle
460 err = meshx_pwm_platform_set_duty_cycle(physical_pin, duty_cycle);
461 if (err != MESHX_SUCCESS) {
462 return err;
463 }
464
465 // Update runtime state
466 pwm_runtime.pwm_states[logical_pin].duty_cycle = duty_cycle;
467
469 "PWM duty cycle set on pin %u to %u%%", logical_pin, duty_cycle);
470 return MESHX_SUCCESS;
471}
meshx_err_t meshx_pwm_platform_set_duty_cycle(uint8_t physical_pin, uint8_t duty_cycle)
Platform-specific PWM duty cycle set.
static meshx_err_t validate_pwm_duty_cycle(uint8_t duty_cycle)
Validate PWM duty cycle.
Definition meshx_pwm.c:207

◆ meshx_pwm_set_frequency()

meshx_err_t meshx_pwm_set_frequency ( uint8_t logical_pin,
uint32_t frequency )

Set PWM frequency.

Parameters
logical_pinLogical pin number (0-255)
frequencyFrequency in Hz
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
516{
518 "Setting PWM frequency on pin %u to %u Hz", logical_pin, frequency);
519
520 // Validate pin
521 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
522 if (err != MESHX_SUCCESS) {
523 return err;
524 }
525
526 // Validate frequency
527 err = validate_pwm_frequency(frequency);
528 if (err != MESHX_SUCCESS) {
529 return err;
530 }
531
532 // Check if PWM is started
533 if (pwm_runtime.pwm_states == NULL || !pwm_runtime.pwm_states[logical_pin].started) {
535 }
536
537 // TODO: Get physical pin from logical pin mapping
538 // For now, use logical pin as physical pin (simplified)
539 uint8_t physical_pin = logical_pin;
540
541 // Set platform-specific PWM frequency
542 err = meshx_pwm_platform_set_frequency(physical_pin, frequency);
543 if (err != MESHX_SUCCESS) {
544 return err;
545 }
546
547 // Update runtime state
548 pwm_runtime.pwm_states[logical_pin].frequency = frequency;
549
551 "PWM frequency set on pin %u to %u Hz", logical_pin, frequency);
552 return MESHX_SUCCESS;
553}
meshx_err_t meshx_pwm_platform_set_frequency(uint8_t physical_pin, uint32_t frequency)
Platform-specific PWM frequency set.
static meshx_err_t validate_pwm_frequency(uint32_t frequency)
Validate PWM frequency.
Definition meshx_pwm.c:186

◆ meshx_pwm_set_resolution()

meshx_err_t meshx_pwm_set_resolution ( uint8_t logical_pin,
uint8_t resolution )

Set PWM resolution.

Parameters
logical_pinLogical pin number (0-255)
resolutionResolution in bits (typically 8-16)
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
598{
600 "Setting PWM resolution on pin %u to %u bits", logical_pin, resolution);
601
602 // Validate pin
603 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
604 if (err != MESHX_SUCCESS) {
605 return err;
606 }
607
608 // Validate resolution
609 err = validate_pwm_resolution(resolution);
610 if (err != MESHX_SUCCESS) {
611 return err;
612 }
613
614 // Check if PWM is started
615 if (pwm_runtime.pwm_states == NULL || !pwm_runtime.pwm_states[logical_pin].started) {
617 }
618
619 // Update runtime state
620 pwm_runtime.pwm_states[logical_pin].resolution = resolution;
621
623 "PWM resolution set on pin %u to %u bits", logical_pin, resolution);
624 return MESHX_SUCCESS;
625}
static meshx_err_t validate_pwm_resolution(uint8_t resolution)
Validate PWM resolution.
Definition meshx_pwm.c:222

◆ meshx_pwm_start()

meshx_err_t meshx_pwm_start ( uint8_t logical_pin)

Start PWM output on pin.

Parameters
logical_pinLogical pin number (0-255)
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
296{
297 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Starting PWM on pin %u", logical_pin);
298
299 // Validate pin
300 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
301 if (err != MESHX_SUCCESS) {
302 return err;
303 }
304
305 // Check if already started
306 if (pwm_runtime.pwm_states != NULL && pwm_runtime.pwm_states[logical_pin].started) {
307 MESHX_LOGW(MODULE_ID_COMPONENT_MESHX_GPIO, "PWM already started on pin %u", logical_pin);
308 return MESHX_SUCCESS;
309 }
310
311 // Get configuration
312 uint32_t frequency = 1000; // Default 1kHz
313 uint8_t duty_cycle = 50; // Default 50%
314 uint8_t resolution = 10; // Default 10-bit
315
316 if (pwm_runtime.pwm_configs != NULL) {
317 frequency = pwm_runtime.pwm_configs[logical_pin].frequency;
318 duty_cycle = pwm_runtime.pwm_configs[logical_pin].duty_cycle;
319 resolution = pwm_runtime.pwm_configs[logical_pin].resolution;
320 }
321
322 // Validate parameters
323 err = validate_pwm_frequency(frequency);
324 if (err != MESHX_SUCCESS) return err;
325
326 err = validate_pwm_duty_cycle(duty_cycle);
327 if (err != MESHX_SUCCESS) return err;
328
329 err = validate_pwm_resolution(resolution);
330 if (err != MESHX_SUCCESS) return err;
331
332 // Allocate PWM channel
333 uint8_t channel;
334 err = allocate_pwm_channel(logical_pin, &channel);
335 if (err != MESHX_SUCCESS) {
337 "Failed to allocate PWM channel for pin %u: %d", logical_pin, err);
338 return err;
339 }
340
341 // TODO: Get physical pin from logical pin mapping
342 // For now, use logical pin as physical pin (simplified)
343 uint8_t physical_pin = logical_pin;
344
345 // Start platform-specific PWM
346 err = meshx_pwm_platform_start(physical_pin, frequency, duty_cycle, resolution);
347 if (err != MESHX_SUCCESS) {
349 "Platform PWM start failed for pin %u: %d", logical_pin, err);
350 return err;
351 }
352
353 // Update runtime state
354 if (pwm_runtime.pwm_states != NULL) {
355 pwm_runtime.pwm_states[logical_pin].started = true;
356 pwm_runtime.pwm_states[logical_pin].frequency = frequency;
357 pwm_runtime.pwm_states[logical_pin].duty_cycle = duty_cycle;
358 pwm_runtime.pwm_states[logical_pin].resolution = resolution;
359 }
360
362 "PWM started on pin %u: %u Hz, %u%%, %u-bit",
363 logical_pin, frequency, duty_cycle, resolution);
364 return MESHX_SUCCESS;
365}
meshx_err_t meshx_pwm_platform_start(uint8_t physical_pin, uint32_t frequency, uint8_t duty_cycle, uint8_t resolution)
Platform-specific PWM start.
static meshx_err_t allocate_pwm_channel(uint8_t logical_pin, uint8_t *channel)
Allocate PWM channel.
Definition meshx_pwm.c:238

◆ meshx_pwm_stop()

meshx_err_t meshx_pwm_stop ( uint8_t logical_pin)

Stop PWM output on pin.

Parameters
logical_pinLogical pin number (0-255)
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
374{
375 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Stopping PWM on pin %u", logical_pin);
376
377 // Validate pin
378 meshx_err_t err = validate_pwm_logical_pin(logical_pin);
379 if (err != MESHX_SUCCESS) {
380 return err;
381 }
382
383 // Check if already stopped
384 if (pwm_runtime.pwm_states == NULL || !pwm_runtime.pwm_states[logical_pin].started) {
385 MESHX_LOGW(MODULE_ID_COMPONENT_MESHX_GPIO, "PWM already stopped on pin %u", logical_pin);
386 return MESHX_SUCCESS;
387 }
388
389 // TODO: Get physical pin from logical pin mapping
390 // For now, use logical pin as physical pin (simplified)
391 uint8_t physical_pin = logical_pin;
392
393 // Stop platform-specific PWM
394 err = meshx_pwm_platform_stop(physical_pin);
395 if (err != MESHX_SUCCESS) {
397 "Platform PWM stop failed for pin %u: %d", logical_pin, err);
398 return err;
399 }
400
401 // Free allocated channel
402 if (pwm_runtime.pwm_configs != NULL) {
403 uint8_t channel = pwm_runtime.pwm_configs[logical_pin].channel;
404 if (channel != 0xFF) {
405 // Remove from allocation tracking
406 for (uint8_t i = 0; i < pwm_runtime.allocated_channels; i++) {
407 if (pwm_runtime.channel_allocation[i] == channel) {
408 // Shift remaining channels
409 for (uint8_t j = i; j < pwm_runtime.allocated_channels - 1; j++) {
410 pwm_runtime.channel_allocation[j] = pwm_runtime.channel_allocation[j + 1];
411 }
412 pwm_runtime.allocated_channels--;
413 break;
414 }
415 }
416 }
417 }
418
419 // Update runtime state
420 pwm_runtime.pwm_states[logical_pin].started = false;
421
422 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "PWM stopped on pin %u", logical_pin);
423 return MESHX_SUCCESS;
424}
meshx_err_t meshx_pwm_platform_stop(uint8_t physical_pin)
Platform-specific PWM stop.