Appiko
simple_pwm.c
1 
19 #include "simple_pwm.h"
20 #include "hal_gpio.h"
21 #include "nrf.h"
22 #include "common_util.h"
23 #include "log.h"
24 #include "nrf_util.h"
25 
29 #define TIMER_ID CONCAT_2(NRF_TIMER, SIMPLE_PWM_TIMER_USED)
30 #define TIMER_IRQN CONCAT_3(TIMER, SIMPLE_PWM_TIMER_USED, _IRQn)
31 #define TIMER_IRQ_Handler CONCAT_3(TIMER, SIMPLE_PWM_TIMER_USED, _IRQHandler)
32 
35 uint32_t pwm_pins[3];
36 
37 
38 void simple_pwm_init(simple_pwm_timer_freq_t freq,uint32_t max_count)
39 {
40  TIMER_ID->TASKS_STOP = 1;
41  TIMER_ID->TASKS_CLEAR = 1;
42 
43  //TODO Enable assertion
44  //ASSERT((config->freq < 10) && (config->freq >= 0));
45  TIMER_ID->PRESCALER = freq;
46 
47  //ASSERT((config->max_count > 2) && (config->max_count < 65536));
48  TIMER_ID->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
49  TIMER_ID->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
50 
51  TIMER_ID->CC[SIMPLE_PWM_MAX_CHANNEL] = max_count;
52 
53  TIMER_ID->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Enabled << TIMER_SHORTS_COMPARE3_CLEAR_Pos;
54 
55  TIMER_ID->EVENTS_COMPARE[SIMPLE_PWM_MAX_CHANNEL] = 0;
56 }
57 
58 void simple_pwm_channel_setup(simple_pwm_channel_t channel, uint32_t pwm_out_pin,
59  uint32_t value)
60 {
61  if(value >= TIMER_ID->CC[SIMPLE_PWM_MAX_CHANNEL])
62  {
63  NRF_GPIOTE->CONFIG[channel+SIMPLE_PWM_GPIOTE_START_CH] =
64  (GPIOTE_CONFIG_MODE_Disabled << GPIOTE_CONFIG_MODE_Pos)
65  | (pwm_pins[channel] << GPIOTE_CONFIG_PSEL_Pos)
66  | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
67  | (GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);
68  hal_gpio_pin_set(pwm_pins[channel]);
69  }
70  else if(value == 0)
71  {
72  NRF_GPIOTE->CONFIG[channel+SIMPLE_PWM_GPIOTE_START_CH] =
73  (GPIOTE_CONFIG_MODE_Disabled << GPIOTE_CONFIG_MODE_Pos)
74  | (pwm_pins[channel] << GPIOTE_CONFIG_PSEL_Pos)
75  | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
76  | (GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);
77  hal_gpio_pin_clear(pwm_pins[channel]);
78  }
79  else
80  {
81  TIMER_ID->EVENTS_COMPARE[channel] = 0;
82  hal_gpio_cfg_output(pwm_out_pin,0);
83  pwm_pins[channel] = pwm_out_pin;
84 
85  NRF_PPI->CH[2*channel].EEP = (uint32_t) &(TIMER_ID->EVENTS_COMPARE[channel]);
86  NRF_PPI->CH[2*channel].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[channel+SIMPLE_PWM_GPIOTE_START_CH]);
87 
88  NRF_PPI->CH[2*channel+1].EEP = (uint32_t) &(TIMER_ID->EVENTS_COMPARE[SIMPLE_PWM_MAX_CHANNEL]);
89  NRF_PPI->CH[2*channel+1].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[channel+SIMPLE_PWM_GPIOTE_START_CH]);
90 
91  NRF_GPIOTE->CONFIG[channel+SIMPLE_PWM_GPIOTE_START_CH] =
92  (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos)
93  | (pwm_pins[channel] << GPIOTE_CONFIG_PSEL_Pos)
94  | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
95  | (GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);
96  TIMER_ID->CC[channel] = value;
97  }
98 }
99 
101 {
102  NRF_PPI->CHENSET = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5);
103 
104  TIMER_ID->TASKS_START = 1;
105 }
106 
108 {
109  NRF_PPI->CHENCLR = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5);
110 
111  TIMER_ID->TASKS_STOP = 1;
112 
113  TIMER_ID->TASKS_SHUTDOWN = 1;
114 }
void simple_pwm_init(simple_pwm_timer_freq_t freq, uint32_t max_count)
Function to initiate PWM module with clock frequency and total time of pulse.
Definition: simple_pwm.c:38
simple_pwm_channel_t
Defines for specifying the three PWM channels.
Definition: simple_pwm.h:74
void simple_pwm_stop()
Function to stop PWM signals.
Definition: simple_pwm.c:107
void simple_pwm_start()
Function to start PWM signals.
Definition: simple_pwm.c:100
#define SIMPLE_PWM_GPIOTE_START_CH
Three GPIOTE channels are used from this number for this module.
Definition: simple_pwm.h:49
void simple_pwm_channel_setup(simple_pwm_channel_t channel, uint32_t pwm_out_pin, uint32_t value)
Function to setup a channel.
Definition: simple_pwm.c:58
simple_pwm_timer_freq_t
Defines for the frequency at which the timer should run for the PWM generation.
Definition: simple_pwm.h:57