void InitI2C(void){ // This will unhang the I2C module if reset while sending DDRJ |= 0xc0; // make the clock & data be output. PTJ |= 0xc0; // Drive them hi DDRJ &= ~0xC0; // Set them back to input. IBCR = 0; IBCR |= IBCR_IBEN_MASK; IBFD = 0x1f; // 100K at 24 MHz IBAD = 0x7e; }
In my opinion, these files are likely to help you.
void delay(){ int i; for( i = 0 ; i < 5000 ; ++i) asm { nop ; nop ; nop ;nop };}void I2CInit(void){ int i = 0; PTCDD |= 3; PTCPE |= 3; PTCD = 3; for( i = 0 ; i < 30 ; ++i ) { delay(); PTCD ^= 1; } PTCD |= 3; PTCDD &= ~3;
I had this problem again, and had to to this to un-hang the external chip...
I had this problem years ago with a Coldfire.... what I did then was to generate SCL pulses until SDA became high (normally up to 8 bits is sufficient). Then generate a STOP condition.
Consider yourself lucky, because that Coldire I was working with that time didn't have a GPIO option on the I2C module's SCL/SDA pin and the I2C controller didn't support freeing the bus, so a HW mod (solder GPIOs to SCL SDA was required.
Henko