Les' Software I2C Libraries "Software_I2C.inc" question?

Started by trastikata, Jun 05, 2022, 02:41 PM

Previous topic - Next topic

trastikata

Hello all,

I was going through the software I2C libraries and noticed something I don't understand, I'd appreciate it if you could clarify it for me.

In I2C_ReadByte Procedure I noticed the creation of the wTimeout variable, used for clock stretching. What puzzles me is why is it declared as Word = $03FF if later on it is used as a byte only For wTimeout = $FF To 0 Step -1 .

Proc I2C_ReadByte(), I2C_bData
    Dim wTimeout As Word = $03FF

    Result = 0                              ' Clear the result of the procedure before entering the loop
    PinInput I2C_bSDA_Pin                   ' Make the SDA pin an input (made high by the pull-up resistor)
    For I2C_bBitIndex = 7 To 0 Step -1      ' Create a loop for the 8-bits to read
        Result = Result << 1                ' Shift the result value left by 1 bit
        '
        ' Wait for any clock stretching required, with a small timeout
        '
        For wTimeout = $FF To 0 Step -1     ' Create a loop for the clock stretching
            PinInput I2C_bSCL_Pin           ' Make the SCL pin an input
            If GetPin I2C_bSCL_Pin = 1 Then Break  ' Exit the loop when the SCL pin is high
        Next                                ' Until the timeout value times out
        '
        ' Read the data
        '
        I2C_hDelay()                        ' Create a small delay
        Result.0 = GetPin I2C_bSDA_Pin      ' Read the state of the SDA pin into bit-0 of the result
        PinLow I2C_bSCL_Pin                 ' Make the SCL pin an output low
        I2C_hDelay()                        ' Create a small delay
    Next
EndProc


top204

My mistake. I originally had a Repeat-Until loop for the timeout and I have forgotten I had assigned a value to the wTimeOut variable when it was created, when I made the change to a For-Next loop. I made it a 16-bit variable so that longer stretching could be done, because the compiler is so fast, loops skip through rapidly. I, personally, think the $FF I used is a bit too low, and the original $03FF might be more suitable for a bit longer delay. It depends on the operating frequency of the device.

I was, originally, going to make the timeout for the clock stretching as a global variable that could be changed depending on the I2C slave's requirements, and a DelayUS 1 command within the loop, so the stretch times would remain the same for all frequencies, but I obviously forgot to do it. :-)

trastikata