AnsweredAssumed Answered

fullon mode and active mode switching

Question asked by hotkernel on Jul 9, 2011
Latest reply on Jul 20, 2011 by hotkernel

Hi,all

 

 

I have some trouble in the pll setting, and hope someone could help me,thanks.

 

 

 

I use the BF512F CPU, and the silicon revision is 0.1; In my application, the cpu should switch power mode between fullon mode and active mode.

 

 

 

I have test about 20 chips,most of the chips can enter to active mode and then go back to fullon mode.But there are two chips always going idle when calling bfrom_SysControl function.

 

 

 

 

I'm not sure if the code has some bugs or the chip's problem.The following is my code:

 

 

 

 

 

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <blackfin.h>

#include <nBlackfin.h>

 

#define PLL_LOCKCNT_VAL_BOTH    0x4000

#define EBIU_SDBCTL_VAL_BOTH    (EBE | EBSZ_32 | EBCAW_9)

#define EBIU_SDBCTL_VAL_ACTIVE  (EBE | EBSZ_32 | EBCAW_9)

 

#define PLL_CTL_VAL_FULLON      (nBYPASS | nOUT_DELAY | nIN_DELAY | nPDWN | nSTOPCK | nPLL_OFF | DF | SET_MSEL(21))

#define PLL_DIV_VAL_FULLON      (SET_SSEL(4) | CSEL_DIV1)

#define VR_CTL_VAL_FULLON       (nSCKELOW | nWAKE | nPHYWE | CLKBUFOE | 0x00B0 | FREQ)

#define EBIU_SDGCTL_VAL_FULLON  (0x80000000 | 0x40000000 | SCTLE | PSS | TWR_1 | TRCD_3 | TRP_3 | TRAS_7 | PASR_ALL | CL_3)

#define EBIU_RDIV_VAL_FULLON    0x03b6                                                             

 

#define PLL_CTL_VAL_ACTIVE      (BYPASS | nOUT_DELAY | nIN_DELAY | nPDWN | nSTOPCK | PLL_OFF | DF | SET_MSEL(21))

#define PLL_DIV_VAL_ACTIVE      (SET_SSEL(1) | CSEL_DIV1)

#define EBIU_SDGCTL_VAL_ACTIVE  (0x80000000 | 0x40000000 | SCTLE | PSS | TWR_1 | TRCD_1 | TRP_1 | TRAS_3 | PASR_ALL | CL_3)

#define EBIU_RDIV_VAL_ACTIVE    0x013c

 

// bypass pll

void ActiveMode(void)

{

u32 sic0, sic1;

u16 div;

 

ADI_SYSCTRL_VALUES freq;

freq.uwPllCtl = PLL_CTL_VAL_ACTIVE;

//freq.uwPllDiv = PLL_DIV_VAL_ACTIVE;

freq.uwPllLockCnt = PLL_LOCKCNT_VAL_BOTH;

 

 

sic1 = *pSIC_IWR1;

 

sic0 = *pSIC_IWR0;                  // Save value of SIC_IWR1 & SIC_IWR0

 

*pSIC_IWR1 = 0x00000000;

 

*pSIC_IWR0 = 0x00000001;      // disable all the interrupt but pll wakeup

 

ssync();

 

  bfrom_SysControl(SYSCTRL_WRITE | SYSCTRL_EXTVOLTAGE | SYSCTRL_PLLCTL | SYSCTRL_LOCKCNT/* | SYSCTRL_PLLDIV*/,

                             &freq,

                             NULL);

 

*pSIC_IWR0 = sic0;

*pSIC_IWR1 = sic1;                  // Restore SIC_IWR1 & SIC_IWR0

ssync();

 

return;

}

 

 

// same sequence as active mode

 

void FullOnMode(void)

