FL2440的板子,修改12M的晶体为16.9344M后,无法启动???

aikchun   2010-6-1 23:04 楼主
请教高手们:
    原FL2440的开发板,晶体为12MHz,修改为16.9344M后,无法启动,不知何因?
    先说一下FL2440的bootloader的组成:
    飞凌开发板提供的bootloader由uboot和eboot两部分组成,前面的uboot实现自拷备,同时引导eboot。
eboot实现引导NK。
    这里需要修改uboot的代码实现更换晶体。但是实践发现无法正常工作。具体我修改步骤如下:
一:option.inc中:
   
  1. ;XTAL_SEL        SETA        12000000       
  2. XTAL_SEL        SETA        16934400

    选择16.9344M的晶体
二:option.inc中,
  1. ;FCLK                SETA        400000000
  2. FCLK                SETA        399651840

    修改FCLK为399.65M
三:option.inc中,添加399.65M的分频参数,这里是在16.9344M的分支选项中添加。
  1. [ FCLK = 399651840
  2. M_MDIV                EQU        110        ;Fin=16.9344MHz
  3. M_PDIV                EQU        3
  4.                 [ CPU_SEL = 32440001
  5. M_SDIV                EQU        1                ; 2440A
  6.                 |
  7. M_SDIV                EQU        0                ; 2440X
  8.                 ]
  9.         ]

四:option.h中,
  1. //#define FIN         (12000000)       
  2. #define FIN                (16934400)


我觉得该改的都改了,可是为什么就是起不来呢?

在最开始在AXD下调试bootloader时,需要初始化SDRAM,FL2440默认是通过AXD运行一会儿
2440Init.axf,达到初始化SDRAM的目的,然后再导入bootloader。这样就能正常运行导入
的bootloader了。这种方法在12M的板子上是没有问题的,但是我换用16.9344M之后,用同
样的2440Init.axf,再导入上面修改后生成的bootloader映像,却不能正常运行。

后来我没有用那个2440Init.axf了,而是找了个2440init.ini的脚本文件,相关代码如下:
  1. com ==================
  2. com Filename: 2440Anorom.ini
  3. com 2003. 5. xx 1st draft.
  4. com 2004. 3. 4  edited for S3C2440A
  5. com ==================

  6. com  For S3C2440A
  7. com  SDRAM_Little_32, 64MB
  8. com  FCLK:101.25MHz  UPLL:48MHz
  9. com  SDRAM refresh: 64ms(8Kcycle) -> 7.8us

  10. swat $vector_catch   0x00
  11. swat $semihosting_enabled   0x00
  12. swat psr %IFt_SVC
  13. com swat psr %IF_SVC32

  14. com [disable Watch-Dog reset]
  15. swat *0x53000000 0



  16. com << Clock setting >>
  17. com [PLL lock time setting maximum]
  18. swat *0x4c000000 ((0xfff<<12)+(0xfff<<0))

  19. com FCLK:HCLK:PCLK=1:3:6.
  20. swat *0x4c000014 ((0<<2)+(3<<1)+(1))

  21. com [FCLK PMS setting:294.9140MHz -> 0x7f,2,2]
  22. swat *0x4c000004 ((0x61<<12)+(0x1<<4)+(0x2<<0))

  23. com [UCLK PMS setting:48MHz -> 0x78,2,3]
  24. swat *0x4c000008 ((0x40<<12)+(0x4<<4)+(0x2<<0))


  25. com << Memory setting >>

  26. com [Bank6/7: 32-bit bus width]
  27. swat *0x48000000 0x22000000

  28. com [Bank0-5: Access cycle: 14-clocks, others:0-clock]
  29. swat *0x48000004 ((0<<13)+(0<<11)+(7<<8)+(0<<6)+(0<<4)+(0<<2)+0)
  30. swat *0x48000008 ((0<<13)+(0<<11)+(7<<8)+(0<<6)+(0<<4)+(0<<2)+0)
  31. swat *0x4800000c ((0<<13)+(0<<11)+(7<<8)+(0<<6)+(0<<4)+(0<<2)+0)
  32. swat *0x48000010 ((0<<13)+(0<<11)+(7<<8)+(0<<6)+(0<<4)+(0<<2)+0)
  33. swat *0x48000014 ((0<<13)+(0<<11)+(7<<8)+(0<<6)+(0<<4)+(0<<2)+0)
  34. swat *0x48000018 ((0<<13)+(0<<11)+(7<<8)+(0<<6)+(0<<4)+(0<<2)+0)

  35. com [Bank6/7: SDRAM, Trcd:2clock, CA:9-bit]
  36. swat *0x4800001c ((3<<15)+(0<<2)+1)
  37. swat *0x48000020 ((3<<15)+(0<<2)+1)

  38. com [SDRAM refresh enable, Trp=2clk, Trc=5clk, Refresh:1654]
  39. swat *0x48000024 ((1<<23)+(0<<22)+(0<<20)+(1<<18)+1654)

  40. com [SCKE_EN enable, SCLK_EN enable, Bank6/7 memory map: 64MB/64MB]
  41. swat *0x48000028 (0x1+(1<<5)+(1<<4))

  42. com [Bank6/7 CL: 3-clocks]
  43. swat *0x4800002c 0x30
  44. swat *0x48000030 0x30


