/**
  @Generated 16-bit Bootloader Source File

  @Company:
    Microchip Technology Inc.

  @File Name: 
    boot_demo.c

  @Summary:
    This is the boot_demo.c file generated using 16-bit Bootloader

  @Description:
    This header file provides implementations for driver APIs for all modules selected in the GUI.
    Generation Information :
        Product Revision  :  16-bit Bootloader - 1.17.2
        Device            :  PIC24FJ1024GA606
    The generated drivers are tested against the following:
        Compiler          :  XC16 v1.36B
        MPLAB             :  MPLAB X v5.15
*/
/*
Copyright (c) [2012-2019] Microchip Technology Inc.  

    All rights reserved.

    You are permitted to use the accompanying software and its derivatives 
    with Microchip products. See the Microchip license agreement accompanying 
    this software, if any, for additional info regarding your rights and 
    obligations.
    
    MICROCHIP SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT 
    WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT 
    LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT 
    AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP OR ITS
    LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT 
    LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE 
    THEORY FOR ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT 
    LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, 
    OR OTHER SIMILAR COSTS. 
    
    To the fullest extend allowed by law, Microchip and its licensors 
    liability will not exceed the amount of fees, if any, that you paid 
    directly to Microchip to use this software. 
    
    THIRD PARTY SOFTWARE:  Notwithstanding anything to the contrary, any 
    third party software accompanying this software is subject to the terms 
    and conditions of the third party's license agreement.  To the extent 
    required by third party licenses covering such third party software, 
    the terms of such license will apply in lieu of the terms provided in 
    this notice or applicable license.  To the extent the terms of such 
    third party licenses prohibit any of the restrictions described here, 
    such restrictions will not apply to such third party software.
*/
#include "../memory/flash.h"
#include "boot_process.h"

#include <stdbool.h>
#include <stdint.h>
#include "boot_config.h"
#include "boot_demo.h"
#include "../uart4.h"

static void RunBootLoader(void);
static bool EnterBootLoadMode(void);


void blink_led(int ton, int toff)
{
   if(ton>0){
   PORTDbits.RD8= 1;
   __delay_ms(ton);
   }
   if(toff>0){
    PORTDbits.RD8= 0;
    __delay_ms(toff);
   }
}

void BOOT_DEMO_Initialize(void)
{    

}

void BOOT_DEMO_Tasks(void)
{
    // imageload is initiated if app flash is empty or
    // designated byte sequence is received (implemented in EnterBootLoadMode)
    // Once in image load, must complete flash cycle or reset/power cycle to exit
    if( (EnterBootLoadMode() == true) || (BOOT_Verify() == false) )
    {
        // LED ON indicates waiting for image load
        // whether from user input or verify check
        PORTDbits.RD8= 1;
        RunBootLoader();
    }
    else
    {
        // diable UART (used by application)
        U4MODEbits.UARTEN = 0;
        U4STAbits.UTXEN = 0;

        BOOT_StartApplication();
    }
}

static bool EnterBootLoadMode(void)
{
    bool retval=false;
//    #warning "Update this function to return 'true' when you want to stay in the boot loader, and 'false' when you want to allow a release to the application code"
         
    /* NOTE: This might be a a push button status on power up, a command from a peripheral, 
     * or whatever is specific to your boot loader implementation */    

    int i=0;
    int j=0;
    
    // return true if four 'U' bytes received before timeout expires.
    // flash LED each time sequence character received.
    // Additional bytes are ignored
     while(i<BOOT_TIMEOUT_SEC && retval==false){
        while(UART4_IsRxReady()){ 
            uint8_t rd_byte=UART4_Read();
                UART4_Write(rd_byte);
           switch(rd_byte){
               case 'U':
                    j++;
                    LED_BLINK(250);
                    break;
                default:
                     break;
            }
            if(j>=4){
                // exit loop when valid sequence complete
                retval=true;
                // turn LED on
                PORTDbits.RD8= 1;
                break;
            }
        }
        i++;
        __delay_ms(1000);
    }
    // blink LED 3x if return false (sequence not received)
    // turn LED ON if sequence received
    for(i=0;i<3;i++){
    blink_led((retval?1:250),(retval?-1:250));
    }
    return retval;
}

static void RunBootLoader()
{
    /* In this example implementation we will process commands in a while(1)
     * loop and only exit if a RESET command is issued by the host.  Change here
     * to customize your boot loaders behavior. 
     *
     * NOTE: there is currently not methods in most MCC drivers to return the
     * peripherals to their reset state.  When jumping to the user application
     * it should be verified that peripherals are all completely reinitialized.
     */
    bool err=false;
    uint16_t i=0;
    while (1)
    {
         enum BOOT_COMMAND_RESULT test=BOOT_ProcessCommand();
        if( (test == BOOT_COMMAND_SUCCESS) ||
            (test == BOOT_COMMAND_NONE) ||
            (test == BOOT_COMMAND_INCOMPLETE)){
            /* Add code here if you want to */
            // blink LED during programming
            // leave ON if error occurs
            i++;
            if(!err){
                if( (i%0xA00)==0 ){
                    LED_TOGGLE(); 
                }
            }
        }else{
            // serious error
            LED_ON();
            err=true;
        }
    }
}