

#include "sysbasetypes.h"                                                                                                   
#include "c6727dsk.h"                                                                                                        


/* ****************************************************************************
  Functionname:     SetAddrLinesForFlash                           */ /*!
  Description:      Set Adr A14-A17 and A18-A20. Set the GPIO-Port-Lines to simulate Address lines.
                    Addresses are shifted 1 position, since the FLASH is a 16Bit-Device.
                    The function tests, if the address range is within the FLASH range and is
                    setting the address offset from the FLASH start.

  @param[in]        U32 Address to write 
  @param[in, out]   

  @pre              McASP configured for GPIO
  @post             -
  @author           Dieter Weuffen
**************************************************************************** */
void SetAddrLinesForFlash(U32 Adr)
{
   if(Adr >= FLASH_START && Adr < FLASH_END)
   {
      Adr -= FLASH_START;
      Adr *= 2;
      Adr += FLASH_START;
   }
   SetAddrHighLines(Adr);
}


/* ****************************************************************************
  Functionname:     SetAddrHighLines                           */ /*!
  Description:      Set Adr A14-A17 and A18-A20. Set the GPIO-Port-Lines to simulate Address lines

  @param[in]        U32 Address to write 
  @param[in, out]   

  @pre              McASP configured for GPIO
  @post             -
  @author           Dieter Weuffen
**************************************************************************** */
void SetAddrHighLines(U32 Adr)
{
   U32   Out=*GPIODAT1;
   
   Out &= ~0x007f0000;            /* Mask Addr to zero */
   Out |= (Adr) & 0x007f0000;     /* Add  Addr bits */
   
   *GPIODAT1 = Out;               /* Write new value */
}




/* ****************************************************************************
  Functionname:     InitEmif                           */ /*!
  Description:      Init the Emif registers for C6727 EVM-usage
                    SDRAM 16Mbytes 32Bit
                    Flash 512KBytes 16Bit
                    
                    The PLL will be initialized as well to ensure SDRAM timing is correct

  @param[in]        -
  @param[in, out]   

  @pre              McASP configured for GPIO to have upper Address lines set up
  @post             -
  @author           Dieter Weuffen
**************************************************************************** */
void InitEmif(void)
{
               
    *(volatile unsigned char *)(EMIF_SDCR+3) = 0x80;          // enter self-refresh mode
    
    InitPll();                              // set EMIF-clock
    
    /* EMIF setup */
    *(volatile unsigned int *)EMIF_SDTIMR   = 0x31114610;
    // SDTIMER
    *(volatile unsigned int *)EMIF_SDSRETR  = 0x00000006;            
    // SDSRETR  
    *(volatile unsigned int *)EMIF_SDRCR    = 0x0000061a;
    // SDRCR 
    *(volatile unsigned int *)EMIF_SDCR     = 0x00000720;     // 32Bit, CAS=2, 4 banks, 8 columns
    // SDCR 
    *(volatile unsigned int *)EMIF_A1CR     = 0x886225bd;
    // A1CR 
}

/* ****************************************************************************
  Functionname:     ResetPll                           */ /*!
  Description:      Set Pll register to default values
                    

  @param[in]        -
  @param[in, out]   

  @pre              -
  @post             -
  @author           Dieter Weuffen
**************************************************************************** */
void ResetPll(void)
{
    /* Set the PLL back to power on reset state*/
    *(volatile unsigned int *)PLL_CSR     = 0x00000058;
    *(volatile unsigned int *)PLL_DIV3    = 0x00008002;
    *(volatile unsigned int *)PLL_DIV2    = 0x00008001;
    *(volatile unsigned int *)PLL_DIV1    = 0x00008000;
    *(volatile unsigned int *)PLL_DIV0    = 0x00008000;
    *(volatile unsigned int *)PLL_M       = 0x0000000d;
    *(volatile unsigned int *)PLL_CMD     = CMD_GOSET;
}

