/*This file is prepared for Doxygen automatic documentation generation.*/
//! \file *********************************************************************
//!
//! \brief This file contains the feature to test USBKEY on prod
//!
//! - Compiler:           IAR EWAVR and GNU GCC for AVR
//! - Supported devices:  AT90USB1287, AT90USB1286, AT90USB647, AT90USB646
//!
//! \author               Atmel Corporation: http://www.atmel.com \n
//!                       Support and FAQ: http://support.atmel.no/
//!
//! ***************************************************************************

/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an Atmel
 * AVR product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
 */

//_____  I N C L U D E S ___________________________________________________

#include "config.h"
#include "conf_usb.h"

#ifndef PROD_TEST
#  define PROD_TEST  DISABLE
#endif

// File system includes required for SYNC mode
#if (PROD_TEST==ENABLE)

#  ifndef __ICCAVR__
#  error PROD_TEST feature run only under IAR
#  endif

#  if TARGET_BOARD != USBKEY
#  error PROD_TEST feature run only under USBKEY
#  endif

#include "modules/file_system/navigation.h"
#include "modules/control_access/ctrl_access.h"
#include "lib_mcu/flash/flash_lib.h"
#include "lib_system\memory\memory.h"
//#include "string.h"

//_____ M A C R O S ________________________________________________________
 
#define  TEST_FLAG_ADDR       0x500
   

//_____ D E C L A R A T I O N S ____________________________________________

// This array allocs a byte in flash (=code)
// which will upgraded after test done
code char g_prd_test At(TEST_FLAG_ADDR);  // By default = at first startup = 0x00

static void launch_test( void );

//! This function runs the production test is necessary
//! 
void prod_test( void )
{
   if( 0x00 != g_prd_test )
      return; // Test already done
   
   launch_test();
   while(1);
}

static void launch_test( void )
{
   volatile U16 u16_tmp;
   U8 flag, save_int;
   char name_first_file[] = "USBKEY.tmp";
   
   // Init interface board
   Joy_init();
   Leds_init();
   Hwb_button_init();
   
   // Check joystick
   while( !Is_btn_middle() );
   while( !Is_joy_right() );
   while( !Is_joy_left() );
   while( !Is_joy_up() );
   while( !Is_joy_down() );
   
   // Format DataFlash
   nav_reset();
   if( !nav_drive_set( 0 ) )
      return;  // Test Error
   
   // Write in four sectors
   memset( fs_g_sector , 0x55 , FS_CACHE_SIZE );
   if (CTRL_GOOD != ram_2_memory( 0 , 16+0 , fs_g_sector ))
      return;  // Test Error
   if (CTRL_GOOD != ram_2_memory( 0 , 16+2 , fs_g_sector ))
      return;  // Test Error
   memset( fs_g_sector , 0xAA , FS_CACHE_SIZE );
   if (CTRL_GOOD != ram_2_memory( 0 , 16+1 , fs_g_sector ))
      return;  // Test Error
   if (CTRL_GOOD != ram_2_memory( 0 , 16+3 , fs_g_sector ))
      return;  // Test Error

   // Check value in sectors
   if (CTRL_GOOD != memory_2_ram( 0 , 16+0 , fs_g_sector ))
      return;  // Test Error
   for( u16_tmp=0; u16_tmp<FS_CACHE_SIZE; u16_tmp++) {
      if( fs_g_sector[u16_tmp] != 0x55 ) 
         return;  // Test Error
   }
   if (CTRL_GOOD != memory_2_ram( 0 , 16+2 , fs_g_sector ))
      return;  // Test Error
   for( u16_tmp=0; u16_tmp<FS_CACHE_SIZE; u16_tmp++) {
      if( fs_g_sector[u16_tmp] != 0x55 ) 
         return;  // Test Error
   }
   if (CTRL_GOOD != memory_2_ram( 0 , 16+1 , fs_g_sector ))
      return;  // Test Error
   for( u16_tmp=0; u16_tmp<FS_CACHE_SIZE; u16_tmp++) {
      if( fs_g_sector[u16_tmp] != 0xAA ) 
         return;  // Test Error
   }
   if (CTRL_GOOD != memory_2_ram( 0 , 16+3 , fs_g_sector ))
      return;  // Test Error
   for( u16_tmp=0; u16_tmp<FS_CACHE_SIZE; u16_tmp++) {
      if( fs_g_sector[u16_tmp] != 0xAA ) 
         return;  // Test Error
   }
   
   if( !nav_drive_format( FS_FORMAT_DEFAULT ) )
      return;  // Test Error
   
   // Create a temporary file on DataFlash
   if( !nav_file_create(name_first_file ))
      return;  // Test Error

   // Update status test flag
   if( !flash_lib_check() )
      return;  // Test Error
   save_int=Get_interrupt_state();
   Disable_interrupt();
   flag = TRUE;
   flash_wr_block( &flag, TEST_FLAG_ADDR, 1 );
   // Restore interrupt state
   if(save_int) { Enable_interrupt(); }

   // Display Led OK
   while( 1 )
   {
      // Blink led green
      Led1_toggle();
      Led2_toggle();
      for( u16_tmp=0; u16_tmp<0xFFFF; u16_tmp++ );
   }
}

#endif // (PROD_TEST==ENABLE)

