Compare commits

...

18 Commits
master ... i2c

Author SHA1 Message Date
kerem 93b0d68eff small changes 3 years ago
kerem 17216782e4 test with laptop 3 years ago
kerem 59d97e1fe6 test with laptop 3 years ago
kerem 3e457d3340 Started wit the i2cWrite and started to implment more strutured I2C base level communication functions to ease the work of future implementations 3 years ago
kerem 23c8899f0f driver level has no more connection with the hardware side of the i2c bus, state machine implmentation is working but needs some more states 3 years ago
kerem 5192d05b68 sarted with the i2c Driver implmentation functions 3 years ago
kerem 913663516e Working i2c function divided as imp_i2c.c and deirver level i2c.c usignt he same header from interfaces/i2c.h 3 years ago
kerem e048155400 Master read byte function is now working 3 years ago
kerem f708b410a9 Able to get register ack from slave ! Finally ! 3 years ago
kerem 68da9734e1 Geting crazy because of hardware issues on the nucleo ! but making progress now 3 years ago
kerem 2602e66c4d the nwewr I2C implmentation on the stm32f042 is wierd triying to figure it out 3 years ago
key e1c061bd1f Init function is fully implmented. I2C Start condition is working, curretnly struggling how to send to the slave the register no that we want to read from 3 years ago
kerem ec2a90186e Starter the init function and implementation from registers 3 years ago
kerem cfbb4a49ea Starter the init function reset function is done 3 years ago
key 63a1ec72a8 Tooo many functions, started implmenting the pollinmg mode. now need to define the registers, init functions and communicate 3 years ago
key e17d96755f Added the state machine for the i2c trasnmition states and started with the functions implementation on a lower layer 3 years ago
key 206f119a12 Configurgnt the struture and typdefs for the i2c channel initilization 3 years ago
key b3ffb7974a Started on the implmentation of the i2c Base adresses and the channel initiation 3 years ago

@ -24,7 +24,7 @@ set(EXECUTABLE ${PROJECT_NAME}) #Create the executable
####################################################################################################
set(INTERFACES_DIR ${CMAKE_SOURCE_DIR}/csl/interfaces)
set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils/assert)
set(DRIVERS_DIR ${CMAKE_DRIVERS_DIR}/drivers)
set(DRIVERS_DIR ${CMAKE_SOURCE_DIR}/drivers)
####################################################################################################
#SUBDIRECTORIES Will add the given folders to the porject an check for CmakeLists.txt
@ -40,6 +40,7 @@ message("${Blue} |--> Compiler Def\t: ${COMPILER_DEFS} ${ColourReset}")
message("${Blue} |--> Project Def\t: ${PROJECT_DEFS} ${ColourReset}")
message("${Blue} |--> Interfaces Dir\t: ${INTERFACES_DIR} ${ColourReset}")
message("${Blue} |--> Libs used\t\t: ${EXTRA_LIBS} ${ColourReset}")
message("${Blue} |--> Drivers used\t\t: ${DRIVERS_DIR} ${ColourReset}")
####################################################################################################
#EXECUTABLE

@ -863,12 +863,12 @@ WARN_LOGFILE =
# directories like /usr/src/myproject. Separate the files or directories with
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
# added by KeY
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/interfaces/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/stm32f042/Drivers/CMSIS/Device/ST/STM32F0xx/Include/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/stm32f042/Src/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/stm32f042/Device/
@CMAKE_CURRENT_SOURCE_DIR@/csl/interfaces/ \
@CMAKE_CURRENT_SOURCE_DIR@/csl/stm32f042/Drivers/CMSIS/Device/ST/STM32F0xx/Include/ \
@CMAKE_CURRENT_SOURCE_DIR@/csl/stm32f042/Src/ \
@CMAKE_CURRENT_SOURCE_DIR@/csl/stm32f042/Device/
# This tag can be used to specify the character encoding of the source files

