// File Name : IIC.c
// Function  : S3C2440 IIC-bus Master Tx/Rx mode Test Program
//             (Interrupt / Non Interrupt (Polling))
// Program   : Shin, On Pil (SOP)
// Date      : May 21, 2002
// Version   : 0.0
// History
//   0.0 : Programming start (March 11, 2002) -> SOP
//====================================================================

#include <string.h> 
// Serial port will be used
#include "2440addr.h"
// Register macro definition
#include "2440lib.h"
// The function to be used , Declaration of functions
#include "def.h" 
// Macro definitions of several variable types
#include "IIC.h"


//volatile Affect the result of compiler compilation , Pointed out that volatile Variables are always possible
// Changed , And volatile Operations related to variables , Don't compile optimization
static U8 _iicData[IICBUFSIZE];  
// Define an array , There are 256 Data
static volatile int _iicDataCount;
//IIC Data count
static volatile int _iicStatus;  
//IIC The state of
static volatile int _iicMode;   
//IIC The pattern of
static int _iicPt;   
//IIC The pointer to
//===================================================================
//       SMDK2440 IIC configuration
//  GPE15=IICSDA, GPE14=IICSCL
//  "Interrupt mode" for IIC block In interrupt mode IIC operation
//===================================================================
//******************[ Test_Iic ]**************************************
void Test_Iic(void)

{

    unsigned int i,j,save_E,save_PE;

    static U8 data[256]; 
// Define a 256 individual 8 An array of bit data
    Uart_Printf("\nIIC Test(Interrupt) using AT24C02\n");
    save_E   = rGPECON;  
// Protection site
    save_PE  = rGPEUP;

    rGPEUP  |= 0xc000;     
//1100 0000 0000 0000 prohibit GPE14,GPE15 Pull up resistance
    rGPECON |= 0xa00000;      
//GPE15:IICSDA , GPE14:IICSCL ( Should be 0xa0000000)???
    pISR_IIC = (unsigned)IicInt; 
// Function to address the vector
    rINTMSK &= ~(BIT_IIC); 
// Can make IIC interrupt
     
//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
      // If PCLK 50.7MHz, IICCLK=PCLK/16=3.17MHz, Tx Clock( Send clock )=IICCLK/16=0.198MHz
    rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
    rIICADD  = 0x10;                   
//2440 slave address=[7:1]=0x10 Slave address
    rIICSTAT = 0x10;                   
//IIC bus data output enable(Rx/Tx) IIC Data output enable
    rIICLC = (1<<2)|(1);      
//Filter enable, 5 clocks SDA output delay       added by junon( It didn't work )
   

    Uart_Printf("Write test data into AT24C02\n");
    for(i=0;i<256;i++)

    Wr24C080(0xa0,(U8)i,i); 
// The address of the slave device is 0xa0, From the inside of the device 0 The address starts at 256 End of address , write in 0~256
          

    for(i=0;i<256;i++)

        data[i] = 0;        
//data All elements of the array are initialized to 0
    Uart_Printf("Read test data from AT24C02\n");

   

    for(i=0;i<256;i++)

        Rd24C080(0xa0,(U8)i,&(data[i]));
// Read data from the device and store it in data Array
       
//Line changed 0 ~ f
    for(i=0;i<16;i++)

    {

        for(j=0;j<16;j++)

            Uart_Printf("%2x",data[i*16+j]); 
// Print the data just read out , namely data The array of values in
        Uart_Printf("\n");                   
// Every time 16 Byte for line
    }

    rINTMSK |= BIT_IIC;   
//IIC End of operation , prohibit IIC interrupt
    rGPEUP  = save_PE;    
// Restore the scene
    rGPECON = save_E;

}


//*************************[ Wr24C080 ]****************************
//      Function name     Slave address    Internal address Written data
//****************************************************************
void Wr24C080(U32 slvAddr,U32 addr,U8 data)

