Updated Drivers

This commit is contained in:
Kevin Thomas
2026-03-23 09:33:04 -04:00
parent 6ee30d0520
commit 91faba6800
31 changed files with 827 additions and 337 deletions
+30 -12
View File
@@ -44,22 +44,40 @@
#define PWM_PIN 0
#define PWM_FREQ_HZ 1000
/**
* @brief Sweep the PWM duty cycle between start and end in given steps
*
* Iterates from start to end with the given step increment, updating
* the PWM duty cycle and printing each value with a 50 ms delay.
*
* @param start Starting duty percentage
* @param end Ending duty percentage
* @param step Increment per iteration (negative for descending)
*/
static void _sweep_duty(int start, int end, int step) {
for (int duty = start; (step > 0) ? duty <= end : duty >= end; duty += step) {
pwm_driver_set_duty_percent((uint8_t)duty);
printf("Duty: %3d%%\r\n", duty);
sleep_ms(50);
}
}
/**
* @brief Application entry point for the PWM LED breathing demo
*
* Initializes PWM at 1 kHz and sweeps the duty cycle up and down
* to produce a smooth LED breathing effect, reporting over UART.
*
* @return int Does not return
*/
int main(void) {
stdio_init_all();
pwm_driver_init(PWM_PIN, PWM_FREQ_HZ);
printf("PWM driver initialized: GPIO%d @ %d Hz\r\n", PWM_PIN, PWM_FREQ_HZ);
while (true) {
for (int duty = 0; duty <= 100; duty += 5) {
pwm_driver_set_duty_percent((uint8_t)duty);
printf("Duty: %3d%%\r\n", duty);
sleep_ms(50);
}
for (int duty = 100; duty >= 0; duty -= 5) {
pwm_driver_set_duty_percent((uint8_t)duty);
printf("Duty: %3d%%\r\n", duty);
sleep_ms(50);
}
_sweep_duty(0, 100, 5);
_sweep_duty(100, 0, -5);
}
}
+23 -8
View File
@@ -36,6 +36,7 @@ static uint pwm_slice;
static uint pwm_chan;
static uint32_t pwm_wrap;
/**
* @brief Compute the PWM clock divider that yields the target frequency
*
@@ -47,24 +48,38 @@ static uint32_t pwm_wrap;
* @param wrap_val Chosen PWM counter wrap value (period - 1)
* @return float Clock divider to program into the PWM slice
*/
static float calc_clk_div(uint32_t freq_hz, uint32_t wrap_val) {
static float _calc_clk_div(uint32_t freq_hz, uint32_t wrap_val) {
uint32_t sys_hz = clock_get_hz(clk_sys);
return (float)sys_hz / ((float)freq_hz * (float)(wrap_val + 1));
}
/**
* @brief Apply the PWM configuration to the active slice
*
* Builds a default config, sets the clock divider for the target frequency,
* programs the wrap value, starts the slice, and zeroes the channel level.
*
* @param freq_hz Desired PWM output frequency in Hz
*/
static void _apply_pwm_config(uint32_t freq_hz) {
pwm_config cfg = pwm_get_default_config();
pwm_config_set_clkdiv(&cfg, _calc_clk_div(freq_hz, pwm_wrap));
pwm_config_set_wrap(&cfg, pwm_wrap);
pwm_init(pwm_slice, &cfg, true);
pwm_set_chan_level(pwm_slice, pwm_chan, 0);
}
void pwm_driver_init(uint32_t pin, uint32_t freq_hz) {
gpio_set_function(pin, GPIO_FUNC_PWM);
pwm_slice = pwm_gpio_to_slice_num(pin);
pwm_chan = pwm_gpio_to_channel(pin);
pwm_wrap = 10000 - 1; // resolution: 0.01% steps
pwm_config cfg = pwm_get_default_config();
pwm_config_set_clkdiv(&cfg, calc_clk_div(freq_hz, pwm_wrap));
pwm_config_set_wrap(&cfg, pwm_wrap);
pwm_init(pwm_slice, &cfg, true);
pwm_set_chan_level(pwm_slice, pwm_chan, 0);
pwm_wrap = 10000 - 1;
_apply_pwm_config(freq_hz);
}
void pwm_driver_set_duty_percent(uint8_t percent) {
if (percent > 100) {
percent = 100;