/* ****************************************************************************
  Functionname:     InitPll                           */ /*!
  Description:      Init the Pll registers to have the full CPU and EMIF speed
                    CPU = 300MHz
                    EMIF = 100MHz
                    
                    The external clock is assumed to be 12MHz

  @param[in]        -
  @param[in, out]   

  @pre              -
  @post             -
  @author           Dieter Weuffen
**************************************************************************** */
void InitPll(void)
{
   int i;
   
    /*------------------------------------------------------*/
    /* When PLLEN is off DSP is running with CLKIN clock    */
    /* source, currently 12MHz or 83.33ns clk rate.         */
    /*------------------------------------------------------*/
    *(volatile unsigned int *)PLL_CSR  &= ~CSR_PLLEN;
    *(volatile unsigned int *)PLL_CSR  &= ~CSR_PLLPWRDN;
    for(i=0;i<1000;i++) {}
   
    // PLL_CSR &= EN 
    
    /* Reset the pll.  PLL takes 125ns to reset. */
    *(volatile unsigned int *)PLL_CSR  |= CSR_PLLRST;
    for(i=0;i<1000;i++) {}

    // PLL_CSR |= RST 
    /*------------------------------------------------------*/
    /* PLLOUT = CLKIN/(DIV0+1) * PLLM                       */
    /* 300    = 12/1 * 25                                   */
    /*------------------------------------------------------*/
    *(volatile unsigned int *)PLL_DIV0    = DIV_ENABLE + 0;
    for(i=0;i<1000;i++) {}
    
    // PLL_DIV0 
    
    *(volatile unsigned int *)PLL_M       = 25;
    for(i=0;i<1000;i++) {}

    // PLL_M 
    /*------------------------------------------------------*/
    /* Program in reverse order.                            */
    /* DSP requires that pheriheral clocks be less then     */
    /* 1/2 the CPU clock at all times.                      */
    /* Order not critical, since changes need GO to come into effect.  */
    /*------------------------------------------------------*/
    *(volatile unsigned int *)PLL_DIV3    = DIV_ENABLE + 2;
    *(volatile unsigned int *)PLL_DIV2    = DIV_ENABLE + 1;
    *(volatile unsigned int *)PLL_DIV1    = DIV_ENABLE + 0;
    *(volatile unsigned int *)PLL_CMD     = CMD_GOSET;
    for(i=0;i<1000;i++) {}
    *(volatile unsigned int *)PLL_CSR    &= ~CSR_PLLRST;
    for(i=0;i<1000;i++) {}
    // PLL_CSR &= RST 
    
    /*------------------------------------------------------*/
    /* Now enable pll path and we are off and running at    */
    /* 300MHz with 100 MHz SDRAM.                            */
    /*------------------------------------------------------*/
    *(volatile unsigned int *)PLL_CSR |= CSR_PLLEN;
    for(i=0;i<1000;i++) {}
    
    // PLL_CSR |= EN 
}


void SetAddrToFlash(void)
{
   SetAddrHighLines(CPLD_SET_FLASH);        // Flash
}

void SetAddrToExpansion(void)
{
   SetAddrHighLines(CPLD_SET_EXPANSION);    // Expansion
}

void SetAddrToControlRegister(void)
{
   SetAddrHighLines(CPLD_SET_REGISTER);     // CPLD Register
}

void InitHPI(void)
{
   /* Disable UHPI */
   *UHPI = 0x00000000;
}

/* ****************************************************************************
  Functionname:     InitGPIO                           */ /*!
  Description:      Setup the Gpio to simulate the address lines
                    
  @param[in]        -
  @param[in, out]   

  @pre              -
  @post             -
  @author           Dieter Weuffen
**************************************************************************** */
void InitGPIO(void)
{
   /* The upper part of the UHPI is used as GPIO-lines */
   *GPIOEN   |= 0x00000200;     /* Enable pin group to be GPIO */
   *GPIODIR1 |= 0x007f0000;     /* HD16-HD22 are the address lines */
   *GPIODAT1 &= ~0x007f0000;    /* clear all address lines to 0 */
}


