analogdevicesinc / msdk

Software Development Kit for Analog Device's MAX-series microcontrollers
Apache License 2.0
60 stars 75 forks source link

Set I2C Freq: 1MHz~2MHz can't be set #969

Open TerryWoo123 opened 3 months ago

TerryWoo123 commented 3 months ago

I found a bug in MXC_I2C_RevA_SetFrequency() of i2C_reva.c . Once I2C clock is set between 1MHz~2MHz, function will return will error E_BAD_PARAM.

  if (hz > MXC_I2C_REVA_FASTPLUS_SPEED && hz <= MXC_I2C_REVA_HIGH_SPEED) {
        // Enable high speed mode
        int hsLowClks, hsHiClks;

        // Calculate the period of SCL and set up 33% duty cycle
        ticksTotal = PeripheralClock / hz;
        hsLowClks = (ticksTotal * 2) / 3 - 1;
        hsHiClks = ticksTotal / 3 - 1;

        // For rounding errors, adjust by 1 clock tick
        if (ticksTotal % 2) {
            hsHiClks++;
        }

        // If we're too slow for high speed, bail out
        if ((hsHiClks > 0xF) || (hsLowClks > 0xF)) {
            return E_BAD_PARAM;
        }

if setting Freq is not high enough to enable HS mode, properly value should be set, instead of return with an error. my suggestion code as below:

        if ((hsHiClks <= 0xF) && (hsLowClks <= 0xF)) 
        {
            hsLowClks = (hsLowClks << MXC_F_I2C_REVA_HSCLK_LO_POS) & MXC_F_I2C_REVA_HSCLK_LO;
            hsHiClks = (hsHiClks << MXC_F_I2C_REVA_HSCLK_HI_POS) & MXC_F_I2C_REVA_HSCLK_HI;

            i2c->hsclk = (hsLowClks | hsHiClks);

            i2c->ctrl |= MXC_F_I2C_REVA_CTRL_HS_EN;

            hz = MXC_I2C_REVA_FAST_SPEED; // High speed preambles will be sent at 400kHz
        }
        else
        {
            // If we're too slow for high speed, bail out
        }