I believe the upstream port of the first module may be I2C, but the downstream port will be the DaisyLinking protocol not I2C. The specifications say “Only connect DUELink modules on the Downlink connection”.
If I am wrong, then would the button be device 1, the default device, or would it be device 2? If device 2, the a Sel(2) command would be needed.
Yes correct. However, DUELink is very dynamic and you can take over the downlink port to manually control it if you want. Won’t be as dynamic and as easy when using DUELink modules but it will work.
Device addresses are a DUELink thing. When you add other devices then they are simply I2C devices and you would use them like you always did pre-DUELink.
It is also possible to have a daisylink of DUELink modules where the last module (and only the last module) is switched to I2C non-DUELink mode (mode #4). This last module can now use DLI2CWr() to access those I2C non-DUELink modules.
So mode must be 4. But in mode part:
4
None
Inactive
5
None
I2C
So mode must be 5.
Is there a mistake in doc (or maybe I’m tired , and it can be ! )
What I want is reproduce the code below (It’s a qwiic button connect to FEZ Pico):
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.I2c;
using GHIElectronics.TinyCLR.Pins;
using System.Diagnostics;
using System.Threading;
namespace FEZ_Pico_qwiic
{
internal class Program
{
static byte[] writeBuffer = new byte[2];
static byte[] readBuffer = new byte[2];
static I2cDevice device;
static void Main()
{
var led = GpioController.GetDefault().OpenPin(SC13048.GpioPin.PA8);
led.SetDriveMode(GpioPinDriveMode.Output);
var settings = new I2cConnectionSettings(0x6F, 400_000); //The slave's address and the bus speed.
var controller = I2cController.FromName(SC13048.I2cBus.I2c1);
device = controller.GetDevice(settings);
Debug.WriteLine("Register: 0x00, " + readSingleReg(0x00).ToString("X"));
while (true)
{
led.Write(GpioPinValue.Low);
Thread.Sleep(500);
led.Write(GpioPinValue.Low);
Thread.Sleep(500);
}
}
static byte readSingleReg(byte address)
{
writeBuffer[0] = address;
device.Write(writeBuffer,0,1);
device.Read(readBuffer,0,1);
return readBuffer[0];
}
static byte writeSingleReg(byte address,byte value)
{
writeBuffer[0] = address;
writeBuffer[1] = value;
device.Write(writeBuffer);
return readSingleReg(address);
}
}
}
And now it’s the script in console:
# Switch Downlink to I2C mode
DLMode(4,0)
Dim B1[]=[0x00]
Dim B2[]=[0x00]
# Write 1 byte to 0x6F and read 1 byte
DLI2CWr(0x6F,B1,B2)
print("B2:",B2[0])
But B2 always contains 0.
I’ve tried to do 2 operations for write and read, but same result:
# Switch Downlink to I2C mode
DLMode(4,0)
Dim B1[]=[0x00]
Dim B2[]=[0x00]
# Write 1 byte to 0x6F and read no byte
DLI2CWr(0x6F,B1,[])
# Read 1 byte
DLI2CWr(0x6F,[],B2)
print("B2:",B2[0])
# Switch Downlink to I2C mode
DLMode(5,0)
Dim B1[]=[0x19,0x00] # [0x19,0x02] will light on
# Write 2 bytes to 0x44 and read nothing
DLI2CWr(0x6f,B1,[])
Button light is off (previously is was on).
So Mode should be 5, and docs must be change. I notice a lot of reference to 4, and only 1 to 5.
Address is correct.
Now I have just to find how to read register, but it is a good start !
Oh that is great news. Docs were corrected, thanks for heling.
Now, to figure out the read issue. Are you sure you need to read register 0? Are there any other registers? I looked at the sparkfun docs but it was not clear to me.
Note that there might be a bug as this is a rarely used feature. We will check on Monday.