{


// Process is :S( Start signal )--- Send device address ---- Device internal address ---- Written data
    _iicMode      = WRDATA;        
// Set to write data mode

    _iicPt        = 0;          
//IIC Pointer to 0 Address
    _iicData[0]   = (U8)addr;
// to Data Array of 0 Element assignment , Internal address
    _iicData[1]   = data;   
// to Data Array of 1 Element assignment , Written data
    _iicDataCount = 2;  
// The initial value of the data count is 2
   

    rIICDS   = slvAddr;                
//0xa0     Give the slave device address to IICDS
    rIICSTAT = 0xf0;                   
//MasTx,Start Set the main sending mode , Write IIC Generate a start signal , Can make RX/TX
     
//Clearing the pending bit isn't needed because the pending bit has been cleared.
    // Start IIC Write , After sending the slave device address , The interrupt , Enter the interrupt function
    while(_iicDataCount!=-1
);// because count yes 2, The conditions don't hold and wait !! After the first interrupt is processed ,count=1, Then judge while The conditions in are not true , Continue to wait for , Wait until the internal address of the slave device is sent , There are two ways to generate an interrupt: enter the interrupt function    


// Following while Statement is to judge whether to receive ACK The signal    

    _iicMode = POLLACK;
// wait for ACK Response mode , A reply indicates that the slave device has received
    while(1)

    {

        rIICDS     = slvAddr;          
//slvAddr=0xa0
        _iicStatus = 0x100;            
//IICSTAT clear??
        rIICSTAT   = 0xf0;             
//MasTx,Start, Main transmission mode , Generate a start signal , Enable serial output , start-up IIC
        rIICCON    = 0xaf;             
//Resumes IIC operation.
          

        while(_iicStatus==0x100);      
//Wait until IICSTAT change
          

        if(!(_iicStatus&0x1))       
// Judge IICSTAT The first 0 Isn't it 0, yes 0 It means to receive ACK 了
            break;                     
//When ACK is received
    }

     rIICSTAT=0xd0; 
           // Generate a stop signal , stop it IIC
     rIICCON=0xaf;  
           // Reconfiguration IICCON.
     Delay(1);                
// Wait until IICSTAT The stop signal is valid
      
//Write is completed.

}

       


//**********************[ Rd24C080 ] ***********************************
// Read random address data read function
// The process :S--- Send device address --- Device internal address --- Send device address --- Reading data ---NOACK--- suspend
void Rd24C080(U32 slvAddr,U32 addr,U8 *data)

{

    _iicMode      = SETRDADDR; 
// Set the read address
    _iicPt        = 0;

    _iicData[0]   = (U8)addr;

    _iicDataCount = 1;  
    rIICDS   = slvAddr;                 
//slvAddr=0xa0 Write the slave address first  
    rIICSTAT = 0xf0;                   
//MasTx,Start Start signal   

     
//Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1);
// because count yes 1, The conditions don't hold and wait !! After the first interrupt is processed ,count=0, Then judge while The conditions in are not true , Continue to wait for , Wait until the internal address of the slave device is sent , There are two ways to generate an interrupt: enter the interrupt function , After executing the interrupt function , here count=-1 So I quit while loop
    _iicMode      = RDDATA; 
// Read data mode  

    _iicPt        = 0;

    _iicDataCount = 1;       
// Read a data ( Address )
   

    rIICDS        = slvAddr;            
//slvAddr=0xa0, Send the slave device address again
    rIICSTAT      = 0xb0;              
//1011,10~MasRx,1~Start,1~RxTx enable Main reception mode
    rIICCON       = 0xaf;              
//Resumes IIC operation.  

    while(_iicDataCount!=-1);    
// wait for , After sending the device address , After the interrupt function executes the second interrupt processing ,count=-1 了 , If the conditions don't hold, exit while, Continue with the following statement
    *data = _iicData[1]; 
// Take from IICDS The data received in is sent to the pointer data,
}


//-------------------------------------------------------------------------
void __irq IicInt(void)         
//IIC Interrupt initialization function  

