// ----------------------------------------------------------------------------
//         ATMEL Microcontroller Software Support 
// ----------------------------------------------------------------------------
// Copyright (c) 2008, 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:
//
// - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the disclaimer below.
//
// Atmel's name may not be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// DISCLAIMER: 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
// 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.
// ----------------------------------------------------------------------------

//----------------------------------------------------------------------------
//  File Name           : at91sam9260-ek-sdram.ini
//  Object              : Generic Macro File for KEIL
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
// _MapRAMAt0()
// Function description: Maps RAM at 0.
//----------------------------------------------------------------------------

DEFINE INT  __mac_i;

FUNC void _MapRAMAt0(){

	
    printf ("Changing mapping: RAM mapped to 0 \n");
    // Test and set Remap
    __mac_i = _RDWORD(0xFFFFEF00);
    if ( ((__mac_i & 0x01) == 0) || ((__mac_i & 0x02) == 0))
	{
		_WDWORD(0xFFFFEF00,0x03);    // toggle remap bits
	}
    else
    {
        printf ("------------------------------- The Remap is done -----------------------------------\n");
	}
}


//----------------------------------------------------------------------------
// _InitRSTC()
// Function description
//   Initializes the RSTC (Reset controller).
//   This makes sense since the default is to not allow user resets, which makes it impossible to
//   apply a second RESET via J-Link
//----------------------------------------------------------------------------

FUNC void _InitRSTC() {

    _WDWORD(0xFFFFFD08,0xA5000001);    // Allow user reset

}

//----------------------------------------------------------------------------
//
//  _PllSetting()
//  Function description
//  Initializes the PMC.
//  1. Enable the Main Oscillator
//  2. Configure PLL
//  3. Switch Master
//----------------------------------------------------------------------------

FUNC void __PllSetting() 
{

    if ((_RDWORD(0xFFFFFC30)&0x3) != 0 ) 
	{
		// Disable all PMC interrupt ( $$ JPP)
		// AT91C_PMC_IDR   ((AT91_REG *) 0xFFFFFC64) //(PMC) Interrupt Disable Register
		// pPmc->PMC_IDR = 0xFFFFFFFF;
	    _WDWORD(0xFFFFFC64,0xFFFFFFFF);
		// AT91C_PMC_PCDR  ((AT91_REG *) 0xFFFFFC14) //(PMC) Peripheral Clock Disable Register
	    _WDWORD(0xFFFFFC14,0xFFFFFFFF);
		// Disable all clock only Processor clock is enabled.
	    _WDWORD(0xFFFFFC04,0xFFFFFFFE);
		// AT91C_PMC_MCKR  ((AT91_REG *) 	0xFFFFFC30) // (PMC) Master Clock Register
	    _WDWORD(0xFFFFFC30,0x00000001);
	    _sleep_(10);
	    // write reset value to PLLA and PLLB
	    // AT91C_PMC_PLLAR ((AT91_REG *) 	0xFFFFFC28) // (PMC) PLL A Register
	    _WDWORD(0xFFFFFC28,0x00003F00);
	
	    // AT91C_PMC_PLLBR ((AT91_REG *) 	0xFFFFFC2C) // (PMC) PLL B Register
	    _WDWORD(0xFFFFFC2C,0x00003F00);
	    _sleep_(10);
	
	    printf ( "------------------------------- PLL  Enable -----------------------------------------");
    
	} 
    else {
   		printf( " ********* Core in SLOW CLOCK mode ********* "); 
	}
}


//----------------------------------------------------------------------------
//
//      __PllSetting100MHz()
// Function description
//  Set core at 200 MHz and MCK at 100 MHz 
//----------------------------------------------------------------------------

FUNC void __PllSetting100MHz()
{

	printf( "------------------------------- PLL Set at 100 MHz ----------------------------------");

	//* pPmc->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN ));
    _WDWORD(0xFFFFFC20,0x00004001);
    _sleep_(10);
	// AT91C_PMC_MCKR  ((AT91_REG *) 	0xFFFFFC30) // (PMC) Master Clock Register
    _WDWORD(0xFFFFFC30,0x00000001);
    _sleep_(10);
	//*   AT91C_BASE_CKGR->CKGR_PLLAR = (AT91C_CKGR_SRCA | ((96 << 16) & AT91C_CKGR_MULA) | 
	//    (AT91C_CKGR_PLLACOUNT | (AT91C_CKGR_OUTA_0 | (9);
    _WDWORD(0xFFFFFC28,0x2060BF09);
    _sleep_(10);
    // Configure PLLB
    _WDWORD(0xFFFFFC2C,0x207C3F0C);
    _sleep_(10);
	//*   AT91C_BASE_PMC->PMC_MCKR =  AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2;;
    _WDWORD(0xFFFFFC30,0x00000102);
     _sleep_(10);

}

//----------------------------------------------------------------------------
//      __initSDRAM()
//  Function description
//  Set SDRAM for works at 100 MHz
//----------------------------------------------------------------------------

