Basic Design of FPGA (IV): IIC Protocol

Summary

Many digital sensors and digital control chips (DDS, serial ADC, serial DAC) communicate with the controller through IIC bus. However, IIC protocol is still a slow mode of communication. The standard IIC rate is 100 kbit/s and the fast mode rate is 400 kbit/s. This paper focuses on how to use counter control and frequency division clock control to complete the reading and writing operation of IIC.

IIC Protocol

_IIC protocol is a multi-computer communication, which consists of SDA data line and SCL clock line. All IIC devices can be mounted on the bus, but each device has a unique device read address and device write address. The device's read/write address can be seen in the chip datasheet using IIC as the digital interface, and the corresponding read/write timing and speed requirements can be found. The following is a general IIC protocol sequence:


_We can summarize the timing status of five IIC protocols:
In idle state, when both SDA and SCL signal lines are in high-level bus idle state.
_2. Start signal, SCL is the beginning of a data transmission marked by the descent edge on the SDA signal line during the high level period. The start signal should be initiated by the host.
Data transmission, under the control of SCL synchronization, SDA serial transmission of each bit, so the transmission of 8 bits data requires 8 SCL clocks. The state of SDA must be stable when SCL is at high level, while the state of SDA must be allowed to change only when SCL is at low level.
_4. Answer signal. Every 8-bit byte transmitted on IIC bus releases the bus during the 9th pulse. A response signal is sent by the receiver. Whether the feedback has been received successfully or not.
_5. Stop signal, release SDA signal line to high level during SCL keeping high level, mark the end of data transmission, IIC bus also returned to idle state.

Counter controls IIC reading and writing

