sarted with the i2c Driver implmentation functions

i2c
kerem 3 years ago
parent 913663516e
commit 5192d05b68

@ -76,12 +76,12 @@ typedef enum{
/*! Enum for clock strechning activation. Can only be implmented as Slave /*! Enum for clock strechning activation. Can only be implmented as Slave
* for more information : https://www.i2c-bus.org/clock-stretching/ */ * for more information : https://www.i2c-bus.org/clock-stretching/ */
typedef enum{ typedef enum{
i2cClockStrechingDisable, /*!< We assume that the master and slave have compatible i2cClockStretchingDisable, /*!< We assume that the master and slave have compatible
Clock frequencies **DEFAULT** */ Clock frequencies **DEFAULT** */
i2cClockStrechingEnable /*!< In situations where an I2C slave is not able to co-operate i2cClockStretchingEnable /*!< In situations where an I2C slave is not able to co-operate
with the clock speed given by the master and needs to slow down. with the clock speed given by the master and needs to slow down.
This is done by a mechanism referred to as clock stretching. */ This is done by a mechanism referred to as clock stretching. */
}i2cClockStreching_t; }i2cClockStretching_t;
/*! Enum for diffenrent wake up methodes wehnin sleep mode */ /*! Enum for diffenrent wake up methodes wehnin sleep mode */
typedef enum{ typedef enum{
@ -106,8 +106,15 @@ typedef enum
{ {
i2cNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */ i2cNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */
i2cInitialized, /*!< I2C CHannle is initilized but not neceserly ready */ i2cInitialized, /*!< I2C CHannle is initilized but not neceserly ready */
i2cStartGenrated, /*!< Generated the star condition */
i2cSlaveAddressSent, /*!< The Salve Address Was Sent to the bus */
i2cOutputBufferFull, /*!< The output buffer of the I2C Periferal is Full */
i2cOutputBufferEmpty, /*!< The output buffer of the I2C Periferal is Empty */
i2cInputBufferFull, /*!< The input buffer of the I2C Periferal Is Full */
i2cInputBufferEmpty, /*!< The input buffer of the I2C Periferal Is Empty */
i2cReady, /*!< Peripheral Initialized and ready for use */ i2cReady, /*!< Peripheral Initialized and ready for use */
i2cBusy, /*!< An internal process is ongoing */ i2cBusy, /*!< An internal process is ongoing */
i2cSlaveNotFound, /*!< Desired Slave was not able to be found */
i2cTransmitting, /*!< Data Transmission process is ongoing */ i2cTransmitting, /*!< Data Transmission process is ongoing */
i2cRecieving, /*!< Data Reception process is ongoing */ i2cRecieving, /*!< Data Reception process is ongoing */
i2cListening, /*!< Address Listen Mode is ongoing */ i2cListening, /*!< Address Listen Mode is ongoing */
@ -123,17 +130,13 @@ typedef struct i2c_t
{ {
i2cCh_t channelNo; /*!< The harware channel to be used */ i2cCh_t channelNo; /*!< The harware channel to be used */
i2cMode_t mode; /*!< Master, Slave or Multymaster Modes */ i2cMode_t mode; /*!< Master, Slave or Multymaster Modes */
uint16_t address; /*!< First and Main address of the device */ uint16_t mainAddress; /*!< First and Main address of the device */
uint16_t addressSecond; /*!< Second address if dual addresse mode is configured */ uint16_t secondAddress; /*!< Second address if dual addresse mode is configured */
i2cAddressCount_t addressCount; /*!< Single or multiple */ i2cAddressCount_t addressCount; /*!< Single or multiple */
i2cAddressSize_t addressSize; /*!< 10 or 7 bit address size */ i2cAddressSize_t addressSize; /*!< 10 or 7 bit address size */
i2cSpeed_t speed; /*!< Bus Speed */ i2cSpeed_t speed; /*!< Bus Speed */
i2cOpperationMode_t opperationMode; /*!< Blocking or non blocking polling, Int or DMA */ i2cOpperationMode_t opperationMode; /*!< Blocking or non blocking polling, Int or DMA */
i2cClockStreching_t streching; /*!< Clock Streching enable onyl in slave mode */ i2cClockStretching_t stretching; /*!< Clock Stretching enable onyl in slave mode */
uint32_t timing; /*!< Specifies the I2C timing. The timings must be
configured in order to guarantee a correct
data hold and setup time,
used in master and slave modes. */
i2cWakeUpTypes_t wakeOn; /*!< Define on which type of action the i2c channel should i2cWakeUpTypes_t wakeOn; /*!< Define on which type of action the i2c channel should
wake up. Only if de prefiral goes to sleep */ wake up. Only if de prefiral goes to sleep */
i2cState_t state; /*!< The current sitate of the I2C Bus */ i2cState_t state; /*!< The current sitate of the I2C Bus */
@ -150,13 +153,13 @@ typedef struct i2c_t
void i2cInit( i2c_t *i2cHardware, /*!< Pointer to I2C hardware Object */ void i2cInit( i2c_t *i2cHardware, /*!< Pointer to I2C hardware Object */
i2cCh_t channelNo, /*!< The harware channel to be used */ i2cCh_t channelNo, /*!< The harware channel to be used */
i2cMode_t mode, /*!< Master, Slave or Multymaster Modes */ i2cMode_t mode, /*!< Master, Slave or Multymaster Modes */
uint16_t address, /*!< First and Main address of the device */ uint16_t mainAddress, /*!< First and Main address of the device */
uint16_t addressSecond, /*!< Second address if dual addresse mode is configured */ uint16_t secondAddress, /*!< Second address if dual addresse mode is configured */
i2cAddressCount_t addressCount, /*!< Single or multiple */ i2cAddressCount_t addressCount, /*!< Single or multiple */
i2cAddressSize_t addressSize, /*!< 10 or 7 bit address size */ i2cAddressSize_t addressSize, /*!< 10 or 7 bit address size */
i2cSpeed_t speed, /*!< Bus Speed */ i2cSpeed_t speed, /*!< Bus Speed */
i2cOpperationMode_t opperationMode, /*!< Blocking or non blocking polling, Int or DMA */ i2cOpperationMode_t opperationMode, /*!< Blocking or non blocking polling, Int or DMA */
i2cClockStreching_t streching, /*!< Clock Streching enable onyl in slave mode */ i2cClockStretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
i2cWakeUpTypes_t wakeOn /*!< Wake up condition */ i2cWakeUpTypes_t wakeOn /*!< Wake up condition */
); );
@ -176,11 +179,17 @@ void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode);
/** /**
* @brief Set the i2c channles mode as Master Slave or Multymaster * @brief Set the i2c channles mode as Master Slave or Multymaster
* @param i2cHardware is the i2c hardware channel * @param i2cHardware is the i2c hardware channel
* @param size Is the Adress isze to be used 7 Bit or 10 Bit
* @param addressOne The forst address for the device * @param addressOne The forst address for the device
* @param addressTwo The second address for the device only if dual address mode is not defined * @param addressTwo The second address for the device only if dual address mode is not defined
*/ */
void i2cSetAddress(i2c_t *i2cHardware, i2cAddressSize_t size, uint16_t addressOne, uint16_t addressTwo); void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress);
/**
* @brief Set the i2c Address Lenght, 7 bit or 8 bit, Master or slave doesn't make any difference
* @param i2cHardware is the i2c hardware channel
* @param size Is the Adress isze to be used 7 Bit or 10 Bit
*/
void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size);
/** /**
* @brief Stets the Communication speed * @brief Stets the Communication speed
@ -196,13 +205,13 @@ void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed);
*/ */
void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation); void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
/** /**
* @brief Sets the finetuning of the Timings for the communication some standards as * @brief Ebales or disables clock stretching functionalities
* SMBUS have different timing requirements
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param The value to be written in the register. This will heavily depend on the hardware * @param The value to be written in the register. This will heavily depend on the hardware
*/ */
void i2cSetTimings(i2c_t *i2cHardware, uint32_t timing); void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching);
/** /**
* @brief Set the wakeup mode * @brief Set the wakeup mode
@ -211,6 +220,12 @@ void i2cSetTimings(i2c_t *i2cHardware, uint32_t timing);
*/ */
void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake); void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake);
/**
* @brief Configures Hardware implmente filters if there are any.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cConfigureFilters(i2c_t *i2cHardware);
/** /**
* @brief Set the timeout to close the i2c wait time if a communication fails. * @brief Set the timeout to close the i2c wait time if a communication fails.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
@ -218,7 +233,6 @@ void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake);
*/ */
void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout); void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
/** /**
* @brief Resets the i2c Periferal to it's inital state. * @brief Resets the i2c Periferal to it's inital state.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
@ -226,10 +240,28 @@ void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
void i2cPeriferalReset(i2c_t *i2cHardware); void i2cPeriferalReset(i2c_t *i2cHardware);
/** /**
* @brief Resets the i2c to it's inital state. * @brief Resets the i2c Harware and register to it's factory deflauts.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/ */
void i2cReset(i2c_t *i2cHardware); void i2cHardwareReset(i2c_t *i2cHardware);
/**
* @brief Enables I2C Hardware BUS & Clock & Pins
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cEnableHardware(i2c_t *i2cHardware);
/**
* @brief Enables I2C Periferal core.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cEnablePeriferal(i2c_t *i2cHardware);
/**
* @brief Disables I2C Periferal core.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cDisablePeriferal(i2c_t *i2cHardware);
/************************************************************************************************** /**************************************************************************************************
I2C Communication functions independen of opperating mode I2C Communication functions independen of opperating mode
@ -269,7 +301,7 @@ void i2cRead(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress,
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red * @param data is the data whic has been red
*/ */
void i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t registerAddress, uint8_t *data); void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t slaveAddress, uint8_t registerAddress, uint8_t *data);
/** /**
* @brief Sends a Single Byte as master to the given devices register. * @brief Sends a Single Byte as master to the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) * this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
@ -300,12 +332,85 @@ void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *register
*/ */
void i2cSlaveSend(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);
/**************************************************************************************************
I2C Hardware functions
***************************************************************************************************/
/** /**
* @brief Initiates a Start condition. * @brief Checks if the device is ready for any type of communication
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/ */
void i2cSendStart(i2c_t *i2cHardware); void i2cIsPeriferalReady(i2c_t *i2cHardware);
/**
* @brief Checks if the device is ready for any type of communication
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cWaitForPeriferal(i2c_t *i2cHardware);
/**
* @brief Generates a Start condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateStart(i2c_t *i2cHardware);
/**
* @brief Generates a Start condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateStop(i2c_t *i2cHardware);
/**
* @brief Generates a NACK condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateNack(i2c_t *i2cHardware);
/**
* @brief Generates a ACK condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateAck(i2c_t *i2cHardware);
/**
* @brief Initiates the communication protocl by sending the slave address on the bus and waits
* for an ACK (aknowledge)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress The address of the slave to be communicated
*/
void i2cSendSlaveAddress(i2c_t *i2cHardware, uint16_t slaveAddress);
/**
* @brief Send the register that we want to read or write.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param registerAddress the register that need to be accessed
*/
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t registerAddress);
/**
* @brief Initiates a Write command with the previously set slave address.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cInitiateWriteCommand(i2c_t *i2cHardware);
/**
* @brief Initiates a read command with the previously set slave address.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cInitiateReadCommand(i2c_t *i2cHardware);
/**
* @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cIsOutputBufferEmpty(i2c_t *i2cHardware);
/**
* @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cIsInputBufferEmpty(i2c_t *i2cHardware);
/************************************************************************************************** /**************************************************************************************************
I2C Communication functions Polling / Blocking Mode I2C Communication functions Polling / Blocking Mode
***************************************************************************************************/ ***************************************************************************************************/
@ -346,11 +451,10 @@ void i2cSlaveRecievePolling(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *r
void i2cSlaveSendPolling(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data); void i2cSlaveSendPolling(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data);
/************************************************************************************************** /**************************************************************************************************
I2C Arbitration Functions for Multymaster mode and slaves clock streching I2C Arbitration Functions for Multymaster mode and slaves clock stretching
***************************************************************************************************/ ***************************************************************************************************/
void i2cClockSynchronise(); // I2C Standart : Clock Syncronization void i2cClockSynchronise(); // I2C Standart : Clock Syncronization
void i2cAbortTransmit(); // I2c Standart : Stop Communication for multimaster mode void i2cAbortTransmit(); // I2c Standart : Stop Communication for multimaster mode
void i2cClockStretch(); // I2C Standart : Optional For Pausing Communication because treatement takes longer than the communication
void i2cArbitration(); // I2C Standart : Arbitration for multimaster mode to define the right master. void i2cArbitration(); // I2C Standart : Arbitration for multimaster mode to define the right master.
void i2cSoftReset(); // I2C Standart : Software reset not supported by all hardware. void i2cSoftReset(); // I2C Standart : Software reset not supported by all hardware.
void i2cBusClear(); // I2C Standart : in case if SCL is stuck void i2cBusClear(); // I2C Standart : in case if SCL is stuck

@ -22,9 +22,250 @@
#include "i2c.h" #include "i2c.h"
void i2cReset(i2c_t *i2cHardware)
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]);
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.
}
}

