/* * Copyright (c) 2015, Freescale Semiconductor, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * o Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * o Neither the name of Freescale Semiconductor, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "i2c_imx.h" /******************************************************************************* * Constant ******************************************************************************/ static const uint32_t i2cClkDivTab[][2] = { {22, 0x20}, {24, 0x21}, {26, 0x22}, {28, 0x23}, {30, 0x00}, {32, 0x24}, {36, 0x25}, {40, 0x26}, {42, 0x03}, {44, 0x27}, {48, 0x28}, {52, 0x05}, {56, 0x29}, {60, 0x06}, {64, 0x2A}, {72, 0x2B}, {80, 0x2C}, {88, 0x09}, {96, 0x2D}, {104, 0x0A}, {112, 0x2E}, {128, 0x2F}, {144, 0x0C}, {160, 0x30}, {192, 0x31}, {224, 0x32}, {240, 0x0F}, {256, 0x33}, {288, 0x10}, {320, 0x34}, {384, 0x35}, {448, 0x36}, {480, 0x13}, {512, 0x37}, {576, 0x14}, {640, 0x38}, {768, 0x39}, {896, 0x3A}, {960, 0x17}, {1024, 0x3B}, {1152, 0x18}, {1280, 0x3C}, {1536, 0x3D}, {1792, 0x3E}, {1920, 0x1B}, {2048, 0x3F}, {2304, 0x1C}, {2560, 0x1D}, {3072, 0x1E}, {3840, 0x1F} }; /******************************************************************************* * Code ******************************************************************************/ /******************************************************************************* * I2C Initialization and Configuration functions ******************************************************************************/ /*FUNCTION********************************************************************** * * Function Name : I2C_Init * Description : Initialize I2C module with given initialize structure. * *END**************************************************************************/ void I2C_Init(I2C_Type* base, i2c_init_config_t* initConfig) { assert(initConfig); /* Disable I2C Module. */ I2C_I2CR_REG(base) &= ~I2C_I2CR_IEN_MASK; /* Reset I2C register to its default value. */ I2C_Deinit(base); /* Set I2C Module own Slave Address. */ I2C_SetSlaveAddress(base, initConfig->slaveAddress); /* Set I2C BaudRate according to i2c initialize struct. */ I2C_SetBaudRate(base, initConfig->clockRate, initConfig->baudRate); } /*FUNCTION********************************************************************** * * Function Name : I2C_Deinit * Description : This function reset I2C module register content to * its default value. * *END**************************************************************************/ void I2C_Deinit(I2C_Type* base) { /* Disable I2C Module */ I2C_I2CR_REG(base) &= ~I2C_I2CR_IEN_MASK; /* Reset I2C Module Register content to default value */ I2C_IADR_REG(base) = 0x0; I2C_IFDR_REG(base) = 0x0; I2C_I2CR_REG(base) = 0x0; } /*FUNCTION********************************************************************** * * Function Name : I2C_SetBaudRate * Description : This function is used to set the baud rate of I2C Module. * *END**************************************************************************/ void I2C_SetBaudRate(I2C_Type* base, uint32_t clockRate, uint32_t baudRate) { uint32_t clockDiv; uint8_t clkDivIndex = 0; assert(baudRate <= 400000); /* Calculate accurate baudRate divider. */ clockDiv = clockRate / baudRate; if (clockDiv < i2cClkDivTab[0][0]) { /* If clock divider is too small, using smallest legal divider */ clkDivIndex = 0; } else if (clockDiv > i2cClkDivTab[sizeof(i2cClkDivTab)/sizeof(i2cClkDivTab[0]) - 1][0]) { /* If clock divider is too large, using largest legal divider */ clkDivIndex = sizeof(i2cClkDivTab)/sizeof(i2cClkDivTab[0]) - 1; } else { while (i2cClkDivTab[clkDivIndex][0] < clockDiv) clkDivIndex++; } I2C_IFDR_REG(base) = i2cClkDivTab[clkDivIndex][1]; } /******************************************************************************* * I2C Bus Control functions ******************************************************************************/ /*FUNCTION********************************************************************** * * Function Name : I2C_SetAckBit * Description : This function is used to set the Transmit Acknowledge * action when receive data from other device. * *END**************************************************************************/ void I2C_SetAckBit(I2C_Type* base, bool ack) { if (ack) I2C_I2CR_REG(base) &= ~I2C_I2CR_TXAK_MASK; else I2C_I2CR_REG(base) |= I2C_I2CR_TXAK_MASK; } /******************************************************************************* * Interrupts and flags management functions ******************************************************************************/ /*FUNCTION********************************************************************** * * Function Name : I2C_SetIntCmd * Description : Enables or disables I2C interrupt requests. * *END**************************************************************************/ void I2C_SetIntCmd(I2C_Type* base, bool enable) { if (enable) I2C_I2CR_REG(base) |= I2C_I2CR_IIEN_MASK; else I2C_I2CR_REG(base) &= ~I2C_I2CR_IIEN_MASK; } /******************************************************************************* * EOF ******************************************************************************/