/**HEADER********************************************************************
* 
* Copyright (c) 2008 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: init_bsp.c$
* $Version : 3.0.17.0$
* $Date    : Jun-4-2009$
*
* Comments:
*
*   This file contains the source functions for functions required to
*   specifically initialize the card.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "bsp.h"
#include "bsp_prv.h"
#include "rtc.h"

const char _PTR_ _mqx_bsp_revision = REAL_NUM_TO_STR(BSP_REVISION);
const char _PTR_ _mqx_io_revision  = REAL_NUM_TO_STR(IO_REVISION);

static uint_32 _bsp_get_hwticks(pointer param);
static void    _bsp_setup_watchdog(void);
static void    _bsp_setup_minifrexbus(void);


const MPC5225_TIMER_INIT_STRUCT _bsp_timers[MCF5225_NUM_TIMERS] = {
   {MCF5225_INT_PIT0, BSP_PIT0_INT_LEVEL, BSP_PIT0_INT_SUBLEVEL},
   {MCF5225_INT_PIT1, BSP_PIT1_INT_LEVEL, BSP_PIT1_INT_SUBLEVEL}
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_enable_card
* Returned Value   : uint_32 result
* Comments         :
*   This function sets up operation of the card.
*
*END*----------------------------------------------------------------------*/

