/**HEADER********************************************************************
* 
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: bsp.h$
* $Version : 1.0.0.0$
* $Date    : Apr-23-2012$
*
* Comments:
*
*   This file includes all include files specific to this target system.
*
*END************************************************************************/
#ifndef _bsp_h_
#define _bsp_h_ 1

#include <bsp_rev.h>
#include <psp.h>
#include <fio.h>
#include <io.h>
#include <fxlc95000.h>
#include <fxlc95000eval.h>			// Target definitions
#include <timer_fxlc95000.h>    // Timer
#include <int_ctrl_fxlc95000.h> // Interrupt controller
#include <i2c.h>                // I2C
#include <i2c_fxlc95xxx.h>      // I2C
#include <flashx.h>             // internal flash
#include <flash_fxlc95xxx.h>    // internal flash
//#include <flash_fxlc95000.h>  // internal flash
#include <fxlc95000bsp.h>       // Fxlc95000 specific


#include <io_mem.h>
#include <io_null.h>
#include <io_gpio.h>



/*!
 *  @brief ROM function type.
 *
 *  This value specifies the particular ROM command to execute. For more information on the
 *  operation and data formats for the commands please see the User Callable ROM Functions
 *  section of the FXLC95000 Hardware Reference Manual.
 *
 */
typedef enum {
    RMF_DEV_INFO        = 0, /**< Retrieves device information data structure                    */
    RMF_FLASH_PROGRAM   = 1, /**< Program flash memory through the flash controller              */
    RMF_FLASH_ERASE     = 2, /**< Erase flash memory, through the flash controller               */
    RMF_EXTENSION       = 3, /**< Execute extended flash functions                               */
    RMF_CRC             = 4, /**< Calculate the CRC over a range in memory                       */
    RMF_CI              = 5, /**< Transfer command to the ROM based command interpreter          */
    RMF_CHANGE_CONFIG   = 6, /**< Update the device capabilities configuration                   */
    RMF_FLASH_PROTECT   = 7, /**< Protect the flash against accidental erasure and programming   */
    RMF_FLASH_UNPROTECT = 8, /**< Unprotect access to the flash program and erase functions      */
    RMF_FLASH_UNSECURE  = 9  /**< Modify the current security status of the device               */
} rmf_func_t;



/*!
 *  @brief ROM function return type.
 *
 *  ROM commands return a single value which may be either a pointer or a value depending upon
 *  which function was called. The fxlc9500x_rom_command() function returns a pointer that can be
 *  assigned to the ptr field in the union, and then handled by user code as either a pointer or
 *  a value, depending on which ROM command was executed.
 *
 *  @member  ptr  - Return value handled as a pointer.
 *  
 *  @member  val  - Return value handled as an integer
 *  
 */
typedef union {
    void               *ptr; 
    unsigned long       val; 
} rmf_return_t;


__declspec(register_abi) asm void* asm_rom_handler(    
    rmf_func_t          func_id,    /**< Specifies which of the ROM functions to execute         */
    void               *addr);       /**< Address of the parameter block used for the ROM function*/


/*!
 *  @brief Calls a ROM based function.
 *
 *  This function provides access to the ROM functions documented in the FXLC95000L Hardware
 *  Reference manual. Please refer to that document for details on the operation of these
 *  functions.
 *
 *  @param  rmf_func_t  - (in) ROM function number, see rmf_func_t type.
 *  
 *  @param  addr        - (in) Not used, pass in zero.
 *  
 *  @return Either provides the address of a parameter block containing the result of the command
 *          or returns a value, depending upon the ROM function called.
 */
__declspec(register_abi) inline asm void* fxlc9500x_rom_command(
    rmf_func_t          func_id,    /**< Specifies which of the ROM functions to execute         */
    void               *addr)       /**< Address of the parameter block used for the ROM function*/
{
    trap #0   // Trap 0 used for rom services.
}