{

u32 sic0, sic1;

u16 div;

 

ADI_SYSCTRL_VALUES freq;

freq.uwPllCtl = PLL_CTL_VAL_FULLON;

freq.uwPllLockCnt = PLL_LOCKCNT_VAL_BOTH;

//freq.uwPllDiv = PLL_DIV_VAL_FULLON;

 

 

sic1 = *pSIC_IWR1;

sic0 = *pSIC_IWR0;

*pSIC_IWR1 = 0x00000000;

*pSIC_IWR0 = 0x00000001;

ssync();

 

bfrom_SysControl(SYSCTRL_WRITE | SYSCTRL_EXTVOLTAGE | SYSCTRL_PLLCTL | SYSCTRL_LOCKCNT/* | SYSCTRL_PLLDIV*/,

                           &freq,

                           NULL);

 

 

*pSIC_IWR0 = sic0;

*pSIC_IWR1 = sic1;

ssync();

 

 

return;

}

 

 

 

void ChangeSdramCfg(bool full)

{

u16 rdiv;

u16 bctl;

u32 gctl;

u16 read;

 

if (full)

{

       rdiv = EBIU_RDIV_VAL_FULLON;

       bctl = EBIU_SDBCTL_VAL_BOTH;

       gctl = EBIU_SDGCTL_VAL_FULLON;

}

else

{

       rdiv = EBIU_RDIV_VAL_ACTIVE;

       bctl = EBIU_SDBCTL_VAL_ACTIVE;

       gctl = EBIU_SDGCTL_VAL_ACTIVE;

}

 

 

while((*pEBIU_SDSTAT & SDCI) == 0){}

 

*pEBIU_SDSTAT |= SDEASE;         /* clear SDRAM EAB sticky error status (W1C) */

*pEBIU_SDRRC = rdiv;                    /* SDRAM Refresh Rate Control Register */

*pEBIU_SDBCTL = bctl;                  /* SDRAM Memory Bank Control Register */

*pEBIU_SDGCTL = gctl;                  /* SDRAM Memory Global Control Register */

ssync();

 

    u16 *pTmp = (u16*) 0x4;

    read = *pTmp;

    while((*pEBIU_SDSTAT & SDRS) == 1){} /* Finalize SDC initialization */

}

 

 

 

void EnterActiveMode(void)

{

ssync();

 

 

*pEBIU_SDGCTL |= SRFS;                    // Enable self-refresh on SDRAM

while(!(*pEBIU_SDSTAT & SDSRA));      // Wait For self refresh active

 

 

ActiveMode();                                       // pll setting sequence, active mode

//_EnterActiveAsm();                             // this assemble code can also work for most of the chips

 

ChangeSdramCfg(FALSE);                    // config sdram for active mode

}

 

 

 

void EnterFullOnMode(void)

{

ssync();

 

 

*pEBIU_SDGCTL |= SRFS;                   // Enable self-refresh on SDRAM

while(!(*pEBIU_SDSTAT & SDSRA));     // Wait For self refresh active

 

 

FullOnMode();                                      // pll setting sequence, fullon mode

ChangeSdramCfg(TRUE);                      // config sdram for fullon mode

}

 

 

 

void main(void)

{

...

// all the code are programmed to the internal flash, and boot up correctly

// I have checked all the chips,the silicon revision is 0.1

 

BlinkLed();              // all of the chip can turn on the led

 

EnterActiveMode();  // the two chips with problems awlays halted in this function when call bfrom_SysControl

Delay_ms(3000);

EnterFullOnMode();

 

...

 

 

while(1)

{

  asm("nop;");

}

 

 

}

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////

 

// following is assemble function for active mode

 

 

#include <bfrom.h>

.import "bfrom.h";

 

 

 

#define SYS_MMR_BASE_512               0xFFC00000

#define SIC_IWR1_512                           0xFFC00164

#define SIC_IWR0_512                           0xFFC00124

#define PLL_DIV_512                             0xFFC00004

 

 

