/*******************************************************************************
*
* E M B E D D E D   W I Z A R D   P R O J E C T
*
*                                                Copyright (c) TARA Systems GmbH
*                                    written by Paul Banach and Manfred Schweyer
*
********************************************************************************
*
* This software is delivered "as is" and shows the usage of other software
* components. It is provided as an example software which is intended to be
* modified and extended according to particular requirements.
*
* TARA Systems hereby disclaims all warranties and conditions with regard to the
* software, including all implied warranties and conditions of merchantability
* and non-infringement of any third party IPR or other rights which may result
* from the use or the inability to use the software.
*
********************************************************************************
*
* DESCRIPTION:
*   This file implements the main.c module for running Embedded Wizard
*   generated GUI applications on a dedicated target with or without the usage
*   of an operating system.
*
*   Important: Please be aware that every Embedded Wizard GUI application
*   requires the execution in a single GUI task!
*   If you are working with an operating system and your software is using
*   several threads/tasks, please take care to access your GUI application
*   only within the context of your GUI thread/task. Use operating system
*   services to exchange data or events between the GUI thread/task and other
*   worker threads/tasks.
*
*   For more information concerning the integration of an Embedded Wizard
*   generated GUI application into your main application, please see
*   https://doc.embedded-wizard.de/main-loop
*
*******************************************************************************/

#include "ewmain.h"
#include "ewrte.h"
#include "ew_bsp_system.h"
#include "ew_bsp_console.h"

#include "canmain.h"

#if EW_USE_FREE_RTOS == 1

  #include "FreeRTOS.h"
  #include "task.h"
  #include "semphr.h"

  #define semtstSTACK_SIZE    configMINIMAL_STACK_SIZE * 10

  static void GuiThread( void * arg );
  static void MCOThread( void * arg );

  TaskHandle_t GuiThreadTaskHandle;
#endif


#if EW_USE_FREE_RTOS == 0

/*******************************************************************************
* FUNCTION:
*   main
*
* DESCRIPTION:
*   The main function for running Embedded Wizard generated GUI applications on
*   a dedicated target without using any operating system (bare metal).
*
* ARGUMENTS:
*   None
*
* RETURN VALUE:
*   None
*
*******************************************************************************/
int main( void )
{
  /* initialize system */
  EwBspSystemInit();

  /* initialize console interface for debug messages */
  EwBspConsoleInit();

  /* initialize Embedded Wizard application */
  if ( EwInit() == 0 )
    return 0;

  EwPrintSystemInfo();

  /* process the Embedded Wizard main loop */
  while( EwProcess())
    ;

  /* de-initialize Embedded Wizard application */
  EwDone();

  /* terminate the system */
  EwBspSystemDone();

  return 0;
}

#endif

#if EW_USE_FREE_RTOS == 1

/*******************************************************************************
* FUNCTION:
*   main
*
* DESCRIPTION:
*   The main function for running Embedded Wizard generated GUI applications on
*   a dedicated target using the FreeRTOS operating system.
*
* ARGUMENTS:
*   None
*
* RETURN VALUE:
*   None
*
*******************************************************************************/
int main( void )
{
  /* initialize system */
  EwBspSystemInit();

  /* initialize console interface for debug messages */
  EwBspConsoleInit();

  /* create thread that drives the Embedded Wizard GUI application... */
  EwPrint( "Create UI thread...                          " );
  xTaskCreate( GuiThread, "EmWi_Task", semtstSTACK_SIZE, NULL, 1, &GuiThreadTaskHandle );
  EwPrint( "[OK]\n" );

  /* create thread that drives the Embedded Wizard GUI application... */
  EwPrint( "Create MCO thread...                         " );
  xTaskCreate( MCOThread, "MCO_Task", configMINIMAL_STACK_SIZE * 80, NULL, 0, NULL );
  EwPrint( "[OK]\n" );

  /* ...and start scheduler */
  vTaskStartScheduler();

  return 0;
}


/*******************************************************************************
* FUNCTION:
*   GuiThread
*
* DESCRIPTION:
*   The GuiThread processes the Embedded Wizard application.
*
* ARGUMENTS:
*   arg - not used.
*
* RETURN VALUE:
*   None.
*
*******************************************************************************/
static void GuiThread( void* arg )
{
  /* initialize Embedded Wizard application */
  EwInit();

  EwPrintSystemInfo();

  vTaskPrioritySet( GuiThreadTaskHandle, 0 );

  /* process the Embedded Wizard main loop */
  while( EwProcess())
    ;

  /* de-initialize Embedded Wizard application */
  EwDone();
}

/*******************************************************************************
* FUNCTION:
*   MCOThread
*
* DESCRIPTION:
*   The MCOThread processes the micro CAN open application.
*   Based on example "EW2020_Demo" by EmSA.
*
* ARGUMENTS:
*   arg - not used.
*
* RETURN VALUE:
*   None.
*
*******************************************************************************/
static void MCOThread( void* arg )
{
  #if USE_LEDS
  // Initialize status LEDs
  //LIBCB_InitLeds(); /* already done with Embedded Wizard HW init */
  #endif

  EwPrint("Starting CANopen Library slave example for \n");
  #ifdef CPU_MIMXRT1021DAG5A
  EwPrint("NXP i.MX RT 1020 on CAN1 (J10 connector)\n");
  #else
  EwPrint("NXP i.MX RT 10xx on CAN2 (J11 connector)\n");
  #endif
  EwPrint("Provided by EmSA - www.em-sa.com/nxp\n");

  // Reset/Initialize CANopen communication
  MCOUSER_ResetCommunication();

  // foreground loop
  while(1)
  {
    #if (USE_REMOTE_ACCESS)
    MCORA_ProcessHost();
    #endif

    // Operate on CANopen protocol stack
    MCO_ProcessStack();

    // Operate on application
    if (MY_NMT_STATE == NMTSTATE_OP)
    {
      USER_Process();
    }
    else if (MY_NMT_STATE == NMTSTATE_PREOP)
    { // Here Self-Autostart
    	MCO_HandleNMTRequest(NMTMSG_OP);
    }

    // Check for CAN Err, auto-recover
    if (MCOHW_GetStatus() & HW_BOFF)
    {
      MCOUSER_FatalError(0xF6F6);
    }
    vTaskDelay( 2 / portTICK_PERIOD_MS );
  }
}

#endif

/* msy, mli */
