TWI. What is the purpose of the adi_twi_SetPrescale()?

I'm using ADSP-SC573 EZ-board.

I try to understand the adi_twi_SetPrescale() function. What is the purpose of this?

The comments says:

Set the TWI prescale value.

The prescale value is used to establish a relationship between the system clock (SCLK) and the TWI controller's internally timed events. The internal time reference is derived from SCLK using a prescaled value. PRESCALE = fSCLK/10MHz

So can I use it like this?

    uint32_t fsysclk;
    uint32_t fsclk0; // Used for SPI0 and SPI1 (See SPI Port—Master Timing in data sheet)
    uint32_t fsclk1; // Used for SPI2

    if (adi_pwr_GetSystemFreq(0, &fsysclk, &fsclk0, &fsclk1)) break;
    
    uint16_t prescale = fsysclk / 10000000;
    if (adi_twi_SetPrescale(hDevice, prescale)) break;

  • Or should I use fsclk0 or fsclk1? What clock does the fSCLK refer to?

  • I believe that comment is wrong.  TWI is tied to SCLK0_0, so you want to use fsclk0.

  • I have investigated the TWI driver.

    For example (I set my clocks):


    // Set the core clock (CCLK) and system clock (SCLK) frequencies
    adi_pwr_SetFreq(0u, 450000000, 225000000); 

    I setup TWI with pre-scaler 11 and rate 100kHz.

    adi_twi_SetPrescale(hDevice, 11);
    
    adi_twi_SetBitRate(hDevice, 100);
    
    adi_twi_SetDutyCycle(hDevice, 50);

    I set a breakpoint in StartDevice() in adi_twi_v1.c() to investigate how many clock cycles it will set for hi and lo. It setts hi = 50 and lo = 50 (period = 100 cycles).

    The I2C internal reference clock is 112.5MHz / 11 (prescaler) = 10.227MHz

    100 cycles at 10.227MHz should give SCL rate = 102.273kHz

    When I measure with my logic analyser I instead get  96.53kHz. Could someone explain this?

    I understand the TWI registers like this (don't know if I'm correct):

    Then why do I get the TWI_SCL of 96.53kHz instead of 102.273kHz

    I also tested with:

      uint32_t result = adi_pwr_Init(0, 25000000);
      result = adi_pwr_SetPowerMode (0u, ADI_PWR_MODE_FULL_ON); // Select full power
      result = adi_pwr_SetFreq(0u, 400000000, 200000000); // Set the core clock (CCLK) and system clock (SCLK) frequencies.

    And

    adi_twi_SetPrescale(hDevice, 10);
    
    adi_twi_SetBitRate(hDevice, 100);
    
    adi_twi_SetDutyCycle(hDevice, 50);

    I got TWI_SCL = 94.34kHz. I didn't get 100kHz as expected.

    If I do a reverse calculation from TWI_SCL = 94.34kHz back to fsclk0 it would look like this:

    The fsclk0 should be 103.774MHz for this to be correct. I don't understand.

    I have verified all clock sources. They are correct:

  • I think I have solved the frequency mismatch. I found this in the reference manual:

    So I think ADI should make a change in the TWI drivers and not use the function adi_twi_SetBitRate() as this name implies that you actually can select a precise rate. You should have a function that allows one to select the  TWI_CLKDIV.CLKHI and TWI_CLKDIV.CLKLO directly.

  • 0
    •  Analog Employees 
    on Aug 25, 2021 9:47 AM in reply to masip

    Hello, 

    Thank you for your suggestion. We will pass this to our internal team.

    Best Regards,

    Santhakumari.K