@ -3,7 +3,7 @@
* @file i2c.h
* @author Kerem Yollu & Edwin Koch
* @date 18.07.2022
* @version 1.0
* @version 1.01
**************************************************************************************************
* @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
@ -16,7 +16,10 @@
* This will also not have a I3C support for the forseable futrue.
*
* @todo
* - 18.07.2021 : Implement the i2c.c.
* - 26.07.2021 : Implement the DMA
* - 26.07.2021 : Implement the Interrupt
* - 26.07.2021 : Implement the Sleep/WakeUp
* - 26.07.2021 : Implement the Slave opperation
**************************************************************************************************
*/
@ -27,61 +30,524 @@
extern "C" {
#endif
#include <stdint.h>
#define I2C_STATE_RESET 1 // Not Initialized
#define I2C_STATE_READY 2 // Ready
#define I2C_STATE_TX 4 // Transmitting
#define I2C_STATE_RX 5 // Receiving
#define I2C_STATE_LISTEN 6 // Listening
#define I2C_STATE_ABORT 7 // Aborted by user
#define I2C_STATE_TIMEOUT 8 // Timeout
#define I2C_STATE_ERROR 9 // Error happened
#define I2C_SPEED_STANDART 1 // Sm 100 kbits/s This mode will be choosen for the constructor.
#define I2C_SPEED_FAST 2 // Fm 400 kbits/s
#define I2C_SPEED_FAST_PLUS 3 // Fm+ 1 Mbits/s
#define I2C_SPEED_HIGH_SPEED 4 // Hs 3.4 Mbits/s
#define I2C_SPEED_ULTRA_FAST 5 // UFm 5 Mbits/s
#define I2C_ADDRESS_7B 1 // 7 bits addressing mode
#define I2C_ADDRESS_10B 2 // 10 bits addressing mode
#define I2C_MODE_MASTER 1 // Single Master Mode
#define I2C_MODE_SLAVE 2 // Slave Mode
#define I2C_MODE_MULTI_MASTER 3 // Multy Master Mode
/* Creator from the CPP Version PLease keep it to define the main init sequence.*/
//ll_i2c(uint16_t address, uint8_t channel, uint8_t mode, uint8_t adressMode); // Creat i2c abject witha agiven channel address & mode speed is by default the slowest.
void i2cRead(uint8_t *reg, uint8_t *buffer, uint8_t &regLenght, uint8_t &bufferLenght); // Defined by me : Read a given number of bytes
void i2cWrite(uint8_t *reg, uint8_t *data, uint8_t &regLenght, uint8_t &dataLenght); // Defined by me : Send a given number of bytes
uint8_t i2cTestDeviceSpeed(); // Defined by me : Cycle trough different modes until device cnat't answer fast enought
uint8_t i2cDiscoverDevices(); // Defined by me : Scan the awailable address range on standart mode to find devices
void i2cInitChannelAsMaster(); // Hardware Specific : Initilise the hardware channel in master mode
void i2cInitChannelAsSlave(); // Hardware Specific : Initilise the hardware channel in slavic mode (@life of boris)
void i2cFreeChannel(); // Hardware Specific : Free the hardware channel for othe recousrces
void i2cClockSynchronise();// I2C Standart : Clock Syncronization
void i2cReadDeviceInfo(); // I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
#include "hardwareDescription.h"
#include "pin.h"
#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2cHardware->channelNo])
uint32_t i2cCR1;
uint32_t i2cCR2;
uint32_t i2cISR;
/*! Enum of possible I2C opperation modes */
typedef enum{
i2cModeMaster, /*!< Master mode : In Master mode, the I2C interface initiates
a data transfer and generates the clock signal. **DEFAULT** */
i2cModeMultyMaster, /*!< Multimaster Mode : In case if more than one master are present
in one I2C bus. In such case each device needs to be able to
cooperate knowing that another device could talking
therefore the bus is busy (Arbirtation).
For More information : https://www.i2c-bus.org/multimaster/ */
i2cModeSlave /*!< Slave mode : A slave device has to always be ready to detect and
process a start condition and to recognize its address */
}i2cMode_t;
/*! Enum of possible I2C speeds */
typedef enum{
i2cSpeedStandart, /*!< SM 100 kbits/s Standart i2c Speed **DEFAULT** */
i2cSpeedFast, /*!< FM 400 kbits/s */
i2cSpeedFastPlus, /*!< FM+ 1 Mbits/s */
i2cSpeedHightSpeed, /*!< HS 3.4 Mbits/s */
i2cSpeedUltraFast /*!< UFM 5 Mbits/s */
}i2cSpeed_t;
/*! Enum of possible I2C Adress sizes */
typedef enum{
i2cAddressSizeSevenBits, /*!< 7 Bits address size **DEFAULT** */
i2cAddressSizeTenBits /*!< 10 Bits address size */
}i2cAddressSize_t;
/*! Enum of possible I2C Address count */
typedef enum{
i2cAddressCountSingle, /*!< Only one address for communication **DEFAULT** */
i2cAddressCountDual /*!< Dual addresses for one device respondng to two addresses */
}i2cAddressCount_t;
/*! Enum for clock strechning activation. Can only be implmented as Slave
* for more information : https://www.i2c-bus.org/clock-stretching/ */
typedef enum{
i2cClockStretchingDisable, /*!< We assume that the master and slave have compatible
Clock frequencies **DEFAULT** */
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. */
}i2cClockStretching_t;
/*! Enum for diffenrent wake up methodes wehnin sleep mode */
typedef enum{
i2cWakeUpDisabled, /*!< No wake up is possible this is the default mode also means that
the sleep function is not implmentes **DEFAULT** */
i2cWakeUpOnAddressMatch /*!< Wakes up on address match, this can be harware dependent */
}i2cWakeUpTypes_t;
/*! Enum operation mode of the i2c channel */
typedef enum{
i2cOpperationPolling, /*!< Polling mode Blocking, i2c communication states are constantly
checked on polling mode so it can be stoped
when interrupts occures **DEFAULT** */
i2cOpperationInt, /*!< Interrut Mode Non-blocking, i2c communications state changes
generates an interrupt and can be handeled this way */
i2cOpperationDma /*!< DMA Mode Non-blocking, I2C communication satets are managed
via Inteerupts and with Direct Memory Access */
}i2cOpperationMode_t;
/*! typedef for the i2c states*/
typedef enum
{
i2cHwIdle, /*!< Hardware is in Idle Mode **DEFAULT** */
i2cHwStartGenerated, /*!< Generated the star condition */
i2cHwOutputBufferFull, /*!< The output buffer of the I2C Periferal is Full */
i2cHwOutputBufferEmpty, /*!< The output buffer of the I2C Periferal is Empty */
i2cHwInputBufferFull, /*!< The input buffer of the I2C Periferal Is Full */
i2cHwInputBufferEmpty, /*!< The input buffer of the I2C Periferal Is Empty */
i2cHwSentRead, /*!< Sent read request */
i2cHwSentWrite, /*!< Sent write request */
i2cHwGotAck, /*!< Recieved ACK */
i2cHwGotNack, /*!< Recieved NACK */
i2cHwSentAck, /*!< Sent ACK */
i2cHwSentNack, /*!< Sent NACK */
i2cHwStopGenerated, /*!< Generated the star condition */
i2cHwError /*!< Error */
} i2cHardwareState_t;
typedef enum
{
i2cPerifNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */
i2cPerifInitialized, /*!< I2C CHannle is initilized but not neceserly ready */
i2cPerifSlaveAddressSent, /*!< The Salve Address Was Sent to the bus */
i2cPerifTransferComplete, /*!< A full communication process is complete (wire or Read) */
i2cPerifTransferOngoign, /*!< A full communication process is in progress (wire or Read) */
i2cPerifReady, /*!< Peripheral Initialized and ready for use */
i2cPerifSlaveNotFound, /*!< Desired Slave was not able to be found */
i2cPerifTransmitting, /*!< Data Transmission process is ongoing */
i2cPerifRecieving, /*!< Data Reception process is ongoing */
i2cPerifListening, /*!< Address Listen Mode is ongoing */
i2cPerifListeningAndTransmitting, /*!< Address Listen Mode and ongoing Data Transmission */
i2cPerifListeningAndRecieveing, /*!< Address Listen Mode and ongoing Data Reception */
i2cPerifAbort, /*!< Abort user request ongoing */
i2cPerifTimeout, /*!< Timeout state */
i2cPerifError /*!< Error */
} i2cPeriferalState_t;
/*! Struture a an i2c channel with all the required propereties*/
typedef struct i2c_t
{
i2cCh_t channelNo; /*!< The harware channel to be used */
i2cMode_t mode; /*!< Master, Slave or Multymaster Modes */
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 */
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 */
i2cHardwareState_t hardwareState; /*!< The current sitate of the I2C Bus */
i2cPeriferalState_t periferalState; /*!< The current sitate of the I2C Bus */
}i2c_t;
/***************************************************************************************************
I2C Configuration functions
***************************************************************************************************/
/**
* @brief Initilize the I2C Hardware
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
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 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 */
i2cClockStretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
i2cWakeUpTypes_t wakeOn /*!< Wake up condition */
);
/**
* @brief De-Initilize the I2C Hardware
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cDeInit(i2c_t *i2cHardware);
/**
* @brief Set the i2c channle to the gievn mode
* @param Channel is the i2c hardware channel
* @param mode The mode for i2c : Master Slave or Multymaster
*/
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 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, 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
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param speed the different awailable speeds
*/
void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed);
/**
* @brief Initiates the opperation mode for the selected i2c Channel
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param opperation define if the i2c channel will opperate on pollin, Interrupt, or DMA modes
*/
void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
/**
* @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 i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching);
/**
* @brief Set the wakeup mode
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param wake the desider wakeup mode for now i have found only one mode.
*/
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
* @param timeout the desider timeout duration in ticks.
*/
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
*/
void i2cPeriferalReset(i2c_t *i2cHardware);
/**
* @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 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
***************************************************************************************************/
/**
* @brief Writes the given amount of data to the selected device. This function will
* automaticaly choose between i2cMasterSend(); or i2cSlaveSend();
* Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data to be written
* @param dataLenght is the total quantity of 8 bit data to be written.
*/
void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
/**
* @brief Reads the given amount of data to the selected device. This function will
* automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve();
* Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data which has been red
* @paran dataLenght is the total quantity of 8 bit data to be red
*/
void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
/**
* @brief Recieve a Single Byte as master from from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @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, 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)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the send command will be sent
* @param registerAddress is the regiter to be written to the device
* @param data is the data to be sent
*/
void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte as slave from given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte as slave from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**************************************************************************************************
I2C Hardware functions
***************************************************************************************************/
/**
* @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 i2cIsPeriferalReady(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 Sende the register adrres with which we want to communicate.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param registerAddress The register address of the slave device that we are communication with
*/
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint16_t *registerAddress);
/**
* @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 i2cSendData(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);
/**
* @brief reads the I2C input buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data);
/**
* @brief writes to the I2C output buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data);
/**
* @brief Checks is transfer is complete
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2cIsTransferComplete(i2c_t *i2cHardware);
/**
* @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param count amount o data to be transfered.
*/
void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count);
/**************************************************************************************************
I2C Communication functions Polling / Blocking Mode
***************************************************************************************************/
/**
* @brief Recieve a Single Byte in polling mode as master from from the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Sends a Single Byte in polling mode as master to the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the send command will be sent
* @param registerAddress is the regiter to be written to the device
* @param data is the data to be sent
*/
void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte in polling mide as slave from the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte in polling mode as slave from the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**************************************************************************************************
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
void i2cBusClear(); // I2C Standart : in case if SCL is stuck
void i2cSetSpeed(uint8_t speed); // I2C Standart
void i2cSetAddress(uint16_t &address); // I2C Standart
void i2cSetAddressMode(); // I2C Standart
void i2cSetTimeout(uint8_t &timeout); // Hardware specific
void i2cSetInterrupt(); // Hardware Specific
void i2cSetDma(); // Hardware specific
/**************************************************************************************************
I2C Extra functions that are not esential for the main functionality
***************************************************************************************************/
/**
* @brief This function will scan every for possible addresses to discover devices on the bus.
* And write them to the Devices list given to him. This function will not discover more
* devices than what he is told.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devices list where the discevered devices will be written
* @param deviceCount Max number of devices to be discovered.
*/
void i2cDiscoverDevices(i2c_t *i2cHardware, uint16_t *devices, uint8_t deviceCount);
/**
* @brief This function will try to communicate with a device with every speed
* allowed by his hardware to find out the maximum communication sppeed possible.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
*/
i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *slaveAddress);
/**
* @brief This function will read the device info register (if awailable) as follows :
* I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to be red
*/
uint32_t i2cReadDeviceInfo(i2c_t *i2cHardware, uint16_t *slaveAddress);
/**
* @brief The selected i2c channel is put on sleep.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cSleep(i2c_t *i2cHardware);
/**
* @brief Error handling.
* @param error The error no generated.
*/
void i2cThrowError(int16_t error); // Defined by me : Private error function for error handling
void i2cPointReg(uint8_t *reg); // Defined by me : Points to the register to be red from
#ifdef __cplusplus
}

