Replies: 34 comments 15 replies
-
Do you have pullup resistors on each I2c lines? |
Beta Was this translation helpful? Give feedback.
-
Yes, and - I can see the I2C packets using an oscilloscope on the pins. (decoded on the scope) |
Beta Was this translation helpful? Give feedback.
-
Could you share the master example? |
Beta Was this translation helpful? Give feedback.
-
@fpistm unable, the master is Ardupilot (which is open source)- if you have some hardware that can run Ardupilot, and configure BATT_MONITOR 5 - then you have that I2C traffic too. The traffic is really nothing special - it is all about spotting a normal 7-bit address that is being interrogated by a master. I bet this is reproducible with a ny simple Arduino program that tried to read data from a I2C device (just set the address to the same on both ends.) |
Beta Was this translation helpful? Give feedback.
-
Please see attached communication capture with device 0xB - the capture should clarify any questions you might have about protocol/timing etc. it is captured using Saleae logic analyzer, which is perfectly multi-platform with nice software: https://www.saleae.com/pages/downloads |
Beta Was this translation helpful? Give feedback.
-
Thanks for inputs. I will try to test on my side but don't know when as I'm fully busy on other tasks. |
Beta Was this translation helpful? Give feedback.
-
Thank you, I am really stuck on this one, I "modernized" previous design (Atmega32u4) by dropping in STM32F103, and now - with plenty of new PCB's manufactured, I am stuck with this issue. |
Beta Was this translation helpful? Give feedback.
-
Additional information; the exactly same happens when SCL=PB10 and SDA=PB11 |
Beta Was this translation helpful? Give feedback.
-
@fpistm I understand that you are busy, but is there some way to ...motivate... you or another competent contributor here to solve this? |
Beta Was this translation helpful? Give feedback.
-
Just a question you said you used a BluePill but you select a blackpill on your screenshot ? |
Beta Was this translation helpful? Give feedback.
-
Yes, the blackpill is an error on my side. After much troubleshooting I made this test app above, and ran it on Atmega32u4 for comparsion/to verify it. BTW: I have also tried to build it on VSCode w/platformio (and Arduino library) - with same results. So me trying both Arduino and all that are kind of desperate attempts to make it work :) |
Beta Was this translation helpful? Give feedback.
-
@fpistm corrected, and I can confirm that setting "Bluepill" as target did not change the result. |
Beta Was this translation helpful? Give feedback.
-
I can confirm this issue exists. |
Beta Was this translation helpful? Give feedback.
-
@ItsXor Thank you! - for making me doubt my sanity. I started to wonder how this was possible, without anyone spotting it before. |
Beta Was this translation helpful? Give feedback.
-
@fpistm Dear STM - please note: "all I want for Christmas is a fix for I2C Slave" - this is the losest "writing to Santa" i ever did. :) |
Beta Was this translation helpful? Give feedback.
-
@fpistm I believe that the commented I uploaded the "Slave based on your sketch" that you posted, Please note how the SCL is suddenly kept low indefinitely. Then another capture: the F103 is running fine for several selconds, and then I connect the I2C bus (where the master is talking to it.) Please note that in both cases: the F103 is the one that is stuck keeping the SCL low - intil reset - disconnecting master leaves a fully functional I2C master. Please see the Saleae logic capture - Saleae capture.zip When SCL is stuck low like that, the "-" is no longer printed. (most likely the device is crashed/hung/looped at that point) |
Beta Was this translation helpful? Give feedback.
-
Please test sketches provided. And what is your full setup. You talk about Ardupilot but it seems to be a dedicated software. What does the Ardupilot software does? Are you sure I2C @ used by the master to request data is the correct one? |
Beta Was this translation helpful? Give feedback.
-
@fpistm Yes, I've been emulating that BMS for several years using Atmega 328 and Atmega32u4 with Arduino libraries. That's why we are now trying to do basic stuff like trying to see a write requests as a slave. I loaded master sketch on another STM32F103 - but it does not generate I2C traffic. (both lines remain high) Here is my slave firmware: Maybe there's something with the toolchain/build environment? |
Beta Was this translation helpful? Give feedback.
-
With pullup on each I2C lines? |
Beta Was this translation helpful? Give feedback.
-
yes, 10k to 5v for both, of course. |
Beta Was this translation helpful? Give feedback.
-
Usually 4.7k and stm32 is 3.3v even if gpio are 5v tolerant. |
Beta Was this translation helpful? Give feedback.
-
I know, but this is not the issue here, I do not see some odd levels when looking at the signals with an oscilloscope, crisp and clear - (when there is something to see) my choice is simply because some of the autopilots use 5v buffers for I/O and then 10k is standard. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Finally I've tested with an Ardunio UNO as master (5V) and BluePill with your slave binary and it works. Edit: I convert this as a discussion |
Beta Was this translation helpful? Give feedback.
-
I assume your master traffic is captured on pins PB6/PB7 This leaves us with two options: 2: This issue started as troubleshooting of devices with LCSC C8734 , assembled by JLCPCB (assembled about 6 weeks ago). - then got confirmed/reproduced on cheap bluepill's on breadboard (those were bought maybe a year ago) Q1: What do we know about the chance of LCSC being infected by bad/fake stock? and the chance for the Bluepills to have the same issue? Q2: would it help if I posted microscope photos of the LCSC assembled parts? Q3: are there some internal serial, some code that can be run to verify the authenticity of the STM32F103 or reveal some known copies ? I have no other boards with big footprint like this, will try to compile and run the code/software on STM32F405 , An older board with STM32F103C8 - and an STM32F103CB |
Beta Was this translation helpful? Give feedback.
-
@fpistm It must have been late yesterday and I must have cocked up something - sorry. So this is some issue, we should not have been able to crash /loop a uC this way. In this case: we see master request 0x29 - (I think it would read 14bytes.) the program does not run long enough to even print the request, it hangs before that. |
Beta Was this translation helpful? Give feedback.
-
Essential progress: Please see the following throw-together test: #include <Wire.h>
#define BATTMONITOR_SMBUS_ADDRESS 0x0B
#define BATTMONITOR_SMBUS_SOLO_CELL_VOLTAGE_EXT 0x29
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
uint8_t buff[12];
if (read_block(BATTMONITOR_SMBUS_SOLO_CELL_VOLTAGE_EXT, buff, 12)) {
for (int i = 0; i < 12; i++) {
Serial.print("0x");
Serial.print(buff[i], HEX);
Serial.print(" ");
}
Serial.println();
} else {
Serial.println("Failed to read data");
}
delay(1000);
bool read_block(uint8_t command, uint8_t* data, uint8_t length) {
Wire.beginTransmission(BATTMONITOR_SMBUS_ADDRESS);
Wire.write(command);
if (Wire.endTransmission() != 0) {
return false; // End transmission and check for a successful transmission
}
Wire.requestFrom(BATTMONITOR_SMBUS_ADDRESS, length);
if (Wire.available() != length) {
return false; // Check if the requested amount of data is available
}
for (uint8_t i = 0; i < length; i++) {
data[i] = Wire.read();
}
return true;
} Please confirm that you can reproduce it. |
Beta Was this translation helpful? Give feedback.
-
@fpistm |
Beta Was this translation helpful? Give feedback.
-
This is the ultimate proof of ..some bug/unintentional issue: You made things not crash/loop by suggesting: That looked as if solved crashing, but then things did not work as intended, I spent some time trying to understand why everything seemed to fall apart. I have made a good package that tests the communication as if this was the actual device: Please load the following two programs: Master: //MASTER
#include <Wire.h>
#define SLAVE_ADDRESS 0x0B
int i = 1;
void setup() {
Wire.begin(); // Join I2C bus as master
Serial.begin(9600);
pinMode(PC13, OUTPUT);
}
void loop() {
Wire.beginTransmission(SLAVE_ADDRESS);
Wire.write(i++);
Wire.endTransmission();
// Request 10 bytes from the slave
Wire.requestFrom(SLAVE_ADDRESS, 10);
// Wait for the data and print it
Serial.print("Received: ");
while (Wire.available()) {
uint8_t byteReceived = Wire.read();
Serial.print(byteReceived);
Serial.print(" ");
}
Serial.println();
delay(500); // Wait 500 milliseconds before repeating
digitalWrite(PC13, !digitalRead(PC13));
}
Slave: //SLAVE
#include <Wire.h>
#define RESPONSE_SIZE 10
volatile uint8_t x = 0;
uint8_t counter = 0;
long last = millis();
void setup() {
Wire.begin(0x0B); //, false, true); << this prevents crashing with real devices, but comes with a terrible effect
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
Serial.begin(115200);
}
void loop() {
if (millis() > last + 500) {
Serial.println(x);
last = millis();
}
}
// This function is called when the master sends data
void receiveEvent(int howMany) {
x = Wire.read();
}
// This function is called when the master requests data
void requestEvent() {
Serial.println("req");
uint8_t response[RESPONSE_SIZE];
for (int i = 0; i < RESPONSE_SIZE; i++) {
response[i] = counter;
counter++;
if (counter > 254) {
counter = 0;
}
}
Wire.write(response, RESPONSE_SIZE); // Send response
}
Please notice the crazy things that are going on once the clock stretching is disabled. I made a video for you: https://drive.google.com/file/d/1vYfU9P-NxrzM06YYjbLcQMxBt_xuhyXR/view?usp=sharing Thank you for looking into this - I hope this helps you understand what is going on here. Additional data with the real I2C master and the same sleve test code, but only 4-byte response (also at 100kHz): With clock stretching disabled: With clock stretching not disabled: |
Beta Was this translation helpful? Give feedback.
-
@fpistm hmm, I'd say you cheated. :) I am also afraid that if the BMS is connected to the running master (think hotswap/groundpower) then it will crash before all the data and calculations can be done (or just be forced to send invalid/empty data while the program is still in requestEvent) As for using print in interrupts, I did it here because testing proved I could get away with it in this case :) But I would like to be able to do proper data calculation before sending. (and be able to rely on clock-stretching until done) - in another application I use, where the data needs to be as fresh as possible, and cannot be sampled at a high rate, this is kind of essential. (to be able to receive a request, compute for a while let's say (0.1-1ms) , then respond.) Also: it will require twice the size of each buffer/each reply to be able to update one buffer/reply, and have another be valid at any given moment. (otherwise I risk sending a buffer that is in the process of being updated) Basically: this should work with some ms delay: void receiveEvent(int howMany) { |
Beta Was this translation helpful? Give feedback.
-
Describe the bug
I2C slave does not recieve requests.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I'd expect it to work like it does on Atmega/atmel controllers - where this code works. see arduino/ArduinoCore-API#241
Than I rebuilt it all using Arduino Core 2.9.0 (current release)
On Core 2.9.0 - the PB6 is at least not pulled low - which is good, but it still does not work.
Desktop (please complete the following information):
Board (please complete the following information):
Beta Was this translation helpful? Give feedback.
All reactions