blob: 79dd6a720ee5c760eee9315c7ccce8be44373a8b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef __PWM_H__
#define __PWM_H__
#include "os/mynewt.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwm_dev;
struct pwm_dev_cfg;
struct pwm_chan_cfg;
/**
* Configure a PWM device.
*
* @param dev The device to configure.
* @param cfg Configuration data for this device. If NULL the device will be
* given default configuration values.
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*pwm_config_device_func_t)(struct pwm_dev *,
struct pwm_dev_cfg *);
/**
* Configure a channel on the PWM device.
*
* @param dev The device to configure.
* @param cnum The channel number to configure.
* @param cfg Configuration data for this channel. If NULL the channel will be
* disabled or given default configuration values.
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*pwm_config_channel_func_t)(struct pwm_dev *,
uint8_t,
struct pwm_chan_cfg *);
/**
* Set the specified duty cycle on a PWM Channel.
*
* This duty cycle is a fractional duty cycle where 0 == off,
* base_freq / pwm_freq == 100% and any value in between is on for fraction clock
* cycles and off for (base_freq / pwm_freq)-fraction clock cycles.
*
* @param dev The device which the channel belongs to.
* @param cnum The channel to configure.
* @param fraction The fraction value.
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*pwm_set_duty_cycle_func_t)(struct pwm_dev *,
uint8_t,
uint16_t);
/**
* Enable a given PWM device.
* This device should start playing on its previously configured channels.
*
* @param dev The PWM device to be enabled.
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*pwm_enable_func_t)(struct pwm_dev *dev);
/**
* Check whether a PWM device is enabled.
*
* @param dev The device which the channel belongs to.
*
* @return true if enabled, false if not.
*/
typedef bool (*pwm_is_enabled_func_t)(struct pwm_dev *);
/**
* Set the frequency for the device's clock.
* This frequency must be between 1/2 the clock frequency and
* the clock divided by the resolution.
*
* @param dev The device to configure.
* @param freq_hz The frequency value in Hz.
*
* @return A value is in Hz on success, negative error code on failure.
*/
typedef int (*pwm_set_frequency_func_t) (struct pwm_dev *, uint32_t);
/**
* Get the underlying clock driving the PWM device.
*
* @param dev
*
* @return value is in Hz on success, negative error code on failure.
*/
typedef int (*pwm_get_clock_freq_func_t) (struct pwm_dev *);
/**
* Get the top value for the cycle counter, i.e. the value which sets
* the duty cycle to 100%.
*
* @param dev
*
* @return value in cycles on success, negative error code on failure.
*/
typedef int (*pwm_get_top_value_funct_t) (struct pwm_dev *dev);
/**
* Get the resolution of the PWM in bits.
*
* @param dev The device to query.
*
* @return The value in bits on success, negative error code on failure.
*/
typedef int (*pwm_get_resolution_bits_func_t) (struct pwm_dev *);
/**
* Disable the PWM device, the device will stop playing while remaining configured.
*
* @param dev The device to disable.
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*pwm_disable_func_t) (struct pwm_dev *);
typedef void (*user_handler_t) (void*);
struct pwm_driver_funcs {
pwm_config_device_func_t pwm_configure_device;
pwm_config_channel_func_t pwm_configure_channel;
pwm_set_duty_cycle_func_t pwm_set_duty_cycle;
pwm_enable_func_t pwm_enable;
pwm_is_enabled_func_t pwm_is_enabled;
pwm_set_frequency_func_t pwm_set_frequency;
pwm_get_clock_freq_func_t pwm_get_clock_freq;
pwm_get_top_value_funct_t pwm_get_top_value;
pwm_get_resolution_bits_func_t pwm_get_resolution_bits;
pwm_disable_func_t pwm_disable;
};
struct pwm_dev {
struct os_dev pwm_os_dev;
struct os_mutex pwm_lock;
struct pwm_driver_funcs pwm_funcs;
uint32_t pwm_chan_count;
uint8_t pwm_instance_id;
};
/**
* PWM channel configuration data.
*
* pin - The pin to be assigned to this pwm channel.
* inverted - Whether this channel's output polarity is inverted or not.
* n_cycles - The number of cycles for the channel to play. 0 for loop mode.
* interrupts - Whether interruptions are to be configured or not.
* data - Driver specific data.
*/
struct pwm_chan_cfg {
uint32_t pin;
bool inverted;
void* data;
};
/**
* PWM device interrupt configuration data.
*
* int_prio - Driver Interrupts priority.
* cycle_handler - A pointer to a user_handler_t function for a cycle interrupt,
* if NULL the interrupt will be disabled.
* seq_end_handler - A pointer to a user_handler_t function for
* a end-of-sequence interrupt, if NULL the interrupt will be disabled.
* cycle_data - User data to be passed to cycle_handler as a parameter.
* seq_end_data - User data to be passed to seq_end_handler as a parameter.
* data - Driver specific device configuration data.
*
*/
struct pwm_dev_cfg {
uint32_t n_cycles;
uint32_t int_prio;
user_handler_t cycle_handler;
user_handler_t seq_end_handler;
void* cycle_data;
void* seq_end_data;
void* data;
};
int pwm_configure_device(struct pwm_dev *dev, struct pwm_dev_cfg *cfg);
int pwm_configure_channel(struct pwm_dev *dev, uint8_t cnum, struct pwm_chan_cfg *cfg);
int pwm_set_duty_cycle(struct pwm_dev *pwm_d, uint8_t cnum, uint16_t fraction);
int pwm_enable(struct pwm_dev *dev);
bool pwm_is_enabled(struct pwm_dev *pwm_d);
int pwm_set_frequency(struct pwm_dev *dev, uint32_t freq_hz);
int pwm_get_clock_freq(struct pwm_dev *dev);
int pwm_get_top_value(struct pwm_dev *dev);
int pwm_get_resolution_bits(struct pwm_dev *dev);
int pwm_disable(struct pwm_dev *dev);
#ifdef __cplusplus
}
#endif
#endif /* __PWM_H__ */