PWM testing, learning

Eventually I would like to drive the typical IR_LED at 38Khz (26 microseconds per cycle). I cloned Binky_PWM to start. 

I thought it prudent to flash a visible LED (led0) at 1hz to confirm I understand... It does flash, but I doubt the rate is 1hz and I don't understand at least three things:

  1. I can't set PWM_HZ(4) to anything lower than 4 or I get no flashing. I expected to enter a 1 here.
  2. I don't fully understand: ret = pwm_set_dt(&pwm_led0, period, period / 2U);  especially "period / 2U". I understand this to be the pulse width, but I expected a value similar to "50" (50%) or "13" (13µs, 50% of the duty cycle at 38Khz)
  3. I don't understand how k_msleep(xxx); works here. Any value for k_msleep doesn't seem to affect the flashing rate, however I am used to bare metal programming and only beginning to use threads, so it's unsurprising that k_msleep behavior is unclear to me.

Ultimately I wish to flash:  38Khz, 50% duty cycle

Potentially, I will also need to modulate the carrier on/off every 600us (I'm using 1ms, 10ms, etc just for my current testing). However unlike TSOP modules, the TSSP module (TSSP58038) I am looking at doesn't appear to require modulation. I thought k_msleep is how I would modulate the 38Khz every 10ms, but maybe that's not how it works.

/**
 * @file Sample app to demonstrate PWM.
 */

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/device.h>
#include <zephyr/drivers/pwm.h>

static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0));

#define ir_rate PWM_HZ(4) //value must be >=4 ???

int main(void)
{
	uint32_t period;
	int ret;

	printk("PWM-based LED Control\n");

	if (!pwm_is_ready_dt(&pwm_led0)) {
		printk("Error: PWM device %s is not ready\n",
		       pwm_led0.dev->name);
		return 0;
	}

	period = ir_rate;
	while (1) {
		ret = pwm_set_dt(&pwm_led0, period, period / 2U); //don't understand duty cycle setting???

		if (ret) {
			printk("Error %d: failed to set pulse width\n", ret);
			return 0;
		}

		k_msleep(10000); //don't understand how k_msleep works here. Doesn't seem to affect anything???
	}
	return 0;
}

Related