IIC.c
上传用户:jankzhpno
上传日期:2022-08-03
资源大小:4763k
文件大小:14k
源码类别:

Windows CE

开发平台:

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