@ -3,150 +3,93 @@
void i2cInit( i2c_t *i2cHardware, /*!< Pointer to I2C hardware Object */ void i2cInit( i2c_t *i2cHardware, /*!< Pointer to I2C hardware Object */
i2cCh_t channelNo, /*!< The harware channel to be used */ i2cCh_t channelNo, /*!< The harware channel to be used */
i2cMode_t mode, /*!< Master, Slave or Multymaster Modes */ i2cMode_t mode, /*!< Master, Slave or Multymaster Modes */
uint16_t address, /*!< First and Main address of the device */ uint16_t mainAddress, /*!< First and Main address of the device */
uint16_t addressSecond, /*!< Second address if dual addresse mode is configured */ uint16_t secondAddress, /*!< Second address if dual addresse mode is configured */
i2cAddressCount_t addressCount, /*!< Single or multiple */ i2cAddressCount_t addressCount, /*!< Single or multiple */
i2cAddressSize_t addressSize, /*!< 10 or 7 bit address size */ i2cAddressSize_t addressSize, /*!< 10 or 7 bit address size */
i2cSpeed_t speed, /*!< Bus Speed */ i2cSpeed_t speed, /*!< Bus Speed */
i2cOpperationMode_t opperationMode, /*!< Blocking or non blocking polling, Int or DMA */ i2cOpperationMode_t opperationMode, /*!< Blocking or non blocking polling, Int or DMA */
i2cClockStreching_t streching, /*!< Clock Streching enable onyl in slave mode */ i2cClockStretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
i2cWakeUpTypes_t wakeOn /*!< Wake up condition */ i2cWakeUpTypes_t wakeOn) /*!< Wake up condition */
)
{ {
i2cHardware->channelNo = channelNo;
i2cHardware->mode = mode;
i2cHardware->mainAddress = mainAddress;
i2cHardware->secondAddress = secondAddress;
i2cHardware->addressCount = addressCount;
i2cHardware->addressSize = addressSize;
i2cHardware->speed = speed;
i2cHardware->opperationMode = opperationMode;
i2cHardware->stretching = stretching;
i2cHardware->wakeOn = wakeOn;
i2cHardware->state = i2cNotInitialized;
i2cReset(i2cHardware); i2cEnableHardware(i2cHardware);
// Enables the i2c bus i2cDisablePeriferal(i2cHardware);
RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2cHardware->channelNo]);
// Make sure that the periferal is disabled. i2cConfigureFilters(i2cHardware);
I2C_BASE->CR1 &= ~I2C_CR1_PE;
//Configure analog filter. Anlalog filter is on i2cSetClockStretch(i2cHardware, stretching);
I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF;
//Configure NoStrech Streching mode is disabled (slave only) i2cSetSpeed(i2cHardware, speed);
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
//Configure the clock i2cSetMode(i2cHardware, opperationMode);
I2C_BASE->TIMINGR = i2cHardware->timing;
//Automatic end mode (master mode) disabled Enablede as default i2cSetAddressLenght(i2cHardware, addressSize);
I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
//I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
if(i2cHardware->mode == i2cModeMaster) i2cSetAddress(i2cHardware, mainAddress, secondAddress);
{
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. i2cEnablePeriferal(i2cHardware);
I2C_BASE->CR1 |= I2C_CR1_PE;
i2cHardware->state = i2cInitialized; i2cHardware->state = i2cInitialized;
} }
void i2cDeInit(i2c_t *i2cHardware) void i2cDeInit(i2c_t *i2cHardware)
{ {
} }
void i2cWrite(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data, uint8_t dataLenght) void i2cWrite( i2c_t *i2cHardware,
{
}
void i2cRead( i2c_t *i2cHardware,
uint16_t *devAddress, uint16_t *devAddress,
uint8_t *registerAddress, uint8_t *registerAddress,
uint8_t *data, uint8_t *data,
uint8_t dataLenght) 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 // this function still doesn't implment 10 bit oopeartion TODO
void i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t registerAddress, uint8_t *data) void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t slaveAddress, 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); i2cWaitForPeriferal(i2cHardware);
i2cHardware->state = i2cTransmitting; i2cHardware->state = i2cTransmitting;
//Slave address i2cInitiateWriteCommand(i2cHardware);
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 i2cSendSlaveAddress(i2cHardware, slaveAddress);
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait until the start condition in generated. i2cSendRegisterAddress(i2cHardware,registerAddress);
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 ? //Is the tranfes complete ?
while(!(I2C_BASE->ISR & (I2C_ISR_TC))); while(!(I2C_BASE->ISR & (I2C_ISR_TC)));
i2cHardware->state = i2cRecieving; i2cHardware->state = i2cRecieving;
//Read Mode i2cInitiateReadCommand(i2cHardware);
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 i2cSendSlaveAddress(i2cHardware, slaveAddress);
while(!(I2C_BASE->ISR & (I2C_ISR_TXE)));
//Wait for the input buffer to be full //Wait for the input buffer to be full
while(!(I2C_BASE->ISR & (I2C_ISR_RXNE))); while(!(I2C_BASE->ISR & (I2C_ISR_RXNE)));
//NACK is generated automatically in master mode. i2cGenerateNack(i2cHardware);
i2cCR1= I2C_BASE->CR1;
i2cCR2= I2C_BASE->CR2;
i2cISR= I2C_BASE->ISR;
// Sned stop command i2cGenerateStop(i2cHardware);
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;