FUNC void __initSDRAM()
{

    // Configure EBI Chip select	
    // pCCFG->CCFG_EBICSA |= AT91C_EBI_CS1A_SDRAMC;
    // AT91C_CCFG_EBICSA ((AT91_REG *) 	0xFFFFEF1C) // (CCFG)  EBI Chip Select Assignement Register
    _WDWORD(0xFFFFEF1C,0x0001003A);
    
    // Configure PIOs
    // AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, AT91C_PC16_D16 to AT91C_PC16_D31
    // pPio->PIO_ASR = periphAEnable; AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) // (PIOC) Select A Register
    // pPio->PIO_BSR = periphBEnable;AT91C_PIOC_BSR  ((AT91_REG *) 0xFFFFF874) // (PIOC) Select B Register
    // pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
    _WDWORD(0xFFFFF870,0xFFFF0000);
    _WDWORD(0xFFFFF874,0x00000000);
    _WDWORD(0xFFFFF804,0xFFFF0000);
    
    // psdrc->SDRAMC_CR =  AT91C_SDRAMC_NC_9  | AT91C_SDRAMC_NR_13 | AT91C_SDRAMC_CAS_2 |
    // AT91C_SDRAMC_NB_4_BANKS | AT91C_SDRAMC_DBW_32_BITS | AT91C_SDRAMC_TWR_2 | AT91C_SDRAMC_TRC_7 |
    // AT91C_SDRAMC_TRP_2 | AT91C_SDRAMC_TRCD_2 | AT91C_SDRAMC_TRAS_5 | AT91C_SDRAMC_TXSR_8 ;
    _WDWORD(0xFFFFEA08,0x85227259);
    _sleep_(10);
    // psdrc->SDRAMC_MR	= 0x00000002;		// Set PRCHG AL
    _WDWORD(0xFFFFEA00,0x00000002);
    // *AT91C_SDRAM	= 0x00000000;			// Perform PRCHG
    _WDWORD(0x20000000,0x00000000);
    _sleep_(10);

    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_RFSH_CMD;		// Set 1st CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    
    // *(AT91C_SDRAM+4)	= 0x00000001;	// Perform CBR
    _WDWORD(0x20000010,0x00000001);
    
    // psdrc->SDRAMC_MR	= 0x00000004;		// Set 2 CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    // *(AT91C_SDRAM+8)	= 0x00000002;	// Perform CBR
    _WDWORD(0x20000020,0x00000002);
    
    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_RFSH_CMD;		// Set 3 CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    // *(AT91C_SDRAM+0xc)	= 0x00000003;	// Perform CBR
    _WDWORD(0x20000030,0x00000003);
       
    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_RFSH_CMD;		// Set 4 CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    // *(AT91C_SDRAM+0x10)	= 0x00000004;	// Perform CBR
    _WDWORD(0x20000040,0x00000004);
       
    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_RFSH_CMD;		// Set 5 CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    // *(AT91C_SDRAM+0x14)	= 0x00000005;	// Perform CBR
    _WDWORD(0x20000050,0x00000005);
       
    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_RFSH_CMD;		// Set 6 CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    // *(AT91C_SDRAM+0x18)	= 0x00000006;	// Perform CBR
    _WDWORD(0x20000060,0x00000006);
       
    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_RFSH_CMD;		// Set 7 CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    // *(AT91C_SDRAM+0x1c)	= 0x00000007;	// Perform CBR
    _WDWORD(0x20000070,0x00000007);
       
    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_RFSH_CMD;		// Set 8 CBR
    _WDWORD(0xFFFFEA00,0x00000004);
    // *(AT91C_SDRAM+0x20)	= 0x00000008;	// Perform CBR
    _WDWORD(0x20000080,0x00000008);
       
    // psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_LMR_CMD;		// Set LMR operation
    _WDWORD(0xFFFFEA00,0x00000003);
    // *(AT91C_SDRAM+0x24)	= 0xcafedede;		// Perform LMR burst=1, lat=2
    _WDWORD(0x20000090,0xCAFEDEDE);
       
    // psdrc->SDRAMC_TR	= (AT91C_MASTER_CLOCK * 7)/1000000;				// Set Refresh Timer 390 for 25MHz (TR= 15.6 * F )
    _WDWORD(0xFFFFEA04,0x000002B9);
    
    //*	psdrc->SDRAMC_MR	= AT91C_SDRAMC_MODE_NORMAL_CMD;		// Set Normal mode
    _WDWORD(0xFFFFEA00,0x00000000);
    
    //*	*AT91C_SDRAM	= 0x00000000;	// Perform Normal mode
    _WDWORD(0x20000000,0x00000000);
    printf( "------------------------------- SDRAM Done at 100 MHz -------------------------------");


}


__PllSetting();                   //* Init PLL
__PllSetting100MHz();    
__initSDRAM();
_MapRAMAt0();                     //* Set the RAM memory at 0x0020 0000 & 0x0000 0000
_InitRSTC(); 
DEBUG_CLOCK = 2000000;
LOAD Objects\\template.axf INCREMENTAL
PC = 0x20000000;
//g,main