/** \file
 *  \brief This file defines and registers the tasks used by the Real-Time Operating System.
 *
 *         See CONFIG_RTOS.h for a detailed description of the functionality implemented by this code.
 */

/* Include Files */
#include "KTag.h"

/* Local Definitions and Constants */

/*---------------------------------------------------------------------------*/
/* Task priorities: Low priority numbers denote low priority tasks.
 *
 * Low == 0 == tskIDLE_PRIORITY
 * ...
 * High == (configMAX_PRIORITIES - 1)
 *
 * See http://www.freertos.org/RTOS-task-priority.html for more information.
 */
#define CAPSENSE_TASK_PRIORITY				(tskIDLE_PRIORITY + 3)
#define SAMPLE_TASK_PRIORITY				(tskIDLE_PRIORITY + 2)
#define FIRE_CONTROL_TASK_PRIORITY		    (tskIDLE_PRIORITY + 1)
#define AUDIO_TASK_PRIORITY		            (tskIDLE_PRIORITY + 2)
#define NEOPIXELS_TASK_PRIORITY		        (tskIDLE_PRIORITY + 2)
#define TAG_SENSORS_TASK_PRIORITY           (tskIDLE_PRIORITY + 5)
#define SWITCHES_TASK_PRIORITY              (tskIDLE_PRIORITY + 2)
#define NVM_EXTERNAL_TASK_PRIORITY       	(tskIDLE_PRIORITY + 2)
#define NVM_ON_CHIP_EEPROM_TASK_PRIORITY	(tskIDLE_PRIORITY + 1)
#define COMM_CONSOLE_TASK_PRIORITY	        (tskIDLE_PRIORITY + 2)
#define COMM_BLE_TASK_PRIORITY	    		(tskIDLE_PRIORITY + 4)


/* External Variables [Only if necessary!] */

/* External Function Prototypes [Only if necessary!] */

/* Public Variables */

//! Array of all the handles for the configured RTOS tasks.
TaskHandle_t * const CONFIG_TaskHandles[] = {&HW_CapSense_Task_Handle,
                                             &Fire_Control_Task_Handle,
                                             &Sample_Task_Handle,
                                             &Audio_Task_Handle,
                                             &NeoPixels_Task_Handle,
                                             &Tag_Sensors_Task_Handle,
                                             &Switches_Task_Handle,
                                             &State_Machine_Task_Handle,
                                             &NVM_ExternalEEPROM_Task_Handle,
                                             &NVM_OnChipEEPROM_Task_Handle,
                                             &COMM_Console_Task_Handle,
                                             &COMM_BLE_Task_Handle};

//! Size of the #CONFIG_TaskHandles array (i.e. the number of configured tasks).
const uint8_t CONFIG_N_TASK_HANDLES = (uint8_t) (sizeof(CONFIG_TaskHandles) / sizeof(TaskHandle_t *));

/* Private Variables */

/* Private Function Prototypes */

/* Public Functions */

void CONFIG_InitTasks(void)
{
    HW_CapSense_Init();
    COMM_I2C_Init();
    NVM_InitExternalEEPROM();
    NVM_InitOnChipEEPROM();
    Sample_Task_Init();
    Init_Fire_Control();
    Tag_Sensors_Init();
    Init_Audio();
    Switches_Init();
    COMM_Console_Init();
    COMM_BLE_Init();
}

//! Registers tasks with the kernel, and then runs them.
/*!
 *  This function should not return.
*/
void CONFIG_RunTasks(void)
{
    (void) xTaskCreate(HW_CapSense_Task,       "CapSense Task",     HW_CAPSENSE_TASK_STACK_SIZE_in_bytes,         NULL, CAPSENSE_TASK_PRIORITY,           &HW_CapSense_Task_Handle);
    (void) xTaskCreate(Fire_Control_Task,      "Fire Control Task", configMINIMAL_STACK_SIZE,                     NULL, FIRE_CONTROL_TASK_PRIORITY,       &Fire_Control_Task_Handle);
    (void) xTaskCreate(Sample_Task,            "Sample Task",       configMINIMAL_STACK_SIZE,                     NULL, SAMPLE_TASK_PRIORITY,             &Sample_Task_Handle);
    (void) xTaskCreate(Audio_Task,             "Audio Task",        configMINIMAL_STACK_SIZE,                     NULL, AUDIO_TASK_PRIORITY,              &Audio_Task_Handle);
    (void) xTaskCreate(NeoPixels_Task,         "NeoPixels Task",    configMINIMAL_STACK_SIZE,                     NULL, NEOPIXELS_TASK_PRIORITY,          &NeoPixels_Task_Handle);
    (void) xTaskCreate(Tag_Sensors_Task,       "Tag Sensors Task",  configMINIMAL_STACK_SIZE,                     NULL, TAG_SENSORS_TASK_PRIORITY,        &Tag_Sensors_Task_Handle);
    (void) xTaskCreate(Switches_Task,          "Switches Task",     configMINIMAL_STACK_SIZE,                     NULL, SWITCHES_TASK_PRIORITY,           &Switches_Task_Handle);
    (void) xTaskCreate(NVM_OnChipEEPROMTask,   "NVMOn",             NVM_ON_CHIP_EEPROM_TASK_STACK_SIZE_in_bytes,  NULL, NVM_ON_CHIP_EEPROM_TASK_PRIORITY, &NVM_OnChipEEPROM_Task_Handle);
    (void) xTaskCreate(NVM_ExternalEEPROMTask, "NVMEx",             NVM_EXTERNAL_EEPROM_TASK_STACK_SIZE_in_bytes, NULL, NVM_EXTERNAL_TASK_PRIORITY,       &NVM_ExternalEEPROM_Task_Handle);
    (void) xTaskCreate(COMM_Console_Task,      "Console Task",      COMM_CONSOLE_TASK_STACK_SIZE_in_bytes,        NULL, COMM_CONSOLE_TASK_PRIORITY,       &COMM_Console_Task_Handle);
    (void) xTaskCreate(COMM_BLE_Task,          "BLE Task",          COMM_BLE_TASK_STACK_SIZE_in_bytes,            NULL, COMM_BLE_TASK_PRIORITY,           &COMM_BLE_Task_Handle);
  
    if (Initialize_SystemK() != SYSTEMK_RESULT_SUCCESS)
    {
        KLOG_ERROR("CONFIG", "Failed to initilaize SystemK!");
    }
    
    /* This should not return. */
    vTaskStartScheduler();
    
    // Something went wrong.
#ifdef DEBUG
    // Break into the debugger.
    __BKPT(0);
#else // DEBUG
    __NVIC_SystemReset();
#endif // DEBUG
}

/* Private Functions */