#define IWR1_DISABLE_ALL_512           0x00000000

 

#define IRQ_PLL_WAKEUP_512             0x00000001

 

 

#define PLL_CTL_VAL_LOPOW              0x0401  /* DF | SET_MSEL(2) */

#define PLL_LOCKCNT_VAL_LOPOW     0x4000

#define PLL_DIV_VAL_LOPOW               0x0001

 

 

#define IMM32_512(reg,val) reg##.H=hi(val); reg##.L=lo(val)

 

 

 

.global __EnterActiveAsm;

 

.section L1_code;

 

 

__EnterActiveAsm:

 

 

    link sizeof(ADI_SYSCTRL_VALUES)+2;

 

    [--SP] = (R7:0,P5:0);

 

    SP += -12;

 

 

      // disable all the interrupt but pll wakeup

 

      IMM32_512(P5,SIC_IWR1_512);                    /* Load SIC_IWR1 reg address      */

 

      R7 = IWR1_DISABLE_ALL_512; 

 

      R6 = [P5];                                                    /* Save value of SIC_IWR1            */

 

      [P5] = R7;                                                    /* Wakeup disable all peripherals   */

 

      IMM32_512(P5,SIC_IWR0_512);                    /* Load SIC_IWR1 reg address      */

      R7 = IRQ_PLL_WAKEUP_512; 

      R5 = [P5];                                                    /* Save value of SIC_IWR0       */

      [P5] = R7;                                                    /* PLL Wakeup Interrupt enable    */

 

      // Setting the PLL_CRL,PLL_LOCKCNT regs' value

      R0 = 0;

      R0.L = PLL_CTL_VAL_LOPOW;

      w[FP+-sizeof(ADI_SYSCTRL_VALUES)+offsetof(ADI_SYSCTRL_VALUES,uwPllCtl)] = R0;

 

 

      R0.L = PLL_LOCKCNT_VAL_LOPOW;

 

      w[FP+-sizeof(ADI_SYSCTRL_VALUES)+offsetof(ADI_SYSCTRL_VALUES,uwPllLockCnt)] = R0;

 

 

#if 0

 

      // write pll_div directly(silicon revision 0.0), and the chip i used was 0.1

 

      R0.L = PLL_DIV_VAL_LOPOW;

      IMM32_512(P5,PLL_DIV_512);

      w[P5] = R0;

 

      R0 = (SYSCTRL_EXTVOLTAGE | SYSCTRL_PLLCTL | SYSCTRL_LOCKCNT | SYSCTRL_WRITE );

 

#else

      // use the BFROM_SYSCONTROL function to set the pll_div

 

      R0.L = PLL_DIV_VAL_LOPOW;

      w[FP+-sizeof(ADI_SYSCTRL_VALUES)+offsetof(ADI_SYSCTRL_VALUES,uwPllDiv)] = R0;

 

      // the first parameter of the BFROM_SYSCONTROL function

      R0 = (SYSCTRL_EXTVOLTAGE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV | SYSCTRL_LOCKCNT | SYSCTRL_WRITE );

#endif

 

      // the second parameter of the BFROM_SYSCONTROL function

      R1 = FP;

      R1 += -sizeof(ADI_SYSCTRL_VALUES);

 

      // the third parameter of the BFROM_SYSCONTROL function

      R2 = 0 (z);

 

      IMM32_512(P4,BFROM_SYSCONTROL);

      call(P4);

 

      IMM32_512(P5,SIC_IWR0_512);

      [P5] = R5;       /* Restore SIC_IWR0 register */

 

      IMM32_512(P5,SIC_IWR1_512);

      [P5] = R6;       /* Restore SIC_IWR1 register */

 

      SP += 12;

      (R7:0,P5:0) = [SP++];

      unlink;

      rts;

 

__EnterActiveAsm.end:

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

Regards,

 

JStyle.

 

消息编辑者为:hotkernel

Outcomes