/*************************************************************************
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA.      *
* All rights reserved. All use of this software and documentation is     *
* subject to the License Agreement located at the end of this file below.*
*************************************************************************/
/******************************************************************************
 *
 * Description
 * ----------- 
 * This programs demonstrates how to configure and control the Altera Video and
 * Image Processing Suite MegaCore functions using a set of software API
 * classes.
 * 
 * In this example, the program uses these classes to access the register map of
 * the following MegaCore functions:
 * 
 * HSMC Bitec Quad Video daughtercard               (HSMC_Quad_Video.hpp)
 * HSMC Bitec DVI I/O daughtercard                  (HSMC_Dual_DVI.hpp)
 * Clocked Video Input                              (Clocked_Video_Input.hpp)
 * Clocked Video Output                             (Clocked_Video_Output.hpp)
 * Frame Buffer                                     (Frame_Buffer.hpp)
 * Mixer                                            (Mixer.hpp)
 * 
 * The software project also provides classes to access the following MegaCore functions:
 * 
 * Clipper                                          (Clipper.hpp)
 * Scaler                                           (Scaler.hpp)
 * Gamma Corrector                                  (Gamma_Corrector.hpp)
 * Base class to start/stop each video function     (Vipcore.hpp)
 * 
 * The VIP Suite functions are controllable at run-time via Avalon-MM Slave interfaces.
 *
 *
 * This program performs the following functions:
 *  - Initialises the HSMC Bitec Quad Video daughtercard     (HSMC_Quad_Video.hpp) 
 *  - Initialises the HSMC Bitec DVI I/O daughtercard        (HSMC_Dual_DVI.hpp)
 *  - Starts the Frame Buffer MegaCore function              (Frame_Buffer.hpp)
 *  - Initialised the Alpha Blending Mixer MegaCore function (Mixer.hpp)
 *  - Starts the Clocked Video Input MegaCore function       (Clock_Video_Input.hpp) 
 *  - Starts the Clocked Video Output MegaCore function      (Clock_Video_Output.hpp) 
 *  - Writes to the Mixer function to change the location of the Quad Video card video 
 *    stream input relative to the test pattern background image 
 */

#include <system.h>
#include "HSMC_Dual_DVI.hpp"
#include "HSMC_Quad_Video.hpp"
#include "Clocked_Video_Input.hpp"
#include "Clocked_Video_Output.hpp"
#include "Frame_Buffer.hpp"
#include "Mixer.hpp"
#include "Scaler.hpp"
#include "unistd.h"

#include "vip_wrapper_for_c_func.h"



#ifdef ALT_VIP_MIX_0_BASE

//Mixer* the_mixer_ptr;
Mixer * the_mixer_ptr = (Mixer *) NULL;

void Mixer_init(){
   /* Initialise and start the Alpha Blending Mixer MegaCore function */
   the_mixer_ptr = new Mixer(ALT_VIP_MIX_0_BASE);
   /* Set position of layer 1 to (0,0) relative to background layer */

   the_mixer_ptr->set_layer_position(1,0,0);
//   the_mixer_ptr->set_layer_position(1,(800-640/2)/2,(480-480/2)/2);

//   the_mixer_ptr->set_layer_enabled(0, false);

   the_mixer_ptr->set_layer_enabled(1, true);
//   the_mixer_ptr->set_layer_enabled(2, true);

//   the_mixer_ptr->set_layer_enabled(1, false);
//   the_mixer_ptr->set_layer_enabled(2, false);

   the_mixer_ptr->start();
}

void Mixer_frame_on_off(int layer, int flg){
  if (the_mixer_ptr == NULL) return;
  if (flg)
    the_mixer_ptr->set_layer_enabled(layer, true);
  else
    the_mixer_ptr->set_layer_enabled(layer, false);
}

void Mixer_set_layer_position(int layer, int x, int y){
  if (the_mixer_ptr == NULL) return;

  the_mixer_ptr->set_layer_position(layer, x, y);
}

#endif

#ifdef ALT_VIP_SCL_0_BASE

Scaler<1,1> * the_scaler_ptr = (Scaler<1,1> *) NULL;
void Scaler_init(){

   the_scaler_ptr = new Scaler<1,1>(ALT_VIP_SCL_0_BASE,0,0);

//   the_scaler_ptr->set_output_size(640/2,480/2);
   the_scaler_ptr->set_output_size(720,480);
   the_scaler_ptr->start();
}


void Scaler_set_output_size( int fw, int fh){
  the_scaler_ptr->set_output_size( fw, fh);
}

#endif















#ifdef DVI_OUTPUT_I2C_MASTER_BASE
void HSMC_Dual_DVI_init(){
   /* Initialise the HSMC Bitec DVI I/O daughtercard */
   HSMC_Dual_DVI dual_dvi_board(DVI_OUTPUT_I2C_MASTER_BASE);
   dual_dvi_board.enable_output();
}
#endif

#ifdef QUAD_VIDEO_I2C_MASTER_BASE
void HSMC_Quad_Video_init(){
   /* Initialise the HSMC Bitec Quad Video daughtercard */
   HSMC_Quad_Video quad_analog_in_board(QUAD_VIDEO_I2C_MASTER_BASE);
   quad_analog_in_board.init();
}
#endif

#ifdef MY_ALT_VIP_VFB_BASE
void Frame_Buffer_Reader_init(){
   /* Start the Frame Buffer MegaCore function */
   Frame_Buffer_Reader the_frame_buffer(MY_ALT_VIP_VFB_BASE);
   the_frame_buffer.start();
}
#endif



#ifdef MY_ALT_VIP_CTI_1_BASE
void Clocked_Video_Input_init(){
   /* Start the Clocked Video Input MegaCore function */
   Clocked_Video_Input the_clocked_video_input(MY_ALT_VIP_CTI_1_BASE);
   the_clocked_video_input.stop(true);
   while (!the_clocked_video_input.is_input_stable()) {
   }
   the_clocked_video_input.start();
}
#endif

#ifdef MY_ALT_VIP_ITC_BASE
void Clocked_Video_Output_init(){
   /* Start the Clocked Video Output MegaCore function */
   Clocked_Video_Output the_clocked_video_output(MY_ALT_VIP_ITC_BASE); 
   /* Wait for data to appear in clocked video output FIFO before starting */  
   while (the_clocked_video_output.get_output_fifo_usedw() == 0) {
   }
   the_clocked_video_output.start();
}      
#endif


