I2C SCL high state inconsistent - i2c

I am using a MCU to read/write to EEPROM, using i2c. The SCL clock high state duration is inconsistent. See the attached screenshot. cyan is SDA, yellow is SCL
When the SCL is held in high state for too long, it could cause data error.
Why is the SCL clock inconsistent?

Related

STM32 seems to ignore GPIO mode and triggers the interrupt on both edges, instead of one

Here's my configuration:
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = 8;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);
When I put the signal on the input pin (square, 2Hz, 3.3Vp-p) I get an interrupt every 250ms, so - on every RISING and falling edge of the signal. I changed the test signal duty cycle to test if it's really what is happening and it confirmed it. I get the interrupt on both edges.
I even debugged the HAL driver to test if it does what I think it does. And yes, it seems to configure the EXTI correctly, only for the falling edge for my pin.
What may be the cause of such behavior? My device is STM32H747I-DISCO discovery board with TouchGFX software used for presentation. The software works correctly, I tested it on measuring the time between other timer interrupts.
I monitor the test signal on the oscilloscope to ensure the input signal on my pin is correct. I tried to use another pin on the same port, but I observe identical behavior. I get interrupts on both rising and falling edges of the signal, despite the pin is configured to trigger the interrupt only on the falling edge.
I also tested the case with the rising edge only. Also in this case I get the interrupt on both edges.
The problem turned out to be a hardware error, a voltage spike I overlooked. The STM32 EXTI input worked correctly all the time. There was indeed a spurious falling edge.
Simulated problem illustration, the 10n capacitor causes voltage spikes and spurious edge detection. In the real circuit, when a digital oscilloscope was used and the time base was too long to capture the spike - the signal looked like a proper square wave. After shortening the time base I noticed the spike. As it is shown on the illustration, this behavior can be easily simulated in a circuit simulator:
SIMULATION LINK
Removing the capacitor from the circuit solved the problem.
To avoid getting noise and other spurious signals on the input shielded wires can be used. The real world circuit was tested and it works properly without the capacitor.
The opto-coupler is just a simplified model of the optical sensor used in the real machine.

STM32 generate 22Mhz clock on gpio out from SystemCoreClock 110Mhz

I want to generate clock for PCA9959 LED driver with my STM32L552. The LED driver needs an external clock at 20 MHz (+/- 15%). I'm trying to generate a 22 MHz clock on port PA8 on STM32L552. I managed to generate a PWM on port PA8, but I can't reach the frequency of ~22Mhz. I arrive at a maximum of 8Mhz.
Here are the PWM parameters:
I'm not sure I filled in the pwm parameters correctly. Normally with his settings I guess I should have a 22 MHz PWM with a 20% duty cycle.
PWM (MHz) = SystemCoreClock (MHz) / Prescaler => 22MhZ = 110MHz / 5
My clock configuration:
Thanks for your help.
The easiest way to output a high speed clock like this is with the MCO peripheral, rather than a timer. Fortunately for you the MCO pin is PA8. Perhaps the person who designed your board knew this and intended you to use MCO. Read the reference manual to see how.
If you do want to use a timer to do 22MHz, then as you have correctly identified you cannot get a 50% duty-cycle on your PWM. I would recommend starting with a 40% or 60%, with an output-compare value of 2-out-of-5 or 3-out-of-5, not 1 as you have above.
There is no detail in the PCA9959 datasheet about what the required mark-space ratio of the clock is, but I guess anything other than 50% could be a problem. You would be better to divide the clock by an even number. Either just divide 110MHz by 6 and output 18.33MHz, or else slow your core down a bit and divide by 4 (reduce the N parameter of your PLL).
Whether you use MCO or PWM don't forget to set the GPIO pin mode to the fastest slew rate available. Maybe the 8MHz you are measuring is the result of aliasing a faster clock that has been through the wrong GPIO mode. You could test this using a scope with at least 100MHz bandwidth.

Problem using SPI2 on a Nucleo-H7 whereas SPI1 works fine

