PD6710.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:10k
源码类别:

uCOS

开发平台:

C/C++

  1. #include "def.h"
  2. #include "option.h"
  3. #include "2440addr.h"
  4. #include "2440lib.h"
  5. #include "2440slib.h" 
  6. #include "PD6710.h"
  7. /*
  8. DESCRIPTIONS OF THE S3C2440 BOARD
  9. EINT3(GPF3)=nIRQ_PCMCIA(nINT_P_CON)=nINTR
  10. EINT8(GPG0)=IRQ_PCMCIA(INT_P_DEV)=IRQ3
  11. A24=1, I/O area (A26 should have been used.)
  12. A24=0, mem area
  13. AEN=nGCS2, 
  14. absolute address
  15. 0x10000000~0x10FFFFFF: memory area
  16. 0x11000000~0x11FFFFFF: I/O area
  17. */
  18. int  PD6710_Init(void);
  19. void PD6710_InitBoard(void);
  20. void PD6710_InitInterrupt(void);
  21. void PD6710_CardEnable(void);
  22. void PD6710_Wr(U8 index, U8 data);
  23. U8 PD6710_Rd(U8 index);
  24. void PD6710_Modify(U8 index,U8 mask,U8 data);
  25. void PD6710_CommonMemAccess(void);
  26. void PD6710_AttrMemAccess(void);
  27. U8 Card_RdAttrMem(U32 memaddr);
  28. U8 Card_RdIO(U32 ioaddr);
  29. void Card_WrIO(U32 ioaddr,U8 data);
  30. void PrintCIS(void);
  31. void __irq IsrPD6710Card(void);
  32. void __irq IsrPD6710Management(void);
  33. volatile int isCardInsert=0;
  34. void _dbg(int i)
  35. {
  36.     Uart_Printf("<%d>",i);
  37.     //Uart_Printf("INT_GENERAL_CTRL=%xn",PD6710_Rd(INT_GENERAL_CTRL));
  38. }
  39. void Test_PD6710(void)
  40. {
  41.     Uart_Printf("[PD6710 test for reading pc_card CIS]n");
  42.     Uart_Printf("Insert PC card!!!n");
  43.     PD6710_InitBoard();
  44.     PD6710_Init();
  45.     PD6710_InitInterrupt();
  46.     //Check if CD1,2 is L. If nCD1,2 is L, the card has been inserted.
  47.     //In this case, the card management interrupt isn't occurred.
  48.     if((PD6710_Rd(INTERFACE_STATUS)&0xc)==0xc) 
  49.     {
  50. Uart_Printf("Card is inserted.n");
  51. Delay(2000); 
  52. //For card contact stablization. This delay is needed for stable operation.
  53. //If this delay isn't here, CF card will not be identified.
  54. PD6710_CardEnable();
  55. PrintCIS();
  56.     }
  57.     while(1)
  58.     {
  59.    if(Uart_GetKey()==0x1b) break;
  60. Uart_Printf(".");
  61. Delay(10000);
  62.     }
  63. }
  64. //IRQ stack size is enlarged to 4096 byte.
  65. void PrintCIS(void)
  66. {
  67.     int i,j;
  68.     int cisEnd=0;
  69.     static U8 str[16];
  70.     U8 c;
  71.     Uart_Printf("[Card Information Structure]n");
  72.     PD6710_AttrMemAccess();
  73.     //search the end of CIS
  74.     while(1)
  75.     {
  76. if(c=Card_RdAttrMem((cisEnd)*2)==0xff) //0xff= termination tuple
  77.     break;
  78. Uart_Printf("cisEnd:%d, CIS RD:%xn", cisEnd, c);
  79. cisEnd++;
  80. cisEnd+=Card_RdAttrMem((cisEnd)*2)+1;
  81.     }
  82.     Uart_Printf("cisEnd=0~%xn",cisEnd);
  83.     for(i=0;i<=cisEnd*2;i+=2)
  84.     {
  85. c=Card_RdAttrMem(i);
  86. str[(i%0x20)/2]=c;
  87. Uart_Printf("%2x,",c);
  88. if((i%0x20)>=0x1e)
  89. {
  90.     Uart_Printf("//");
  91.     for(j=0;j<0x10;j++)
  92. if(str[j]>=' ' && str[j]<=127)Uart_Printf("%c",str[j]);
  93. else Uart_Printf(".");
  94.     Uart_Printf("n");
  95. }
  96.     }
  97.     Uart_Printf("n");
  98. }
  99. #define B6710_Tacs (0x0) // 0clk
  100. #define B6710_Tcos (0x3) // 4clk
  101. #define B6710_Tacc (0x7) // 14clk
  102. #define B6710_Tcoh (0x1) // 1clk
  103. #define B6710_Tah (0x0) // 0clk
  104. #define B6710_Tacp (0x3) // 6clk
  105. #define B6710_PMC (0x0) // normal(1data)
  106. void PD6710_InitBoard(void)
  107. {
  108. //Initialize S3C2440 for PD6710
  109.     rGPFCON=rGPFCON&~(3<<6)|(2<<6); //EINT3(GPF3)=nIRQ_PCMCIA(nINT_P_CON)=nINTR
  110.     rGPGCON=rGPGCON&~(3<<0)|(2<<0);     //EINT8(GPG0)=IRQ_PCMCIA(INT_P_DEV)=IRQ3
  111.     rBWSCON=rBWSCON&~(0xf<<8)|(0xd<<8);   //nGCS2=nUB/nLB(nSBHE),nWAIT,16-bit
  112.     rBANKCON2=((B6710_Tacs<<13)+(B6710_Tcos<<11)+(B6710_Tacc<<8)+(B6710_Tcoh<<6)
  113. +(B6710_Tah<<4)+(B6710_Tacp<<2)+(B6710_PMC));
  114. }
  115. void PD6710_InitInterrupt(void)
  116. {
  117.     //EINT7(GPE7)=nINT_P_CON=nINTR
  118.     //EINT6(GPE6)=nINT_P_DEV=IRQ3
  119.     rEXTINT0=rEXTINT0&~(7<<12)|(2<<12);
  120. //EINT3(GPF3)=nIRQ_PCMCIA(nINT_P_CON)=nINTR =falling edge
  121.     rEXTINT1=rEXTINT1&~(7<<0)|(4<<0);   
  122. //EINT8(GPG0)=IRQ_PCMCIA(INT_P_DEV)=IRQ3 =rising edge
  123.     pISR_EINT3=(U32)IsrPD6710Management; //nINT_P_CON
  124.     pISR_EINT8_23=(U32)IsrPD6710Card; //nINT_P_DEV
  125.     rSRCPND = BIT_EINT3|BIT_EINT8_23; //to clear the previous pending states
  126.     rINTPND = BIT_EINT3|BIT_EINT8_23;
  127.     rINTMSK=~(BIT_EINT3|BIT_EINT8_23);  
  128.     rEINTMASK=rEINTMASK&~(1<<8)|(0<<8); //EINTMASK[8]=enable interrupt.
  129. }
  130. int PD6710_Init(void)
  131. {
  132.     //Initialize PD-6710
  133.     PD6710_Wr(POWER_CTRL,(0<<7)|(1<<5)|(0<<4)|(0<<0)); 
  134. //output2card_disable,AUTO_POWER,VCC_POWER_OFF,Vpp1=0V
  135.     PD6710_Wr(INT_GENERAL_CTRL,(1<<7)|(0<<5)|(1<<4)|(3<<0)); 
  136. //nSTSCHG=status change(not RI input),mem_card_interface,
  137. //manage_int=-INTR pin, nINT_P_DEV=IRQ3
  138.     PD6710_Wr(MANAGEMENT_INT_CONFIG,(1<<0)|(1<<3)|(3<<4)); 
  139. //status_change_int_enable, card_detect_int_enable, IRQ disabled(IRQ_3)
  140. //Is nINTR pin used???
  141.     PD6710_Wr(IO_WINDOW_CTRL,0|(0<<3));
  142. //IO0=8bit,timing_set_0
  143.     // I/O windows must never include 3e0h and 3e1h 
  144.     // IO AREA=0x3f8~0x3ff(COM1) ->0x3f8~0x3ff
  145.     PD6710_Wr(SYS_IO_MAP0_START_L,0xf8);
  146.     PD6710_Wr(SYS_IO_MAP0_START_H,0x3);
  147.     PD6710_Wr(SYS_IO_MAP0_END_L,0xff);
  148.     PD6710_Wr(SYS_IO_MAP0_END_H,0x3);           
  149.     PD6710_Wr(CARD_IO_MAP0_OFFSET_L,0x0);
  150.     PD6710_Wr(CARD_IO_MAP0_OFFSET_H,0x0);
  151.     //PD6710_Wr(SYS_MEM_MAP0_START_L,0x10); 
  152.     //If this is memory window, the lowest 64KB should be reserved.
  153.     PD6710_Wr(SYS_MEM_MAP0_START_L,0x0); //MEM0=8bit data width
  154.      //To access CIS, I have known that memory window bus width should be
  155.      //  8-bit by experiment. 
  156.      //Originally, CIS uses 8-bit bus. But, Why not in 16-bit bus width?
  157.     PD6710_Wr(SYS_MEM_MAP0_START_H,0x0);
  158.     PD6710_Wr(SYS_MEM_MAP0_END_L,0x0f); //0x0 ~ 0xffff
  159.     PD6710_Wr(SYS_MEM_MAP0_END_H,0x0|(0<<6)); //timing_set_0
  160.     PD6710_Wr(CARD_MEM_MAP0_OFFSET_L,0x0);
  161.     PD6710_Wr(CARD_MEM_MAP0_OFFSET_H,0x0|(1<<6)); //nREG=active 
  162.      //MEM AREA=0x0~0xFFFF ->0x0~0xFFFFFF
  163.     
  164.     PD6710_Wr(MAPPING_ENABLE,1|(1<<6));
  165.      //memory map 0 enabled, I/O map 0 enabled
  166.     
  167.     PD6710_Wr(MISC_CTRL1,(0<<7)|(1<<4)|(1<<3)|(1<<2)|(1<<1)); 
  168.      //INPACK_ignored,speak_enable,edge_irq_intr,edge_management_intr,nVCC_3_enabled(temp)
  169.     PD6710_Wr(MISC_CTRL2,1|(1<<1)|(1<<4)); 
  170.      //25Mhz_bypass,low_power_dynamic,IRQ12=drive_LED
  171.     
  172.     PD6710_Wr(FIFO_CTRL,0x80); //Flush FIFO
  173.     //before configuring timing register, FIFO should be cleared.
  174.     //default access time is 300ns
  175.     PD6710_Wr(SETUP_TIMING0,0x2); //80ns(no spec)
  176.     PD6710_Wr(CMD_TIMING0,0x8); //320ns(by spec,25Mhz clock)
  177.     PD6710_Wr(RECOVERY_TIMING0,0x2); //80ns(no spec)
  178.     
  179.     PD6710_Wr(CHIP_INFO,0x0);
  180.     if((PD6710_Rd(CHIP_INFO)&0xc0)!=0xc0 || (PD6710_Rd(CHIP_INFO)&0xc0)!=0x00 )
  181.     {
  182.      Uart_Printf("PD6710 hardware identification error!!!n");
  183.      return 0;
  184.     }
  185.     return 1;
  186. }
  187. void PD6710_CardEnable(void) //after insertion interrupt
  188. {
  189.     if(PD6710_Rd(MISC_CTRL1)&0x1)  //MISC_CTRL1[0] 0=3.3V  1=5.0V 
  190.     {
  191.      PD6710_Modify(MISC_CTRL1,0x2,0x0); //nVCC_5_enabled
  192.      Uart_Printf("5.0V card is detected.n");
  193.     }
  194.     else
  195.     {
  196.      PD6710_Modify(MISC_CTRL1,0x2,0x2); //nVCC_3_enabled
  197.      Uart_Printf("3.3V card is detected.n");
  198.     }
  199.     PD6710_Modify(POWER_CTRL,(1<<4)|3,(1<<4)|1);
  200.      //VCC_POWER_on,VPP=Vcc(3.3V or 5.0V)
  201.     Delay(100);
  202.      //Delay 10ms should be here for power stabilization.
  203.      //If this time is not here, the program may halt 
  204. // in case that the pc card has been inserted before power_on   
  205. //But, Why?
  206.     
  207.     Delay(10); //RESET should be Hi-Z for minimum 1ms
  208.     PD6710_Modify(INT_GENERAL_CTRL,(1<<6),0); //RESET=active(H)
  209.     PD6710_Modify(POWER_CTRL,(1<<7),(1<<7)); //output2card_enable(RESET=Hi-Z -> output)
  210.     PD6710_Modify(INT_GENERAL_CTRL,(1<<6),0); //RESET=active(H)
  211.     Delay(1); //wait for minimum 10us
  212.     PD6710_Modify(INT_GENERAL_CTRL,(1<<6),(1<<6)); //RESET=inactive(L)
  213.     Delay(200); //wait for 20ms
  214.     //READY pin isn't available in mem_io_card mode.
  215.     //So, don't check READY pin on I/O card.
  216.     //while(!(PD6710_Rd(INTERFACE_STATUS)&0x20)); //INTERFACE_STATUS[5]=READY_PIN_STATUS
  217.     PD6710_Modify(INT_GENERAL_CTRL,(1<<5),(1<<5)); //mem_card -> mem_io_card
  218.     
  219.     Delay(5000); 
  220. //If this delay isn't here, some CF card will not be identified.
  221.     //In oder to remove this delay, I think, we have to check READY signal.
  222. }
  223. void PD6710_Wr(U8 index, U8 data)
  224. {
  225.     rPD6710_INDEX=index;
  226.     rPD6710_DATA=data;
  227. }
  228. U8 PD6710_Rd(U8 index)
  229. {
  230.     //nREG=L
  231.     rPD6710_INDEX=index;
  232.     return rPD6710_DATA;
  233. }
  234. void PD6710_Modify(U8 index,U8 mask,U8 data)
  235. {
  236.     //nREG=L
  237.     rPD6710_INDEX=index;
  238.     rPD6710_DATA=(rPD6710_DATA)&~mask|data;
  239. }
  240. U8 Card_RdAttrMem(U32 memaddr)
  241. {
  242.     //nREG=L
  243.     return *((volatile U8 *)(PD6710_MEM_BASE_ADDRESS+memaddr));
  244. }
  245. U8 Card_RdIO(U32 ioaddr)
  246. {
  247.     return *((volatile U8 *)(PD6710_IO_BASE_ADDRESS+ioaddr));
  248. }    
  249. void Card_WrIO(U32 ioaddr,U8 data)
  250. {
  251.     *((volatile U8 *)(PD6710_IO_BASE_ADDRESS+ioaddr))=data;
  252. }
  253. /*
  254. 1) I/O access: nREG=L(automatic)
  255. attribute memory access: nREG=L
  256. common memory access: nREG=H
  257. 2) Before accessing Common memory area,
  258. PD6710_BeginCommonMemAccess() should be called to make nREG 'H'.
  259. */
  260. void PD6710_CommonMemAccess(void)
  261. {
  262.     PD6710_Modify(CARD_MEM_MAP0_OFFSET_H,(1<<6),(0<<6)); //nREG=inactive, H
  263. }
  264. void PD6710_AttrMemAccess(void)
  265. {
  266.     PD6710_Modify(CARD_MEM_MAP0_OFFSET_H,(1<<6),(1<<6)); //nREG=active, L
  267. }
  268. void __irq IsrPD6710Management(void)    //nINT_P_CON
  269. {
  270.     U8 cardStat;
  271.     //ClearPending(BIT_EINT7);     
  272.     Uart_Printf("nPD6710 interrupt is occurred.n");
  273.     
  274.     Delay(2000); 
  275. //For card contact stablization. This delay is needed for operation stability
  276. //If this delay isn't here, some CF card may not be identified.
  277.  
  278.     cardStat=PD6710_Rd(CARD_STAT_CHANGE);
  279.     //Card detect changed?
  280.     if(cardStat&0x8)
  281.     {
  282. //check if CD1,2 is L.
  283. if((PD6710_Rd(INTERFACE_STATUS)&0xc)==0xc) 
  284. {
  285.     Uart_Printf("Card is inserted.n");
  286.     PD6710_CardEnable();
  287.     PrintCIS();
  288. }
  289. else
  290. {
  291.     Uart_Printf("Card is ejected.n");
  292.     PD6710_Init(); //can be removed.
  293. }
  294.     }
  295.     ClearPending(BIT_EINT3); 
  296. //For level interrupt, the int pending should be cleared at the end of ISR.
  297. }
  298. void __irq IsrPD6710Card(void) //nINT_P_DEV
  299. {
  300.     rEINTPEND=(1<<8); //EINTPEND[8] is cleared.
  301.     ClearPending(BIT_EINT8_23);
  302.     Uart_Printf("PC card interrupt is occurred.n");
  303. }