Closed pasko-zh closed 8 years ago
@FWeinb I cannot reproduce your issue.
Today I had some time to look at the library again. It should be fine already in the current version: If you do brzo_i2c_write(buffer, 2, false)
, it will actually pass &buffer[0]
. You can also do for instance brzo_i2c_write(&buffer[5], 2, false)
.
Now, inside the function brzo_i2c_write
referring to data[0]
is relative to the base pointer passed to brzo_i2c_write(uint8_t *data ...
: In the former case data[0]
refers to buffer[0]
in the latter to buffer[5]
. Since I was not 100% sure, if everything is fine with the inline assembly too, I ran some tests today. But it should be fine.
Can you confirm this? Or, if you still have the issue, drop me your code, so that I can check it again.
Thanks
I did the tests with an ADT7420, here is the full code:
#include "brzo_i2c\brzo_i2c.h"
uint8_t SDA_PIN = 5;
uint8_t SCL_PIN = 4;
uint8_t ADT7420_ADR = 0x49;
uint8_t buffer[10];
uint8_t error = 0;
float temp = 0.0;
uint8_t ICACHE_RAM_ATTR get_temp_celsius(float *t) {
uint32_t ADC_code = 0;
uint8_t bcode = 0;
brzo_i2c_start_transaction(ADT7420_ADR, 400);
buffer[0] = 0x03;
buffer[1] = 0xA0;
buffer[5] = 0x03;
buffer[6] = 0xA0;
// sends buffer[0] and buffer[1]
brzo_i2c_write(buffer, 2, false);
// Works, too: I.e. sends buffer[5] and buffer[6]
brzo_i2c_write(&buffer[5], 2, false);
buffer[0] = 0x00;
brzo_i2c_write(buffer, 1, true);
brzo_i2c_read(buffer, 2, false);
bcode = brzo_i2c_end_transaction();
if (bcode == 0) {
ADC_code = ((buffer[0] << 8) | buffer[1]);
*t = ADC_code / 128.0;
return 0;
}
else return bcode;
}
void setup() {
delay(1000);
Serial.begin(115200);
brzo_i2c_setup(SDA_PIN, SCL_PIN, 2000);
}
void loop() {
Serial.println("Waiting 5 seconds...");
delay(5000);
error = get_temp_celsius(&temp);
if (error == 0) {
Serial.print("Temp = ");
Serial.println(temp, 8);
}
else {
Serial.print("Brzo error : ");
Serial.println(error);
}
}
I will do my tests again. Thank you for investigating.
I tried the following for communicating with an OLED display using an SSD1306
uint8_t sendBuffer[1];
sendBuffer[0] = 0x40;
brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);
for (uint16_t i=0; i<DISPLAY_BUFFER_SIZE; i += 16) {
brzo_i2c_write(sendBuffer, 1, true);
brzo_i2c_write(&buffer[i], 16, true);
yield();
}
brzo_i2c_end_transaction();
In this example I want to send the whole image (saved in buffer
) to the display. The SSD1306 expects 0x40
every 16 bytes.
Is it supported to have to writes
like that?
Without having yet tested/checked your code, I think it should work (concerning the &buffer[.]
issue)
UDPATE: I can confirm that &buffer[.]
works already with the current version 1.00.
However, after the loop has finished, the last write
had a repeated START. According to the i2c specification, you should have a STOP sequence to free the bus. I.e., the last write
before calling brzo_i2c_end_transaction
should have no repeated start.
So, most probably you are stalling the i2c bus after the loop has finished.
brzo_i2c_write/read(uint8_t *data, uint8_t no_of_bytes, boolean repeated_start)
expects a pointer to a buffer*data
. It then always sends/reads theno_of_bytes
starting from the beginning of the buffer, i.e.data[0]
...data[no_of_bytes - 1]
.Instead,
brzo_i2c_write/read
should allow that any pointer to an elemen (of array of byte) is passed to it and that this then taken as the base address from whichno_of_bytes
is sent/read. E.g.,brzo_i2c_write(&buffer[4], 5, true)
would send 5 bytes starting frombuffer[4]