uint_32 _bsp_enable_card
   (
      void
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR	kernel_data;
   uint_32					result;

   /* Set the CPU type */
   _mqx_set_cpu_type(MQX_CPU);

#if MQX_EXIT_ENABLED
   /* Set the bsp exit handler, called by _mqx_exit */
   _mqx_set_exit_handler(_bsp_exit_handler);
#endif

   /* Initialize the MCF5225 support functions */
   _mcf5225_initialize_support(0);

   /*
   ** Initialize the interrupt handling
   */
   /* Mask all interrupts */
   _mcf5225_int_mask_all();

   _int_set_vector_table(BSP_INTERRUPT_VECTOR_TABLE);

   result =  _psp_int_init(BSP_FIRST_INTERRUPT_VECTOR_USED,
      BSP_LAST_INTERRUPT_VECTOR_USED);
   if (result != MQX_OK) {
      return result;
   } /* Endif */

   /* Initialize the timer interrupt */
   _time_set_timer_vector(BSP_TIMER_INTERRUPT_VECTOR);
   if (_int_install_isr(BSP_TIMER_INTERRUPT_VECTOR,
      (void (_CODE_PTR_)(pointer))_bsp_timer_isr, NULL) == NULL)
   {
      return MQX_TIMER_ISR_INSTALL_FAIL;
   } /* Endif */

   _GET_KERNEL_DATA(kernel_data);

   kernel_data->TIMER_HW_REFERENCE = _mcf5225_timer_init_freq(BSP_TIMER,
       BSP_ALARM_FREQUENCY, BSP_SYSTEM_CLOCK, FALSE);

   _time_set_hwtick_function(_bsp_get_hwticks,
      (pointer)kernel_data->TIMER_HW_REFERENCE);
   _time_set_hwticks_per_tick(kernel_data->TIMER_HW_REFERENCE);
   _time_set_ticks_per_sec(BSP_ALARM_FREQUENCY);

   _mcf5225_timer_unmask_int(BSP_TIMER);

#if BSPCFG_ENABLE_CPP
   /* initialize C++ constructors */
   __cpp_init();
#endif

   /* Initialize RTC and MQX time */
#if BSPCFG_ENABLE_RTCDEV
   _bsp_rtc_io_init ();
   _rtc_sync_with_mqx (TRUE);
#endif

#if BSPCFG_ENABLE_IO_SUBSYSTEM
   /* Initialize the I/O Sub-system */
   result = _io_init();
   if (result != MQX_OK) {
      return result;
   } /* Endif */

   /* Install device drivers */
#if BSPCFG_ENABLE_TTYA
   _mcf52xx_uart_serial_polled_install("ttya:", &_bsp_uart0_init,
      _bsp_uart0_init.QUEUE_SIZE);
#endif
#if BSPCFG_ENABLE_TTYB
   _mcf52xx_uart_serial_polled_install("ttyb:", &_bsp_uart1_init,
      _bsp_uart1_init.QUEUE_SIZE);
#endif
#if BSPCFG_ENABLE_TTYC
   _mcf52xx_uart_serial_polled_install("ttyc:", &_bsp_uart2_init,
      _bsp_uart2_init.QUEUE_SIZE);
#endif

#if BSPCFG_ENABLE_ITTYA
   _mcf52xx_uart_serial_int_install("ittya:", &_bsp_uart0_init,
      _bsp_uart0_init.QUEUE_SIZE);
#endif
#if BSPCFG_ENABLE_ITTYB
   _mcf52xx_uart_serial_int_install("ittyb:", &_bsp_uart1_init,
      _bsp_uart1_init.QUEUE_SIZE);
#endif
#if BSPCFG_ENABLE_ITTYC
   _mcf52xx_uart_serial_int_install("ittyc:", &_bsp_uart2_init,
      _bsp_uart2_init.QUEUE_SIZE);
#endif

#if BSPCFG_ENABLE_I2C0
   _mcf52xx_i2c_polled_install("i2c0:", &_bsp_i2c0_init);
#endif
#if BSPCFG_ENABLE_I2C1
   _mcf52xx_i2c_polled_install("i2c1:", &_bsp_i2c1_init);
#endif
#if BSPCFG_ENABLE_II2C0
   _mcf52xx_i2c_int_install("ii2c0:", &_bsp_i2c0_init);
#endif
#if BSPCFG_ENABLE_II2C1
   _mcf52xx_i2c_int_install("ii2c1:", &_bsp_i2c1_init);
#endif

	_mcf52xx_P5Q_spi_install("PCM:", &_bsp_P5Q_spi_init);
	_mcf52xx_AD7652_install("A7652:", &_bsp_ad7652_init);
	_mcf52xx_AD5546_install("A5546:", &_bsp_ad5546_init);


#if BSPCFG_ENABLE_ADC
   _io_adc_install("adc:");
#endif

   /* アプリケーション未実装のためコメント化 */
   _io_sensor_install("sensor:");

   /* Initialize the default serial I/O */
   _io_serial_default_init();

   /* Install the GPIO driver */
#if BSPCFG_ENABLE_GPIODEV   
   _io_gpio_install("gpio:");
#endif

/* install internal flash */
#if BSPCFG_ENABLE_FLASHX
    _mcf5225_internal_flash_install("flashx:", BSPCFG_FLASHX_SIZE);
#endif

#endif

   /*
   ** Enable/disable the watchdog timer
   ** The initialization mode is defined by BSP_WATCHDOG_INITIALIZATION macro	
   */   
   _bsp_setup_watchdog();

	_bsp_setup_minifrexbus();

   return MQX_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_exit_handler
* Returned Value   : none
* Comments         :
*    This function is called when MQX exits
*
*END*----------------------------------------------------------------------*/

void _bsp_exit_handler
   (
      void
   )
{ /* Body */
   uint_16   temp;

   temp = _psp_set_sr(0x2700);
   _mcf5225_int_mask_all();

} /* Endbody */


/*ISR*********************************************************************
*
* Function Name    : _bsp_timer_isr
* Returned Value   : void
* Comments         :
*    The timer ISR is the interrupt handler for the clock tick.
*
*END**********************************************************************/

void _bsp_timer_isr
   (
      pointer dummy
   )
{ /* Body */
#if BSP_WATCHDOG_INITIALIZATION != BSP_WATCHDOG_DISABLED
   // Service the watchdog timer to verify we are still in control
   VMCF5225_STRUCT_PTR reg_ptr = _PSP_GET_IPSBAR();
   reg_ptr->SCM.CWSR = 0x55;
   reg_ptr->SCM.CWSR = 0xAA;
#endif

   _mcf5225_timer_clear_int(BSP_TIMER);
   _time_notify_kernel();

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_hwticks
* Returned Value   : uint_32
* Comments         :
*    This function returns the number of hw ticks that have elapsed
* since the last interrupt
*
*END*----------------------------------------------------------------------*/

static uint_32 _bsp_get_hwticks
   (
      pointer param
   )
{ /* Body */

   return _mcf5225_get_hwticks(BSP_TIMER);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_setup_watchdog
* Returned Value   : uint_32
* Comments         :
*    This function initializes the watchdog timer according to the definition
* BSP_WATCHDOG_INITIALIZATION in m52259demo.h
*
*END*----------------------------------------------------------------------*/

static void _bsp_setup_watchdog
   (
      void
   )
{ /* Body */

   VMCF5225_STRUCT_PTR reg_ptr = _PSP_GET_IPSBAR();

   reg_ptr->SCM.CWCR = 0;

   if (reg_ptr->SCM.CWCR & MCF5225_SCM_CWCR_CWTAVAL) {
      reg_ptr->SCM.CWCR = MCF5225_SCM_CWCR_CWTAVAL;
   } /* Endif */
   if (reg_ptr->SCM.CWCR & MCF5225_SCM_CWCR_CWTIC) {
      reg_ptr->SCM.CWCR = MCF5225_SCM_CWCR_CWTIC;
   } /* Endif */

   // Clear the watchdog count
   reg_ptr->SCM.CWSR = 0x55;
   reg_ptr->SCM.CWSR = 0xAA;

#if BSP_WATCHDOG_INITIALIZATION != BSP_WATCHDOG_DISABLED
   reg_ptr->SCM.CWCR = 0
# if BSP_WATCHDOG_INITIALIZATION == BSP_WATCHDOG_RESET
# error Watchdog resets immediately for some reason
      | MCF5225_SCM_CWCR_CWRI
# endif
      | MCF5225_SCM_CWCR_CWE
      | MCF5225_SCM_CWCR_CWT(BSP_WATCHDOG_DELAY);
#endif

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_setup_watchdog
* Returned Value   : uint_32
* Comments         :
*    This function initializes the watchdog timer according to the definition
* MCF5225_WATCHDOG_INITIALIZATION in m52259demo.h
*
*END*----------------------------------------------------------------------*/

static void _bsp_setup_minifrexbus(void)
{
	VMCF5225_GPIO_STRUCT_PTR		gpio_ptr;
	VMCF5XXX_MINIFB_STRUCT_PTR		minifb;

	gpio_ptr = _bsp_get_gpio_base_address();
	minifb = (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->FB);

	/* -- MiniFrexbus Setup -- */

	/*  Chip-Select Address Register */
	minifb->CSAR0 = MCF5XXX_FBCS_CSAR_BA(0x80000000);

	/*  Chip-Select Mask Register */
	minifb->CSMR0 = MCF5XXX_FBCS_CSMR_BAM_64K|MCF5XXX_FBCS_CSMR_V;

	/* Chip-Select Control Register */
	minifb->CSCR0 = (MCF5XXX_FBCS_CSCR_ASET(0)|MCF5XXX_FBCS_CSCR_RDAH(3)|MCF5XXX_FBCS_CSCR_WRAH(3)|
						MCF5XXX_FBCS_CSCR_WS(1)|MCF5XXX_FBCS_CSCR_MUX|MCF5XXX_FBCS_CSCR_AA|MCF5XXX_FBCS_CSCR_PS_16);

	/* Chip-Select Address Register */
	minifb->CSAR1 = MCF5XXX_FBCS_CSAR_BA(0x80100000);

	/* Chip-Select Mask Register */
	minifb->CSMR1 = MCF5XXX_FBCS_CSMR_BAM_64K|MCF5XXX_FBCS_CSMR_V;

	/* Chip-Select Control Register */
	minifb->CSCR1 = (MCF5XXX_FBCS_CSCR_ASET(0)|MCF5XXX_FBCS_CSCR_RDAH(3)|MCF5XXX_FBCS_CSCR_WRAH(3)|
						MCF5XXX_FBCS_CSCR_WS(1)|MCF5XXX_FBCS_CSCR_MUX|MCF5XXX_FBCS_CSCR_AA|MCF5XXX_FBCS_CSCR_PS_16);

	/* -- MiniFrexbus GPIO Setup -- */

	/* FB_D0-D7 GPIO */
	gpio_ptr->PTHPAR = 0x00;

	/* FB_AD0-AD7 Primary Function */
	gpio_ptr->PTEPAR = 0xff;

	/* FB_AD8-AD15 Primary Function */
	gpio_ptr->PTFPAR = 0xff;

	/* FB_AD16-AD19 GPIO/FB_RW,FB_OE Primary Function */
	gpio_ptr->PTGPAR = (gpio_ptr->PTGPAR & (~0xc0))|0xc0;

	/* FB_CS0 Primary Function */
	gpio_ptr->PTGPAR |= 0x20;

	/* FB_CS1 Secondary Function(Alt 1) */
	gpio_ptr->PASPAR = (gpio_ptr->PASPAR & (~0x30)) | 0x20;


	/* LED0/1 GPIO SETUP */
	gpio_ptr->PTCPAR = gpio_ptr->PTCPAR & (~0x000f);
	gpio_ptr->DDRTC = gpio_ptr->DDRTC | 0x0003;
	gpio_ptr->PORTTC = (gpio_ptr->PORTTC & (~0x0003)) | 0x0001;


	gpio_ptr->PNQPAR = gpio_ptr->PNQPAR & (~0xcc00);
	gpio_ptr->DDRNQ  = gpio_ptr->DDRNQ  & (~0xa0);
}

/* EOF */
