I2C Functionality on the KEA not Responding

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C Functionality on the KEA not Responding

1,000 Views
kaslewis
Contributor III

I am trying to get the I2C module working on the KEA but I am having no luck with this. I can see using a logic that the SCL line goes high before the SDA line and at the end the SDA goes low before the SCL, but there is no data being transmitted. Below is the code that I am using, any help would be very much appreciated.

Thankfully

Kas

Sorry I tried to insert the code in code format but the insert function completely screwed up everything so I had to do it without

/******************************************************************************
*    LAB1 - Serial Communications Interface (UART)                             *
*                                                                             *
*       This lab demonstrates how to use the UART module to receive and send   *
*    characters. Using interrupts, it waits for characters sent from a PC     *
*    terminal and echoes the received data.  *
*                                     *

*       To use this demo you need to open a  serial terminal. The OpenSDA port  *

*       is used to communicate via UART2 to the KEA64 microcontroller.          *
*                                                                             *
*       Open the Terminal Utility and set the baud rate to 9600, leave all    *
*    the other settings with the default values. Click the Open Port button   *
*    and the console should connect. Every character you write to the serial  *
*    console will be replied by the KEA64 MCU.                                 *
******************************************************************************/

/**********************************************************************************************

* External objects

**********************************************************************************************/

#include "derivative.h" /* include peripheral declarations */

#include "UART.h"

#include "CLK.h"

#define MWSR                   0x00  /* Master write  */

#define MRSW                   0x01  /* Master read */

#define i2c_Start()            I2C0_C1     |= 0x10;\

                               I2C0_C1     |= I2C_C1_MST_MASK

#define i2c_write_byte(data)   I2C0_D = data

#define i2c_Wait()             while((I2C0_S & I2C_S_IICIF_MASK)==0) {} \

                                 I2C0_S |= I2C_S_IICIF_MASK;

#define i2c_Stop()             I2C0_C1  &= ~I2C_C1_MST_MASK;\

                               I2C0_C1  &= ~I2C_C1_TX_MASK

/**********************************************************************************************

* Global variables

**********************************************************************************************/

unsigned char MasterTransmission;

/**********************************************************************************************

* Constants and macros

**********************************************************************************************/

/**********************************************************************************************

* Local types

**********************************************************************************************/

/**********************************************************************************************

* Local function prototypes

*********************************************************************************************/

void Enable_Interrupt(UINT8 vector_number);

void Uart_Interrupt (UINT8 data);

void i2cInit();

void Pause(void);

void writeRegister(unsigned char slaveID, unsigned char registerAddress, unsigned char data);

unsigned char readRegister(unsigned char slaveID, unsigned char registerAddress);

/**********************************************************************************************

* Local variables

**********************************************************************************************/

/**********************************************************************************************

* Local functions

**********************************************************************************************/

/**********************************************************************************************

* Global functions

**********************************************************************************************/

/***********************************************************************************************

*

* @brief    main() - Program entry function

* @param    none

* @return   none

*

************************************************************************************************/

int main(void)

{

UINT32 counter = 0;
long int delay;
Clk_Init();/* Configure clocks to run at 20 Mhz*/
UART_Init();/*Initialize Uart 2 at 9600 bauds */
i2cInit();
Uart_SetCallback(Uart_Interrupt);/* Set the callback function that the UART driver will call when receiving a char */
Enable_Interrupt(INT_UART2); /* Enable UART2 interrupt */
for(;;) { 
counter++;
readRegister(0x4B, 0x0B);
for(delay = 0; delay < 999999; delay++);
}
return 0;

}

/***********************************************************************************************

*

* @brief    Uart_Interrupt(UINT8 data). Serial reception callback. This function is called each time a character

*is received on the serial port.

* @param    data received from serial port

* @return   none

*

************************************************************************************************/

void Uart_Interrupt (UINT8 data)

{

Uart_SendChar(data); /* Echos data that is received*/

}

/***********************************************************************************************

*

* @brief    Enable_Interrupt(UINT8 vector_number). Enable interrupts from desired module.

* @param    Module interrupt number from the interrupts vector table

* @return   none

*

************************************************************************************************/

void Enable_Interrupt(UINT8 vector_number)

{

vector_number= vector_number-16;
/* Set the ICPR and ISER registers accordingly */
NVIC_ICPR |= 1 << (vector_number%32);
NVIC_ISER |= 1 << (vector_number%32);

}