{

    U32 iicSt,i;

   

    rSRCPND = BIT_IIC;         
//Clear pending bit So that the next interrupt can be executed
    rINTPND = BIT_IIC;         
//Clear pending bit So that the next interrupt can be executed
    iicSt   = rIICSTAT;        
// hold IICSTAT The value of the status register is assigned to iicSt
   

    if(iicSt & 0x8){}          
//When bus arbitration is failed. When bus arbitration fails , Perform null operation
    if(iicSt & 0x4){}          
//When a slave address is matched with. When received from address and IICADD When the address matches in , Perform null operation
    if(iicSt & 0x2){}          
//When a slave address is 0000000b. Received from address
0000000b
    if(iicSt & 0x1){}          
//When ACK isn't received Not received ACK The reply signal performs a null operation
    switch(_iicMode)            
// Perform different operations depending on the mode
    {

       case POLLACK:  
//ACK Pattern
           _iicStatus = iicSt;
// Give Way _iicStatus Is equal to IICSTAT Value
           break;
       case RDDATA: 
// Read data mode
           if((_iicDataCount--)==0)
//count For the initial 1, Don't execute if Code segment . After finishing count=0. A second break , If conditions are established, it will be carried out if Internal code
           {

               _iicData[_iicPt++] = rIICDS;    
// Put the IICDS The value in is read out to _iicData[1]
           

               rIICSTAT = 0x90;                
//Stop MasRx condition 1001 0000 Generate a stop signal
               rIICCON  = 0xaf;                
//Resumes IIC operation. recovery IIC operation
               Delay(1);                       
//Wait until stop condtion is in effect.
                                                //Too long time... Wait until the stop signal works
                                               
//The pending bit will not be set after issuing stop condition.

               break;                          
// Jump back to the read function    
           }   

            
// The last byte cannot be generated without reading it ACK. Read IICDS Data in
           _iicData[_iicPt++] = rIICDS;        
//The last data has to be read with no ack.
           if((_iicDataCount)==0)

               rIICCON = 0x2f;                  
// Because the conditions are established, so the implementation of rIICCON=0x2f; The host produces NOACK, Release IIC operation
           else

               rIICCON = 0xaf;                
// produce ACK, Release IIC operation
               break;
        case WRDATA: 
// Write data mode
            if((_iicDataCount--)==0)          
// Judge whether it is after subtraction 0.(2 From minus to 1, Not for 0)
            {

                rIICSTAT = 0xd0;               
//Stop MasTx condition Generate a stop signal
                rIICCON  = 0xaf;               
//Resumes IIC operation. recovery IIC The operation of
                Delay(1);                      
//Wait until stop condtion is in effect. Wait until the stop signal works
                      
//The pending
bit will not be set after issuing stop condition.
                break;   

            }

           
// After subtraction, it is not 0, Then execute the following statement
            rIICDS = _iicData[_iicPt++];       
//_iicPt++ It's to judge first , Post autoplus , So this statement is rIICDS = _iicData[0], Because in the function _iicData[0]=addr,
                                               
// That is, to the slave device addr Address sending data
            for(i=0;i<10;i++);                 
// stay IICSCL There is a build-up time before the rising edge
             

            rIICCON = 0xaf;                    
// recovery IIC The operation of
            break;

           


//SETRDADDR Interrupt in mode :
/* After the first interrupt processing :count=0,_iicData[0]=IICDS The value in ( Sending again from device address )*/
/* After the second interrupt processing :count=-1,_iicPt=1( receive IICDS The interrupt generated after the value of */
        case SETRDADDR:                    
// Set the read address             


//          Uart_Printf("[ S%d ]",_iicDataCount); 
            if((_iicDataCount--)==0)
// Judge whether it is after subtraction 0
                break;                         
//IIC operation is stopped because of IICCON[4]   
            rIICDS = _iicData[_iicPt++];

            for(i=0;i<10;i++);                 
//For setup time until rising edge of IICSCL
            rIICCON = 0xaf;                    
//Resumes IIC operation.
            break;

 
//SETRDADDR Interrupt in mode :
 /* After the first interruption :count=0,iicPt=1( Send from device address )*/
 /* After the second interruption :count=-1,iicPt=1 because if The internal code is to jump back to the read function , It didn't go on if Outside code , therefore iicPt=1( Send from the internal address of the device )
        default:

            break;     

    }

}
 
 
 
//       SMDK2440 IIC configuration
//  GPE15=IICSDA, GPE14=IICSCL
//  "Non-Interrupt" mode for IIC block
//===================================================================

//*********************[ Test_Iic2 ]*********************************
void Test_Iic2(void)

{

    unsigned int i,j,save_E,save_PE;

    static U8 data[256];

   

    Uart_Printf("[ IIC Test(Polling) using KS24C080 ]\n");
    save_E   = rGPECON;

    save_PE  = rGPEUP;
    rGPEUP  |= 0xc000;                 
//Pull-up disable
    rGPECON |= 0xa00000;               
//GPE15:IICSDA , GPE14:IICSCL( Should be changed to 0xa0000000)  
     
//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
    rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);
    rIICADD  = 0x10;                   
//2440 slave address = [7:1]
    rIICSTAT = 0x10;                   
//IIC bus data output enable(Rx/Tx)
 //rIICLC = (1<<2)|(3);  // Filter enable, 15 clocks SDA output delay     added by junon

   

    Uart_Printf("Write test data into KS24C080\n");
    for(i=0;i<256;i++)

        _Wr24C080(0xa0,(U8)i,255-i);

    for(i=0;i<256;i++)

        data[i] = 0;
    Uart_Printf("Read test data from KS24C080\n");

    for(i=0;i<256;i++)

        _Rd24C080(0xa0,(U8)i,&(data[i]));
    for(i=0;i<16;i++)

    {

        for(j=0;j<16;j++)

            Uart_Printf("%2x ",data[i*16+j]);

        Uart_Printf("\n");

    }

   

    rGPEUP  = save_PE;

    rGPECON = save_E;

}
//**************[ _Wr24C080 ]*****************************************
void _Wr24C080(U32 slvAddr,U32 addr,U8 data)

{

    _iicMode      = WRDATA;  
// Set to write data mode
    _iicPt        = 0;       
//IIC Pointer to 0 Address
    _iicData[0]   = (U8)addr;
// to Data Array of 0 Element assignment , Internal address
    _iicData[1]   = data;    
// to Data Array of 1 Element assignment , Written data
    _iicDataCount = 2;       
// The initial value of the data count is 2
   

    rIICDS        = slvAddr;
//0xa0     Give the slave device address to IICDS
     
//Master Tx mode, Start(Write), IIC-bus data output enable Set the main sending mode , Write IIC Generate a start signal , Can make RX/TX
     
//Bus arbitration sucessful, Address as slave status flag Cleared,
     
//Address zero status flag cleared, Last received bit is 0
    rIICSTAT      = 0xf0;     

     
//Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1)

       Run_IicPoll();
    _iicMode = POLLACK;
    while(1)

    {

        rIICDS     = slvAddr;

        _iicStatus = 0x100;            
//To check if _iicStatus is changed
        rIICSTAT   = 0xf0;             
//Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
        rIICCON    = 0xaf;             
//Resumes IIC operation.
        while(_iicStatus==0x100) 

            Run_IicPoll();

             

        if(!(_iicStatus & 0x1))

            break;                     
//When ACK is received
    }

    rIICSTAT = 0xd0;                   
//Master Tx condition, Stop(Write), Output Enable
    rIICCON  = 0xaf;                   
//Resumes IIC operation.
    Delay(1);                          
//Wait until stop condtion is in effect.

      //Write is completed.

}

       


//************************[ _Rd24C080 ]********************************
void _Rd24C080(U32 slvAddr,U32 addr,U8 *data)

{

    _iicMode      = SETRDADDR;

    _iicPt        = 0;

    _iicData[0]   = (U8)addr;

    _iicDataCount = 1;
    rIICDS   = slvAddr;

    rIICSTAT = 0xf0;                   
//MasTx,Start 
     
//Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1)

        Run_IicPoll();
    _iicMode      = RDDATA;

    _iicPt        = 0;

    _iicDataCount = 1;

   

    rIICDS   = slvAddr;

    rIICSTAT = 0xb0;                   
//Master Rx,Start
    rIICCON  = 0xaf;                   
//Resumes IIC operation.  

    while(_iicDataCount!=-1)

        Run_IicPoll();
    *data = _iicData[1];

}
//**********************[ Run_IicPoll ]*********************************
// This function is used to determine whether a byte has been sent or received , Because it has been explained that , Just pass it on
It's over , There will be interruptions , send IIC Control register bit4 Set up 1. This function determines the bit , If
by 1, That means the transmission is complete , You can do the following byte transfer , If it is 0, Then continue to wait , Until it changes
by 1. If it becomes 1, Just call IicPoll function .
 //********************************************************************//

void Run_IicPoll(void)

{

    if(rIICCON & 0x10)                 
       IicPoll();

}      

   


//**********************[IicPoll ]**************************************
// The body of this function is a switch  sentence , It's used to determine what's going on , And carry on
Corresponding read and write operations . This function mainly reflects I2C The temporal
//***********************************************************************//
void IicPoll(void)

{

    U32 iicSt,i;

   

    iicSt = rIICSTAT;

    if(iicSt & 0x8){}                  
//When bus arbitration is failed.
    if(iicSt & 0x4){}                  
//When a slave address is matched with IICADD
    if(iicSt & 0x2){}                  
//When a slave address is 0000000b
    if(iicSt & 0x1){}                  
//When ACK isn't received
    switch(_iicMode)

    {

        case POLLACK:

            _iicStatus = iicSt;

            break;
        case RDDATA:

            if((_iicDataCount--)==0)

            {

                _iicData[_iicPt++] = rIICDS;

           

                rIICSTAT = 0x90;               
//Stop MasRx condition
                rIICCON  = 0xaf;               
//Resumes IIC operation.

                Delay(1);                      
//Wait until stop condtion is in effect.
                                               
//Too long time...
                                               
//The pending bit will not be set after issuing stop condition.
                break;   

            }     

            _iicData[_iicPt++] = rIICDS;

                       
//The last data has to be read with no ack.
            if((_iicDataCount)==0)

                rIICCON = 0x2f;                
//Resumes IIC operation with NOACK. 

            else

                rIICCON = 0xaf;                
//Resumes IIC operation with ACK
            break;
        case WRDATA:

            if((_iicDataCount--)==0)

            {

                rIICSTAT = 0xd0;               
//stop MasTx condition
                rIICCON  = 0xaf;               
//resumes IIC operation

                Delay(1);                      
//wait until stop condtion is in effect.
                      
//The pending bit will not be set after issuing stop condition.
                break;   

            }

            rIICDS = _iicData[_iicPt++];       
//_iicData[0] has dummy.
            for(i=0;i<10;i++);                 
//for setup time until rising edge of IICSCL
            rIICCON = 0xaf;                    
//resumes IIC operation.
            break;
        case SETRDADDR:


//          Uart_Printf("[S%d]",_iicDataCount);
            if((_iicDataCount--)==0)

            {

                break;                 
//IIC operation is stopped because of IICCON[4]   

            }

            rIICDS = _iicData[_iicPt++];

            for(i=0;i<10;i++);         
//for setup time until rising edge of IICSCL
            rIICCON = 0xaf;            
//resumes IIC operation.
            break;
        default:

            break;     

    }

}

mini2440 Bare metal I2C More articles about

  1. mini2440 Bare metal music player ( It's a long time ago )

    [ It's been written for a long time . Somewhat chaotic , There's no time to organize . As a record .] The picture paste is invalid . No picture uploaded , If you want, download the document directly . Project purpose : adopt IIS, Touch screen ,LCD The module realizes the function of music player (button On a . The following piece . Play . ...

  2. mini2440 Bare metal test ——DMA Direct access Realization Uart( A serial port ) signal communication

    This can only be used as my preliminary understanding MDA Open the door Realization function : Pass string data through DMA0 The channel passes to UTXH0, And then at the terminal Show . After data transmission .DMA0 The interrupt ,beep The sound , LED bright . DMA Basic knowledge Department of Computer Science ...

  3. mini2440 Bare metal test —RTC The alarm clock is broken , The beat breaks

    Copyright notice : Blog address :http://blog.csdn.net/muyang_ren. The source code can be found in my github Look for it on the Internet https://blog.csdn.net/muyang_ren/articl ...

  4. mini2440 Bare metal test —— Watchdog interrupt and reset operation

    How a watchdog works : Suppose the time of a complete execution cycle of the system program is Tp, The watchdog's timing period is Ti,Ti>Tp, When the program is running normally , The timer will not overflow , If the system can't work in due to interference and other reasons Tp Change the value of the timer at any time , Timer ...

  5. mini2440 Bare metal program , Download to nand Inside , Copied to the sdram Not running in

    According to Wei Dongshan's video sdram The bare metal code of , Wrote a , adopt minitools Download to 0x30000000, And then burn it to nand in , It doesn't work properly . After trying various methods , There is only one solution , Just don't use ...

  6. mini2440 The bare metal program is downloaded to sdram Can not run .

    In today's Write a simple led The assembler for , Download to mini2440 Of nand flash It's going to work , But download to sdram It doesn't work inside . It turns out that there are several points to pay attention to , To be in sdram Run in ...

  7. mini2440 Bare metal MMU( Two )(mmu.c) ( turn )

    classification :  The embedded http://blog.chinaunix.net/uid-26435987-id-3082166.html( turn ) /********************************* ...

  8. 8、 ... and 、mini2440 Bare metal program UART(2)UART0 And PC Serial port communication 【 turn 】

    from :http://blog.csdn.net/shengnan_wu/article/details/8309417 Copyright notice : This article is an original blog article , No reprint without the permission of the blogger . 1. Related schematics 2. Related to send ...

  9. 8、 ... and 、mini2440 Bare metal program UART(1) Brief introduction 【 turn 】

    from :http://blog.csdn.net/shengnan_wu/article/details/8298869 One . summary          S3C2440 Universal asynchronous receive and send (UART) It provides three ...

Random recommendation

  1. Hide left quick navigation except DMS Other areas outside the navigation tree

    <style type="text/css"> /* Hide left quick navigation except DMS Other areas outside the navigation tree */ .ms-quicklaunchouter { display: n ...

  2. Use Script Element sending JSONP request

    // According to the specified URL Send a JSONP request // And then pass the corresponding data to the callback function // stay URL Add a name to it jsonp The query parameters of , The name of the callback function used to specify the request function getJSON ...

  3. BZOJ_1858_[Scoi2010] Sequence of operations _ Line segment tree

    BZOJ_1858_[Scoi2010] Sequence of operations _ Line segment tree Description lxhgww Recently received a 01 Sequence , The sequence contains n Number , These numbers are either 0, Or 1, Now there are five transformation operations and queries for this sequence ...

  4. 【Java】 The finger of the sword offer(32) Print binary tree from top to bottom

    This article references from < The finger of the sword offer> A Book , The code uses Java Language . more :< The finger of the sword Offer>Java Realize the ensemble    subject ( One ) Print each node of the binary tree from top to bottom , Nodes on the same layer follow the order from left to right ...

  5. java In generics E,K,V,T,U,S

    notes : java Generic types use uppercase , And it's shorter , This is common stay java In the library , Using variables E Represents the element type of the collection K and V The key representing the data of the database table respectively key And the value value The type of T( It can also be used if necessary ...

  6. Activator Cannot create an instance that contains a paradigm parameter

    Activator Contains specific methods , To create object types locally or remotely , Or get a reference to an existing remote object . This class cannot be inherited . Specific introduction :http://msdn.microsoft.com/zh-cn/library ...

  7. jspSmartUpload Upload and download usage examples

    --------------------------------------------------------------------- ServletUpload.java Upload package ...

  8. Codeforces Beta Round #3 C. Tic-tac-toe Simulation question

    C. Tic-tac-toe Topic linking : http://www.codeforces.com/contest/3/problem/C Description Certainly, everyone i ...

  9. Swift Of String And OC Of NSString The difference between

    Swift Of String A type is a value type . If you create a new string value , So when it's constant . Variable assignment operation or in function / Method , The value will be copied . In different circumstances , Will create a new copy of the existing string value , And the new copy is ...

  10. be based on HTML5 Move web application

    One . be based on HTML5 Move web application 1.canvas mapping 2. multimedia 3. The local store 4. Offline applications 5. Use geographic location 6. Move web frame   Two . Specify 1.HTML5 The biggest change in standards is support Web mapping ...