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/ked/csl/stm32f042/Src/imp_i2c.c

272 lines
6.4 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"
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 i2cWaitForPeriferal(i2c_t *i2cHardware)
{
while(i2cHardware->state != i2cReady)
{
i2cIsPeriferalReady(i2cHardware);
}
}
void i2cIsPeriferalReady(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_BUSY))!=I2C_ISR_BUSY)
{
i2cHardware->state = i2cReady;
}
else
{
i2cHardware->state = i2cBusy;
}
}
void i2cSendSlaveAddress(i2c_t *i2cHardware, uint16_t slaveAddress)
{
if(i2cHardware->addressSize == i2cAddressSizeSevenBits)
{
// 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
//Set Buffer size / which is alredy full with the device address to be sent
I2C_BASE->CR2 |= 1 << I2C_CR2_NBYTES_Pos;
}
else if(i2cHardware->addressSize == i2cAddressSizeTenBits)
{
//to implement
}
i2cGenerateStart(i2cHardware);
// Wait until the data in the ouput buffer is put to the i2c BUS
while(i2cHardware->state == i2cOutputBufferFull)
{
i2cIsOutputBufferEmpty(i2cHardware);
}
}
void i2cGenerateStart(i2c_t *i2cHardware)
{
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait until the start condition in generated.
while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
i2cHardware->state = i2cStartGenrated;
// This device places the salve address automaticalyy in the buffer before sending the star condition
i2cHardware->state = i2cOutputBufferFull;
}
void i2cGenerateStop(i2c_t *i2cHardware)
{
// Sned stop command
I2C_BASE->CR2 |= I2C_CR2_STOP;
}
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 i2cIsOutputBufferEmpty(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_TXE)) == I2C_ISR_TXE)
{
i2cHardware->state = i2cOutputBufferEmpty;
}
else
{
i2cHardware->state = i2cOutputBufferFull;
}
}
void i2cIsInputBufferEmpty(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_RXNE)) == I2C_ISR_RXNE)
{
i2cHardware->state = i2cInputBufferFull;
}
else
{
i2cHardware->state = i2cInputBufferEmpty;
}
}
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t registerAddress)
{
//Register to be sent
I2C_BASE->TXDR |= registerAddress;
i2cHardware->state = i2cOutputBufferFull;
while(i2cHardware->state == i2cOutputBufferFull)
{
i2cIsOutputBufferEmpty(i2cHardware);
}
}
void i2cGenerateNack(i2c_t *i2cHardware)
{
if(i2cHardware->mode == i2cModeMaster)
{
//IN master mode this ic geretes NACK's otomatically
}
else if(i2cHardware->mode == i2cModeSlave)
{
// to be written.
}
}