|
|
@ -1,30 +1,19 @@
|
|
|
|
/**
|
|
|
|
|
|
|
|
**************************************************************************************************
|
|
|
|
|
|
|
|
* @file i2c.c
|
|
|
|
|
|
|
|
* @author Kerem Yollu & Edwin Koch
|
|
|
|
|
|
|
|
* @date 18.07.2022
|
|
|
|
|
|
|
|
* @version 1.0
|
|
|
|
|
|
|
|
**************************************************************************************************
|
|
|
|
|
|
|
|
* @brief I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
|
|
|
|
|
|
|
|
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
|
|
|
|
|
|
|
|
* This will also not have a I3C support for the forseable futrue. This code is generated for the stm32f4xK6 series of mcu for stm
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* **Detailed Description :**
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
|
|
|
|
|
|
|
|
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
|
|
|
|
|
|
|
|
* This will also not have a I3C support for the forseable futrue.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @todo
|
|
|
|
|
|
|
|
* - 18.07.2021 : Implement the i2c.c
|
|
|
|
|
|
|
|
**************************************************************************************************
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "i2c.h"
|
|
|
|
#include "i2c.h"
|
|
|
|
#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2cHardware->channelNo])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void i2cInit(i2c_t *i2cHardware)
|
|
|
|
void i2cInit( i2c_t *i2cHardware, /*!< Pointer to I2C hardware Object */
|
|
|
|
|
|
|
|
i2cCh_t channelNo, /*!< The harware channel to be used */
|
|
|
|
|
|
|
|
i2cMode_t mode, /*!< Master, Slave or Multymaster Modes */
|
|
|
|
|
|
|
|
uint16_t address, /*!< First and Main address of the device */
|
|
|
|
|
|
|
|
uint16_t addressSecond, /*!< Second address if dual addresse mode is configured */
|
|
|
|
|
|
|
|
i2cAddressCount_t addressCount, /*!< Single or multiple */
|
|
|
|
|
|
|
|
i2cAddressSize_t addressSize, /*!< 10 or 7 bit address size */
|
|
|
|
|
|
|
|
i2cSpeed_t speed, /*!< Bus Speed */
|
|
|
|
|
|
|
|
i2cOpperationMode_t opperationMode, /*!< Blocking or non blocking polling, Int or DMA */
|
|
|
|
|
|
|
|
i2cClockStreching_t streching, /*!< Clock Streching enable onyl in slave mode */
|
|
|
|
|
|
|
|
i2cWakeUpTypes_t wakeOn /*!< Wake up condition */
|
|
|
|
|
|
|
|
)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
i2cReset(i2cHardware);
|
|
|
|
i2cReset(i2cHardware);
|
|
|
|
|
|
|
|
|
|
|
|
// Enables the i2c bus
|
|
|
|
// Enables the i2c bus
|
|
|
@ -34,16 +23,16 @@ void i2cInit(i2c_t *i2cHardware)
|
|
|
|
I2C_BASE->CR1 &= ~I2C_CR1_PE;
|
|
|
|
I2C_BASE->CR1 &= ~I2C_CR1_PE;
|
|
|
|
|
|
|
|
|
|
|
|
//Configure analog filter. Anlalog filter is on
|
|
|
|
//Configure analog filter. Anlalog filter is on
|
|
|
|
I2C_BASE->CR1 |= I2C_CR1_ANFOFF;
|
|
|
|
I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF;
|
|
|
|
|
|
|
|
|
|
|
|
//Configure NoStrech Streching mode is disabled (slave only)
|
|
|
|
//Configure NoStrech Streching mode is disabled (slave only)
|
|
|
|
//I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
|
|
|
|
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
|
|
|
|
|
|
|
|
|
|
|
|
//Configure the clock
|
|
|
|
//Configure the clock
|
|
|
|
I2C_BASE->TIMINGR = i2cHardware->timing;
|
|
|
|
I2C_BASE->TIMINGR = i2cHardware->timing;
|
|
|
|
|
|
|
|
|
|
|
|
//Automatic end mode (master mode) Enablede as default
|
|
|
|
//Automatic end mode (master mode) disabled Enablede as default
|
|
|
|
//I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
|
|
|
|
I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
|
|
|
|
//I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
|
|
|
|
//I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
|
|
|
|
|
|
|
|
|
|
|
|
if(i2cHardware->mode == i2cModeMaster)
|
|
|
|
if(i2cHardware->mode == i2cModeMaster)
|
|
|
@ -63,17 +52,16 @@ void i2cInit(i2c_t *i2cHardware)
|
|
|
|
//activating the Perriferal.
|
|
|
|
//activating the Perriferal.
|
|
|
|
I2C_BASE->CR1 |= I2C_CR1_PE;
|
|
|
|
I2C_BASE->CR1 |= I2C_CR1_PE;
|
|
|
|
|
|
|
|
|
|
|
|
i2cCR1= I2C_BASE->CR1;
|
|
|
|
|
|
|
|
i2cCR2= I2C_BASE->CR2;
|
|
|
|
|
|
|
|
i2cISR= I2C_BASE->ISR;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
i2cHardware->state = i2cInitialized;
|
|
|
|
i2cHardware->state = i2cInitialized;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void i2cDeInit(i2c_t *i2cHardware)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void i2cReset(i2c_t *i2cHardware)
|
|
|
|
void i2cWrite(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data, uint8_t dataLenght)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
RCC->APB1RSTR |= (1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
|
|
|
|
|
|
|
|
RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void i2cRead( i2c_t *i2cHardware,
|
|
|
|
void i2cRead( i2c_t *i2cHardware,
|
|
|
@ -100,12 +88,13 @@ void i2cRead( i2c_t *i2cHardware,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// this function still doesn't implment 10 bit oopeartion TODO
|
|
|
|
// this function still doesn't implment 10 bit oopeartion TODO
|
|
|
|
uint8_t i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t registerAddress, uint8_t *data)
|
|
|
|
void i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t registerAddress, uint8_t *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// Wait until no communication is ongoign
|
|
|
|
// Wait until no communication is ongoign
|
|
|
|
while((I2C_BASE->ISR & (I2C_ISR_BUSY))==I2C_ISR_BUSY);
|
|
|
|
while((I2C_BASE->ISR & (I2C_ISR_BUSY))==I2C_ISR_BUSY);
|
|
|
|
|
|
|
|
|
|
|
|
i2cHardware->state = i2cRecieving;
|
|
|
|
i2cHardware->state = i2cTransmitting;
|
|
|
|
|
|
|
|
|
|
|
|
//Slave address
|
|
|
|
//Slave address
|
|
|
|
I2C_BASE->CR2 |= devAddress << 1; // The bit no 0 is not taken in concideration in 7bit mode
|
|
|
|
I2C_BASE->CR2 |= devAddress << 1; // The bit no 0 is not taken in concideration in 7bit mode
|
|
|
@ -131,11 +120,11 @@ uint8_t i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t registe
|
|
|
|
//Wait untill all is Transfered
|
|
|
|
//Wait untill all is Transfered
|
|
|
|
while(!(I2C_BASE->ISR & (I2C_ISR_TXE)));
|
|
|
|
while(!(I2C_BASE->ISR & (I2C_ISR_TXE)));
|
|
|
|
|
|
|
|
|
|
|
|
// working well up to this point
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Is the tranfes complete ?
|
|
|
|
//Is the tranfes complete ?
|
|
|
|
while(!(I2C_BASE->ISR & (I2C_ISR_TC)));
|
|
|
|
while(!(I2C_BASE->ISR & (I2C_ISR_TC)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
i2cHardware->state = i2cRecieving;
|
|
|
|
|
|
|
|
|
|
|
|
//Read Mode
|
|
|
|
//Read Mode
|
|
|
|
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
|
|
|
|
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
|
|
|
|
|
|
|
|
|
|
|
@ -160,6 +149,23 @@ uint8_t i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t registe
|
|
|
|
I2C_BASE->CR2 |= I2C_CR2_STOP;
|
|
|
|
I2C_BASE->CR2 |= I2C_CR2_STOP;
|
|
|
|
|
|
|
|
|
|
|
|
//read dtaa from the input register to clear it out
|
|
|
|
//read dtaa from the input register to clear it out
|
|
|
|
data = I2C_BASE->RXDR;
|
|
|
|
*data = I2C_BASE->RXDR;
|
|
|
|
return data;
|
|
|
|
|
|
|
|
|
|
|
|
i2cHardware->state = i2cReady;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void i2cMasterSend(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|