Hi Torben,
I'm replying with the mailing-list in Cc, as this might also be
interesting for others.
As mentioned earlier, the issue is that the FL2000 has a very inflexible
I2C implementation that was only intended (I guess?) for I2C EEPROMs.
The PCF8574 you want to use is much simpler, as it expects only one data
byte after being addressed.
If you can live with only 6 of the 8 outputs on your port expander, you
might still be able to get it working.
What the FL2000 does for an I2C write is the following:
START, I2C_ADDR(W), REG_ADDR, DATA[0], STOP
START, I2C_ADDR(W), REG_ADDR+1, DATA[1], STOP
START, I2C_ADDR(W), REG_ADDR+2, DATA[2], STOP
START, I2C_ADDR(W), REG_ADDR+3, DATA[3], STOP
As you can see, REG_ADDR is the first byte of data that is being sent to
the device after the address. This is where you need to put the data
you want to set on the IO expander outputs. As the FL2000
auto-increments the register address, you need to set the lowest 2 bits
to 0, so that the increment is not carried to the higher bits. But that
also means that output 0 and 1 of your port-expander will toggle with
each write and are not controllable by you.
From the datasheet of the PCF8574:
"If other
data bytes are sent from the master, following the
acknowledge, they are ignored by this device."
That means that DATA[0-3] are completely ignored, which probably means
that the device will send a NAK for that byte.
So the transfer always will fail from the view of the FL2000, so you
must ignore the return value of fl2k_i2c_write(), which means you also
have no feedback if the slave is actually present or not.
The first thing I would suggest trying is writing a non-zero reg_addr to
all possible slave addresses and observe the output of the port
expander. If you have a logic analyzer, I suggest to use that and have a
look at the I2C bus.
If all that doesn't work, using a small MCU and dealing with the FL2000
I2C oddities there is probably the easiest solution.
Regards,
Steve
On 17.06.2018 21:11, Torben Keil wrote:
Hi Steve,
I tried my luck with i2c... but I wasn't successful.
There's a PCF8574 (Portextender) connected directly on the I2C interface
of fl2k.
Here's my code:
torben@Mworkstation: <mailto:torben@Mworkstation:>~/Amateurfunk/C++$ cat
fl2k_i2c.cpp
// g++ fl2k_i2c.cpp -L/home/torben/Amateurfunk/osmo-fl2k/build/src
-I/home/torben/Amateurfunk/osmo-fl2k/include -losmo-fl2k -o fl2k-i2c_test
#include "osmo-fl2k.h"
#include <iostream>
#include <bitset>
int main (int argc, char *argv[] ) {
int status;
fl2k_dev_t *dev = NULL;
uint8_t i2c_addr = 0b01000001; // Letztes Bit: Read / #Write
uint8_t reg_addr = 0;
uint8_t *data = new uint8_t[10];
uint32_t dev_index = 0;
fl2k_open(&dev, (uint32_t)dev_index);
if (NULL == dev) {
std::cerr << "Failed to open fl2k device " <<
dev_index
<< std::endl;
return -1;
}
for (i2c_addr=0; i2c_addr<128; i2c_addr++) {
status = fl2k_i2c_read(dev, i2c_addr, reg_addr, data);
if( status >= 0 ) {
std::cout << "Adress: " << i2c_addr;
std::cout << "; I2C-Status: " << status <<
"; Data: ";
for( int i=0; i<static_cast<int>(status); i++) {
std::cout << " " << std::bitset<8>(data[i]);
}
std::cout << std::endl;
}
data[0]=127;
for (i2c_addr=0; i2c_addr<128; i2c_addr++) {
//fl2k_i2c_write(fl2k_dev_t *dev, uint8_t i2c_addr, uint8_t
reg_addr, uint8_t *data);
status = fl2k_i2c_write(dev, i2c_addr, 0, data);
if( status >= 0 ) {
std::cout << "Write Adress: " << i2c_addr;
std::cout << "; I2C-Status: " << status <<
std::endl;
} else {
std::cout << static_cast<int>(i2c_addr) <<
"\t";
}
}
}
fl2k_close(dev);
free(data);
return 0;
}
Output of that program after a fresh reboot of the system:
torben@Mworkstation:~/Amateurfunk/C++$ ./fl2k-i2c_test
Kernel mass storage driver is attached, detaching driver. This may take
more than 10 seconds!
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
117 118 119 120 121 122 123 124 125 126 127
So there's nothing reachable via I2C.
What am I doing wrong here?
Greetings,
Torben
Am 17.06.2018 03:18, schrieb Steve Markgraf:
> Hi Torben,
>
> On 16.06.2018 09:40, Torben Keil wrote:
>> do you have a git repository for the code so that I could have a try?
>
> I've debugged and cleaned up the I2C code and just pushed it.
> I2C transfers with the FL2000 seem to fail from time to time, so make
> sure to check the return code of fl2k_i2c_read()/fl2k_i2c_write().
>
> Regards,
> Steve