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

uCOS

开发平台:

C/C++

  1. //====================================================================
  2. // File Name : IIC.c
  3. // Function  : S3C2440 IIC-bus Master Tx/Rx mode Test Program
  4. //             (Interrupt / Non Interrupt (Polling))
  5. // Program   : Shin, On Pil (SOP)
  6. // Date      : May 21, 2002
  7. // Version   : 0.0
  8. // History
  9. //   0.0 : Programming start (March 11, 2002) -> SOP
  10. //====================================================================
  11. #include <string.h>
  12. #include "2440addr.h"
  13. #include "2440lib.h"
  14. #include "def.h"
  15. #include "IIC.h"
  16. static U8 _iicData[IICBUFSIZE];
  17. static volatile int _iicDataCount;
  18. static volatile int _iicStatus;
  19. static volatile int _iicMode;
  20. static int _iicPt;
  21. //===================================================================
  22. //       SMDK2440 IIC configuration
  23. //  GPE15=IICSDA, GPE14=IICSCL
  24. //  "Interrupt mode" for IIC block
  25. //=================================================================== 
  26. void * func_iic_test[][2]=
  27. {
  28. //     "0123456789012345" max 15磊 肺茄沥窍咯 comment窍技夸.
  29. //IIC 
  30. (void *)Test_Iic,  "IIC(KS24C080)INT",
  31. (void *)Test_Iic2, "IIC(KS24C080)POL",
  32. 0,0
  33. };
  34. void Iic_Test(void)
  35. {
  36. int i;
  37. Uart_Printf("n======  IIC Test program start ======n");
  38. while(1)
  39. {
  40. i=0;
  41. Uart_Printf("nn");
  42. while(1)
  43. {   //display menu
  44. Uart_Printf("%2d:%s",i,func_iic_test[i][1]);
  45. i++;
  46. if((int)(func_iic_test[i][0])==0)
  47. {
  48. Uart_Printf("n");
  49. break;
  50. }
  51. if((i%4)==0)
  52. Uart_Printf("n");
  53. }
  54. Uart_Printf("nPress Enter key to exit : ");
  55. i = Uart_GetIntNum();
  56. if(i==-1) break; // return.
  57. if(i>=0 && (i<((sizeof(func_iic_test)-1)/8)) ) // select and execute...
  58. ( (void (*)(void)) (func_iic_test[i][0]) )();
  59. }
  60. Uart_Printf("n====== IIC Test program end ======n");
  61. }
  62. //******************[ Test_Iic ]**************************************
  63. void Test_Iic(void)
  64. {
  65.     unsigned int i,j,save_E,save_PE;
  66.     static U8 data[256];
  67.     Uart_Printf("[ IIC Test(Interrupt) using KS24C080 ]n");
  68.     save_E   = rGPECON;
  69.     save_PE  = rGPEUP;
  70.     rGPEUP  |= 0xc000;                  //Pull-up disable
  71.     rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL 
  72.     pISR_IIC = (unsigned)IicInt;
  73.     rINTMSK &= ~(BIT_IIC);
  74.       //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
  75.       // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
  76.     rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
  77.     rIICADD  = 0x10;                    //2440 slave address = [7:1]
  78.     rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
  79. rIICLC = (1<<2)|(1);   // Filter enable, 15 clocks SDA output delay       added by junon
  80.     
  81.     Uart_Printf("Write test data into KS24C080n");
  82.     for(i=0;i<256;i++)
  83.         Wr24C080(0xa0,(U8)i,i);
  84.            
  85.     for(i=0;i<256;i++)
  86.         data[i] = 0;
  87.     Uart_Printf("Read test data from KS24C080n");
  88.     
  89.     for(i=0;i<256;i++)
  90.         Rd24C080(0xa0,(U8)i,&(data[i])); 
  91.         //Line changed 0 ~ f
  92.     for(i=0;i<16;i++)
  93.     {
  94.         for(j=0;j<16;j++)
  95.             Uart_Printf("%2x ",data[i*16+j]);
  96.         Uart_Printf("n");
  97.     }
  98.     rINTMSK |= BIT_IIC;    
  99.     rGPEUP  = save_PE;
  100.     rGPECON = save_E;
  101. }
  102. //*************************[ Wr24C080 ]****************************
  103. void Wr24C080(U32 slvAddr,U32 addr,U8 data)
  104. {
  105.     _iicMode      = WRDATA;
  106.     _iicPt        = 0;
  107.     _iicData[0]   = (U8)addr;
  108.     _iicData[1]   = data;
  109.     _iicDataCount = 2;
  110.     
  111.     rIICDS   = slvAddr;                 //0xa0
  112.     rIICSTAT = 0xf0;                    //MasTx,Start
  113.       //Clearing the pending bit isn't needed because the pending bit has been cleared.
  114.     
  115.     while(_iicDataCount!=-1);
  116.     _iicMode = POLLACK;
  117.     while(1)
  118.     {
  119.         rIICDS     = slvAddr;
  120.         _iicStatus = 0x100;
  121.         rIICSTAT   = 0xf0;              //MasTx,Start
  122.         rIICCON    = 0xaf;              //Resumes IIC operation. 
  123.            
  124.         while(_iicStatus==0x100);
  125.            
  126.         if(!(_iicStatus&0x1))
  127.             break;                      //When ACK is received
  128.     }
  129.     rIICSTAT = 0xd0;                    //Stop MasTx condition 
  130.     rIICCON  = 0xaf;                    //Resumes IIC operation. 
  131.     Delay(1);                           //Wait until stop condtion is in effect.
  132.        //Write is completed.
  133. }
  134.         
  135. //**********************[ Rd24C080 ] ***********************************
  136. void Rd24C080(U32 slvAddr,U32 addr,U8 *data)
  137. {
  138.     _iicMode      = SETRDADDR;
  139.     _iicPt        = 0;
  140.     _iicData[0]   = (U8)addr;
  141.     _iicDataCount = 1;
  142.     rIICDS   = slvAddr;
  143.     rIICSTAT = 0xf0;                    //MasTx,Start  
  144.       //Clearing the pending bit isn't needed because the pending bit has been cleared.
  145.     while(_iicDataCount!=-1);
  146.     _iicMode      = RDDATA;
  147.     _iicPt        = 0;
  148.     _iicDataCount = 1;
  149.     
  150.     rIICDS        = slvAddr;
  151.     rIICSTAT      = 0xb0;               //MasRx,Start
  152.     rIICCON       = 0xaf;               //Resumes IIC operation.   
  153.     while(_iicDataCount!=-1);
  154.     *data = _iicData[1];
  155. }
  156. //-------------------------------------------------------------------------
  157. void __irq IicInt(void)
  158. {
  159.     U32 iicSt,i;
  160.     
  161.     rSRCPND = BIT_IIC;          //Clear pending bit
  162.     rINTPND = BIT_IIC;
  163.     iicSt   = rIICSTAT; 
  164.     
  165.     if(iicSt & 0x8){}           //When bus arbitration is failed.
  166.     if(iicSt & 0x4){}           //When a slave address is matched with IICADD
  167.     if(iicSt & 0x2){}           //When a slave address is 0000000b
  168.     if(iicSt & 0x1){}           //When ACK isn't received
  169.     switch(_iicMode)
  170.     {
  171.        case POLLACK:
  172.            _iicStatus = iicSt;
  173.            break;
  174.        case RDDATA:
  175.            if((_iicDataCount--)==0)
  176.            {
  177.                _iicData[_iicPt++] = rIICDS;
  178.             
  179.                rIICSTAT = 0x90;                 //Stop MasRx condition 
  180.                rIICCON  = 0xaf;                 //Resumes IIC operation.
  181.                Delay(1);                        //Wait until stop condtion is in effect.
  182.                                                 //Too long time... 
  183.                                                 //The pending bit will not be set after issuing stop condition.
  184.                break;    
  185.            }      
  186.            _iicData[_iicPt++] = rIICDS;         //The last data has to be read with no ack.
  187.            if((_iicDataCount)==0)
  188.                rIICCON = 0x2f;                  //Resumes IIC operation with NOACK.  
  189.            else 
  190.                rIICCON = 0xaf;                  //Resumes IIC operation with ACK
  191.                break;
  192.         case WRDATA:
  193.             if((_iicDataCount--)==0)
  194.             {
  195.                 rIICSTAT = 0xd0;                //Stop MasTx condition 
  196.                 rIICCON  = 0xaf;                //Resumes IIC operation.
  197.                 Delay(1);                       //Wait until stop condtion is in effect.
  198.                        //The pending bit will not be set after issuing stop condition.
  199.                 break;    
  200.             }
  201.             rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.
  202.             for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
  203.               
  204.             rIICCON = 0xaf;                     //resumes IIC operation.
  205.             break;
  206.         case SETRDADDR:
  207. //          Uart_Printf("[ S%d ]",_iicDataCount);
  208.             if((_iicDataCount--)==0)
  209.                 break;                          //IIC operation is stopped because of IICCON[4]    
  210.             rIICDS = _iicData[_iicPt++];
  211.             for(i=0;i<10;i++);                  //For setup time until rising edge of IICSCL
  212.             rIICCON = 0xaf;                     //Resumes IIC operation.
  213.             break;
  214.         default:
  215.             break;      
  216.     }
  217. }
  218. //===================================================================
  219. //       SMDK2440 IIC configuration
  220. //  GPE15=IICSDA, GPE14=IICSCL
  221. //  "Non-Interrupt" mode for IIC block
  222. //=================================================================== 
  223. //*********************[ Test_Iic2 ]*********************************
  224. void Test_Iic2(void)
  225. {
  226.     unsigned int i,j,save_E,save_PE;
  227.     static U8 data[256];
  228.     
  229.     Uart_Printf("[ IIC Test(Polling) using KS24C080 ]n");
  230.     save_E   = rGPECON;
  231.     save_PE  = rGPEUP;
  232.     rGPEUP  |= 0xc000;                  //Pull-up disable
  233.     rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL    
  234.       //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
  235.     rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);
  236.     rIICADD  = 0x10;                    //2440 slave address = [7:1]
  237.     rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
  238. //rIICLC = (1<<2)|(3);  // Filter enable, 15 clocks SDA output delay     added by junon
  239.     
  240.     Uart_Printf("Write test data into KS24C080n");
  241.     for(i=0;i<256;i++)
  242.         _Wr24C080(0xa0,(U8)i,255-i);
  243.     for(i=0;i<256;i++)
  244.         data[i] = 0;
  245.     Uart_Printf("Read test data from KS24C080n");
  246.     for(i=0;i<256;i++)
  247.         _Rd24C080(0xa0,(U8)i,&(data[i])); 
  248.     for(i=0;i<16;i++)
  249.     {
  250.         for(j=0;j<16;j++)
  251.             Uart_Printf("%2x ",data[i*16+j]);
  252.         Uart_Printf("n");
  253.     }
  254.     
  255.     rGPEUP  = save_PE;
  256.     rGPECON = save_E;
  257. }
  258. //**************[ _Wr24C080 ]*****************************************
  259. void _Wr24C080(U32 slvAddr,U32 addr,U8 data)
  260. {
  261.     _iicMode      = WRDATA;
  262.     _iicPt        = 0;
  263.     _iicData[0]   = (U8)addr;
  264.     _iicData[1]   = data;
  265.     _iicDataCount = 2;
  266.     
  267.     rIICDS        = slvAddr;            //0xa0
  268.       //Master Tx mode, Start(Write), IIC-bus data output enable
  269.       //Bus arbitration sucessful, Address as slave status flag Cleared,
  270.       //Address zero status flag cleared, Last received bit is 0
  271.     rIICSTAT      = 0xf0;      
  272.       //Clearing the pending bit isn't needed because the pending bit has been cleared.
  273.     while(_iicDataCount!=-1)
  274.        Run_IicPoll();
  275.     _iicMode = POLLACK;
  276.     while(1)
  277.     {
  278.         rIICDS     = slvAddr;
  279.         _iicStatus = 0x100;             //To check if _iicStatus is changed 
  280.         rIICSTAT   = 0xf0;              //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
  281.         rIICCON    = 0xaf;              //Resumes IIC operation. 
  282.         while(_iicStatus==0x100)  
  283.             Run_IicPoll();
  284.               
  285.         if(!(_iicStatus & 0x1))
  286.             break;                      //When ACK is received
  287.     }
  288.     rIICSTAT = 0xd0;                    //Master Tx condition, Stop(Write), Output Enable
  289.     rIICCON  = 0xaf;                    //Resumes IIC operation. 
  290.     Delay(1);                           //Wait until stop condtion is in effect.
  291.       //Write is completed.
  292. }
  293.         
  294. //************************[ _Rd24C080 ]********************************
  295. void _Rd24C080(U32 slvAddr,U32 addr,U8 *data)
  296. {
  297.     _iicMode      = SETRDADDR;
  298.     _iicPt        = 0;
  299.     _iicData[0]   = (U8)addr;
  300.     _iicDataCount = 1;
  301.     rIICDS   = slvAddr;
  302.     rIICSTAT = 0xf0;                    //MasTx,Start  
  303.       //Clearing the pending bit isn't needed because the pending bit has been cleared.
  304.     while(_iicDataCount!=-1)
  305.         Run_IicPoll();
  306.     _iicMode      = RDDATA;
  307.     _iicPt        = 0;
  308.     _iicDataCount = 1;
  309.     
  310.     rIICDS   = slvAddr;
  311.     rIICSTAT = 0xb0;                    //Master Rx,Start
  312.     rIICCON  = 0xaf;                    //Resumes IIC operation.   
  313.     while(_iicDataCount!=-1)
  314.         Run_IicPoll();
  315.     *data = _iicData[1];
  316. }
  317. //**********************[ Run_IicPoll ]*********************************
  318. void Run_IicPoll(void)
  319. {
  320.     if(rIICCON & 0x10)                  //Tx/Rx Interrupt Enable
  321.        IicPoll();
  322. }       
  323.     
  324. //**********************[IicPoll ]**************************************
  325. void IicPoll(void)
  326. {
  327.     U32 iicSt,i;
  328.     
  329.     iicSt = rIICSTAT; 
  330.     if(iicSt & 0x8){}                   //When bus arbitration is failed.
  331.     if(iicSt & 0x4){}                   //When a slave address is matched with IICADD
  332.     if(iicSt & 0x2){}                   //When a slave address is 0000000b
  333.     if(iicSt & 0x1){}                   //When ACK isn't received
  334.     switch(_iicMode)
  335.     {
  336.         case POLLACK:
  337.             _iicStatus = iicSt;
  338.             break;
  339.         case RDDATA:
  340.             if((_iicDataCount--)==0)
  341.             {
  342.                 _iicData[_iicPt++] = rIICDS;
  343.             
  344.                 rIICSTAT = 0x90;                //Stop MasRx condition 
  345.                 rIICCON  = 0xaf;                //Resumes IIC operation.
  346.                 Delay(1);                       //Wait until stop condtion is in effect.
  347.                                                 //Too long time... 
  348.                                                 //The pending bit will not be set after issuing stop condition.
  349.                 break;    
  350.             }      
  351.             _iicData[_iicPt++] = rIICDS;
  352.                         //The last data has to be read with no ack.
  353.             if((_iicDataCount)==0)
  354.                 rIICCON = 0x2f;                 //Resumes IIC operation with NOACK.  
  355.             else 
  356.                 rIICCON = 0xaf;                 //Resumes IIC operation with ACK
  357.             break;
  358.         case WRDATA:
  359.             if((_iicDataCount--)==0)
  360.             {
  361.                 rIICSTAT = 0xd0;                //stop MasTx condition 
  362.                 rIICCON  = 0xaf;                //resumes IIC operation.
  363.                 Delay(1);                       //wait until stop condtion is in effect.
  364.                        //The pending bit will not be set after issuing stop condition.
  365.                 break;    
  366.             }
  367.             rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.
  368.             for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
  369.             rIICCON = 0xaf;                     //resumes IIC operation.
  370.             break;
  371.         case SETRDADDR:
  372. //          Uart_Printf("[S%d]",_iicDataCount);
  373.             if((_iicDataCount--)==0)
  374.             {
  375.                 break;                  //IIC operation is stopped because of IICCON[4]    
  376.             }
  377.             rIICDS = _iicData[_iicPt++];
  378.             for(i=0;i<10;i++);          //for setup time until rising edge of IICSCL
  379.             rIICCON = 0xaf;             //resumes IIC operation.
  380.             break;
  381.         default:
  382.             break;      
  383.     }
  384. }