_In "Basic Design of FPGA (3): UART Serial Communication", we have come into contact with the method of using counter to control timing, which is also practical in controlling IIC communication. A complete write operation is as follows:

     case( i ) 
            0: // iic Start
             begin
                    isOut <= 1;                         //SDA port output

                    if( C1 == 0 ) rSCL <= 1'b1;
                    else if( C1 == 200 ) rSCL <= 1'b0;       //SCL from high to low

                    if( C1 == 0 ) rSDA <= 1'b1; 
                    else if( C1 == 100 ) rSDA <= 1'b0;        //SDA changes from high to low 

                    if( C1 == 250 -1) begin C1 <= 9'd0; i <= i + 1'b1; end
                    else C1 <= C1 + 1'b1;
             end

             1: // Write Device Addr
             begin rData <= {4'b1010, 3'b000, 1'b0}; i <= 5'd7; Go <= i + 1'b1; end         

             2: // Wirte Word Addr
             begin rData <= Addr_Sig; i <= 5'd7; Go <= i + 1'b1; end

             3: // Write Data
             begin rData <= WrData; i <= 5'd7; Go <= i + 1'b1; end

             4: //iic Stop
             begin
                isOut <= 1'b1;

                if( C1 == 0 ) rSCL <= 1'b0;
                else if( C1 == 50 ) rSCL <= 1'b1;     //SCL first changes from low to high       

                 if( C1 == 0 ) rSDA <= 1'b0;
                 else if( C1 == 150 ) rSDA <= 1'b1;     //SDA from low to high  

                 if( C1 == 250 -1 ) begin C1 <= 9'd0; i <= i + 1'b1; end
                 else C1 <= C1 + 1'b1; 
             end

             5:
             begin isDone <= 1'b1; i <= i + 1'b1; end       //Write I2C to End

             6: 
             begin isDone <= 1'b0; i <= 5'd0; end

             7,8,9,10,11,12,13,14:                         //Send Device Addr/Word Addr/Write Data
             begin
                 isOut <= 1'b1;
                  rSDA <= rData[14-i];                      //Send high-bit first

                  if( C1 == 0 ) rSCL <= 1'b0;
                 else if( C1 == 50 ) rSCL <= 1'b1;
                  else if( C1 == 150 ) rSCL <= 1'b0; 

                  if( C1 == F250K -1 ) begin C1 <= 9'd0; i <= i + 1'b1; end
                  else C1 <= C1 + 1'b1;
             end

             15:                                          // waiting for acknowledge
             begin
                 isOut <= 1'b0;                            //Change SDA port to input
                 if( C1 == 100 ) isAck <= SDA;

                  if( C1 == 0 ) rSCL <= 1'b0;
                  else if( C1 == 50 ) rSCL <= 1'b1;
                  else if( C1 == 150 ) rSCL <= 1'b0;

                  if( C1 == F250K -1 ) begin C1 <= 9'd0; i <= i + 1'b1; end
                  else C1 <= C1 + 1'b1; 
             end

             16:
             if( isAck != 0 ) i <= 5'd0;
             else i <= Go; 

            endcase

When writing data to IIC bus, three 8 bits bytes of data are needed to be written to the device write address, the device write address and the data to be written in turn. i represents different states on the bus, and controls the jump between states through the counter. When i is 0, the start signal is sent; when i is 7-14, the transmission of 8 bits data is controlled; when i is 1, 2 and 3, the device address, byte address and data are respectively called 7-14 to complete the data transmission; the rest are stop bit, reply bit, IIC communication completion position and so on.
_The method of reading data from devices is the same as this, but usually it is necessary to write device address and device address to IIC bus before reading data. The whole process of reading data is a little more troublesome than writing data, but as long as the process of jumping between States is well controlled.

Frequency Division Clock Control IIC Read and Write

_The method of controlling communication time sequence by counter is very flexible, almost all of the time sequence methods can be accomplished by this method; the disadvantage is that it is too troublesome to control the jump between states, and the more complicated the time sequence is, the more troublesome it is to use. In fact, in the "FPGA acquisition-transmission-display system (2): temperature acquisition based on FPGA and Ethernet transmission", when I am working on DS18B20. Sequence control is the method of counter control. DS18B20 requires a lot of timing, so the state jump in DS18B20 is quite complex.

In fact, when controlling IIC, a serial protocol with fixed clock rate, a low-frequency communication clock can be generated in external frequency or PLL to control the data transmission process. As follows:

    always@(posedge clock_i2c)
    begin
       if(reset_n==1'b0) begin
          tr_end<=0;
          ack1<=1;
          ack2<=1;
          ack3<=1;
          sclk<=1;
          reg_sdat<=1;
       end
       else
          case(cyc_count)
          0:begin ack1<=1;ack2<=1;tr_end<=0;sclk<=1;reg_sdat<=1;end
          1:reg_sdat<=0;                 //Begin transmission
          2:sclk<=0;
          3:reg_sdat<=i2c_data[23];          
          4:reg_sdat<=i2c_data[22];
          5:reg_sdat<=i2c_data[21];
          6:reg_sdat<=i2c_data[20];
          7:reg_sdat<=i2c_data[19];
          8:reg_sdat<=i2c_data[18];
          9:reg_sdat<=i2c_data[17];
          10:reg_sdat<=i2c_data[16];
          11:reg_sdat<=1;                //Response signal       
          12:begin reg_sdat<=i2c_data[15];ack1<=i2c_sdat;end
          13:reg_sdat<=i2c_data[14];
          14:reg_sdat<=i2c_data[13];
          15:reg_sdat<=i2c_data[12];
          16:reg_sdat<=i2c_data[11];
          17:reg_sdat<=i2c_data[10];
          18:reg_sdat<=i2c_data[9];
          19:reg_sdat<=i2c_data[8];
          20:reg_sdat<=1;                //Response signal       
          21:begin reg_sdat<=i2c_data[7];ack2<=i2c_sdat;end
          22:reg_sdat<=i2c_data[6];
          23:reg_sdat<=i2c_data[5];
          24:reg_sdat<=i2c_data[4];
          25:reg_sdat<=i2c_data[3];
          26:reg_sdat<=i2c_data[2];
          27:reg_sdat<=i2c_data[1];
          28:reg_sdat<=i2c_data[0];
          29:reg_sdat<=1;                //Response signal       
          30:begin ack3<=i2c_sdat;sclk<=0;reg_sdat<=0;end
          31:sclk<=1;
          32:begin reg_sdat<=1;tr_end<=1;end             //IICEnd of transmission
          endcase

__can see that the sensitive target of this always block is clock_i2c, the IIC clock signal after frequency division. The whole transmission process is clear at a glance. These two timing control methods are not only suitable for IIC protocol, but also for other serial protocols. This method will still be used in the next chapter of "Basic Design of FPGA (V): SPI Protocol".

Keywords: REST

Added by flhtc on Thu, 13 Jun 2019 01:47:43 +0300