diff --git a/I2C_Wrapper.c b/I2C_Wrapper.c new file mode 100644 index 0000000..4f1b8bb --- /dev/null +++ b/I2C_Wrapper.c @@ -0,0 +1,48 @@ +/** + ****************************************************************************** + * @file lib.c + * @author Auto-generated by STM32CubeIDE + * @version V1.0 + * @date 16/11/2024 10:47:31 + * @brief Default under dev library file. + ****************************************************************************** +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal.h" + + +#include "C://Users//diogo//STM32CubeIDE//workspace_1.16.1//I2C_Wrapper//Src//I2C_Wrapper.h" + +/** Functions ----------------------------------------------------------------*/ +uint8_t I2C_writeReg(I2C_INTERFACE *interface){ + uint8_t status; + uint8_t temp_send[255]; + temp_send[0] = interface->register_address; + memcpy(&temp_send[1], interface->send_data, interface->num_bytes); + /* + for (int i = 0; i < interface->num_bytes; i++) { + temp_send[i + 1] = interface->send_data[i]; + } + */ + status = HAL_I2C_Master_Transmit(interface->hi2c, interface->device_address, temp_send, interface->num_bytes + 1, 1000); //resend + if(status != HAL_OK) + return status; + + //Confirming the data + + status = HAL_I2C_Master_Transmit(interface->hi2c, interface->device_address, interface->register_address, 1, 1000); //Send the register address + if(status != HAL_OK) + return status; + HAL_Delay(50); //Double check if this actually needed + status = HAL_I2C_Master_Receive(interface->hi2c, interface->device_address , interface->received_data, interface->num_bytes, 1000); //Listen for the value stored + if(status != HAL_OK) + return status; + + for(int i=0; inum_bytes; i++){ // Check the data match what was sent + if(interface->send_data[i] != interface->received_data[i]){ + return COMM_ERROR; + } + } + return HAL_OK; +} diff --git a/I2C_Wrapper.h b/I2C_Wrapper.h new file mode 100644 index 0000000..304abc7 --- /dev/null +++ b/I2C_Wrapper.h @@ -0,0 +1,31 @@ +/* + * I2C_Wrapper.h + * + * Created on: Nov 16, 2024 + * Author: diogo + */ + +#ifndef I2C_WRAPPER_H_ +#define I2C_WRAPPER_H_ + + +#define COMM_ERROR 5; + +typedef struct I2C_DATA_PACKAGE{ + I2C_HandleTypeDef *hi2c; //I2Cx used - I2C_INTERFACE.hi2c = &hi2cx + uint8_t device_address; //Address of the device you wish to communicate with + uint8_t register_address; //Register of the device you want to access + uint8_t num_bytes; //Number of bytes you will be accessing (DO NOT count the register address!) + uint8_t send_data[254]; //Array with the data you want to write + uint8_t received_data[255];//Array that the data read will be saved +}I2C_INTERFACE; + + +//Function Prototypes +//================================================================ +uint8_t I2C_writeReg(I2C_INTERFACE *interface); +/* + * Function to Write a register + * */ + +#endif /* I2C_WRAPPER_H_ */ diff --git a/I2C_Wrapper/i2c_wrapper.cpp b/I2C_Wrapper/i2c_wrapper.cpp new file mode 100644 index 0000000..c9e5859 --- /dev/null +++ b/I2C_Wrapper/i2c_wrapper.cpp @@ -0,0 +1,68 @@ +/* + * i2c_wrapper.cpp + * + * Created on: Nov 16, 2024 + * Author: diogo + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "i2c_wrapper.hpp" + + + +/** Member Function Implementations ------------------------------------------*/ + +// Write to a register +uint8_t I2C_Wrapper::writeReg() { + uint8_t status; + // Create a std::array to store the data to be sent + std::array tempSend = {0}; // Size 255 for register Address + data + tempSend[0] = registerAddress; + + // Copy the data into tempSend array starting from index 1 + std::copy(sendData.begin(), sendData.begin() + numBytes , tempSend.begin() + 1); + + // Send the register address and data + status = HAL_I2C_Master_Transmit(hi2c, deviceAddress, tempSend.data(), numBytes + 1, 1000); + if (status != HAL_OK) + return status; + + // Confirm the data + status = HAL_I2C_Master_Transmit(hi2c, deviceAddress, ®isterAddress, 1, 1000); // Send the register address again + if (status != HAL_OK) + return status; + + uint8_t receivedData[255]; + status = HAL_I2C_Master_Receive(hi2c, deviceAddress, receivedData, numBytes, 1000); // Read back data + if (status != HAL_OK) + return status; + + // Verify the data + for (int i = 0; i < numBytes; ++i) { + if (sendData[i] != receivedData[i]) + return COMM_ERROR; // Data mismatch + } + + return HAL_OK; // Success +} + +// Read from a register +uint8_t I2C_Wrapper::readReg() { + uint8_t status; + + // Send the register address + status = HAL_I2C_Master_Transmit(hi2c, deviceAddress, ®isterAddress, 1, 1000); + if (status != HAL_OK) + return status; + + // Read the data from the register + status = HAL_I2C_Master_Receive(hi2c, deviceAddress, receiveData.data(), numBytes, 1000); + return status; +} + + +void I2C_Wrapper::updDeviceAddr(uint8_t newAddress){ + deviceAddress = newAddress; +} + diff --git a/I2C_Wrapper/i2c_wrapper.hpp b/I2C_Wrapper/i2c_wrapper.hpp new file mode 100644 index 0000000..9f782fd --- /dev/null +++ b/I2C_Wrapper/i2c_wrapper.hpp @@ -0,0 +1,88 @@ +/* + * i2c_wrapper.hpp + * + * Created on: Nov 16, 2024 + * Author: diogo + */ + +#ifndef I2C_WRAPPER_HPP_ +#define I2C_WRAPPER_HPP_ + +#include + +extern "C" { + #include "stm32h7xx_hal.h" +} + +#define COMM_ERROR 5 + + +/** + * @brief Wrapper for I2C communication with specific device. + */ +class I2C_Wrapper { +public: + //Constructor + //================================================================= + /** + * @brief Constructs the I2C_Wrapper object. + * @param i2c Pointer to the I2C handle. + * @param deviceAddress 8-bit device address. + */ + I2C_Wrapper(I2C_HandleTypeDef* i2c, uint8_t deviceAddress) + : hi2c(i2c), deviceAddress(deviceAddress) {} + //================================================================= + + + //Variables + //================================================================= + uint8_t registerAddress; + uint8_t numBytes; // Don't include the byte for the register address + std::array sendData; // 254 + 1 for the register address + std::array receiveData; + //================================================================= + + + + // Functions + //================================================================= + /** + * @brief Writes data to a register on the I2C device. + * + * This function writes the data stored in the `sendData` buffer to the + * register specified by `registerAddress` on the I2C device. + * + * @return uint8_t 0 if success, non-zero if an error occurs. + */ + uint8_t writeReg(); + + + + /** + * @brief Reads data from a register on the I2C device. + * + * This function reads data from the register specified by `registerAddress` + * on the I2C device into the `receiveData` buffer. + * + * @return uint8_t 0 if success, non-zero if an error occurs. + */ + uint8_t readReg(); + + + /** + * @brief Update the device address variable + * + * @param newAddress 8-bits long address of the new device. + * + */ + void I2C_Wrapper::updDeviceAddr(uint8_t newAddress); + //================================================================= + +private: + I2C_HandleTypeDef* hi2c; + uint8_t deviceAddress; +}; + + + +#endif /* I2C_WRAPPER_HPP_ */ diff --git a/README.md b/README.md index 75072ad..79986b0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # CommunicationSystemsSubmodule -This repository will host drivers for communication protocols such as UART drivers. +This repository will host drivers for communication protocols such as I2C drivers.