| /* |
| * 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, const 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 |
| ******************************************************************************/ |