/*********************************************************************//** * @brief Set Own slave address in I2C peripheral corresponding to * parameter specified in OwnSlaveAddrConfigStruct. * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @param[in] OwnSlaveAddrConfigStruct Pointer to a I2C_OWNSLAVEADDR_CFG_Type * structure that contains the configuration information for the * specified I2C slave address. * @return None **********************************************************************/ void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct) { uint32_t tmp; CHECK_PARAM(PARAM_I2Cx(I2Cx)); CHECK_PARAM(PARAM_I2C_SLAVEADDR_CH(OwnSlaveAddrConfigStruct->SlaveAddrChannel)); CHECK_PARAM(PARAM_FUNCTIONALSTATE(OwnSlaveAddrConfigStruct->GeneralCallState)); tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \ | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK; switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel) { case 0: I2Cx->I2ADR0 = tmp; I2Cx->I2MASK0 = I2C_I2MASK_MASK((uint32_t) \ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); break; case 1: I2Cx->I2ADR1 = tmp; I2Cx->I2MASK1 = I2C_I2MASK_MASK((uint32_t) \ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); break; case 2: I2Cx->I2ADR2 = tmp; I2Cx->I2MASK2 = I2C_I2MASK_MASK((uint32_t) \ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); break; case 3: I2Cx->I2ADR3 = tmp; I2Cx->I2MASK3 = I2C_I2MASK_MASK((uint32_t) \ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); break; } }
/*********************************************************************//** * @brief De-initializes the I2C peripheral registers to their * default reset values. * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 :I2C0 peripheral * - LPC_I2C1 :I2C1 peripheral * @return None **********************************************************************/ void I2C_DeInit(LPC_I2Cn_Type* I2Cx) { CHECK_PARAM(PARAM_I2Cx(I2Cx)); /* Disable I2C control */ I2Cx->CONCLR = I2C_I2CONCLR_I2ENC; }
/*********************************************************************//** * @brief Enable or disable I2C peripheral's operation * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @param[in] NewState New State of I2Cx peripheral's operation * @return none **********************************************************************/ void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState) { CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); CHECK_PARAM(PARAM_I2Cx(I2Cx)); if (NewState == ENABLE) { I2Cx->I2CONSET = I2C_I2CONSET_I2EN; } else { I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; } }
/*********************************************************************//** * @brief Enable/Disable I2C monitor mode * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 * @param[in] NewState New State of this function, should be: * - ENABLE: Enable monitor mode. * - DISABLE: Disable monitor mode. * @return None **********************************************************************/ void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState) { CHECK_PARAM(PARAM_I2Cx(I2Cx)); CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); if (NewState == ENABLE) { I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; } else { I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK; } }
/*********************************************************************//** * @brief Configures functionality in I2C monitor mode * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @param[in] MonitorCfgType Monitor Configuration type, should be: * - I2C_MONITOR_CFG_SCL_OUTPUT: I2C module can 'stretch' * the clock line (hold it low) until it has had time to * respond to an I2C interrupt. * - I2C_MONITOR_CFG_MATCHALL: When this bit is set to '1' * and the I2C is in monitor mode, an interrupt will be * generated on ANY address received. * @param[in] NewState New State of this function, should be: * - ENABLE: Enable this function. * - DISABLE: Disable this function. * @return None **********************************************************************/ void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState) { CHECK_PARAM(PARAM_I2Cx(I2Cx)); CHECK_PARAM(PARAM_I2C_MONITOR_CFG(MonitorCfgType)); CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); if (NewState == ENABLE) { I2Cx->MMCTRL |= MonitorCfgType; } else { I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK; } }
/*********************************************************************//** * @brief Enable/Disable I2C monitor mode * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @param[in] NewState New State of this function, should be: * - ENABLE: Enable monitor mode. * - DISABLE: Disable monitor mode. * @return None **********************************************************************/ void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState) { CHECK_PARAM(PARAM_I2Cx(I2Cx)); CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); if (NewState == ENABLE) { I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; I2Cx->I2CONSET = I2C_I2CONSET_AA; I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; } else { I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK; I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_AAC; } I2C_MonitorBufferIndex = 0; }
/********************************************************************//** * @brief Initializes the I2Cx peripheral with specified parameter. * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 :I2C0 peripheral * - LPC_I2C1 :I2C1 peripheral * @param[in] clockrate Target clock rate value to initialized I2C * peripheral (Hz) * @return None *********************************************************************/ void I2C_Init(LPC_I2Cn_Type *I2Cx, uint32_t clockrate) { uint32_t tem; CHECK_PARAM(PARAM_I2Cx(I2Cx)); if (I2Cx==LPC_I2C0) { /* Set up clock for I2C0 module */ //LPC_CGU->BASE_VPB1_CLK = (SRC_PL160M_0<<24) | (1<<11); CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_APB1); /* Select weather standard, fast, fast plus mode*/ if(clockrate>=1000000)// Fast mode plus: 1MHz, high speed 3.4MHz LPC_SCU->SFSI2C0 = SFSI2C0_CONFIGURE_FASTPLUS_HIGHSPEED_MODE; else // standard 100KHz, fast 400KHz LPC_SCU->SFSI2C0 = SFSI2C0_CONFIGURE_STANDARD_FAST_MODE; } else if (I2Cx==LPC_I2C1) { /* Set up clock for I2C1 module */ //LPC_CGU->BASE_VPB3_CLK = (SRC_PL160M_0<<24) | (1<<11); CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_APB3); /* Configure pin function for I2C1*/ LPC_SCU->SFSP2_3 = SFSP2_3_CONFIGURE_I2C1_SDA; /* SDA */ LPC_SCU->SFSP2_4 = SFSP2_4_CONFIGURE_I2C1_SCL; /* SCL */ /* Check if I2C1 run fast mode*/ if(clockrate != 400000) return; } else { // Up-Support this device return; } /* Set clock rate */ if(clockrate<1000) //make sure SCLH,SCLL not exceed its 16bit value return; tem = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M3CORE) / clockrate; I2Cx->SCLH = (uint32_t)(tem / 2); I2Cx->SCLL = (uint32_t)(tem - I2Cx->SCLH); /* Set I2C operation to default */ I2Cx->CONCLR = (I2C_I2CONCLR_AAC |I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC); }
/********************************************************************//** * @brief Initializes the I2Cx peripheral with specified parameter. * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @param[in] clockrate Target clock rate value to initialized I2C * peripheral (Hz) * @return None *********************************************************************/ void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate) { CHECK_PARAM(PARAM_I2Cx(I2Cx)); if (I2Cx==LPC_I2C0) { /* Set up clock and power for I2C0 module */ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE); /* As default, peripheral clock for I2C0 module * is set to FCCLK / 2 */ CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C0, CLKPWR_PCLKSEL_CCLK_DIV_2); } else if (I2Cx==LPC_I2C1) { /* Set up clock and power for I2C1 module */ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, ENABLE); /* As default, peripheral clock for I2C1 module * is set to FCCLK / 2 */ CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C1, CLKPWR_PCLKSEL_CCLK_DIV_2); } else if (I2Cx==LPC_I2C2) { /* Set up clock and power for I2C2 module */ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, ENABLE); /* As default, peripheral clock for I2C2 module * is set to FCCLK / 2 */ CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C2, CLKPWR_PCLKSEL_CCLK_DIV_2); } else { // Up-Support this device return; } /* Set clock rate */ I2C_SetClock(I2Cx, clockrate); /* Set I2C operation to default */ I2Cx->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC); }
/*********************************************************************//** * @brief De-initializes the I2C peripheral registers to their * default reset values. * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @return None **********************************************************************/ void I2C_DeInit(LPC_I2C_TypeDef* I2Cx) { CHECK_PARAM(PARAM_I2Cx(I2Cx)); /* Disable I2C control */ I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; if (I2Cx==LPC_I2C0) { /* Disable power for I2C0 module */ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, DISABLE); } else if (I2Cx==LPC_I2C1) { /* Disable power for I2C1 module */ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, DISABLE); } else if (I2Cx==LPC_I2C2) { /* Disable power for I2C2 module */ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, DISABLE); } }
/*********************************************************************//** * @brief Setup clock rate for I2C peripheral * @param[in] I2Cx I2C peripheral selected, should be: * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @param[in] target_clock : clock of SSP (Hz) * @return None ***********************************************************************/ static void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock) { uint32_t temp; CHECK_PARAM(PARAM_I2Cx(I2Cx)); // Get PCLK of I2C controller if (I2Cx == LPC_I2C0) { temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C0) / target_clock; } else if (I2Cx == LPC_I2C1) { temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; } else if (I2Cx == LPC_I2C2) { temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C2) / target_clock; } /* Set the I2C clock value to register */ I2Cx->I2SCLH = (uint32_t)(temp / 2); I2Cx->I2SCLL = (uint32_t)(temp - I2Cx->I2SCLH); }
/*********************************************************************//** * @brief Get data from I2C data buffer in monitor mode. * @param[in] I2Cx I2C peripheral selected, should be * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @return None * Note: In monitor mode, the I2C module may lose the ability to stretch * the clock (stall the bus) if the ENA_SCL bit is not set. This means that * the processor will have a limited amount of time to read the contents of * the data received on the bus. If the processor reads the I2DAT shift * register, as it ordinarily would, it could have only one bit-time to * respond to the interrupt before the received data is overwritten by * new data. **********************************************************************/ uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx) { CHECK_PARAM(PARAM_I2Cx(I2Cx)); return ((uint8_t)(I2Cx->I2DATA_BUFFER)); }