Previous Page
    /******************************************************************************
    * I2C.c - I2C module is written for I2C0 assuming physical connection to
    *         PTE19(SCL) and PTE18(SDA). SCL of ~333kHz and 7-bit addressing
    *
    * Created on: Oct 13, 2014
    *   Author: ATC
    *   Edited by: Spencer Black Jan 27, 2015
    *       - Modified to work with Kinetis MK02F12810
    *       - Edited formatting for readability
    *       - Added 'I2C_Send_Char()'
    *       - Changed SCL frequency to ~333kHz
    *******************************************************************************
    * Master Includes
    ******************************************************************************/
    #include "includes.h"

    /******************************************************************************
    * PWM Defines
    ******************************************************************************/
    #define FREQDIVIDE 0x16    //Frequency divider of 104

    /******************************************************************************
    * Private Global Variables
    ******************************************************************************/
    static INT8U slaveAddress = 0x00;

    /******************************************************************************
    * Public Function prototypes
    ******************************************************************************/
    void I2C_Init(void);
    void I2C_DeInit(void);
    void I2C_SetSlaveAddress(INT8U address);
    INT8U I2C_GetSlaveAddress(void);
    INT8U I2C_SendStart(INT8U data);
    INT8U I2C_Send_Char(INT8U data);
    void I2C_Set_TX(void);
    void I2C_Set_RX(void);
    void I2C_ISR(void);

    /******************************************************************************
    * Function Definitions
    *******************************************************************************
    * I2C_Init(void) - Public
    *
    * PARAMETERS: none.
    *
    * DESCRIPTION: Initialize I2C0: Master mode, 7-bit addressing
    *
    * Edited by Spencer Black March 26, 2015
    *   - PortE clock initialized in main program.
    *   - Changed to proper open drain for K02 MCU
    *   - Changed Baud Rate, Bus Clock/ICR register = ~384kHz
    ******************************************************************************/
    void I2C_Init(void){
        SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;   //Enable I2C0 clock

        //PORTE_PCR18: ISF=0,MUX=4
        PORTE_PCR18 = (uint32_t)((PORTE_PCR18 &
                      (uint32_t)~(uint32_t)(PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03)))
                      | (uint32_t)(PORT_PCR_MUX(0x04)));
        PORTE_PCR18 |= PORT_PCR_ODE_MASK;   //Set SDA to open drain

        //PORTE_PCR19: ISF=0,MUX=4
        PORTE_PCR19 = (uint32_t)((PORTE_PCR19 &
                      (uint32_t)~(uint32_t)(PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03)))
                    | (uint32_t)(PORT_PCR_MUX(0x04)));
        PORTE_PCR19 |= PORT_PCR_ODE_MASK;   //Set SCL to open drain

        I2C0_F  = I2C_F_ICR(FREQDIVIDE);    //Set baud rate to 384kHz
        I2C0_C1 = I2C_C1_IICEN_MASK;        //Enable I2C0
    }

    /******************************************************************************
    * I2C_DeInit(void) - Public
    *
    * PARAMETERS: none.
    *
    * DESCRIPTION: Disables I2C0 and turns off I2C0 clock.
    ******************************************************************************/
    void I2C_DeInit(void){
        I2C0_C1 &= ~I2C_C1_IICEN_MASK;      //Disabled I2C0
        SIM_SCGC4 &= ~SIM_SCGC4_I2C0_MASK;  //Disable I2C0 clock
    }

    /******************************************************************************
    * I2C_SendStart(void) - Public
    *
    * PARAMETERS: none.
    *
    * DESCRIPTION: Sends start command on I2C Bus.
    ******************************************************************************/
    void I2C_Set_TX(void){
        while(I2C0_S & I2C_S_BUSY_MASK); //Wait for bus to become idle
        I2C0_C1 |= I2C_C1_TX_MASK;       //Set TX mode
        I2C0_C1 |= I2C_C1_MST_MASK;      //Set Master mode
    }

    /******************************************************************************
    * I2C_SendStop(void) - Public
    *
    * PARAMETERS: none.
    *
    * DESCRIPTION: Sends stop command on I2C Bus and switches to
    *              slave mode and rx mode.
    ******************************************************************************/
    void I2C_Set_RX(void){
        while(!(I2C0_S & I2C_S_TCF_MASK)); //Wait for transfer complete flag to set
        I2C0_C1 &= ~(I2C_C1_MST_MASK);     //Set Slave mode
        I2C0_C1 &= ~(I2C_C1_TX_MASK);      //Set RX mode
    }

    /******************************************************************************
    * I2C_SetSlaveAddress(INT8U address) - Public
    *
    * PARAMETERS: address - address of slave to be addressed.
    *
    * DESCRIPTION: Sets slave address variable.  This function must be
    *               called once prior to communicating with a slave.
    ******************************************************************************/
    void I2C_SetSlaveAddress(INT8U address){
        slaveAddress = address;
    }

    /******************************************************************************
    * INT8U I2C_GetSlaveAddress(void) - Public
    *
    * PARAMETERS: none.
    *
    * RETURN: INT8U - slave address.
    *
    * DESCRIPTION: Returns current slave address.
    ******************************************************************************/
    INT8U I2C_GetSlaveAddress(void){
        return slaveAddress;
    }

    /******************************************************************************
    * INT8U I2C_SendStart(INT8U data) - Public
    *
    * PARAMETERS: INT8U data - 8-bit byte to send.
    *
    * RETURN: error code.  returns 1 if transmit was successful, 0 if failed.
    *
    * DESCRIPTION: Sends slave address and a single byte to the slave.  User must
    *              have previously set slave address using I2C_SetSlaveAddress().
    *              Function returns 0 if any bytes are not acknowledged by slave.
    *              This is a blocking routine. User is responsible for generating
    *              start and stop commands.
    ******************************************************************************/
    INT8U I2C_SendStart(INT8U data){
        I2C0_D = (I2C_GetSlaveAddress()<<1);    //Send slave address
        while(!(I2C0_S & I2C_S_IICIF_MASK));    //Wait for flag
                I2C0_S |= I2C_S_IICIF_MASK;     //Clear flag
        if(I2C0_S & I2C_S_RXAK_MASK){
            return 0;                           //RX NAK'd
        }

        I2C0_D = data;                          //Send data byte
        while(!(I2C0_S & I2C_S_IICIF_MASK));    //Wait for flag
                I2C0_S |= I2C_S_IICIF_MASK;     //Clear flag
        if(I2C0_S & I2C_S_RXAK_MASK){
            return 0;                           //RX NAK'd
        }
        return 1;
    }

    /******************************************************************************
    * INT8U I2C_Send_Char(INT8U data)
    *
    * PARAMETERS: INT8U data - 8-bit byte to send.
    *
    * RETURN: Returns a 1 if transmit was successful, 0 if failed.
    *
    * DESCRIPTION: Sends a single byte to the slave. Function returns 0 if any
    *              bytes are not acknowledged by slave.  This is a blocking
    *              routine. User is responsible for generating start and stop
    *              commands.
    ******************************************************************************/
    INT8U I2C_Send_Char(INT8U data){
        I2C0_D = data;                          //Send data byte
        while(!(I2C0_S & I2C_S_IICIF_MASK));    //Wait for flag
                I2C0_S |= I2C_S_IICIF_MASK;     //Clear flag
        if(I2C0_S & I2C_S_RXAK_MASK){
            return 0;                           //RX NAK'd
        }
        return 1;
    }
    

Previous Page