7.5 KiB
PWM Device
Open PWM Device
int mr_dev_open(const char *path, int flags);
| Parameter | Description |
|---|---|
| path | Device path |
| flags | Flag for opening device |
| Return Value | |
>=0 |
Device descriptor |
<0 |
Error code |
path: PWM device path usually is:pwmx、pwm1、pwm2.flags: Flag for opening device, supportMR_O_RDONLY、MR_O_WRONLY、MR_O_RDWR.
Note: When using, the PWM device should be opened separately for different tasks with the appropriate flags
for management and permission control, to ensure they will not interfere with each other.
Close PWM Device
int mr_dev_close(int desc);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| Return Value | |
=0 |
Close successfully |
<0 |
Error code |
Note: When closing the device, all channels will be automatically restored to the default configuration. The channels need to be reconfigured after reopening (can disable this feature).
Control PWM Device
int mr_dev_ioctl(int desc, int cmd, void *args);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| cmd | Command code |
| args | Command parameter |
| Return Value | |
=0 |
Set successfully |
<0 |
Error code |
cmd: Command code, support:MR_IOC_PWM_SET_CHANNEL: Set channel number.MR_IOC_PWM_SET_CHANNEL_CONFIG: Set channel configuration.MR_IOC_PWM_SET_FREQ: Set frequency.MR_IOC_PWM_GET_CHANNEL: Get channel number.MR_IOC_PWM_GET_CHANNEL_CONFIG: Get channel configuration.MR_IOC_PWM_GET_FREQ: Get frequency.
Set/Get Channel Number
Channel number range: 0 ~ 31.
/* Define channel number */
#define CHANNEL_NUMBER 1
/* Set channel number */
mr_dev_ioctl(ds, MR_IOC_PWM_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER));
/* Get channel number */
int number;
mr_dev_ioctl(ds, MR_IOC_PWM_GET_CHANNEL, &number);
Independent of PWM interface:
/* Define channel number */
#define CHANNEL_NUMBER 1
/* Set channel number */
mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, CHANNEL_NUMBER));
/* Get channel number */
int number;
mr_dev_ioctl(ds, MR_IOC_GPOS, &number);
Set/Get Channel Configuration
Channel configuration:
MR_DISABLE: Disable channel.MR_ENABLE: Enable channel.
struct mr_pwm_config config = {MR_ENABLE, MR_PWM_POLARITY_NORMAL};
/* Set channel configuration */
mr_dev_ioctl(ds, MR_IOC_PWM_SET_CHANNEL_CONFIG, &config);
/* Get channel configuration */
mr_dev_ioctl(ds, MR_IOC_PWM_GET_CHANNEL_CONFIG, &config);
Independent of PWM interface:
int config[] = {MR_ENABLE, 0};
/* Set channel configuration */
mr_dev_ioctl(ds, MR_IOC_SCFG, &config);
/* Get channel configuration */
mr_dev_ioctl(ds, MR_IOC_GCFG, &config);
Set/Get Frequency
/* Define frequency */
#define PWM_FREQ 1000
/* Set frequency */
mr_dev_ioctl(ds, MR_IOC_PWM_SET_FREQ, MR_MAKE_LOCAL(uint32_t, PWM_FREQ));
/* Get frequency */
uint32_t freq;
mr_dev_ioctl(ds, MR_IOC_PWM_GET_FREQ, &freq);
Independent of PWM interface:
/* Define frequency */
#define PWM_FREQ 1000
/* Set frequency */
mr_dev_ioctl(ds, (0x01), MR_MAKE_LOCAL(uint32_t, PWM_FREQ));
/* Get frequency */
uint32_t freq;
mr_dev_ioctl(ds, (-(0x01)), &freq);
Read PWM Channel Duty Cycle
ssize_t mr_dev_read(int desc, void *buf, size_t count);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| buf | Read data buffer |
| count | Read data size |
| Return Value | |
>=0 |
Size of reading data |
<0 |
Error code |
/* Read duty cycle */
uint32_t duty;
int ret = mr_dev_read(ds, &duty, sizeof(duty));
/* Check if reading succeeds */
if (ret != sizeof(duty))
{
return ret;
}
Note: The reading data is PWM duty cycle, ranging from 0 to 1000000.
The minimum unit for single reading is uint32_t, which is 4 bytes.
Write PWM Channel Duty Cycle
ssize_t mr_dev_write(int desc, const void *buf, size_t count);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| buf | Write data buffer |
| count | Write data size |
| Return Value | |
>=0 |
Size of writing data |
<0 |
Error code |
/* Write duty cycle */
uint32_t duty = 500000;
int ret = mr_dev_write(ds, &duty, sizeof(duty));
/* Check if writing succeeds */
if (ret != sizeof(duty))
{
return ret;
}
Note: The writing data is PWM duty cycle, ranging from 0 to 1000000.
The minimum unit for single writing is uint32_t, which is 4 bytes.
Example:
#include "include/mr_lib.h"
/* Define channel number and frequency */
#define CHANNEL_NUMBER 1
#define FREQ 1000
/* PWM device descriptor */
int pwm_ds = -1;
void pwm_init(void)
{
int ret = MR_EOK;
/* PWM initialization */
pwm_ds = mr_dev_open("pwm1", MR_O_RDWR);
if (pwm_ds < 0)
{
mr_printf("PWM1 open failed: %s\r\n", mr_strerror(pwm_ds));
return;
}
/* Print PWM descriptor */
mr_printf("PWM1 desc: %d\r\n", pwm_ds);
/* Set to channel 1*/
mr_dev_ioctl(pwm_ds, MR_IOC_PWM_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER));
/* Set channel enable */
ret = mr_dev_ioctl(pwm_ds, MR_IOC_PWM_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(struct mr_pwm_config, MR_ENABLE, MR_PWM_POLARITY_NORMAL));
if (ret < 0)
{
mr_printf("Channel%d enable failed: %s\r\n", CHANNEL_NUMBER, mr_strerror(ret));
return;
}
ret = mr_dev_ioctl(pwm_ds, MR_IOC_PWM_SET_FREQ, MR_MAKE_LOCAL(uint32_t, FREQ));
if (ret < 0)
{
mr_printf("Freq configure failed: %s\r\n", mr_strerror(ret));
}
}
/* Export to automatic initialization (APP level) */
MR_INIT_APP_EXPORT(pwm_init);
int main(void)
{
/* Automatically initialize (pwm_init function will be automatically called here) */
mr_auto_init();
/* Write duty cycle */
uint32_t duty = 500000;
int ret = mr_dev_write(pwm_ds, &duty, sizeof(duty));
/* Check if writing succeeds */
if (ret != sizeof(duty))
{
mr_printf("Write failed: %s\r\n", mr_strerror(ret));
return ret;
}
while(1)
{
}
}
The PWM frequency is set to 1000Hz, and channel 1 outputs 50% duty cycle.