I have a problem with my board when I try to write data to a serial (I2C) RAM (FM24C16B).
I use PortF bits 2&3 with two 4.7K resistors (pull ups) and a bit banged I2C.
Transfers are correct as long as I do no set or clear any other PortF pin (prior to a transfer).
If I do then on the first byte that i send, the serial RAM does not acknowledge.
It also happens if I set a pin that is already set (I did it for testing).
Repeating transfers always fail.
Initially I used the on chip I2C interface but I had problems too. After a complete
transfer (Stop condition) the BUSY flag was set (not normal) and after the next transfer
the arbitration lost flag, ending as an unsucessful transfer.
There are no interrupt routines. The loads on PortF pins are small (optocouplers) and
are active when the port pins are cleared.Drive strength and slew rate are normal.
I use Codewarrior 6.3 assembler for the program.
To solve the problem I did the following:
Changed resistor values to 1.8K
Changed the MCU. The problem remains.Next step is to change the serial RAM...
Any ideas?
Solved! Go to Solution.
Chris,
where are your waveforms?
I guess your problem is coupled with the fact that port bits are not fully independent. Even using bit set/clear instructions, whole 8bits register is read, modified and written back. When bit direction is set for input and you "write to another bit", input bit state is read and latched to be outputted when you change pin direction to output. Isn't this what happens in your case?
Regards,
Edward
Chris,
where are your waveforms?
I guess your problem is coupled with the fact that port bits are not fully independent. Even using bit set/clear instructions, whole 8bits register is read, modified and written back. When bit direction is set for input and you "write to another bit", input bit state is read and latched to be outputted when you change pin direction to output. Isn't this what happens in your case?
Regards,
Edward
Hi Edward again,
I came back today, and I realised that the defective PCB track did not cause the problem. After the PCB repair I tested the routine and I figured wrong a branch instruction. So from your responce and the 9S08DZ32 data sheet (" It is a good programming practice to write to the port data register before changing the direction of a port pin to become an output. This ensures that the pin will not be driven momentarily with an old data value that happened to be in the port data register") I did the following: In the I2C start routine I used the instructions LDA PTFD>AND #$F3 (so bits 2&3 ="0")>STA PTFD. That solved the problem. I then used a USB logic analyser to check the signals and they are now OK.
I apologize for my previous post.
Regards
Chris
Hi Edward,
thank you for your responce.
Yes, this is the case. Initially, before the bit banged I2C routine is executed, I clear bits 2&3 of the data direction register (so they become inputs>Hi) and clear PortF bits 2&3 on the output latch. Then in the I2C routine I set/clear the DDR register bits 2&3 and the pins are cleared(outputs>Low)/set(inputs>Hi).
It would be a drama if setting/clearing a bit could affect the operation of another one on the same port. What I didn't think of in the first place, is what is common to their operation. And that was the power line!. I use the 48pin package. There are two Vdd and two Vss lines.The PCB at 'the second' pair was defective. So I soldered two wires to power that pair and problem solved!
Now I can say "That's another fine mess I've got me into" :smileyhappy:
Regards
Chris