/*****************************************************************************
* Copyright (c) 2008 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Npttypes.h>
#include "narmnvrm.h"
#include "bsp_bldr.h"
#include "gpio.h"
#include <scm_reg.h>
#include "simpleserial.h"
#include "platformCodes.h"




/*ad*
 * Determines whether to force download the application image.
 *
 * The default implementation does this by determining if specific GPIO pins
 * or register bits are set to the required logic states.
 *
 * @external 
 * @category BSP:BootLoader 
 * @since 7.4 
 *
 *
 * @return TRUE        Force Execute the backup recovery application image.
 * @return FALSE       Do not force execute the backup recovery application image.
 *
*ad*/
BOOLEAN customizeIsImageDownloadForced(void)
{
    int result = FALSE;
#ifndef DOTNETMF
    unsigned long orig_value = *NARM_PORTC_ADDR;

    /* Check if user is force executing one of the recovery processes  */
    /* by checking the states of the PORTC1 and PORTC5 GPIO lines.     */
    /* Shorting pins 3 (MFGI) and 4 (GND) of the MFG header sets PORTC1*/
    /* to 0, while leaving the pins open sets PORTC1 to 1.  The MFG    */
    /* header is located at P5 on the old carrier board and is located */
    /* at P9 on the new carrier board.  On the old carrier board,      */
    /* shorting pins 2 (GND) and 3 (_INIT) of P12 sets PORTC5 to 0,    */
    /* while leaving the pins open sets PORTC5 to 1.  On the new       */
    /* carrier board, shorting pins 20 (_INIT) and 16 (GND) of P3 sets */
    /* PORTC5 to 0, while leaving the pins open sets PORTC5 to 1.  We  */
    /* set PORTC1 and PORTC5 as input GPIO lines before checking the   */
    /* logic state.                                                    */

    /* Forcing a image download requires that both GPIO lines are 0. */
    
    narm_write_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, mode,
                    (narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, mode) & ~(BIT_5 | BIT_1)));
    narm_write_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, dir,
                    (narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, dir) & ~(BIT_5 | BIT_1)));
    narm_write_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, reserved,
                    (narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, reserved) & ~(BIT_5 | BIT_1)));

    if ( !(narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, data) & (BIT_5 | BIT_1)) )
    {
        result = TRUE;
    }

    /* restore the original value */
    *NARM_PORTC_ADDR = orig_value;
#endif
    
    return result;    
}


/*ad*
 * Determines whether to force execute the backup recovery application image.
 *
 * The default implementation does this by determining if specific GPIO pins or
 * specific register bits are set to the required logic states.
 *
 * @external 
 * @category BSP:BootLoader 
 * @since 7.4 
 *
 *
 * @return TRUE        Force Execute the backup recovery application image.
 * @return FALSE       Do not force execute the backup recovery application image.
 *
*ad*/
BOOLEAN customizeIsBackupRecoveryImageForced(void)
{
    int result = FALSE;
#ifndef DOTNETMF
    unsigned long orig_value = *NARM_PORTC_ADDR;


    /* Check if user is force executing one of the recovery processes  */
    /* by checking the states of the PORTC1 and PORTC5 GPIO lines.     */
    /* Shorting pins 3 (MFGI) and 4 (GND) of the MFG header sets PORTC1*/
    /* to 0, while leaving the pins open sets PORTC1 to 1.  The MFG    */
    /* header is located at P5 on the old carrier board and is located */
    /* at P9 on the new carrier board.  On the old carrier board,      */
    /* shorting pins 2 (GND) and 3 (_INIT) of P12 sets PORTC5 to 0,    */
    /* while leaving the pins open sets PORTC5 to 1.  On the new       */
    /* carrier board, shorting pins 20 (_INIT) and 16 (GND) of P3 sets */
    /* PORTC5 to 0, while leaving the pins open sets PORTC5 to 1.  We  */
    /* set PORTC1 and PORTC5 as input GPIO lines before checking the   */
    /* logic state.                                                    */
    
    /* Forcing a backup recovery image execution requires that PORTC1  */
    /* is 0 and PORTC5 is 1.                                           */
    
    narm_write_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, mode,
                    (narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, mode) & ~(BIT_5 | BIT_1)));
    narm_write_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, dir,
                    (narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, dir) & ~(BIT_5 | BIT_1)));
    narm_write_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, reserved,
                    (narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, reserved) & ~(BIT_5 | BIT_1)));

    if ( !(narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, data) & BIT_1) &&
         (narm_read_reg (NARM_PORTX_REG, NARM_PORTC_ADDR, data) & BIT_5) )
    {
        result = TRUE;
    }

    /* restore the original value */
    *NARM_PORTC_ADDR = orig_value;
#endif
    
    return result;    
}


/*ad*
 * User implemented bootloader Flash application image processing routine.
 *
 * This function allows the user to implement a customized Flash application
 * image processing algorithm.  When #define BSP_BOOTLOADER_RECOVERY_METHOD
 * is set to BSP_BOOTLOADER_CUSTOMIZED_RECOVERY in the platform's bsp_bldr.h
 * file, the bootloader will execute the Flash application image processing
 * algorithm in customizedApplicationImageHandler() and bypass the default
 * NET+OS Flash application image processing algorithm.  This customized
 * algorithm must execute an application image if the image is valid, and
 * perform an application image recovery if the image is invalid.  The
 * application image recovery process can include any of the NET+OS recovery
 * methods.
 *
 *
 * @category BSP:BootLoader 
 * @since 7.4 
 *
*ad*/
void customizedApplicationImageHandler(void)
{
    /* Users implement their own Flash application image processing routine */

    bsp_printf("\n\nBootloader executing the user implemented Flash application image processing routine\n\n");
}
