/* Copyright (c) 2020-2021, EmbeddedCentric.com
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//////////////////////////////////////////////////////////////////////////////////
// Company: EmbeddedCentric.com
// Create Date:    04 Jan. 2021
// Title: Nordic nRF5x BLE In-Depth Training Course -Foundation Level (Lesson 8 - Exerciser 1)  
// Description: A simple demo program that controls LED1 on the nRF52840-DK
// -through TIMER0 compare event(interrupt).
// Development Kit Used: nRF52480-DK.
// Notes: 
// Tested on nRF5 SDK v17.0.2
//////////////////////////////////////////////////////////////////////////////////

#include <stdbool.h>
#include "nrf_gpio.h"      //The GPIO Hardware Access Layer (HAL)
#include "nrf_drv_timer.h" // TIMER Driver (3rd Layer)
#include "boards.h"       //GPIO definitions for the nRF52840-DK (aka pca10056)

// An event handler "interrupt handler" for the timer. The interrupt handler will be called every time the event is triggered. 
void timer0_event_handler(nrf_timer_event_t event_type, void* p_context)
{
  nrf_gpio_pin_toggle(BSP_LED_1); // Toggle BSP_LED_0 = LED1 
}

//create a constant variable of type struct nrf_drv_timer_t and initialize it with the desired TIMER number(0-5 for nRF52840) to use.
const nrf_drv_timer_t TIMER0_INS = NRF_DRV_TIMER_INSTANCE(0);

int main(void)
{
    uint32_t time_ms = 1000; //Time(in milliseconds) between consecutive compare events.
    uint32_t time_ticks; // converted time in ticks to set the capture register of the timer.

    nrf_gpio_cfg_output(BSP_LED_1); //Configure pin 13 as standard output. BSP_LED_0 is pin 13 in the nRF52840-DK. 

    //Create a variable of type struct  nrf_drv_timer_config_t and initialize this variable to NRF_DRV_TIMER_DEFAULT_CONFIG.
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    
    //Set timer bit width to 32 bit <3> instead of the default 16 bit for better timer resolution.
    timer_cfg.bit_width = 3; 

    //Initialize timer
    nrf_drv_timer_init(&TIMER0_INS, &timer_cfg, timer0_event_handler);
	//Typically you should check for errors here in production code (To be covered in future lessons)

    //converting time in milliseconds to timer ticks.
    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER0_INS, time_ms);

   //set the timer compare/capture in extended compare mode, which means it will keep triggering indefinitely
   //NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK is a shortcut to clear  the timer after compare0 is triggered 
    nrf_drv_timer_extended_compare(
         &TIMER0_INS, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    
   //Enable TIMER0
    nrf_drv_timer_enable(&TIMER0_INS); 

    while (true)
    {
     //In real applications, you add your project code that need to be run in main context here and then sleep.
     //Enter sleep(Put the CPU to sleep the TIMER is setup in interrupt mode ), more on sleep modes in Lesson 14.
      __SEV();
      __WFE();
      __WFE();
    }
}

/*************************** End of file ****************************/