@ -110,9 +110,11 @@ int main(int argc, char *argv[])
{ {
uint8_t i = 0; uint8_t i = 0;
uint8_t slaveAddress = 0xC0; uint16_t slaveAddress = 0xC0;
uint8_t registerToRead = 0x00; uint8_t registerToRead = 0x00;
uint8_t i2cRecieved = 0; uint8_t i2cRecieved = 0;
i2c_t i2c_1;
// making array with all available timers // making array with all available timers
//timerNo_t timers[MAX_TIMER_CHANNEL_COUNT] = {timer_1, timer_2, timer_3, timer_14, timer_16, timer_17}; //timerNo_t timers[MAX_TIMER_CHANNEL_COUNT] = {timer_1, timer_2, timer_3, timer_14, timer_16, timer_17};
@ -145,34 +147,16 @@ int main(int argc, char *argv[])
pinWrite(pinB3,0); pinWrite(pinB3,0);
// Pin configuration for i2c
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);
i2c_t i2c_1; print_Usart(usart2, "\n\r");
/*
i2c_1.channelNo = I2C_CH_1;
i2c_1.mode = i2cModeMaster;
i2c_1.address = 0x0;
i2c_1.addressSecond = 0x00;
i2c_1.addressCount = i2cAddressCountSingle;
i2c_1.addressSize = i2cAddressSizeSevenBits;
i2c_1.speed = i2cSpeedStandart;
i2c_1.opperationMode = i2cOpperationPolling;
i2c_1.streching = i2cClockStrechingDisable;
i2c_1.timing = 0x2000090E; // Taken from stm code generator
i2c_1.wakeOn = i2cWakeUpDisabled;
i2c_1.state = i2cNotInitialized;
*/
i2cInit(&i2c_1, I2C_CH_1, i2cModeMaster, 0x00,0x00, i2cAddressCountSingle, i2cAddressSizeSevenBits, i2cSpeedStandart, i2cOpperationPolling, i2cClockStrechingDisable, i2cWakeUpDisabled);
i2cInit(&i2c_1, I2C_CH_1, i2cModeMaster, 0x00,0x00, i2cAddressCountSingle, i2cAddressSizeSevenBits, i2cSpeedStandart, i2cOpperationPolling, i2cClockStretchingDisable, i2cWakeUpDisabled);
i2cMasterRecieve(&i2c_1,slaveAddress,registerToRead,&i2cRecieved); i2cMasterRecieve(&i2c_1,slaveAddress,registerToRead,&i2cRecieved);
printBinary8(i2cRecieved,0);
print_Usart(usart2, "\n\r");
i2cMasterRecieve(&i2c_1,slaveAddress,registerToRead+1,&i2cRecieved);
printBinary8(i2cRecieved,0); printBinary8(i2cRecieved,0);
print_Usart(usart2, "\n\r"); print_Usart(usart2, "\n\r");

Loading…
Cancel
Save