I'm trying to get some I2C ISR code working on my KL02Z device. I'm getting complete garbage with no reliable start sequence clock. I am getting a bit bogged down.
Is there anyone who can verify my I2C init and baud rate calculation? Am I doing something stupid here?
void i2c_master_init(void)
{
// disable IRQ I2C0 vector is 24
NVIC_ICER = 1 << (8%32);
SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK; // enable IIC0 clock
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; // enable PORTA clock
PORTA_PCR3 |= PORT_PCR_MUX(2);
PORTA_PCR4 |= PORT_PCR_MUX(2);
/* Configure Divider Register - about 375K baud rate with 24MHZ bus clock */
I2C0_F |= (I2C_F_MULT(1) | I2C_F_ICR(9));
I2C0_C1 |= (I2C_C1_IICEN_MASK | // enable IIC
I2C_C1_IICIE_MASK | // interrupt enable
I2C_C1_TX_MASK); // enable TX mode
// enable_irq(8);
NVIC_ICPR |= 1 << (8%32);
NVIC_ISER |= 1 << (8%32);
}
If I perform a write with a address then I start off with something like............
I2C0_S |= I2C_S_IICIF_MASK;
NVIC_ICER = 1 << (8%32);
I2C0_C1 |= I2C_C1_TX_MASK; // write direction
I2C0_C1 |= I2C_C1_MST_MASK; // Generate START SIGNAL
I2C0_D = ((addr << 1) | WRITE); // Write 7-bit Slave Address + WRITE bit
while (0 == (I2C0_S & I2C_S_IICIF_MASK))
{ }; // wait for address transferred
//enable_irq(8);
Sorry I should have added that I have some 4K7 pull ups on my slave device.
Clive
A change that you need to make is to enable the ports used to be open-drain. Presently they are configured as push-pull so can't work as I2C.
I also advise the following to be tolerant to I2C bus lock-up: I2C device dead-lock recovery
Regards
Mark
Thanks Mark. How do I do that, only the KL02 has no open drain control registers to do this?
Clive
My mistake, your part has pseudo-open-drain pins when you set them to I2C mode.
What board do you have? I have attached a binary for the accelerometer on the FRDM-KL02Z - it uses the same pins as you have configured and reads the accelerometer continuously (back-to-back I2C reads for ever - on the UART command line interface via the Virtual COM at 115k Baud go to the I2C menu and activate the print-out of values with "acc_on"), whereby you can then use the debugger to dump the registers to work out any differences to yours.
You can get source code at http://www.utasker.com/forum/index.php?topic=1721.0
Regards
Mark
I have a FRDM-KL02Z. I have no working debugger with Eclipse yet (I gave up trying to get the openSDA debugger working with Eclipse). I have tried some known code and I still cannot get the I2C to clock out a slave address. I get a valid start condition, but the start condition is never followed by the address being clocked out. I'm hitting my ISR without any issue. At the moment I'm completely out of ideas.
Clive
Are you not using CodeWarrior? If you are having debugging issues try also CooCox CoIDE or IAR Quickstart (much simpler to work with than CW).
If you attach your binary file I could load it to my board and possibily tell you what is going wrong - you would need to show the Tx routine (C source code) and tell me which address it starts at (in the map file). Essentially, apart for the I2C port mapping, there is no difference between operation on KL02 in comparison to a K70 or any other KL/K device.
Regards
Mark
Hi Mark,
I got the issue sorted. It turned out to be faulty hardware and not code.
I'm using Eclipse and GCC because its free. Trouble with the free tools is you have to jump through hoops to get it all to work.
Thanks for taking the time to reply to my plight.
Clive
OK. Good to hear that the issue is solved.
Note that CooCox CoIDE and KDS are also free.
The IAR Kickstart works up to 32k and CW10.x up to 128k so are also effectively free for A KL02 ;-)
Regards
Mark