//function to init the PWM -> results in a PWM signal and an inverted PWM signal on pins CALLIOPE_SM_PIN_IN2 and CALLIOPE_SM_PIN_IN1
void CalliopeSoundMotor::PWM_init()
{
    //init pins
    nrf_gpio_cfg_output(CALLIOPE_SM_PIN_IN1);
    nrf_gpio_cfg_output(CALLIOPE_SM_PIN_IN2);
    nrf_gpio_pin_clear(CALLIOPE_SM_PIN_IN1);
    nrf_gpio_pin_clear(CALLIOPE_SM_PIN_IN2);

    //create tasks to perform on timer compare match
    NRF_GPIOTE->POWER = 1;
    //task 0
    nrf_gpiote_task_configure(0, CALLIOPE_SM_PIN_IN1, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    nrf_gpiote_task_enable(0);
    //task 1
    nrf_gpiote_task_configure(1, CALLIOPE_SM_PIN_IN2, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    nrf_gpiote_task_enable(1);

    //Three NOPs are required to make sure configuration is written before setting tasks or getting events
    __NOP();
    __NOP();
    __NOP();

    //connect the tasks to the corresponding compare match events, toggle twice per period (PWM)
    //connect task 0
    NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[0];
    NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];
    //connect task 1
    NRF_PPI->CH[1].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[1];
    NRF_PPI->CH[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1];

    //connect task 0
    NRF_PPI->CH[2].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[2];
    NRF_PPI->CH[2].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];
    //connect task 1
    NRF_PPI->CH[3].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[3];
    NRF_PPI->CH[3].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1];

    NRF_PPI->CHENSET = 15; // bits 0 - 3 for channels 0 - 3

     //init TIMER2 for PWM use
    NRF_TIMER2->POWER = 1;
    NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
    NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER2->PRESCALER = CALLIOPE_SM_PRESCALER_M;
    NRF_TIMER2->TASKS_CLEAR = 1;

    //initialize compare registers
    //set compare registers 0 and 1 (duty cycle for PWM on pins CALLIOPE_SM_PIN_IN1 and CALLIOPE_SM_PIN_IN2)
    NRF_TIMER2->CC[0] = CALLIOPE_SM_PERIOD_M - CALLIOPE_SM_DEFAULT_DUTY_M;
    NRF_TIMER2->CC[1] = CALLIOPE_SM_DEFAULT_DUTY_M-1;
    //set compare register 2 and 3 (period for PWM on pins CALLIOPE_SM_PIN_IN1 and CALLIOPE_SM_PIN_IN2)
    NRF_TIMER2->CC[2] = CALLIOPE_SM_PERIOD_M-1;
    NRF_TIMER2->CC[3] = CALLIOPE_SM_PERIOD_M;
    NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk;
}
/**
 * @brief Initialize PPI to toggle GPIO pins on Softdevice events. Initialize GPIO to set it
 *        according to Softdevice arbiter client events.
 */
static void raal_softdevice_event_gpio_toggle_init(void)
{
#if RAAL_SOFTDEVICE
    nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_ACTIVE);
    nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_EXTEND_REQ);
    nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_SESSION_IDLE);
    nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_RADIO_IRQ);
    nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_FAILED);
    nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_BLOCKED);
    nrf_gpio_cfg_output(PIN_DBG_RTC0_EVT_REM);

    nrf_gpiote_task_configure(5, PIN_DBG_RTC0_EVT_REM, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);

    nrf_gpiote_task_enable(5);

    nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, (uint32_t) &NRF_RTC0->EVENTS_COMPARE[1], nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5));

    nrf_ppi_channel_enable(NRF_PPI_CHANNEL5);
#endif // RAAL_SOFTDEVICE
}
/**
 * @brief Initialize PPI to toggle GPIO pins on radio events.
 */
static void radio_event_gpio_toggle_init(void)
{
    nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_END);
    nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_DISABLED);
    nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_READY);
    nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_FRAMESTART);
    nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_EDEND);
    nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_PHYEND);

    nrf_gpiote_task_configure(0, PIN_DBG_RADIO_EVT_END, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    nrf_gpiote_task_configure(1, PIN_DBG_RADIO_EVT_DISABLED, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    nrf_gpiote_task_configure(2, PIN_DBG_RADIO_EVT_READY, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    nrf_gpiote_task_configure(3, PIN_DBG_RADIO_EVT_FRAMESTART, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    nrf_gpiote_task_configure(4, PIN_DBG_RADIO_EVT_EDEND, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    nrf_gpiote_task_configure(5, PIN_DBG_RADIO_EVT_PHYEND, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);

    nrf_gpiote_task_enable(0);
    nrf_gpiote_task_enable(1);
    nrf_gpiote_task_enable(2);
    nrf_gpiote_task_enable(3);
    nrf_gpiote_task_enable(4);
    nrf_gpiote_task_enable(5);

    nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL0, (uint32_t) &NRF_RADIO->EVENTS_END,        nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0));
    nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL1, (uint32_t) &NRF_RADIO->EVENTS_DISABLED,   nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1));
    nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL2, (uint32_t) &NRF_RADIO->EVENTS_READY,      nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2));
    nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL3, (uint32_t) &NRF_RADIO->EVENTS_FRAMESTART, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3));
    nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL4, (uint32_t) &NRF_RADIO->EVENTS_EDEND,      nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_4));
    nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, (uint32_t) &NRF_RADIO->EVENTS_PHYEND,     nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5));

    nrf_ppi_channel_enable(NRF_PPI_CHANNEL0);
    nrf_ppi_channel_enable(NRF_PPI_CHANNEL1);
    nrf_ppi_channel_enable(NRF_PPI_CHANNEL2);
    nrf_ppi_channel_enable(NRF_PPI_CHANNEL3);
    nrf_ppi_channel_enable(NRF_PPI_CHANNEL4);
    nrf_ppi_channel_enable(NRF_PPI_CHANNEL5);
}