/*******************************************************************************
  MPLAB Harmony Application Source File

  Company:
    Microchip Technology Inc.

  File Name:
    app_drv_usart1.c

  Summary:
    This file contains the source code for the MPLAB Harmony application.

  Description:
    This file contains the source code for the MPLAB Harmony application.  It
    implements the logic of the application's state machine and it may call
    API routines of other MPLAB Harmony modules in the system, such as drivers,
    system services, and middleware.  However, it does not call any of the
    system interfaces (such as the "Initialize" and "Tasks" functions) of any of
    the modules in the system or make any assumptions about when those functions
    are called.  That is the responsibility of the configuration-specific system
    files.
 *******************************************************************************/

// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include "app_drv_usart1.h"
#include "app_drv_usart2.h"
#include "driver/usart/drv_usart.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

// *****************************************************************************
// *****************************************************************************
// Section: Global Data Definitions
// *****************************************************************************
// *****************************************************************************
DRV_HANDLE Uart1Handle;
DRV_USART_BUFFER_HANDLE Uart1WriteTransferHandle;
DRV_USART_BUFFER_HANDLE Uart1ReadTransferHandle;
volatile int Uart1WriteComplete = false;
volatile int Uart1ReadComplete = false;
char Uart1WriteBuf[50];
char Uart1ReadBuf[50];

// *****************************************************************************
/* Application Data

  Summary:
    Holds application data

  Description:
    This structure holds the application's data.

  Remarks:
    This structure should be initialized by the APP_DRV_USART1_Initialize function.

    Application strings and buffers are be defined outside this structure.
*/

APP_DRV_USART1_DATA app_drv_usart1Data;

void USART1printf( const char *format, ... )
{
    size_t len=0;
    va_list args = {0};

    va_start( args, format );
    len = vsnprintf( Uart1WriteBuf, sizeof(Uart1WriteBuf), format, args );
    va_end( args );

    if( len > 0 && len < sizeof(Uart1WriteBuf) )
    {
        Uart1WriteBuf[len] = '\0';
        DRV_USART_WriteBufferAdd(Uart1Handle, Uart1WriteBuf, strlen(Uart1WriteBuf), &Uart1WriteTransferHandle);
        while( DRV_USART_BufferStatusGet(Uart1WriteTransferHandle)!=DRV_USART_BUFFER_EVENT_COMPLETE )
        {}
    }	
}

// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************
void Uart1TransferHandler( DRV_USART_BUFFER_EVENT event, DRV_USART_BUFFER_HANDLE bufferHandle, uintptr_t context )
{
    switch( event )
    {
    case DRV_USART_BUFFER_EVENT_PENDING: break;
    case DRV_USART_BUFFER_EVENT_COMPLETE:
        if(bufferHandle == Uart1ReadTransferHandle)
            Uart1ReadComplete = true;
        if(bufferHandle == Uart1WriteTransferHandle)
            Uart1WriteComplete = true;
        break;
    case DRV_USART_BUFFER_EVENT_HANDLE_EXPIRED:
    case DRV_USART_BUFFER_EVENT_ERROR:
    case DRV_USART_BUFFER_EVENT_HANDLE_INVALID:
        app_drv_usart1Data.state = APP_DRV_USART1_STATE_ERROR;
        break;
    }
}

// *****************************************************************************
// *****************************************************************************
// Section: Application Local Functions
// *****************************************************************************
// *****************************************************************************


/* TODO:  Add any necessary local functions.
*/


// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void APP_DRV_USART1_Initialize ( void )

  Remarks:
    See prototype in app_drv_usart1.h.
 */

void APP_DRV_USART1_Initialize ( void )
{
    /* Place the App state machine in its initial state. */
    app_drv_usart1Data.state = APP_DRV_USART1_STATE_INIT;



    /* TODO: Initialize your application's state machine and other
     * parameters.
     */
}


/******************************************************************************
  Function:
    void APP_DRV_USART1_Tasks ( void )

  Remarks:
    See prototype in app_drv_usart1.h.
 */

void APP_DRV_USART1_Tasks ( void )
{
    switch ( app_drv_usart1Data.state )
    {
    case APP_DRV_USART1_STATE_INIT:
        Uart1Handle = DRV_USART_Open(DRV_USART_INDEX_0, DRV_IO_INTENT_READWRITE);
        if(Uart1Handle == DRV_HANDLE_INVALID)
        {
            app_drv_usart1Data.state = APP_DRV_USART1_STATE_ERROR;
        }
        else
        {
            USART1printf("DRV_USART1: Hello world\r\n");
            // sprintf(Uart1WriteBuf, "DRV_USART1: Hello world\r\n");
            // DRV_USART_WriteBufferAdd(Uart1Handle, Uart1WriteBuf, strlen(Uart1WriteBuf), &Uart1WriteTransferHandle);
            // while( DRV_USART_BufferStatusGet(Uart1WriteTransferHandle)!=DRV_USART_BUFFER_EVENT_COMPLETE )
            // {}

            DRV_USART_BufferEventHandlerSet(Uart1Handle, Uart1TransferHandler, 0);

            app_drv_usart1Data.state = APP_DRV_USART1_STATE_READ;
        }
        break;

    case APP_DRV_USART1_STATE_READ:
        DRV_USART_ReadBufferAdd(Uart1Handle, Uart1ReadBuf, 1, &Uart1ReadTransferHandle);
        if(Uart1ReadTransferHandle == DRV_USART_BUFFER_HANDLE_INVALID)
        {
            app_drv_usart1Data.state = APP_DRV_USART1_STATE_ERROR;
        }
        else
        {
            app_drv_usart1Data.state = APP_DRV_USART1_STATE_READ_WAIT_COMPLETE;
        }
        break;

    case APP_DRV_USART1_STATE_READ_WAIT_COMPLETE:
        if(Uart1ReadComplete == true)
        {
            Uart1ReadComplete = false;
            app_drv_usart1Data.state = APP_DRV_USART1_STATE_READ; // Modify this Line
            app_drv_usart2Data.state = APP_DRV_USART2_STATE_WRITE;
        }
        break;

    case APP_DRV_USART1_STATE_WRITE:
        sprintf(Uart1WriteBuf, "Receive : %s (DRV_USART2)\r\n", Uart2ReadBuf); // Modify this Line
        DRV_USART_WriteBufferAdd(Uart1Handle, Uart1WriteBuf, strlen(Uart1WriteBuf), &Uart1WriteTransferHandle);
        if(Uart1WriteTransferHandle == DRV_USART_BUFFER_HANDLE_INVALID)
        {
            app_drv_usart1Data.state = APP_DRV_USART1_STATE_ERROR;
        }
        else
        {
            app_drv_usart1Data.state = APP_DRV_USART1_STATE_WRITE_WAIT_COMPLETE;
        }
        break;

    case APP_DRV_USART1_STATE_WRITE_WAIT_COMPLETE:
        if(Uart1WriteComplete == true)
        {
            Uart1WriteComplete = false;
            app_drv_usart1Data.state = APP_DRV_USART1_STATE_READ_WAIT_COMPLETE; // Modify this Line			
        }
        break;

    case APP_DRV_USART1_STATE_ERROR:
        app_drv_usart1Data.state = APP_DRV_USART1_STATE_IDLE;
        break;

    case APP_DRV_USART1_STATE_IDLE:
        break;
    }
}


/*******************************************************************************
 End of File
 */