/*!<
 * @Example
 *    Example code below shows how to call the fxlc9500x_rom_command() to
 *    invoke ROM services.
 *
 * @snippet examples
 *
 *  rmf_return_t rmf_ret;
 *  rmf_ret.ptr = fxlc9500x_rom_command(
 *                    RMF_DEV_INFO,  // ROM function to be called = Get Device Info
 *                    0              // this command does not take any arguments
 *                );
 */


/*!
 * 
 *  @brief Returns the device version information.
 *
 *  This function copies a device info structure to the supplied memory location and returns the
 *  number of bytes that were copied to the location.
 *
 *  @param length - (in) Maximum number of bytes to copy to destination.  Normally
 *              this would be sizeof(device_info_t).
 *  @param *id_ptr  - (in) Pointer to instance of device_info_t.  The device info 
 *              data will be copied to this pointer.  The data
 *              structure contains:
 *
 *  uint32              device_id;   - ROM: Pseudo random part identification value
 *  uint16              rom_version; - ROM: ROM version code: major.minor
 *  uint16              fw_version;  - FW:  Firmware version code: major.minor
 *  uint16              hw_version;  - ROM: Hardware version code: major.minor
 *  uint16              build_code;  - FW:  Firmware build number and date code. The value is
 *                                          encoded in the following bit fields:
 *                                          - [15:12] daily build number, 0 to 15
 *                                          - [11: 8] build month, 1 to 12
 *                                          - [ 7: 3] build day, 1 to 31
 *                                          - [ 2: 0] build year, 2010 to 2017
 *  uint16              part_number; - FW:  BCD encoded part number, e.g. 0x5000
 *  uint8               reset_cause; - FW:  Lower 5 bits from the RCSR reports reset source.
 *  uint8               secure_mode; - FW:  Lower 2 bits of FOPT report the security mode of
 *                                          the device: 2 = secure, otherwise not secure.
 *
 *  The values marked ROM are retrieved from the ROM using the ROM device infor command, while the
 *  vales marked with FW are written by the firmware.
 *
 *  The number of bytes copied to the destination is limited to the lesser of the number of bytes
 *  requested in the device structure, and the length of the device info structure.
 *
 *  @return The number of bytes copied to the supplied destination.
 */
__declspec(register_abi) uint_32 device_info_get(
    uint_32         length,
    uint_16         *id_ptr);

/*!
 * Maximum bytes of ROM information for FXLC95000 device. 
 */
#define ROM_DEVICE_INFO_MAX_BYTES   16


extern volatile uint_32 bsptimer_counter32;


#ifdef DEBUG_ENABLE_FRAMECOUNTER
extern volatile uint_32 bspframe_counter32;
#endif


/* V1 platform can not work with irq level or sublevel, we can only unmask all interrupts */
//#define _bsp_int_init(irq, level, sublevel, unmask) _fxlc95000_int_unmask_all( void )
#define _bsp_unmask_all_irq() _fxlc95000_int_unmask_all( )
#define _bsp_mask_all_irq() _fxlc95000_int_mask_all(  )


#if (BSP_TIMER == BSP_TIMER_USE_PDB)
  extern uint_32 _bsp_change_ticktime(volatile uint_32);
#endif
  
#if (BSP_TIMER == BSP_TIMER_USE_PDB) 
extern uint_32 _bsp_get_ticktime(void);
#endif

extern _mqx_int _bsp_i2c_io_init (uint_8);
extern uint_32 get_kernel_free_mem(void);


/*
 * Defines and prototypes for handling nmi interrupts.
 */
#define INT_NMI_BIT       (0)
#define FRAMEERR_NMI_BIT  (1)
#define SW7_NMI_BIT       (2)

#define INT_NMI_BIT_MASK        (1 << INT_NMI_BIT)
#define FRAMEERR_NMI_BIT_MASK   (1 << FRAMEERR_NMI_BIT)
#define SW7_NMI_BIT_MASK        (1 << SW7_NMI_BIT)


extern __declspec(register_abi) uint_8 _get_nmi_source(void);
extern __declspec(register_abi) void _clear_nmi_source(uint_8 nmi_bit);
extern __declspec(register_abi) void _clear_all_nmi_source(void);


#endif
