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/drivers/i2c.c

172 lines
4.6 KiB

#include "i2c.h"
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);
// Enables the i2c bus
RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2cHardware->channelNo]);
// Make sure that the periferal is disabled.
I2C_BASE->CR1 &= ~I2C_CR1_PE;
//Configure analog filter. Anlalog filter is on
I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF;
//Configure NoStrech Streching mode is disabled (slave only)
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
//Configure the clock
I2C_BASE->TIMINGR = i2cHardware->timing;
//Automatic end mode (master mode) disabled Enablede as default
I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
//I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
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
}
}
//activating the Perriferal.
I2C_BASE->CR1 |= I2C_CR1_PE;
i2cHardware->state = i2cInitialized;
}
void i2cDeInit(i2c_t *i2cHardware)
{
}
void i2cWrite(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data, uint8_t dataLenght)
{
}
void i2cRead( i2c_t *i2cHardware,
uint16_t *devAddress,
uint8_t *registerAddress,
uint8_t *data,
uint8_t dataLenght)
{
i2cHardware->state = i2cBusy;
switch(i2cHardware->mode)
{
case i2cModeMaster: // Implement for loops for more than one byte.
i2cMasterRecieve(i2cHardware, devAddress, registerAddress, data);
break;
case i2cModeSlave:
i2cSlaveRecieve(i2cHardware, devAddress, registerAddress, data);
break;
case i2cModeMultyMaster:
// TO implement
break;
default:
i2cThrowError(1);
}
}
// this function still doesn't implment 10 bit oopeartion TODO
void i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t registerAddress, uint8_t *data)
{
// Wait until no communication is ongoign
while((I2C_BASE->ISR & (I2C_ISR_BUSY))==I2C_ISR_BUSY);
i2cHardware->state = i2cTransmitting;
//Slave address
I2C_BASE->CR2 |= devAddress << 1; // The bit no 0 is not taken in concideration in 7bit mode
//Write Mode
I2C_BASE->CR2 &= ~I2C_CR2_RD_WRN;
//Set Buffer size
I2C_BASE->CR2 |= 1 << I2C_CR2_NBYTES_Pos;
//Generate start condition
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait until the start condition in generated.
while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
//Check if the TX buffer is empty
while(!(I2C_BASE->ISR & (I2C_ISR_TXE)));
//Register to be sent
I2C_BASE->TXDR |= registerAddress;
//Wait untill all is Transfered
while(!(I2C_BASE->ISR & (I2C_ISR_TXE)));
//Is the tranfes complete ?
while(!(I2C_BASE->ISR & (I2C_ISR_TC)));
i2cHardware->state = i2cRecieving;
//Read Mode
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
//Set Buffer size
I2C_BASE->CR2 |= 1 << I2C_CR2_NBYTES_Pos;
//New start condition to read from the slave
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait untill all is Transfered
while(!(I2C_BASE->ISR & (I2C_ISR_TXE)));
//Wait for the input buffer to be full
while(!(I2C_BASE->ISR & (I2C_ISR_RXNE)));
//NACK is generated automatically in master mode.
i2cCR1= I2C_BASE->CR1;
i2cCR2= I2C_BASE->CR2;
i2cISR= I2C_BASE->ISR;
// Sned stop command
I2C_BASE->CR2 |= I2C_CR2_STOP;
//read dtaa from the input register to clear it out
*data = I2C_BASE->RXDR;
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)
{
}