diff --git a/ked/csl/interfaces/i2c.h b/ked/csl/interfaces/i2c.h index 688b84d..c1d8a2f 100755 --- a/ked/csl/interfaces/i2c.h +++ b/ked/csl/interfaces/i2c.h @@ -76,12 +76,12 @@ typedef enum{ /*! Enum for clock strechning activation. Can only be implmented as Slave * for more information : https://www.i2c-bus.org/clock-stretching/ */ 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** */ - 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. This is done by a mechanism referred to as clock stretching. */ -}i2cClockStreching_t; +}i2cClockStretching_t; /*! Enum for diffenrent wake up methodes wehnin sleep mode */ typedef enum{ @@ -106,8 +106,15 @@ typedef enum { i2cNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */ 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 */ i2cBusy, /*!< An internal process is ongoing */ + i2cSlaveNotFound, /*!< Desired Slave was not able to be found */ i2cTransmitting, /*!< Data Transmission process is ongoing */ i2cRecieving, /*!< Data Reception process 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 */ 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 */ + uint16_t mainAddress; /*!< First and Main address of the device */ + uint16_t secondAddress; /*!< 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 */ - 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. */ + i2cClockStretching_t stretching; /*!< Clock Stretching enable onyl in slave mode */ i2cWakeUpTypes_t wakeOn; /*!< Define on which type of action the i2c channel should wake up. Only if de prefiral goes to sleep */ 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 */ 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 */ + uint16_t mainAddress, /*!< First and Main address of the device */ + uint16_t secondAddress, /*!< 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 */ + i2cClockStretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */ 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 * @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 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 @@ -196,13 +205,13 @@ void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed); */ void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation); + /** - * @brief Sets the finetuning of the Timings for the communication some standards as - * SMBUS have different timing requirements + * @brief Ebales or disables clock stretching functionalities * @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 */ -void i2cSetTimings(i2c_t *i2cHardware, uint32_t timing); +void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching); /** * @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); +/** + * @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. * @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); - /** * @brief Resets the i2c Periferal to it's inital state. * @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); /** - * @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 */ -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 @@ -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 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. * 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); +/************************************************************************************************** + 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 */ -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 ***************************************************************************************************/ @@ -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); /************************************************************************************************** - 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 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 i2cSoftReset(); // I2C Standart : Software reset not supported by all hardware. void i2cBusClear(); // I2C Standart : in case if SCL is stuck diff --git a/ked/csl/stm32f042/Src/imp_i2c.c b/ked/csl/stm32f042/Src/imp_i2c.c index d37b25b..0f1c9c7 100644 --- a/ked/csl/stm32f042/Src/imp_i2c.c +++ b/ked/csl/stm32f042/Src/imp_i2c.c @@ -22,9 +22,250 @@ #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]); } + +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. + } +} diff --git a/ked/drivers/i2c.c b/ked/drivers/i2c.c index 237c74f..972e6ca 100644 --- a/ked/drivers/i2c.c +++ b/ked/drivers/i2c.c @@ -3,150 +3,93 @@ 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 */ + uint16_t mainAddress, /*!< First and Main address of the device */ + uint16_t secondAddress, /*!< 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 */ - ) + i2cClockStretching_t stretching, /*!< Clock Stretching 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]); + 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; + + i2cEnableHardware(i2cHardware); + + i2cDisablePeriferal(i2cHardware); + + i2cConfigureFilters(i2cHardware); + + i2cSetClockStretch(i2cHardware, stretching); - // Make sure that the periferal is disabled. - I2C_BASE->CR1 &= ~I2C_CR1_PE; + i2cSetSpeed(i2cHardware, speed); - //Configure analog filter. Anlalog filter is on - I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF; + i2cSetMode(i2cHardware, opperationMode); - //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; + i2cSetAddressLenght(i2cHardware, addressSize); + + i2cSetAddress(i2cHardware, mainAddress, secondAddress); + + i2cEnablePeriferal(i2cHardware); 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, +void i2cWrite( 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) +void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t slaveAddress, uint8_t registerAddress, uint8_t *data) { - // Wait until no communication is ongoign - while((I2C_BASE->ISR & (I2C_ISR_BUSY))==I2C_ISR_BUSY); + i2cWaitForPeriferal(i2cHardware); 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; + i2cInitiateWriteCommand(i2cHardware); - //Generate start condition - I2C_BASE->CR2 |= I2C_CR2_START; - - //Wait until the start condition in generated. - while(!(I2C_BASE->ISR & (I2C_ISR_BUSY))); + i2cSendSlaveAddress(i2cHardware, slaveAddress); - //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))); + i2cSendRegisterAddress(i2cHardware,registerAddress); //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; + i2cInitiateReadCommand(i2cHardware); - //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))); + i2cSendSlaveAddress(i2cHardware, slaveAddress); //Wait for the input buffer to be full while(!(I2C_BASE->ISR & (I2C_ISR_RXNE))); + + i2cGenerateNack(i2cHardware); - //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; + i2cGenerateStop(i2cHardware); //read dtaa from the input register to clear it out *data = I2C_BASE->RXDR; diff --git a/main.c b/main.c index eb868c0..035392f 100644 --- a/main.c +++ b/main.c @@ -110,9 +110,11 @@ int main(int argc, char *argv[]) { uint8_t i = 0; - uint8_t slaveAddress = 0xC0; + uint16_t slaveAddress = 0xC0; uint8_t registerToRead = 0x00; uint8_t i2cRecieved = 0; + i2c_t i2c_1; + // 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}; @@ -145,34 +147,16 @@ int main(int argc, char *argv[]) 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; - /* - 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); + print_Usart(usart2, "\n\r"); + + i2cInit(&i2c_1, I2C_CH_1, i2cModeMaster, 0x00,0x00, i2cAddressCountSingle, i2cAddressSizeSevenBits, i2cSpeedStandart, i2cOpperationPolling, i2cClockStretchingDisable, i2cWakeUpDisabled); i2cMasterRecieve(&i2c_1,slaveAddress,registerToRead,&i2cRecieved); + printBinary8(i2cRecieved,0); + print_Usart(usart2, "\n\r"); + + i2cMasterRecieve(&i2c_1,slaveAddress,registerToRead+1,&i2cRecieved); printBinary8(i2cRecieved,0); print_Usart(usart2, "\n\r");