Since your I2C works at 100Khz, but not 400 Khz, it is a good idea to look at the various factors that have an effect on timing.
1: Check that your slave board supports 400Khz.
2: Resistor values are too big.
When the timing is increased from 100k to 400k, the period of the clock drops from 10 us to 2.5 us.
This means that the rising edge of your data/clock signals has a significantly less amount of time to settle. the time taken is calculated as follows:
t = rc
the capacitance on the bus is usually constant and a property of each device. It sounds like you have these. Add them up.
The resistor values are the next variable. Since you have three in parallel, you need to add them using 1/Rt = 1/R1 + 1/R2 + 1/R3
and so on. You only need one resistor on the bus, so having three in parallel is going to lower the total resistance.
You can now calculate t using the above formula. If it is more than 300ns (just over 10% of your clock period at 400k), then the rise time is out of I2C spec. Here, table 5, page 32.
If you'd like to calculate the correct resistor value, you can re-arrange the above formula to get R=t/c
and work from there, where T is 300ns or less.
For set_in, you’re passing I2C_PORT
, which is PORTB
, but you need to pass in DDRB
.
Best Answer
Good document about the subject is Bi-directional level shifter for I2C-bus and other systems which uses a single mosfet as a bi-directional level shifter.