Help I2C TWR-K53N512

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

Help I2C TWR-K53N512

828 Views
phamminhthuan
Contributor II

Hello everybody,

I'm using Kit TWR-K53N512 to control OLED SSD1306 with I2C. But I can't write a library for I2C from K53 datasheet. I didn't find I2C library for K53 on freescale website.

Do you have its I2C library? Please help me.

Thanks and Regards!

Tags (1)
0 Kudos
3 Replies

494 Views
isaacavila
NXP Employee
NXP Employee

Hi Pham,

There is no I2C library for TWR-K53N512 board but there is a good example (made for TWR-K60D100 target but it should work for K53 as well.).

You can download this sample code (and more) in package:

https://www.freescale.com/webapp/sps/download/preDownload.jsp

This demo uses linked files so be sure to download build and src folders on your CodeWarrior's workspace.

Hope this can help,

Regards,

Isaac Avila

0 Kudos

494 Views
phamminhthuan
Contributor II

Thank very much, Isaac Avila

I read K53 datasheet and write i2C library following íts datasheet. But It isn't run. I am using IAR Workbend for ARM.

Can you tell me how to write I2C library?

Thanks and Regards

0 Kudos

494 Views
isaacavila
NXP Employee
NXP Employee

Hi Pham Minh Thuan,

I2C example (the one that i referred to in last post) is also available for IAR workbench.

I can give some basic guidance on writing your I2C library, first of all, you need to think which method you will use: Polling or Interrupt.

In I2C example, polling is used.

There should be a function that initializes I2C module (clocking I2C module, configure I2C used pins, enable I2C module, set Slave Address and set SDA and SCL hold time):

void hal_i2c_init(void)

{

      /* Clocking I2C0 module */

SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;

/* Use PTD8 as I2C0 SCL pin */

PORTD_PCR8 = PORT_PCR_MUX(2);

/* Use PTD9 as I2C0 SDA pin */

PORTD_PCR9 = PORT_PCR_MUX(2);

/* Configure I2C rate to Bus clock / (mul x SCL divider)

* for this case, Bus clock is configured to 50MHz (Core clock 100MHz, Bus clock 50MHz, see, sysinit.c)

* I2C Baud rate = 50 MHz / (2 x 160) = 156 250 kbps */

I2C0_F  = 0x60;

/* Enables IICEN flag (I2C Enable) */

I2C0_C1 = 0x80;

/* As we will use MCU as master, I2C0_F isn't set

* I2C0_A1 = desired_addres_value;

* */

}

In this function, you can use some parameters for configuring your I2C module as user defined them: for example, I2C baud rate, Slave address, etc. You can also use a structure that groups these fields:

typedef struct {

uint32_t i2c_baud_rate;

uint8_t  i2c_address;

bool    i2c_enable_interrupt;

}I2C_CONFIG;

After configuration is achieved, you must send or request bytes to slave (configuration was made for I2C being master). You can define basic functions such as write byte, get ack, and so on (according to I2C protocol specifications). I commented function to read data from MMA8451 accelerometer in example code:

uint8_t hal_dev_mma8451_read_reg(uint8_t addr)

{

uint8_t result;

/* Configure I2C module as Master and Configure as Transmit mode */

i2c_start(I2C0_B);

/* Write to Slave address and send WRITE identifier (last bit to 0)*/

i2c_write_byte(I2C0_B, I2C_ADDR_MMA8451 | I2C_WRITE);

/* Wait for IICIF flag (One byte transfer) */

i2c_wait(I2C0_B);

/* Verify if ACK was received */

i2c_get_ack(I2C0_B);

/* As we want to send a byte (register), we send this byte*/

i2c_write_byte(I2C0_B, addr);

/* Wait for IICIF flag (One byte transfer) */

i2c_wait(I2C0_B);

/* Verify if ACK was received */

i2c_get_ack(I2C0_B);

/* Start a new transaction */

i2c_repeated_start(I2C0_B);

/* Want to read a register */

i2c_write_byte(I2C0_B, I2C_ADDR_MMA8451 | I2C_READ);

/* Wait for IICIF flag (One byte transfer) */

i2c_wait(I2C0_B);

/* Verify if ACK was received */

i2c_get_ack(I2C0_B);

/* Change to RX mode to received requested data */

i2c_set_rx_mode(I2C0_B);

/* Send a nack after receiving next byte */

i2c_give_nack(I2C0_B);

/* Read data */

result = i2c_read_byte(I2C0_B);

/* Wait until nack is sent*/

i2c_wait(I2C0_B);

/* Stop transmission (switch to slave mode and RX mode) */

i2c_stop(I2C0_B);

/* As nack was sent in last received byte, there is still one byte to be received */

result = i2c_read_byte(I2C0_B);

pause();

return result;

}


As you could see, basically, this procedure uses functions to write, get_ack and switch to slave when needed.

There is another way to implement this driver, it could be made using interrupt, this is done by setting IICIE bit in I2C_C1 register, as all I2C interrupt sources uses the same interrupt vector, you need to implement routine as shown on Reference Manual:

I2C Routine.jpg

Basically, function to read, send/get ack and switch to master or slave are needed, you just need to follow the flow expressed in this routine or do a polling-specific routine according to your slave’s specifications.

If there is still doubts on I2C routine, you can run I2C example and see on oscilloscope exchanged-data between master and slave.

Hope this can help,

Best Regards,

Isaac

0 Kudos