I've connected an RTL8710 (in "Rtlduino" form) to a MCP23008 (on a breadboard) via I2C as follows:
I'm using rustl8710 to program the RTL8710, which works fine and I've already hooked up a display via SPI without any issues.
I've got this code set up to test the MCP23008:
led1.write(DigitalValue::High);
let mut handle = i2c_t::default();
i2c_init(&mut handle as *mut i2c_t, PinName::PC_4, PinName::PC_5);
i2c_frequency(&mut handle as *mut i2c_t, 1000);
led2.write(DigitalValue::High);
if i2c_write(&mut handle as *mut i2c_t, 0x20, &[ 0x00, 0xff as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0 ][0] as *const i8, 11, 1) != 1
{
panic!("Byte write failed!");
}
led3.write(DigitalValue::High);
loop { }
Feel free to ignore all lines starting with led*
, those simply pull some GPIO pins high to light up the 3 internal LEDs on the device so I can see if it works without using gdb
.
Alternatively, this C code demonstrates the same problem:
#include "i2c_api.h"
#include "PinNames.h"
void main(void)
{
ConfigDebugInfo = 0xffffffff;
char data[] = { 0x00, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
i2c_t handle;
i2c_init(&handle, PC_4, PC_5);
i2c_frequency(&handle, 1000);
i2c_write(&handle, 0x20, data, 11, 1);
while(1) { }
}
Paste the code above in place of main
in main.c
and then flash and run the code using make && make flash && make debug
. The code will never reach the while
loop, and hang on i2c_write
.
The code effectively does the same thing as this code in an Adafruit library for the MCP23008.
I2C set-up (first 5 lines) works, but when calling i2c_write
the RTL8710 just hangs infinitely somewhere in a loop in RtkI2CSend_Patch () at component/soc/realtek/8195a/fwlib/src/hal_i2c.c:1324
(according to gdb
)
The MCP23008 is working fine, I've successfully used that on an ATTiny85.
Other things that might be relevant:
- PC_5 (aka GC5) is also connected to a button on the evaluation board, which pulls the pin high when it's not pressed.
- The RTL8710 prints
RTL8195A[HAL]: ISR 0 didb't bee register!!!␊
to the UART_LOG ports. This appears to be from a function that isn't available in source form so I'm not quite sure how I should interpret that.
What am I doing wrong?
Best Answer
As it turns out, I was indeed not the only one to notice this issue. In both the 3.5a and 4.0b SDKs (rustl8710 is using the 3.5a SDK), there is a bug in the I2C code. Realtek have released a fix for this bug, but this fix is not included in the SDK downloads, nor listed on the download page, nor listed in the release notes.
Instead, you have to download a fixed library from the FAQ page here: https://www.amebaiot.com/en/ameba-sdk-faq/. For rustl8710, which uses the 3.5a SDK, you'd click on 'Fix 3.5a GCC SDK I2C problem', then download the linked zip file (note: you might need to create an account before you can download the file). This zip file contains a single
lib_platform.a
, which you'll have to copy over the existing file incomponent/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform.a
.After this, use these
make
commands to rebuild everything:For me, I2C still doesn't work the first time after flashing. This can be worked around by starting a debug session using
make debug
, then quitting usingq
and restarting the debug session usingmake debug
again.