/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is property of Nordic Semiconductor ASA.
 * Terms and conditions of usage are described in detail in NORDIC
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 */

/** @file
 * @defgroup blinky_example_main main.c
 * @{
 * @ingroup blinky_example_freertos
 *
 * @brief Blinky FreeRTOS Example Application main file.
 *
 * This file contains the source code for a sample application using FreeRTOS to blink LEDs.
 *
 */

#include <stdbool.h>
#include <stdint.h>

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "bsp.h"
#include "nordic_common.h"
#include "nrf_drv_clock.h"
#include "sdk_errors.h"
#include "app_error.h"
#include "nrf_drv_gpiote.h"

#define TIMER_RESET_PIN 4
#define LED_PIN 20

#define TIMER_PERIOD      1000          /**< Timer period. LED1 timer will expire after 1000 ms */

TaskHandle_t  led_toggle_task_handle;   /**< Reference to LED0 toggling FreeRTOS task. */
TimerHandle_t led_toggle_timer_handle;  /**< Reference to LED1 toggling FreeRTOS timer. */

static void led_toggle_task_function (void * pvParameter)
{

    UNUSED_PARAMETER(pvParameter);
    while (true)
    {
    	vTaskSuspend( NULL );
		nrf_gpio_pin_set( LED_PIN );
		vTaskDelay( pdMS_TO_TICKS(50) );
		nrf_gpio_pin_clear( LED_PIN );
    }
}

/**@brief The function to call when the LED1 FreeRTOS timer expires.
 *
 * @param[in] pvParameter   Pointer that will be used as the parameter for the timer.
 */
static void led_toggle_timer_callback (void * pvParameter)
{
    UNUSED_PARAMETER(pvParameter);

    vTaskResume(led_toggle_task_handle);
}

void gpioteIrqHandler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	BaseType_t contextSwitch = 0;

    if ( (pin == TIMER_RESET_PIN) && (action == NRF_GPIOTE_POLARITY_LOTOHI) )
	{
		xTimerResetFromISR( led_toggle_timer_handle, &contextSwitch );
	    vTaskResume(led_toggle_task_handle);
	}
}

int main(void)
{
    ret_code_t err_code;

    /* Initialize clock driver for better time accuracy in FREERTOS */
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    /* Configure LED-pins as outputs */
    nrf_gpio_cfg_output( LED_PIN );

	//Configure and initialize TIMER_RESET_PIN irq
	APP_ERROR_CHECK(nrf_drv_gpiote_init());

	nrf_drv_gpiote_in_config_t IrqConfig = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
	IrqConfig.pull = NRF_GPIO_PIN_PULLDOWN;
	APP_ERROR_CHECK(nrf_drv_gpiote_in_init(TIMER_RESET_PIN, &IrqConfig, gpioteIrqHandler));
	nrf_drv_gpiote_in_event_enable(TIMER_RESET_PIN, true);

    /* Create task for LED0 blinking with priority set to 2 */
    UNUSED_VARIABLE(xTaskCreate(led_toggle_task_function, "LED0", 2048, NULL, 2, &led_toggle_task_handle));

    /* Start timer */
    led_toggle_timer_handle = xTimerCreate( "LED1", pdMS_TO_TICKS(TIMER_PERIOD), pdTRUE, NULL, led_toggle_timer_callback);
    UNUSED_VARIABLE(xTimerStart(led_toggle_timer_handle, 0));

    /* Activate deep sleep mode */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    /* Start FreeRTOS scheduler. */
    vTaskStartScheduler();

    while (true)
    {
        /* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
         * in vTaskStartScheduler function. */
    }
}

/**
 *@}
 **/
