55 #define PRINTF(...) printf(__VA_ARGS__)
60 #define PWM_GPTIMER_NUM_TO_BASE(x) ((GPT_0_BASE) + ((x) << 12))
63 pwm_configured(uint8_t
timer, uint8_t ab)
67 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
68 offset = (ab) ? 4 : 0;
71 (REG(gpt_base +
GPTIMER_TAMR + offset) & GPTIMER_TAMR_TAMR_PERIODIC)) {
82 for(timer = PWM_TIMER_0; timer <= PWM_TIMER_3; timer++)
83 for(ab = PWM_TIMER_A; ab <= PWM_TIMER_B; ab++)
84 if(pwm_configured(timer, ab) &&
93 pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab)
96 uint32_t interval_load, duty_count, copy;
97 uint32_t gpt_base, gpt_en, gpt_dir;
99 if((freq < PWM_FREQ_MIN) || (freq > PWM_FREQ_MAX) ||
100 (duty < PWM_DUTY_MIN) || (duty > PWM_DUTY_MAX) ||
101 (timer > PWM_TIMER_MAX) || (timer < PWM_TIMER_MIN)) {
102 PRINTF(
"PWM: Invalid PWM settings\n");
107 if((ab == PWM_TIMER_A) && (timer == PWM_TIMER_0)) {
108 PRINTF(
"PWM: GPT0 (timer A) is reserved for clock_delay_usec()\n");
112 PRINTF(
"PWM: F%08luHz: %u%% on GPT%u-%u\n", freq, duty, timer, ab);
116 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
120 if(ab == PWM_TIMER_B) {
126 PRINTF(
"PWM: GPT_x_BASE 0x%08lX (%u)\n", gpt_base, offset);
130 copy &= ~(gpt_en | gpt_dir);
142 REG(gpt_base +
GPTIMER_CFG) = PWM_GPTIMER_CFG_SPLIT_MODE;
146 REG(gpt_base +
GPTIMER_TAMR + offset) |= GPTIMER_TAMR_TAMR_PERIODIC;
157 duty_count = ((interval_load * duty) + 1) / 100;
160 interval_load, duty_count);
163 REG(gpt_base +
GPTIMER_TAILR + offset) = ((uint16_t *)&interval_load)[0] - 1;
165 REG(gpt_base +
GPTIMER_TAMATCHR + offset) = ((uint16_t *)&duty_count)[0] - 1;
167 REG(gpt_base +
GPTIMER_TAPR + offset) = ((uint8_t *)&interval_load)[2];
169 REG(gpt_base +
GPTIMER_TAPMR + offset) = ((uint8_t *)&duty_count)[2];
173 PRINTF(
"PWM: TnILR %lu ", REG(gpt_base + (
GPTIMER_TAILR + offset)));
175 PRINTF(
"TnPR %lu ", REG(gpt_base + (
GPTIMER_TAPR + offset)));
176 PRINTF(
"TnPMR %lu\n", REG(gpt_base + (
GPTIMER_TAPMR + offset)));
182 pwm_stop(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin, uint8_t state)
184 uint32_t gpt_base, gpt_dis;
186 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
187 (timer > PWM_TIMER_MAX)) {
188 PRINTF(
"PWM: Invalid PWM values\n");
192 if(!pwm_configured(timer, ab)) {
193 PRINTF(
"PWM: GPTn not configured as PWM\n");
199 PRINTF(
"PWM: Invalid pin/port settings\n");
204 if((state != PWM_OFF_WHEN_STOP) && (state != PWM_ON_WHEN_STOP)) {
205 PRINTF(
"PWM: Invalid pin state when PWM is halt\n");
209 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
222 PRINTF(
"PWM: OFF -> Timer %u (%u)\n", timer, ab);
227 pwm_start(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin)
229 uint32_t gpt_base, gpt_en, gpt_sel;
231 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
232 (timer > PWM_TIMER_MAX)) {
233 PRINTF(
"PWM: Invalid PWM values\n");
237 if(!pwm_configured(timer, ab)) {
238 PRINTF(
"PWM: GPTn not configured as PWM\n");
244 PRINTF(
"PWM: Invalid pin/port settings\n");
249 gpt_sel = IOC_PXX_SEL_GPT0_ICP1 + (timer * 2);
250 if(ab == PWM_TIMER_B) {
257 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
260 PRINTF(
"PWM: ON -> Timer %u (%u) IOC_PXX_SEL_GPTx_IPCx 0x%08lX\n", timer, ab,
268 uint32_t gpt_base, gpt_dir;
270 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
271 (timer > PWM_TIMER_MAX) || (dir > PWM_SIGNAL_INVERTED)) {
272 PRINTF(
"PWM: Invalid PWM values\n");
276 if(!pwm_configured(timer, ab)) {
277 PRINTF(
"PWM: GPTn not configured as PWM\n");
281 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
289 PRINTF(
"PWM: Signal direction (%u) -> Timer %u (%u)\n", dir, timer, ab);
296 uint32_t gpt_base, gpt_dir;
298 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
299 (timer > PWM_TIMER_MAX)) {
300 PRINTF(
"PWM: Invalid PWM values\n");
304 if(!pwm_configured(timer, ab)) {
305 PRINTF(
"PWM: GPTn not configured as PWM\n");
309 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
317 PRINTF(
"PWM: direction toggled -> Timer %u (%u)\n", timer, ab);
325 uint8_t offset = (ab == PWM_TIMER_B) ? 4 : 0;
326 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
328 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
329 (timer > PWM_TIMER_MAX)) {
330 PRINTF(
"PWM: Invalid PWM values\n");
336 PRINTF(
"PWM: Invalid pin/port settings\n");
340 if(!pwm_configured(timer, ab)) {
341 PRINTF(
"PWM: GPTn not configured as PWM\n");
346 pwm_stop(timer, ab, port, pin, PWM_OFF_WHEN_STOP);
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to input.
#define GPTIMER_CTL_TBEN
Timer B enable.
#define SYS_CTRL_RCGCGPT_GPT0
GPT0 clock enable, CPU running.
#define GPIO_PIN_MASK(PIN)
Converts a pin number to a pin mask.
#define IOC_OVERRIDE_DIS
Override Disabled.
#define GPTIMER_TAMR_TAAMS
Timer A alternate mode.
static const nrf_drv_timer_t timer
Timer instance used for rtimer.
int8_t pwm_start(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin)
Once configured, starts the PWM.
#define SYS_CTRL_SCGCGPT
GPT[3:0] clocks - sleep mode.
#define SYS_CTRL_SCGCGPT_GPT0
GPT0 clock enable, CPU IDLE.
#define IOC_OVERRIDE_OE
Output Enable.
#define GPTIMER_TAMR
GPTM Timer A mode.
#define GPTIMER_CTL_TAEN
Timer A enable.
#define GPIO_D_NUM
GPIO_D: 3.
void ioc_set_sel(uint8_t port, uint8_t pin, uint8_t sel)
Function select for Port:Pin.
#define GPIO_CLR_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE low.
#define SYS_CTRL_DCGCGPT_GPT0
GPT0 clock enable, PM0.
#define SYS_CTRL_DCGCGPT
GPT[3:0] clocks - PM0.
int8_t pwm_stop(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin, uint8_t state)
Halts the PWM in a given GPT/timer.
#define GPIO_SET_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE high.
int8_t pwm_set_direction(uint8_t timer, uint8_t ab, uint8_t dir)
Sets the PWM duty cycle signal direction (high/low)
#define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to output.
#define GPTIMER_TAPMR
GPTM Timer A prescale match.
Header file with declarations for the I/O Control module.
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be software controlled with PIN_MASK of port with PORT_BASE. ...
#define GPIO_PORT_TO_BASE(PORT)
Converts a port number to the port base address.
Header file for the cc2538 System Control driver.
#define GPTIMER_CTL_TAPWML
Timer A PWM output level.
#define SYS_CTRL_RCGCGPT
GPT[3:0] clocks - active mode.
#define GPTIMER_TAMATCHR
GPTM Timer A match.
int8_t pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab)
Configures the general purpose timer in PWM mode.
void lpm_register_peripheral(lpm_periph_permit_pm1_func_t permit_pm1_func)
Register a peripheral function which will get called by the LPM module to get 'permission' to drop to...
int8_t pwm_disable(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin)
Disables a previously PWM configured GPTn.
#define GPTIMER_TAILR
GPTM Timer A interval load.
int8_t pwm_toggle_direction(uint8_t timer, uint8_t ab)
Toggle the PWM signal direction (inverts the current duty cycle)
#define GPTIMER_CFG
GPTM configuration.
#define GPIO_PERIPHERAL_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be under peripheral control with PIN_MASK of port with PORT_BASE.
#define GPTIMER_TAPR
GPTM Timer A prescale.
Header file for the CC2538 PWM driver.
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
uint32_t sys_ctrl_get_sys_clock(void)
Returns the actual system clock in Hz.
#define GPTIMER_CTL_TBPWML
Timer B PWM output level.
#define GPTIMER_CTL
GPTM control.