AnsweredAssumed Answered

MKL25 I2C write issue

Question asked by Lisa Fernandez on Jan 26, 2015
Latest reply on Feb 2, 2015 by Butcher

Hi Freescale Microcontroller forum,


I'm trying to use I2C on my MKL25Z128 microcontroller to write to a slave device. I've used Processor Expert to set everything up for me. However, no signals go out on my SCL and SDA lines. They both stay high.


I'm in the fortunate position that I use this exact uc with the same PE settings in another project. This other project works fine, and I have found the line of code where their behaviors differ. It happens in the middle of a function generated by PE:


/* ===================================================================*/
LDD_TError I2C_MasterSendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, LDD_I2C_TSize Size, LDD_I2C_TSendStop SendStop)
  I2C_TDeviceData *DeviceDataPrv = (I2C_TDeviceData *)DeviceDataPtr;

  /* Device state test - this test can be disabled by setting the "Ignore enable test"
     property to the "yes" value in the "Configuration inspector" */
  if(!DeviceDataPrv->EnUser) {         /* Is the device disabled by user? */
    return ERR_DISABLED;               /* If yes then error */
  if (Size == 0x00U) {                 /* Test variable Size on zero */
    return ERR_OK;                     /* If zero then OK */
  if (DeviceDataPrv->SendStop == LDD_I2C_SEND_STOP) {
    if ((I2C_PDD_GetBusStatus(I2C0_BASE_PTR) == I2C_PDD_BUS_BUSY) || /* Is the bus busy? */  \
       ((DeviceDataPrv->SerFlag & MASTER_IN_PROGRES) != 0x00U) || \
       (DeviceDataPrv->OutLenM != 0x00U))  {
      return ERR_BUSY;                 /* If yes then error */
  } else {
    if (((DeviceDataPrv->SerFlag & MASTER_IN_PROGRES) != 0x00U) || /* Is the bus busy? */  \
      (DeviceDataPrv->OutLenM != 0x00U))  {
      return ERR_BUSY;                 /* If yes then error */
  /* {Default RTOS Adapter} Critical section begin, general PE function is used */
  DeviceDataPrv->SerFlag |= MASTER_IN_PROGRES; /* Set flag "busy" */
  DeviceDataPrv->OutPtrM = (uint8_t *)BufferPtr; /* Save pointer to data for transmitting */
  DeviceDataPrv->OutLenM = Size;       /* Set the counter of output bufer's content */
  DeviceDataPrv->SendStop = SendStop;  /* Set generating stop condition */
  I2C_PDD_SetTransmitMode(I2C0_BASE_PTR, I2C_PDD_TX_DIRECTION); /* Set TX mode */
  if (I2C_PDD_GetMasterMode(I2C0_BASE_PTR) == I2C_PDD_MASTER_MODE) { /* Is device in master mode? */
    I2C_PDD_RepeatStart(I2C0_BASE_PTR); /* If yes then repeat start cycle generated */
  } else {
    I2C_PDD_SetMasterMode(I2C0_BASE_PTR, I2C_PDD_MASTER_MODE); /* If no then start signal generated */
  I2C_PDD_WriteDataReg(I2C0_BASE_PTR, 0xECU); /* Send slave address */
  /* {Default RTOS Adapter} Critical section end, general PE function is used */
  return ERR_OK;                       /* OK */


When this function is reached, the uc has been initialized and enabled using PE code. Both I12 and I2C interrupts have been enabled. This function further configures the uc I2C to be in master transmit mode. The problem occurs at line 38. In the other (working project), completion of this line sets the BUSY register ("Bus is busy") and the IICIF register ("Interrupt pending"). However, in my current project, neither of these two registers are set.


Here are some debugging checks I've made on my own:

--SCL and SDA pins have correct mux setup as I2C signals.

--Slave address is correct.

--I physically disconnected the slave, so that the SCL and SDA lines didn't lead anywhere, and tested the code. The same result happens.

--Clock is configured for 375 kHz, which (as far as I know) is within spec for the I2C peripheral.

--The I2C0 prescaler is set to 1. I saw (here: KL25Z and I2C: Missing Repeated Start Condition | MCU on Eclipse) that there is possibly a bug related to this prescaler.


Any suggestions you can offer would be greatly appreciated! I wasn't sure what parts of my code are relevant, but I'm happy to post more if there is something else you need to see. Just let me know!