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, uint32_t count, uint8_t timer,
97 uint32_t interval_load, duty_count, copy;
98 uint32_t gpt_base, gpt_en, gpt_dir;
100 if((freq < PWM_FREQ_MIN) || (freq > PWM_FREQ_MAX) ||
101 (duty < PWM_DUTY_MIN) || (duty > PWM_DUTY_MAX) ||
102 (timer > PWM_TIMER_MAX) || (timer < PWM_TIMER_MIN)) {
103 PRINTF(
"PWM: Invalid PWM settings\n");
108 if((ab == PWM_TIMER_A) && (timer == PWM_TIMER_0)) {
109 PRINTF(
"PWM: GPT0 (timer A) is reserved for clock_delay_usec()\n");
113 PRINTF(
"PWM: F%08luHz: %u%%/%lu on GPT%u-%u\n", freq, duty, count, timer, ab);
115 lpm_register_peripheral(permit_pm1);
117 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
121 if(ab == PWM_TIMER_B) {
127 PRINTF(
"PWM: GPT_x_BASE 0x%08lX (%u)\n", gpt_base, offset);
131 copy &= ~(gpt_en | gpt_dir);
143 REG(gpt_base +
GPTIMER_CFG) = PWM_GPTIMER_CFG_SPLIT_MODE;
147 REG(gpt_base +
GPTIMER_TAMR + offset) |= GPTIMER_TAMR_TAMR_PERIODIC;
151 if((!duty) && (!count)) {
162 duty_count = ((interval_load * duty) + 1) / 100;
168 interval_load, duty_count);
171 REG(gpt_base +
GPTIMER_TAILR + offset) = ((uint16_t *)&interval_load)[0] - 1;
173 REG(gpt_base +
GPTIMER_TAMATCHR + offset) = ((uint16_t *)&duty_count)[0] - 1;
175 REG(gpt_base +
GPTIMER_TAPR + offset) = ((uint8_t *)&interval_load)[2];
177 REG(gpt_base +
GPTIMER_TAPMR + offset) = ((uint8_t *)&duty_count)[2];
181 PRINTF(
"PWM: TnILR %lu ", REG(gpt_base + (
GPTIMER_TAILR + offset)));
183 PRINTF(
"TnPR %lu ", REG(gpt_base + (
GPTIMER_TAPR + offset)));
184 PRINTF(
"TnPMR %lu\n", REG(gpt_base + (
GPTIMER_TAPMR + offset)));
190 pwm_stop(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin, uint8_t state)
192 uint32_t gpt_base, gpt_dis;
194 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
195 (timer > PWM_TIMER_MAX)) {
196 PRINTF(
"PWM: Invalid PWM values\n");
200 if(!pwm_configured(timer, ab)) {
201 PRINTF(
"PWM: GPTn not configured as PWM\n");
207 PRINTF(
"PWM: Invalid pin/port settings\n");
212 if((state != PWM_OFF_WHEN_STOP) && (state != PWM_ON_WHEN_STOP)) {
213 PRINTF(
"PWM: Invalid pin state when PWM is halt\n");
217 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
230 PRINTF(
"PWM: OFF -> Timer %u (%u)\n", timer, ab);
235 pwm_start(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin)
237 uint32_t gpt_base, gpt_en, gpt_sel;
239 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
240 (timer > PWM_TIMER_MAX)) {
241 PRINTF(
"PWM: Invalid PWM values\n");
245 if(!pwm_configured(timer, ab)) {
246 PRINTF(
"PWM: GPTn not configured as PWM\n");
252 PRINTF(
"PWM: Invalid pin/port settings\n");
257 gpt_sel = IOC_PXX_SEL_GPT0_ICP1 + (timer * 2);
258 if(ab == PWM_TIMER_B) {
265 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
268 PRINTF(
"PWM: ON -> Timer %u (%u) IOC_PXX_SEL_GPTx_IPCx 0x%08lX\n", timer, ab,
276 uint32_t gpt_base, gpt_dir;
278 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
279 (timer > PWM_TIMER_MAX) || (dir > PWM_SIGNAL_INVERTED)) {
280 PRINTF(
"PWM: Invalid PWM values\n");
284 if(!pwm_configured(timer, ab)) {
285 PRINTF(
"PWM: GPTn not configured as PWM\n");
289 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
297 PRINTF(
"PWM: Signal direction (%u) -> Timer %u (%u)\n", dir, timer, ab);
304 uint32_t gpt_base, gpt_dir;
306 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
307 (timer > PWM_TIMER_MAX)) {
308 PRINTF(
"PWM: Invalid PWM values\n");
312 if(!pwm_configured(timer, ab)) {
313 PRINTF(
"PWM: GPTn not configured as PWM\n");
317 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
325 PRINTF(
"PWM: direction toggled -> Timer %u (%u)\n", timer, ab);
333 uint8_t offset = (ab == PWM_TIMER_B) ? 4 : 0;
334 gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer);
336 if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) ||
337 (timer > PWM_TIMER_MAX)) {
338 PRINTF(
"PWM: Invalid PWM values\n");
344 PRINTF(
"PWM: Invalid pin/port settings\n");
348 if(!pwm_configured(timer, ab)) {
349 PRINTF(
"PWM: GPTn not configured as PWM\n");
354 pwm_stop(timer, ab, port, pin, PWM_OFF_WHEN_STOP);
Header file for the CC2538 PWM driver.
Header file for the cc2538 System Control driver.
#define GPIO_SET_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE high.
#define GPTIMER_TAPR
GPTM Timer A prescale.
Header file with register and macro declarations for the cc2538 GPIO module.
#define GPTIMER_TAILR
GPTM Timer A interval load.
#define GPTIMER_CTL_TBPWML
Timer B PWM output level.
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 GPTIMER_TAPMR
GPTM Timer A prescale match.
#define GPIO_CLR_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE low.
Header file with declarations for the I/O Control module.
#define GPTIMER_TAMATCHR
GPTM Timer A match.
#define SYS_CTRL_SCGCGPT_GPT0
GPT0 clock enable, CPU IDLE.
#define IOC_OVERRIDE_DIS
Override Disabled.
#define GPIO_PIN_MASK(PIN)
Converts a pin number to a pin mask.
int8_t pwm_toggle_direction(uint8_t timer, uint8_t ab)
Toggle the PWM signal direction (inverts the current duty cycle)
#define GPTIMER_CTL_TAEN
Timer A enable.
#define GPTIMER_TAMR
GPTM Timer A mode.
#define GPTIMER_CTL_TBEN
Timer B enable.
#define GPIO_D_NUM
GPIO_D: 3.
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be software controlled with PIN_MASK of port with PORT_BASE. ...
#define SYS_CTRL_RCGCGPT
GPT[3:0] clocks - active mode.
#define SYS_CTRL_DCGCGPT_GPT0
GPT0 clock enable, PM0.
int8_t pwm_set_direction(uint8_t timer, uint8_t ab, uint8_t dir)
Sets the PWM duty cycle signal direction (high/low)
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
#define SYS_CTRL_RCGCGPT_GPT0
GPT0 clock enable, CPU running.
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to input.
#define GPTIMER_CTL_TAPWML
Timer A PWM output level.
#define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to output.
#define SYS_CTRL_SCGCGPT
GPT[3:0] clocks - sleep mode.
uint32_t sys_ctrl_get_sys_clock(void)
Returns the actual system clock in Hz.
#define IOC_OVERRIDE_OE
Output Enable.
#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_CTL
GPTM control.
int8_t pwm_enable(uint32_t freq, uint8_t duty, uint32_t count, uint8_t timer, uint8_t ab)
Configures the general purpose timer in PWM mode.
void ioc_set_sel(uint8_t port, uint8_t pin, uint8_t sel)
Function select for Port:Pin.
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 SYS_CTRL_DCGCGPT
GPT[3:0] clocks - PM0.
int8_t pwm_disable(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin)
Disables a previously PWM configured GPTn.
#define GPIO_PORT_TO_BASE(PORT)
Converts a port number to the port base address.
#define GPTIMER_CFG
GPTM configuration.
#define GPTIMER_TAMR_TAAMS
Timer A alternate mode.