void i2cInit(){

//I2C setup
SIM_SCGC |= SIM_SCGC_I2C_MASK;
SIM_PINSEL |= SIM_PINSEL_I2C0PS_MASK;

    I2C0_F = 0x00;

    I2C0_C1 = I2C_C1_IICEN_MASK | I2C_C1_MST_MASK | I2C_C1_IICIE_MASK;

}

/*******************************************************************/

/*!

* Pause Routine

*/

void Pause(void){

    int n;

    for(n=1;n<50;n++) {

      asm("nop");

    }

}

unsigned char readRegister(unsigned char slaveID, unsigned char registerAddress)

{

unsigned char result;
unsigned int j;
MasterTransmission = MRSW;
slaveID = slaveID << 1;
slaveID |= MasterTransmission;
i2c_Start();
i2c_write_byte(slaveID);
i2c_Wait();
I2C0_D = registerAddress;
i2c_Wait();
/* Do a repeated start */
I2C0_C1 |= I2C_C1_RSTA_MASK;
/* Send Slave Address */
I2C0_D = (slaveID << 1) | 0x01; //read address
i2c_Wait();
/* Put in Rx Mode */
I2C0_C1 &= (~I2C_C1_TX_MASK);
/* Turn off ACK */
I2C0_C1 |= I2C_C1_TXAK_MASK;
/* Dummy read */
result = I2C0_D ;
for (j=0; j<5000; j++){};
i2c_Wait();
/* Send stop */
i2c_Stop();
result = I2C0_D ;
Pause();
return result;

}

void writeRegister(unsigned char slaveID, unsigned char registerAddress, unsigned char data)

{

MasterTransmission = MWSR;
slaveID = slaveID << 1;
slaveID |= MasterTransmission;
i2c_Start();
i2c_write_byte(slaveID);
i2c_Wait();
I2C0_D = registerAddress;
i2c_Wait();
I2C0_D = data;
i2c_Wait();
i2c_Stop();

}

Labels (1)
3 Replies

621 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Kas,

There is I2C sample code available for KEXX serials, please kindly refer to http://cache.freescale.com/files/software_development_tools/snippets/KEXX_I2C_SC.zip for details, which work together with ke_drv_lib to implement read or write data by I2C interface. which include the master and slave sample code.


Hope that helps,


Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

621 Views
kaslewis
Contributor III

Hello Kan,

Are there any simple, barebones examples. I am looking to something very simple. I do not want to use drivers, macros and anything else. I am looking for a simple example to get the I2C working correctly and where I can see EXACTLY what registers are being used. It appears whenever I ask for help here I get more examples and demo code that is using bloated code. I am looking preferably for someone to look at the SMALL code snippet I have provided and point out what is wrong not give me 20 more examples from other Kinetis controllers and that use 3 or 4 files. KISS = KEEP IT SIMPLE...

Thank you

621 Views
helferog
Contributor II

Hi Kas,

I found myself today in the same situation.

For any other programmer who will face the same issue in the future, here is the code i used to sucessfully write over i2c:

error_t i2c_set_dac(i2c_data_t address_byte, i2c_data_t low_byte, i2c_data_t high_byte)
{
   error_t error = ERROR_SUCCESS;
   i2c_data_t first_byte = 0;


   // generate start condition
   I2C0_C1 |= I2C_C1_MST_MASK;

   // LSB is not write flag
   first_byte = address_byte << 1;
   // push data to send
   I2C0_D = first_byte;
   // wait until sent
   while((I2C0_S & I2C_S_IICIF_MASK)==0);
   // delete interrupt flag
   I2C0_S &= I2C_S_IICIF_MASK;
   // check for ack
   if( (I2C0_S & I2C_S_RXAK_MASK)!= 0 ){
      error |= ERROR_FAILED;
   }


   // push data to send
   I2C0_D = high_byte;
   // wait until sent
   while((I2C0_S & I2C_S_IICIF_MASK)==0);
   // delete interrupt flag
   I2C0_S &= I2C_S_IICIF_MASK;
   // check for ack
   if( (I2C0_S & I2C_S_RXAK_MASK)!= 0 ){
      error |= ERROR_FAILED;
   }

   // push data to send
   I2C0_D = low_byte;
   // wait until sent
   while((I2C0_S & I2C_S_IICIF_MASK)==0);
   // delete interrupt flag
   I2C0_S &= I2C_S_IICIF_MASK;
   // check for ack
   if( (I2C0_S & I2C_S_RXAK_MASK)!= 0 ){
      error |= ERROR_FAILED;
   }


   // generate stop condition
   I2C0_C1 &= ~I2C_C1_MST_MASK;

   return error;
}

Best regards,

Roger

0 Kudos