My setup is the following: a Nucleo board (Nucleo 144 embedding a STM32H743) is configured as SPI Master. Another identical board is configured as SPI Slave.
For the Master I setup the SPI1 (pins GND, D11, D12 and D13 - PA5,6,7- of the CN7 connector) with following config:
GPIO: very high speed, alternate function 5
SPI: prescaler DIV8, interrupts enabled, simplex communication, no Slave Select
all clocks set to maximum (CPU 400MHz, etc...)
For the Slave I setup the SPI1 too (same pins), it works fine.
Then I tried to switch to SPI2 peripheral for the Slave board and could not make it work (no change to master board).
I chose the pins D18 (PB13) for SCK, A7 (PC2) for MISO and A2 (PC3) for MOSI.
I've checked the following points:
SPI2 periph clock is enabled
GPIOB and C clocks are enabled and pins PB13, PC2 and PC3 are set up the same way as PA5,6,7 in previous setup.
for the GND I tried different GND pins on the board, I don't know if it makes a difference.
the GPIOs used for SPI2 are not used elsewhere in my code. I've got them from the datasheet of STM32H743ZI
What I see:
my slave is still receiving the SCK signal correctly: I get the correct number of RXP interrupts.
the data received by the slave is corrupted.
however the data send by the slave to the master is correct.
I think the MOSI signal is badly configured, either physically or logically. I tried the other GPIO pins whose alternate function can be SPI2_MOSI but same behaviour.
Is there a specificity to SPI2 and/or this GPIO setup ? Does the GND location on the board matter ?
I "fixed" (?) the issue by setting a pull-down to the SPI2 input GPIO on Slave side. I don't really understand why it was working without pull-down on SPI1 neither why this pull down is needed on a Slave ?

No clock signal at the SCL pin of Sparkfun nRF52832 breakout board

I am trying to use the Sparkfun nRF52832 breakout board as a master in I2C communication. I am using Arduino IDE to program the module. I defined pins 24 and 25 as SCL and SDA, respectively, and used wire.begin() in the setup to configure it as a master. I expect to see the clock signal when I connect the board to the oscilloscope, but I just see 3.3v dc signals at both scl and sda pins. Would you please tell me what's wrong?
I used pull-up resistors.

I2C slave - clock stretching

Do you guys know how to enable the clock stretching for I2C slave?
Is it enough to just put this function I2C_StretchClockCmd(I2C2, ENABLE) in the initialization of I2C?
How does clock stretching work exactly?
Seems for me yes, that's enough. Here is a background:
Clock Generation
The SCL clock is always generated by the I2C master. The specification requires minimum periods for the low and high phases of the clock signal. Hence, the actual clock rate may be lower than the nominal clock rate e.g. in I2C buses with large rise times due to high capacitances.
Clock Stretching
I2C devices can slow down communication by stretching SCL: During an SCL low phase, any I2C device on the bus may additionally hold down SCL to prevent it to rise high again, enabling them to slow down the SCL clock rate or to stop I2C communication for a while. This is also referred to as clock synchronization.
Note: The I2C specification does not specify any timeout conditions for clock stretching, i.e. any device can hold down SCL as long as it likes.
In an I2C communication the master device determines the clock speed. Unlike RS232 the I2C bus provides an explicit clock signal which relieves master and slave from synchronizing exactly to a predefined baud rate.
However, there are situations where an I2C slave is not able to co-operate with the clock speed given by the master and needs to slow down a little. This is done by a mechanism referred to as clock stretching.
An I2C slave is allowed to hold down the clock if it needs to reduce the bus speed. The master on the other hand is required to read back the clock signal after releasing it to high state and wait until the line has actually gone high.
How does the I2C clock speed affect the duration of clock stretching introduced by the I2C slave?
Clock stretching is a phenomenon where the I2C slave pulls the SCL line low on the 9th clock of every I2C data transfer (before the ACK stage). The clock is pulled low when the CPU is processing the I2C interrupt to evaluate either the address or process a data received from Master or to prepare the next data when Master is reading from the slave.
The time the clock is pull low depends on the time the CPU takes to process the interrupt and hence is dependent on the CPU speed and not the I2C clock speed.
Why we need the clock stretching? The same thing can be achieved at the time of acknowledgement of the slave on 9th bit the of clock.
The things can be achieved by holding the Data line to till the slave internal process get over.