在运行AXD之后, 先通过OB命令执行上面的脚本,给SDRAM初始化,同时初始化看
门狗等,这时汇编下的代码可以跑过去了,在汇编下设置寄存器操作LED灯正常。
程序跳到C语言之后,打印串口信息为乱码。但是仔细看了下FCLK,HCLK,PCLK,
配置的是正确的呀?
而且在AXD下通过观察CLKDIVN以及MPLLCON的值,和汇编中设置的是完全匹配的。
单步在C语言中跟踪,跟踪的函数代码如下:
  1. static void cal_cpu_bus_clk(void)
  2. {
  3.         U32 val;
  4.         U8 m, p, s;
  5.        
  6.         val = rMPLLCON;
  7.         m = (val>>12)&0xff;
  8.         p = (val>>4)&0x3f;
  9.         s = val&3;

  10.         //(m+8)*FIN*2 不要超出32位数!
  11.         FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<
  12.        
  13.         val = rCLKDIVN;
  14.         m = (val>>1)&3;
  15.         p = val&1;       
  16.         val = rCAMDIVN;
  17.         s = val>>8;
  18.        
  19.         switch (m) {
  20.         case 0:
  21.                 HCLK = FCLK;
  22.                 break;
  23.         case 1:
  24.                 HCLK = FCLK>>1;
  25.                 break;
  26.         case 2:
  27.                 if(s&2)
  28.                         HCLK = FCLK>>3;
  29.                 else
  30.                         HCLK = FCLK>>2;
  31.                 break;
  32.         case 3:
  33.                 if(s&1)
  34.                         HCLK = FCLK/6;
  35.                 else
  36.                         HCLK = FCLK/3;
  37.                 break;
  38.         }
  39.        
  40.         if(p)
  41.                 PCLK = HCLK>>1;
  42.         else
  43.                 PCLK = HCLK;
  44.        
  45.         if(s&0x10)
  46.                 cpu_freq = HCLK;
  47.         else
  48.                 cpu_freq = FCLK;
  49.                
  50.         val = rUPLLCON;
  51.         m = (val>>12)&0xff;
  52.         p = (val>>4)&0x3f;
  53.         s = val&3;
  54.         UPLL = ((m+8)*FIN)/((p+2)*(1<
  55.         if(UPLL==96*MEGA)
  56.                 rCLKDIVN |= 8;        //UCLK=UPLL/2
  57.         UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
  58. }

发现读出来的rMPLLCON的值时而是正确的,时而又是错误的。
一旦读出的是错误的,在后面的打印信息中将会出现异常。
为什么同一个程序,时而读的是对的,时而读的又是错的呢?
难道换个晶体,还要对SDRAM进行重配置不成?
期待高手指点,感激不尽。

回复评论 (8)

玩超频呀,hoho, 不一定稳定的,

打印信息乱,你要重新计算 波特率 ,然后修改,

SDram flash 都要工作时序的,所以你要修改他们的工作时钟看看,
点赞  2010-6-2 08:16
已经解决问题_^_
点赞  2010-6-2 09:38
说一下怎么解决的,给别人留个参考么。
点赞  2010-6-2 10:01
估计是时钟配置的问题
点赞  2010-6-2 10:10
引用: 引用 2 楼 armeasy 的回复:

已经解决问题_^_


问问题,让别人帮忙,自己解决了,又不说是怎么解决的
是不是有点讨厌,大家说说!
点赞  2010-6-2 12:52
问问题,让别人帮忙,自己解决了,又不说是怎么解决的
是不是有点讨厌,大家说说!

不是有点讨厌,而是特别讨厌。
楼上的先别急嘛,又遇到怪问题了。
又被我改出问题来了。
一并总结好了回上来。
点赞  2010-6-2 13:50
实际测试,将晶体换回16.9344M后,按三星推荐的399M配置,MPLLCON按110,3,1配置,如果CLKDIVN设置为7,即1:3:6,能够进C,但是像上面说的,读寄存器的值不稳定,时而正确时而错误,换用1:4:8配置后,PCLK降为50M左右,接近50M,这时读出来的数就再也没错了。这时已经能进C,串口打印一切正常了。
但是很奇怪,上午我已经调 好可以烧bootloader了,即USB通信正常了,我为了修改那种ini的OB配置方式,搞一个脚本,结果导致USB无法连接了,而且一跑到usbDmain函数就崩了。用脚本配置模式导致。后来恢复用OB配置方式,问题依旧,再也没法像上午那样能够USB正常连接了。
具体USB代码如下:
  1. void UsbdMain(void)
  2. {
  3.     //int i;
  4.     //U8 tmp1;
  5.     //U8 oldTmp1=0xff;
  6.    
  7.     //ChangeUPllValue(0x38,2,1);        // UCLK=96Mhz     
  8.     // ChangeUPllValue(0x38,2,2);        // UCLK=48Mhz     
  9.     InitDescriptorTable();
  10.     //ResetUsbd();
  11.    
  12.     rGPGUP  |= 1<<9;                //disable pull-up
  13.         rGPGCON &= ~(3<<18);       
  14.         Delay(2000);
  15.         rGPGDAT |= 1<<9;                //high   
  16.         rGPGCON |= 1<<18;                //output       
  17.    
  18.     ConfigUsbd();
  19.    
  20.     //DetectVbus(); //not used in S3C2400X

  21.     PrepareEp1Fifo();
  22. #if 0   
  23.     while(1)
  24.     {
  25.             if(DbgPrintfLoop())continue;
  26.            
  27.             Delay(5000);
  28.             if((i++%2)==0)Led_Display(0x8);
  29.             else Led_Display(0x0);
  30.     }
  31. #endif   
  32. }

子函数代码如下:
void ConfigUsbd(void)
  1. {

  2.     ReconfigUsbd();
  3. /*
  4.     pISR_USBD =(unsigned)IsrUsbd;
  5.     ClearPending(BIT_USBD);
  6.     rINTMSK&=~(BIT_USBD);  
  7. */   
  8. [color=#FF0000]    rINTMSK&=~(BIT_USBD); [/color]
  9. }

单步,程序就是执行完红色部分后,彻底崩溃。
分析了好久,不知是什么原因?????
点赞  2010-6-2 14:54
上面红色没显示,执行到这句:
rINTMSK&=~(BIT_USBD);
程序在12M晶体下都全是正常运行的关键。很奇怪。
点赞  2010-6-2 14:57
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复