You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
KED/env/csl/stm32f042/Src/imp_i2c.c

302 lines
7.5 KiB

/**
**************************************************************************************************
* @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"
#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2cHardware->channelNo])
uint8_t temp8 = 0;
uint16_t temp16 = 0;
void i2cEnableHardware(i2c_t *i2cHardware)
{
i2cHardwareReset(i2cHardware);
// Enables the i2c bus
RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2cHardware->channelNo]);
pinInit(pinA9);
pinInit(pinA10);
pinConfig(pinA9, alternate, openDrain, pullUp, fast);// I2C SCL
pinConfig(pinA10, alternate, openDrain, pullUp, fast);// I2C CSA
pinSetAlternate(pinA9, 4);
pinSetAlternate(pinA10, 4);
}
void i2cHardwareReset(i2c_t *i2cHardware)
{
// Resete the I2C hardware using the reset registers,
RCC->APB1RSTR |= (1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
}
void i2cEnablePeriferal(i2c_t *i2cHardware)
{
I2C_BASE->CR1 |= I2C_CR1_PE;
}
void i2cDisablePeriferal(i2c_t *i2cHardware)
{
I2C_BASE->CR1 &= ~I2C_CR1_PE;
}
void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode)
{
//This device will set himself automatically to master mode
if(i2cHardware->mode == i2cModeMaster)
{
//Automatic end mode (master mode) disabled Enablede as default
I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
//I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
}
else if(i2cHardware->mode == i2cModeSlave)
{
// to be written.
}
}
void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress)
{
}
void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size)
{
if(i2cHardware->mode == i2cModeMaster)
{
if(i2cHardware->addressSize == i2cAddressSizeTenBits)
{
I2C_BASE->CR2 |= I2C_CR2_ADD10; // 10 Bit addressing
I2C_BASE->CR2 &= ~I2C_CR2_HEAD10R; // 7 Bit header read turned on DEFAULT
}
else
{
I2C_BASE->CR2 &= ~I2C_CR2_ADD10; // 7 Bit addressing DEFAULT
I2C_BASE->CR2 |= I2C_CR2_HEAD10R; // 7 Bit header read turned off DEFAULT
}
}
else if(i2cHardware->mode == i2cModeSlave)
{
// to be written.
}
}
void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching)
{
if(i2cHardware->stretching == i2cClockStretchingEnable)
{
I2C_BASE->CR1 &=~ I2C_CR1_NOSTRETCH;
}
else if(i2cHardware->stretching == i2cClockStretchingDisable)
{
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
}
}
void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed)
{
switch(speed)
{
case i2cSpeedStandart:
I2C_BASE->TIMINGR = 0x2000090E;
break;
case i2cSpeedFast:
break;
case i2cSpeedFastPlus:
break;
case i2cSpeedHightSpeed:
break;
case i2cSpeedUltraFast:
break;
default:
break;
}
}
void i2cConfigureFilters(i2c_t *i2cHardware)
{
//Anlalog filter is on
I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF;
}
/**************************************************************************************************
I2C Hardware functions
***************************************************************************************************/
void i2cGenerateStart(i2c_t *i2cHardware)
{
I2C_BASE->CR2 &=~ I2C_CR2_STOP;
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait until the start condition in generated.
while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
i2cHardware->hardwareState = i2cHwStartGenerated;
// This device places the salve address automaticalyy in the output buffer before sending the star condition
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
void i2cGenerateStop(i2c_t *i2cHardware)
{
// Send stop command
I2C_BASE->CR2 |= I2C_CR2_STOP;
I2C_BASE->CR2 &=~ I2C_CR2_START;
i2cHardware->hardwareState = i2cHwStopGenerated;
}
void i2cIsPeriferalReady(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_BUSY))!=I2C_ISR_BUSY)
{
i2cHardware->periferalState = i2cPerifReady;
}
}
void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count)
{
I2C_BASE->CR2 &= ~(0xFF << I2C_CR2_NBYTES_Pos);
I2C_BASE->CR2 |= (count << I2C_CR2_NBYTES_Pos);
}
void i2cSendSlaveAddress(i2c_t *i2cHardware, uint16_t *slaveAddress)
{
// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode
i2cGenerateStart(i2cHardware);
// Wait until the data in the ouput buffer is put to the i2c BUS
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
{
i2cIsOutputBufferEmpty(i2cHardware);
}
}
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress)
{
i2cSendData(i2cHardware,registerAddress);
}
void i2cInitiateWriteCommand(i2c_t *i2cHardware)
{
I2C_BASE->CR2 &= ~I2C_CR2_RD_WRN;
}
void i2cInitiateReadCommand(i2c_t *i2cHardware)
{
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
}
void i2cSendData(i2c_t *i2cHardware, uint8_t *registerAddress)
{
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
{
i2cIsOutputBufferEmpty(i2cHardware);
}
i2cSetOutputRegister(i2cHardware,registerAddress);
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
{
i2cIsOutputBufferEmpty(i2cHardware);
}
}
void i2cIsOutputBufferEmpty(i2c_t *i2cHardware)
{
if((i2cHardware->periferalState) == i2cPerifTransmitting)
{
if((I2C_BASE->ISR & (I2C_ISR_TXIS)) == I2C_ISR_TXIS)
{
i2cHardware->hardwareState = i2cHwOutputBufferEmpty;
}
else
{
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
}
else if((i2cHardware->periferalState) == i2cPerifRecieving)
{
if((I2C_BASE->ISR & (I2C_ISR_TXE)) == I2C_ISR_TXE)
{
i2cHardware->hardwareState = i2cHwOutputBufferEmpty;
}
else
{
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
}
}
void i2cIsInputBufferEmpty(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_RXNE)) == I2C_ISR_RXNE)
{
i2cHardware->hardwareState = i2cHwInputBufferFull;
}
else
{
i2cHardware->hardwareState = i2cHwInputBufferEmpty;
}
}
void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data)
{
*data = I2C_BASE->RXDR;
}
void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data)
{
I2C_BASE->TXDR = *data;
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
void i2cIsTransferComplete(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_TC)) == I2C_ISR_TC)
{
i2cHardware->periferalState = i2cPerifTransferComplete;
}
else
{
i2cHardware->periferalState = i2cPerifTransferOngoign;
}
}
void i2cGenerateNack(i2c_t *i2cHardware)
{
if(i2cHardware->mode == i2cModeMaster)
{
//IN master mode this ic geretes NACK's otomatically
i2cHardware->hardwareState = i2cHwSentNack;
}
else if(i2cHardware->mode == i2cModeSlave)
{
// to be written.
}
}