@ -221,7 +221,7 @@ static const uint8_t timerBus_No[MAX_TIMER_CHANNEL_COUNT] = {
/*!
* Timer Prescaler resolution list TO BE DELETED IF NOT NEEDED
* */
static const uint32_t timerRes_Prescaler[MAX_TIMER_CHANNEL_COUNT] = {
static const uint32_t timerRes_Prescaler[MAX_TIMER_CHANNEL_COUNT] = {
0xFFFF, /*!< Timer 1 Prescaler Max Value */
0xFFFF, /*!< Timer 2 Prescaler Max Value */
0xFFFF, /*!< Timer 3 Prescaler Max Value */
@ -242,6 +242,33 @@ static const uint32_t spiBase_Addr_List[MAX_SPI_CHANNEL_COUNT] = {
};
/*! Awailable I2C Channels Hadware dependent Register independent */
typedef enum{
I2C_CH_1
}i2cCh_t;
/*! I2C Channel Base adress Hadware dependent Register dependent*/
static const uint32_t i2cBase_Addr_List[MAX_I2C_CHANNEL_COUNT] = {
I2C1_BASE
};
/*! RCC Bus number index list connected to the I2C */
static const uint8_t i2cBus_No[MAX_I2C_CHANNEL_COUNT] = {
1 /*!< I2C1 is connected to bus 1 */
};
/*! RCC I2C clock enable bit position for the given register*/
static const uint8_t i2cBus_En_bitPos[MAX_I2C_CHANNEL_COUNT] = {
RCC_APB1ENR_I2C1EN_Pos
};
/*! RCC I2C reset bit position for the given register*/
static const uint8_t i2cBus_Rst_bitPos[MAX_I2C_CHANNEL_COUNT] = {
RCC_APB1RSTR_I2C1RST_Pos
};
#ifdef __cplusplus
}
#endif

@ -35,3 +35,8 @@ target_compile_definitions(stmSPI PRIVATE ${C_DEFS})
target_include_directories(stmSPI PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::spi ALIAS stmSPI)
add_library(stmI2C imp_i2c.c)
target_compile_options(stmI2C PRIVATE ${C_FLAGS})
target_compile_definitions(stmI2C PRIVATE ${C_DEFS})
target_include_directories(stmI2C PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::imp_i2c ALIAS stmI2C)

@ -0,0 +1,299 @@
/**
**************************************************************************************************
* @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"
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, uint16_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.
}
}

@ -71,10 +71,11 @@ set (MAIN_FLAGS ${C_FLAGS})
set (MAIN_DEFS ${C_DEFS})
list(APPEND EXTRA_LIBS sub::startup)
#list(APPEND EXTRA_LIBS sub::translator)
list(APPEND EXTRA_LIBS sub::delay)
list(APPEND EXTRA_LIBS sub::pin)
list(APPEND EXTRA_LIBS sub::usart)
list(APPEND EXTRA_LIBS sub::timer)
list(APPEND EXTRA_LIBS sub::init)
list(APPEND EXTRA_LIBS sub::spi)
list(APPEND EXTRA_LIBS sub::i2c)
list(APPEND EXTRA_LIBS sub::imp_i2c)

@ -1 +1,5 @@
# add_subdirectory(${CSL_USED})
add_library(I2C i2c.c)
target_compile_options(I2C PRIVATE ${C_FLAGS})
target_compile_definitions(I2C PRIVATE ${C_DEFS})
target_include_directories(I2C PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::i2c ALIAS I2C)

@ -0,0 +1,182 @@
#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 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 */
i2cClockStretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
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->hardwareState = i2cHwIdle;
i2cHardware->periferalState = i2cPerifNotInitialized;
i2cEnableHardware(i2cHardware);
i2cDisablePeriferal(i2cHardware);
i2cConfigureFilters(i2cHardware);
i2cSetClockStretch(i2cHardware, stretching);
i2cSetSpeed(i2cHardware, speed);
i2cSetMode(i2cHardware, opperationMode);
i2cSetAddressLenght(i2cHardware, addressSize);
i2cSetAddress(i2cHardware, mainAddress, secondAddress);
i2cEnablePeriferal(i2cHardware);
i2cHardware->periferalState = i2cPerifNotInitialized;
}
void i2cDeInit(i2c_t *i2cHardware)
{
}
void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
{
switch(i2cHardware->mode)
{
case i2cModeMaster:
i2cMasterRecieve(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cModeSlave:
break;
case i2cModeMultyMaster:
break;
}
}
// this function still doesn't implment 10 bit oopeartion TODO
void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
switch(i2cHardware->opperationMode)
{
case i2cOpperationPolling :
i2cMasterRecievePolling(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cOpperationInt:
break;
case i2cOpperationDma:
break;
}
}
void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
{
switch(i2cHardware->mode)
{
case i2cModeMaster:
i2cMasterSend(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cModeSlave:
break;
case i2cModeMultyMaster:
break;
}
}
void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
switch(i2cHardware->opperationMode)
{
case i2cOpperationPolling :
i2cMasterSendPolling(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cOpperationInt:
break;
case i2cOpperationDma:
break;
}
}
void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
while(i2cHardware->periferalState != i2cPerifReady)
{
i2cIsPeriferalReady(i2cHardware);
}
i2cHardware->periferalState = i2cPerifTransmitting;
i2cInitiateWriteCommand(i2cHardware);
i2cSetTransferCounter(i2cHardware,2);
i2cSendSlaveAddress(i2cHardware, slaveAddress);
i2cSendRegisterAddress(i2cHardware,registerAddress);
i2cSendData(i2cHardware,data);
while(i2cHardware->periferalState != i2cPerifTransferComplete)
{
i2cIsTransferComplete(i2cHardware);
}
i2cCR2 = I2C_BASE->CR2;
i2cGenerateStop(i2cHardware);
i2cHardware->periferalState = i2cPerifReady;
i2cHardware->hardwareState = i2cHwIdle;
}
void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
while(i2cHardware->periferalState != i2cPerifReady)
{
i2cIsPeriferalReady(i2cHardware);
}
i2cHardware->periferalState = i2cPerifTransmitting;
i2cSetTransferCounter(i2cHardware,1);
i2cInitiateWriteCommand(i2cHardware);
i2cSendSlaveAddress(i2cHardware, slaveAddress);
i2cSendRegisterAddress(i2cHardware,registerAddress);
while(i2cHardware->periferalState != i2cPerifTransferComplete)
{
i2cIsTransferComplete(i2cHardware);
}
i2cInitiateReadCommand(i2cHardware);
i2cSendSlaveAddress(i2cHardware, slaveAddress);
i2cHardware->periferalState = i2cPerifRecieving;
while(i2cHardware->hardwareState != i2cHwInputBufferFull)
{
i2cIsInputBufferEmpty(i2cHardware);
}
i2cGenerateNack(i2cHardware);
i2cGenerateStop(i2cHardware);
i2cReadInputRegister(i2cHardware, data);
i2cHardware->periferalState = i2cPerifReady;
i2cHardware->hardwareState = i2cHwIdle;
}

@ -1,7 +0,0 @@
add_library(ledDriver led.cpp)
target_compile_options(ledDriver PRIVATE ${C_FLAGS})
target_compile_definitions(ledDriver PRIVATE ${C_DEFS})
target_include_directories(ledDriver PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_library(sub::led ALIAS ledDriver)

@ -1,30 +0,0 @@
#include "led.hpp"
Led::Led(Pin* pin_ptr)
{
pin = pin_ptr;
pin->init();
pin->setMode(Pin::mode::output);
pin->setSpeed(Pin::speed::fast);
}
Led::~Led()
{
}
void Led::on()
{
pin->write(true);
}
void Led::off()
{
pin->write(false);
}
void Led::toggle()
{
pin->toggle();
}

@ -1,20 +0,0 @@
#ifndef _LED_HPP
#define _LED_HPP
class Led
{
public:
Led(Pin *pin_ptr);
~Led();
void on();
void off();
void toggle();
private:
Pin *pin;
};
#endif /* __LED_HPP */

@ -1,82 +0,0 @@
#include "spi_ch.h"
// generic implementation of spi channel class
uint8_t spiCH_readReg(spi_ch_t *spi_ch,
uint8_t reg_address) {
uitn8_t buf;
// select target device
pinWrite(spi_ch->pin,0);
// send address of target register
spi_trx(spi_ch->spi, reg_address);
// read from target register
buf = spi_trx(spi->spi,0x00);
// release target device
pinWrite(spi_ch->pin,1);
return buf;
}
void spiCH_autoReadBlock(spi_ch_t *spi_ch,
uint8_t start_address,
uint8_t* buffer,
uint8_t buf_len) {
uint8_t i = 0;
// select target device
pinWrite(spi_ch->pin,0);
// send address of starting register
spi_trx(spi_ch->spi, reg_address);
// read block from device
for(;i < buf_len;i++) {
buffer[i] = spi_trx(spi_ch->spi, 0x00);
}
// release target device
pinWrite(spi_ch->pin,1);
}
void spiCH_writeReg(spi_ch_t *spi_ch,
uint8_t reg_address,
uint8_t data) {
// select target device
pinWrite(spi_ch->pin,0);
// send address of target register
spi_trx(spi_ch->spi, reg_address);
// write to target register
spi_trx(spi->spi, data);
// release target device
pinWrite(spi_ch->pin,1);
}
void spiCH_writeBlock(spi_ch_t *spi_ch,
uint8_t start_address,
const uint8_t *data,
uint8_t data_len) {
uint8_t i = 0;
// select target device
pinWrite(spi_ch->pin,0);
// send address of starting register
spi_trx(spi_ch->spi, reg_address);
// read block from device
for(;i < buf_len;i++) {
spi_trx(spi_ch->spi, data[i]);
}
// release target device
pinWrite(spi_ch->pin,1);
}

141
main.c

@ -4,7 +4,7 @@
#include "usart.h"
#include "ascii.h"
#include "timer.h"
#include "spi.h"
#include "i2c.h"
void timer_test(timerNo_t timer, pinNo_t pin)
{
@ -39,13 +39,86 @@ void timer_capture_compare_test(timerNo_t timer)
}
void printBinary32(uint32_t toPrint, uint8_t lsbFirst)
{
int i;
char pt;
print_Usart(usart2, "\n\r");
if(lsbFirst)
{
print_Usart(usart2, "Bit Pos | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|");
print_Usart(usart2, "\n\r");
print_Usart(usart2, "Bits |");
for(i=0; i < 32; i++)
{
pt = (toPrint >> i) & 1;
usartSendChar(usart2, ' ');
usartSendChar(usart2, pt + 0x30);
usartSendChar(usart2, '|');
}
}
else
{
print_Usart(usart2, "Bit Pos |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|");
print_Usart(usart2, "\n\r");
print_Usart(usart2, "Bits |");
for(i=0; i < 32; i++)
{
pt = (toPrint >> (31-i)) & 1;
usartSendChar(usart2, ' ');
usartSendChar(usart2, pt + 0x30);
usartSendChar(usart2, '|');
}
}
}
void printBinary8(uint8_t toPrint, uint8_t lsbFirst)
{
int i;
char pt;
print_Usart(usart2, "\n\r");
if(lsbFirst)
{
print_Usart(usart2, "Bit Pos | 0| 1| 2| 3| 4| 5| 6| 7|");
print_Usart(usart2, "\n\r");
print_Usart(usart2, "Bits |");
for(i=0; i < 8; i++)
{
pt = (toPrint >> i) & 1;
usartSendChar(usart2, ' ');
usartSendChar(usart2, pt + 0x30);
usartSendChar(usart2, '|');
}
}
else
{
print_Usart(usart2, "Bit Pos | 7| 6| 5| 4| 3| 2| 1| 0|");
print_Usart(usart2, "\n\r");
print_Usart(usart2, "Bits |");
for(i=0; i < 8; i++)
{
pt = (toPrint >> (7-i)) & 1;
usartSendChar(usart2, ' ');
usartSendChar(usart2, pt + 0x30);
usartSendChar(usart2, '|');
}
}
}
int main(int argc, char *argv[])
{
uint8_t i = 0;
uint16_t slaveAddress = 0xC0;
uint8_t registerToRead = 0x00;
uint8_t i2cRecieved = 0;
uint8_t i2cToWrite = 0xFF;
uint8_t i2cDataLenght = 1;
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};
//timerNo_t timers[MAX_TIMER_CHANNEL_COUNT] = {timer_1, timer_2, timer_3, timer_14, timer_16, timer_17};
delayInitMs(8000000, 1000); // Clock Freq and Divider for ARM library
@ -54,7 +127,6 @@ int main(int argc, char *argv[])
setupInit(); // This is the sescond call of System init the assebly start code is calling it before the main.
usartInit( usart2,
pinA2,
pinA15,
@ -65,51 +137,54 @@ int main(int argc, char *argv[])
//clears screen and send the wellcome messgae
print_Usart(usart2, ASCII_clear);
print_Usart(usart2, "HEllooo to our KED project\n\r");
print_Usart(usart2, "Hello to our KED project\n\r");
//blinks 10 times to indicate the sicsessfull init if the device
for(i = 0 ; i < 10 ; i++) {
for(i = 0 ; i < 2 ; i++) {
delayMs(100);
pinToggle(pinB3);
delayMs(100);
}
pinWrite(pinB3,0);
pinInit(pinA5);
pinInit(pinA6);
pinInit(pinA7);
pinSetAlternate(pinA5, 0); // SPI1_SCK
pinSetAlternate(pinA6, 0); // SPI1_MISO
pinSetAlternate(pinA7, 0); // SPI1_MOSI
spi_init(SPI_CH_1);
print_Usart(usart2, "\n\r");
for(i = 0 ; i < 20 ; i++) {
delayMs(50);
pinToggle(pinB3);
delayMs(50);
}
for(i = 10; i > 0; i--) {
spi_trx(SPI_CH_1, 0xAE);
}
for(i = 0 ; i < 10 ; i++) {
i2cInit(&i2c_1, I2C_CH_1, i2cModeMaster, 0x00,0x00, i2cAddressCountSingle, i2cAddressSizeSevenBits, i2cSpeedStandart, i2cOpperationPolling, i2cClockStretchingDisable, i2cWakeUpDisabled);
/*
i2cRead(&i2c_1, &slaveAddress, &registerToRead, &i2cRecieved, &i2cDataLenght);
printBinary8(i2cRecieved,0);
print_Usart(usart2, "\n\r");
registerToRead += 1;
i2cRead(&i2c_1, &slaveAddress, &registerToRead, &i2cRecieved, &i2cDataLengh);
printBinary8(i2cRecieved,0);
*/
registerToRead = 1;
i2cToWrite = 0xFF;
print_Usart(usart2, "\n\r");
//i2cWrite(&i2c_1, &slaveAddress, &registerToRead, &i2cToWrite, &i2cDataLenght);
printBinary32(i2cCR2,0);
print_Usart(usart2, "\n\r");
i2cRead(&i2c_1, &slaveAddress, &registerToRead, &i2cRecieved,&i2cDataLenght);
printBinary8(i2cRecieved,0);
print_Usart(usart2, "\n\r");
print_Usart(usart2, "\n\r");
print_Usart(usart2, "All is working fine\n\r");
while(1)
{
delayMs(100);
pinToggle(pinB3);
delayMs(100);
}
//timer_capture_compare_test(timer_2);
//print_Usart(usart2, "All is working fine \r\n");
while(1)
{
}
return 1;
}

@ -3,9 +3,7 @@
dir=$(pwd)
echo $dir
tmux new -s 'git' -d 'fish'
tmux new -s 'compile' -d 'fish'
tmux new -s 'main' -d 'fish'
cd $dir/ked/csl/stm32f042/Src/
@ -17,7 +15,4 @@ tmux new -s 'device' -d 'fish'
cd $dir/ked/csl/interfaces/
tmux new -s 'interface' -d 'fish'
cd $dir/ked/
tmux new -s 'KED submodule' -d 'fish'
tmux a
tmux a -t compile

Loading…
Cancel
Save