From a44abc72ec29217247d8b318f9be3ae491c74a8c Mon Sep 17 00:00:00 2001 From: SMFSW Date: Thu, 30 Nov 2017 01:32:44 +0100 Subject: [PATCH] v1.1: fixed bus speed calc & returning configuration value applied instead of bool --- Doxyfile | 2 +- Release Notes.txt | 5 + examples/ci2c_advanced/ci2c_advanced.ino | 4 +- library.properties | 2 +- src/ci2c.c | 280 +++++++++++----------- src/ci2c.h | 283 ++++++++++++----------- 6 files changed, 291 insertions(+), 285 deletions(-) diff --git a/Doxyfile b/Doxyfile index c77cf77..86df2ac 100755 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Arduino Hardware I2C for AVR MCUs (plain c)" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.0 +PROJECT_NUMBER = 1.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/Release Notes.txt b/Release Notes.txt index 88a2514..37763a8 100755 --- a/Release Notes.txt +++ b/Release Notes.txt @@ -15,6 +15,11 @@ Feel free to share your thoughts @ xgarmanboziax@gmail.com about: ------------ ** Actual: +v1.1 29 Nov 2017: +- Frequency calculation fix (thanks to TonyWilk) +- Set Frequency higher than Fast Mode (400KHz) will set bus to Fast Mode (frequency is up to 400KHz on AVR) +- I2C_set_xxx now returns values applied, not bool + v1.0 21 Nov 2017: - Added const qualifier for function parameters - Return from comm functions if bytes to R/W set to 0 diff --git a/examples/ci2c_advanced/ci2c_advanced.ino b/examples/ci2c_advanced/ci2c_advanced.ino index 4753c88..99ec91d 100755 --- a/examples/ci2c_advanced/ci2c_advanced.ino +++ b/examples/ci2c_advanced/ci2c_advanced.ino @@ -64,7 +64,7 @@ void loop() { */ bool I2C_wr_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes) { - if (bytes == 0) { return false; } + if (bytes == 0) { return false; } slave->reg_addr = reg_addr; @@ -100,7 +100,7 @@ bool I2C_wr_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, */ bool I2C_rd_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes) { - if (bytes == 0) { return false; } + if (bytes == 0) { return false; } slave->reg_addr = reg_addr; diff --git a/library.properties b/library.properties index da23ab2..03a46be 100755 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=cI2C -version=1.0 +version=1.1 author=SMFSW maintainer=SMFSW sentence=Arduino Hardware I2C for AVR (in plain c) diff --git a/src/ci2c.c b/src/ci2c.c index c6e50d5..9293724 100755 --- a/src/ci2c.c +++ b/src/ci2c.c @@ -1,6 +1,6 @@ /*!\file ci2c.c ** \author SMFSW -** \version 1.0 +** \version 1.1 ** \copyright MIT SMFSW (2017) ** \brief arduino master i2c in plain c code **/ @@ -35,13 +35,13 @@ #define clrRegBit(r, b) r &= (uint8_t) (~(1 << b)) //!< clear bit \b b in register \b r #define invRegBit(r, b) r ^= (1 << b) //!< invert bit \b b in register \b r -/*! \struct i2c - * \brief static ci2c bus config and control parameters - */ +/*!\struct i2c +** \brief static ci2c bus config and control parameters +**/ static struct { - /*! \struct cfg - * \brief ci2c bus parameters - */ + /*!\struct cfg + ** \brief ci2c bus parameters + **/ struct { I2C_SPEED speed; //!< i2c bus speed uint8_t retries; //!< i2c message retries when fail @@ -57,12 +57,12 @@ static bool I2C_wr(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, c static bool I2C_rd(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes); -/*! \brief Init an I2C slave structure for cMI2C communication - * \param [in] slave - pointer to the I2C slave structure to init - * \param [in] sl_addr - I2C slave address - * \param [in] reg_sz - internal register map size - * \return nothing - */ +/*!\brief Init an I2C slave structure for cMI2C communication +** \param [in] slave - pointer to the I2C slave structure to init +** \param [in] sl_addr - I2C slave address +** \param [in] reg_sz - internal register map size +** \return nothing +**/ void I2C_slave_init(I2C_SLAVE * slave, const uint8_t sl_addr, const I2C_INT_SIZE reg_sz) { (void) I2C_slave_set_addr(slave, sl_addr); @@ -73,23 +73,23 @@ void I2C_slave_init(I2C_SLAVE * slave, const uint8_t sl_addr, const I2C_INT_SIZE slave->status = I2C_OK; } -/*! \brief Redirect slave I2C read/write function (if needed for advanced use) - * \param [in] slave - pointer to the I2C slave structure to init - * \param [in] func - pointer to read/write function to affect - * \param [in] rw - 0 = write function, 1 = read function - * \return nothing - */ +/*!\brief Redirect slave I2C read/write function (if needed for advanced use) +** \param [in] slave - pointer to the I2C slave structure to init +** \param [in] func - pointer to read/write function to affect +** \param [in] rw - 0 = write function, 1 = read function +** \return nothing +**/ void I2C_slave_set_rw_func(I2C_SLAVE * slave, const ci2c_fct_ptr func, const I2C_RW rw) { ci2c_fct_ptr * pfc = (ci2c_fct_ptr*) (rw ? &slave->cfg.rd : &slave->cfg.wr); *pfc = func; } -/*! \brief Change I2C slave address - * \param [in, out] slave - pointer to the I2C slave structure to init - * \param [in] sl_addr - I2C slave address - * \return true if new address set (false if address is >7Fh) - */ +/*!\brief Change I2C slave address +** \param [in, out] slave - pointer to the I2C slave structure to init +** \param [in] sl_addr - I2C slave address +** \return true if new address set (false if address is >7Fh) +**/ bool I2C_slave_set_addr(I2C_SLAVE * slave, const uint8_t sl_addr) { if (sl_addr > 0x7F) { return false; } @@ -97,33 +97,33 @@ bool I2C_slave_set_addr(I2C_SLAVE * slave, const uint8_t sl_addr) return true; } -/*! \brief Change I2C registers map size (for access) - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_sz - internal register map size - * \return true if new size is correct (false otherwise and set to 16bit by default) - */ +/*!\brief Change I2C registers map size (for access) +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_sz - internal register map size +** \return true if new size is correct (false otherwise and set to 16bit by default) +**/ bool I2C_slave_set_reg_size(I2C_SLAVE * slave, const I2C_INT_SIZE reg_sz) { slave->cfg.reg_size = reg_sz > I2C_16B_REG ? I2C_16B_REG : reg_sz; return !(reg_sz > I2C_16B_REG); } -/*! \brief Set I2C current register address - * \attribute inline - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_addr - register address - * \return nothing - */ +/*!\brief Set I2C current register address +** \attribute inline +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_addr - register address +** \return nothing +**/ static inline void __attribute__((__always_inline__)) I2C_slave_set_reg_addr(I2C_SLAVE * slave, const uint16_t reg_addr) { slave->reg_addr = reg_addr; } -/*! \brief Enable I2c module on arduino board (including pull-ups, - * enabling of ACK, and setting clock frequency) - * \param [in] speed - I2C bus speed in KHz - * \return nothing - */ +/*!\brief Enable I2c module on arduino board (including pull-ups, + * enabling of ACK, and setting clock frequency) +** \param [in] speed - I2C bus speed in KHz +** \return nothing +**/ void I2C_init(const uint16_t speed) { // Set SDA and SCL to ports with pull-ups @@ -138,9 +138,9 @@ void I2C_init(const uint16_t speed) (void) I2C_set_speed(speed); } -/*! \brief Disable I2c module on arduino board (releasing pull-ups, and TWI control) - * \return nothing - */ +/*!\brief Disable I2c module on arduino board (releasing pull-ups, and TWI control) +** \return nothing +**/ void I2C_uninit() { // Release SDA and SCL ports pull-ups @@ -156,9 +156,9 @@ void I2C_uninit() } -/*! \brief I2C bus reset (Release SCL and SDA lines and re-enable module) - * \return nothing - */ +/*!\brief I2C bus reset (Release SCL and SDA lines and re-enable module) +** \return nothing +**/ void I2C_reset(void) { TWCR = 0; @@ -166,70 +166,70 @@ void I2C_reset(void) setRegBit(TWCR, TWEN); } -/*! \brief Change I2C frequency - * \param [in] speed - I2C speed in kHz (max 1MHz) - * \return true if change is successful (false otherwise) - */ -bool I2C_set_speed(const uint16_t speed) +/*!\brief Change I2C frequency +** \param [in] speed - I2C speed in KHz (max 400KHz on avr) +** \return Configured bus speed +**/ +uint16_t I2C_set_speed(const uint16_t speed) { - i2c.cfg.speed = (I2C_SPEED) ((speed == 0) ? (uint16_t) I2C_STD : ((speed > (uint16_t) I2C_HS) ? (uint16_t) I2C_STD : speed)); + i2c.cfg.speed = (I2C_SPEED) ((speed == 0) ? (uint16_t) I2C_STD : ((speed > (uint16_t) I2C_FM) ? (uint16_t) I2C_FM : speed)); clrRegBit(TWCR, TWEN); // Ensure i2c module is disabled // Set prescaler and clock frequency clrRegBit(TWSR, TWPS0); clrRegBit(TWSR, TWPS1); - TWBR = ((F_CPU / (i2c.cfg.speed * 1000)) - 16) / 2; + TWBR = (((F_CPU / 1000) / i2c.cfg.speed) - 16) / 2; I2C_reset(); // re-enable module - return (i2c.cfg.speed == speed); + return i2c.cfg.speed; } -/*! \brief Change I2C ack timeout - * \param [in] timeout - I2C ack timeout (500 ms max) - * \return true if change is successful (false otherwise) - */ -bool I2C_set_timeout(const uint16_t timeout) +/*!\brief Change I2C ack timeout +** \param [in] timeout - I2C ack timeout (500 ms max) +** \return Configured timeout +**/ +uint16_t I2C_set_timeout(const uint16_t timeout) { static const uint16_t max_timeout = 500; i2c.cfg.timeout = (timeout > max_timeout) ? max_timeout : timeout; - return (i2c.cfg.timeout == timeout); + return i2c.cfg.timeout; } -/*! \brief Change I2C message retries (in case of failure) - * \param [in] retries - I2C number of retries (max of 8) - * \return true if change is successful (false otherwise) - */ -bool I2C_set_retries(const uint8_t retries) +/*!\brief Change I2C message retries (in case of failure) +** \param [in] retries - I2C number of retries (max of 8) +** \return Configured number of retries +**/ +uint8_t I2C_set_retries(const uint8_t retries) { static const uint16_t max_retries = 8; i2c.cfg.retries = (retries > max_retries) ? max_retries : retries; - return (i2c.cfg.retries == retries); + return i2c.cfg.retries; } -/*! \brief Get I2C busy status - * \return true if busy - */ +/*!\brief Get I2C busy status +** \return true if busy +**/ bool I2C_is_busy(void) { return i2c.busy; } -/*! \brief This function reads or writes the provided data to/from the address specified. - * If anything in the write process is not successful, then it will be repeated - * up till 3 more times (default). If still not successful, returns NACK - * \param [in, out] slave - pointer to the I2C slave structure to init - * \param [in] reg_addr - register address in register map - * \param [in] data - pointer to the first byte of a block of data to write - * \param [in] bytes - indicates how many bytes of data to write - * \param [in] rw - 0 = write, 1 = read operation - * \return I2C_STATUS status of write attempt - */ +/*!\brief This function reads or writes the provided data to/from the address specified. + * If anything in the write process is not successful, then it will be repeated + * up till 3 more times (default). If still not successful, returns NACK +** \param [in, out] slave - pointer to the I2C slave structure to init +** \param [in] reg_addr - register address in register map +** \param [in] data - pointer to the first byte of a block of data to write +** \param [in] bytes - indicates how many bytes of data to write +** \param [in] rw - 0 = write, 1 = read operation +** \return I2C_STATUS status of write attempt +**/ static I2C_STATUS I2C_comm(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes, const I2C_RW rw) { - uint8_t retry = i2c.cfg.retries; - bool ack = false; - ci2c_fct_ptr fc = (ci2c_fct_ptr) (rw ? slave->cfg.rd : slave->cfg.wr); + uint8_t retry = i2c.cfg.retries; + bool ack = false; + ci2c_fct_ptr fc = (ci2c_fct_ptr) (rw ? slave->cfg.rd : slave->cfg.wr); if (I2C_is_busy()) { return slave->status = I2C_BUSY; } i2c.busy = true; @@ -246,45 +246,45 @@ static I2C_STATUS I2C_comm(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * return slave->status = ack ? I2C_OK : I2C_NACK; } -/*! \brief This function writes the provided data to the address specified. - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_addr - register address in register map - * \param [in] data - pointer to the first byte of a block of data to write - * \param [in] bytes - indicates how many bytes of data to write - * \return I2C_STATUS status of write attempt - */ +/*!\brief This function writes the provided data to the address specified. +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_addr - register address in register map +** \param [in] data - pointer to the first byte of a block of data to write +** \param [in] bytes - indicates how many bytes of data to write +** \return I2C_STATUS status of write attempt +**/ I2C_STATUS I2C_write(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes) { return I2C_comm(slave, reg_addr, data, bytes, I2C_WRITE); } -/*! \brief This function reads data from the address specified and stores this - * data in the area provided by the pointer. - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_addr - register address in register map - * \param [in, out] data - pointer to the first byte of a block of data to read - * \param [in] bytes - indicates how many bytes of data to read - * \return I2C_STATUS status of read attempt - */ +/*!\brief This function reads data from the address specified and stores this + * data in the area provided by the pointer. +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_addr - register address in register map +** \param [in, out] data - pointer to the first byte of a block of data to read +** \param [in] bytes - indicates how many bytes of data to read +** \return I2C_STATUS status of read attempt +**/ I2C_STATUS I2C_read(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes) { return I2C_comm(slave, reg_addr, data, bytes, I2C_READ); } -/*! \brief Start i2c_timeout timer - * \attribute inline - * \return nothing - */ +/*!\brief Start i2c_timeout timer +** \attribute inline +** \return nothing +**/ static inline void __attribute__((__always_inline__)) I2C_start_timeout(void) { i2c.start_wait = (uint16_t) millis(); } -/*! \brief Test i2c_timeout - * \attribute inline - * \return true if i2c_timeout occured (false otherwise) - */ +/*!\brief Test i2c_timeout +** \attribute inline +** \return true if i2c_timeout occured (false otherwise) +**/ static inline uint8_t __attribute__((__always_inline__)) I2C_timeout(void) { return (((uint16_t) millis() - i2c.start_wait) >= i2c.cfg.timeout); } -/*! \brief Send start condition - * \return true if start condition acknowledged (false otherwise) - */ +/*!\brief Send start condition +** \return true if start condition acknowledged (false otherwise) +**/ bool I2C_start(void) { I2C_start_timeout(); @@ -300,9 +300,9 @@ bool I2C_start(void) return false; } -/*! \brief Send stop condition - * \return true if stop condition acknowledged (false otherwise) - */ +/*!\brief Send stop condition +** \return true if stop condition acknowledged (false otherwise) +**/ bool I2C_stop(void) { I2C_start_timeout(); @@ -315,10 +315,10 @@ bool I2C_stop(void) return true; } -/*! \brief Send byte on bus - * \param [in] dat - data to be sent - * \return true if data sent acknowledged (false otherwise) - */ +/*!\brief Send byte on bus +** \param [in] dat - data to be sent +** \return true if data sent acknowledged (false otherwise) +**/ bool I2C_wr8(const uint8_t dat) { TWDR = dat; @@ -338,10 +338,10 @@ bool I2C_wr8(const uint8_t dat) return false; } -/*! \brief Receive byte from bus - * \param [in] ack - true if wait for ack - * \return true if data reception acknowledged (false otherwise) - */ +/*!\brief Receive byte from bus +** \param [in] ack - true if wait for ack +** \return true if data reception acknowledged (false otherwise) +**/ uint8_t I2C_rd8(const bool ack) { I2C_start_timeout(); @@ -357,11 +357,11 @@ uint8_t I2C_rd8(const bool ack) return ((((TWI_STATUS == MR_DATA_NACK) && (!ack)) || ((TWI_STATUS == MR_DATA_ACK) && (ack))) ? true : false); } -/*! \brief Send I2C address - * \param [in] slave - pointer to the I2C slave structure - * \param [in] rw - read/write transaction - * \return true if I2C chip address sent acknowledged (false otherwise) - */ +/*!\brief Send I2C address +** \param [in] slave - pointer to the I2C slave structure +** \param [in] rw - read/write transaction +** \return true if I2C chip address sent acknowledged (false otherwise) +**/ bool I2C_sndAddr(I2C_SLAVE * slave, const I2C_RW rw) { TWDR = (slave->cfg.addr << 1) | rw; @@ -382,16 +382,16 @@ bool I2C_sndAddr(I2C_SLAVE * slave, const I2C_RW rw) } -/*! \brief This procedure calls appropriate functions to perform a proper send transaction on I2C bus. - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_addr - register address in register map - * \param [in] data - pointer to the first byte of a block of data to write - * \param [in] bytes - indicates how many bytes of data to write - * \return Boolean indicating success/fail of write attempt - */ +/*!\brief This procedure calls appropriate functions to perform a proper send transaction on I2C bus. +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_addr - register address in register map +** \param [in] data - pointer to the first byte of a block of data to write +** \param [in] bytes - indicates how many bytes of data to write +** \return Boolean indicating success/fail of write attempt +**/ static bool I2C_wr(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes) { - if (bytes == 0) { return false; } + if (bytes == 0) { return false; } (void) I2C_slave_set_reg_addr(slave, reg_addr); @@ -418,16 +418,16 @@ static bool I2C_wr(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, c } -/*! \brief This procedure calls appropriate functions to perform a proper receive transaction on I2C bus. - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_addr - register address in register map - * \param [in, out] data - pointer to the first byte of a block of data to read - * \param [in] bytes - indicates how many bytes of data to read - * \return Boolean indicating success/fail of read attempt - */ +/*!\brief This procedure calls appropriate functions to perform a proper receive transaction on I2C bus. +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_addr - register address in register map +** \param [in, out] data - pointer to the first byte of a block of data to read +** \param [in] bytes - indicates how many bytes of data to read +** \return Boolean indicating success/fail of read attempt +**/ static bool I2C_rd(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes) { - if (bytes == 0) { return false; } + if (bytes == 0) { return false; } (void) I2C_slave_set_reg_addr(slave, reg_addr); diff --git a/src/ci2c.h b/src/ci2c.h index 55ddae5..b3196dd 100755 --- a/src/ci2c.h +++ b/src/ci2c.h @@ -1,6 +1,6 @@ /*!\file ci2c.h ** \author SMFSW -** \version 1.0 +** \version 1.1 ** \copyright MIT SMFSW (2017) ** \brief arduino i2c in plain c declarations **/ @@ -25,49 +25,49 @@ #ifdef __cplusplus -extern "C"{ +extern "C" { #endif #define DEF_CI2C_NB_RETRIES 3 //!< Default cI2C transaction retries #define DEF_CI2C_TIMEOUT 100 //!< Default cI2C timeout -/*! \enum enI2C_RW - * \brief I2C RW bit enumeration - * \attribute packed enum - */ +/*!\enum enI2C_RW +** \brief I2C RW bit enumeration +** \attribute packed enum +**/ typedef enum __attribute__((__packed__)) enI2C_RW { I2C_WRITE = 0, //!< I2C rw bit (write) I2C_READ //!< I2C rw bit (read) } I2C_RW; -/*! \enum enI2C_SPEED - * \brief I2C bus speed - * \attribute packed enum - */ +/*!\enum enI2C_SPEED +** \brief I2C bus speed +** \attribute packed enum +**/ typedef enum __attribute__((__packed__)) enI2C_SPEED { I2C_STD = 100, //!< I2C Standard (100KHz) I2C_FM = 400, //!< I2C Fast Mode (400KHz) - I2C_FMP = 1000, //!< I2C Fast mode + (1MHz) - I2C_HS = 3400 //!< I2C High Speed (3.4MHz) + I2C_FMP = 1000, //!< I2C Fast mode + (1MHz): will set speed to Fast Mode (up to 400KHz on avr) + I2C_HS = 3400 //!< I2C High Speed (3.4MHz): will set speed to Fast Mode (up to 400KHz on avr) } I2C_SPEED; -/*! \enum enI2C_STATUS - * \brief I2C slave status - * \attribute packed enum - */ +/*!\enum enI2C_STATUS +** \brief I2C slave status +** \attribute packed enum +**/ typedef enum __attribute__((__packed__)) enI2C_STATUS { I2C_OK = 0x00, //!< I2C OK I2C_BUSY, //!< I2C Bus busy I2C_NACK //!< I2C Not Acknowledge } I2C_STATUS; -/*! \enum enI2C_INT_SIZE - * \brief I2C slave internal address registers size - * \attribute packed enum - */ +/*!\enum enI2C_INT_SIZE +** \brief I2C slave internal address registers size +** \attribute packed enum +**/ typedef enum __attribute__((__packed__)) enI2C_INT_SIZE { I2C_NO_REG = 0x00, //!< Internal address registers not applicable for slave I2C_8B_REG, //!< Slave internal address registers space is 8bits wide @@ -78,14 +78,14 @@ typedef enum __attribute__((__packed__)) enI2C_INT_SIZE { typedef bool (*ci2c_fct_ptr) (void*, const uint16_t, uint8_t*, const uint16_t); //!< i2c read/write function pointer typedef -/*! \struct StructI2CSlave - * \brief ci2c slave config and control parameters - * \attribute packed struct - */ +/*!\struct StructI2CSlave +** \brief ci2c slave config and control parameters +** \attribute packed struct +**/ typedef struct __attribute__((__packed__)) StructI2CSlave { - /*! \struct cfg - * \brief ci2c slave parameters - */ + /*!\struct cfg + ** \brief ci2c slave parameters + **/ struct { uint8_t addr; //!< Slave address I2C_INT_SIZE reg_size; //!< Slave internal registers size @@ -101,136 +101,137 @@ typedef struct __attribute__((__packed__)) StructI2CSlave { /*** I2C SLAVE FUNCTIONS ***/ /***************************/ -/*! \brief Init an I2C slave structure for cMI2C communication - * \param [in] slave - pointer to the I2C slave structure to init - * \param [in] sl_addr - I2C slave address - * \param [in] reg_sz - internal register map size - * \return nothing - */ +/*!\brief Init an I2C slave structure for cMI2C communication +** \param [in] slave - pointer to the I2C slave structure to init +** \param [in] sl_addr - I2C slave address +** \param [in] reg_sz - internal register map size +** \return nothing +**/ void I2C_slave_init(I2C_SLAVE * slave, const uint8_t sl_addr, const I2C_INT_SIZE reg_sz); -/*! \brief Redirect slave I2C read/write function (if needed for advanced use) - * \param [in] slave - pointer to the I2C slave structure to init - * \param [in] func - pointer to read/write function to affect - * \param [in] rw - 0 = write function, 1 = read function - * \return nothing - */ +/*!\brief Redirect slave I2C read/write function (if needed for advanced use) +** \param [in] slave - pointer to the I2C slave structure to init +** \param [in] func - pointer to read/write function to affect +** \param [in] rw - 0 = write function, 1 = read function +** \return nothing +**/ void I2C_slave_set_rw_func(I2C_SLAVE * slave, const ci2c_fct_ptr func, const I2C_RW rw); -/*! \brief Change I2C slave address - * \param [in, out] slave - pointer to the I2C slave structure to init - * \param [in] sl_addr - I2C slave address - * \return true if new address set (false if address is >7Fh) - */ +/*!\brief Change I2C slave address +** \param [in, out] slave - pointer to the I2C slave structure to init +** \param [in] sl_addr - I2C slave address +** \return true if new address set (false if address is >7Fh) +**/ bool I2C_slave_set_addr(I2C_SLAVE * slave, const uint8_t sl_addr); -/*! \brief Change I2C registers map size (for access) - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_sz - internal register map size - * \return true if new size is correct (false otherwise and set to 16bit by default) - */ +/*!\brief Change I2C registers map size (for access) +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_sz - internal register map size +** \return true if new size is correct (false otherwise and set to 16bit by default) +**/ bool I2C_slave_set_reg_size(I2C_SLAVE * slave, const I2C_INT_SIZE reg_sz); -/*! \brief Get I2C slave address - * \attribute inline - * \param [in] slave - pointer to the I2C slave structure - * \return I2C slave address - */ +/*!\brief Get I2C slave address +** \attribute inline +** \param [in] slave - pointer to the I2C slave structure +** \return I2C slave address +**/ inline uint8_t __attribute__((__always_inline__)) I2C_slave_get_addr(const I2C_SLAVE * slave) { return slave->cfg.addr; } -/*! \brief Get I2C register map size (for access) - * \attribute inline - * \param [in] slave - pointer to the I2C slave structure - * \return register map using 16bits if true (1Byte otherwise) - */ +/*!\brief Get I2C register map size (for access) +** \attribute inline +** \param [in] slave - pointer to the I2C slave structure +** \return register map using 16bits if true (1Byte otherwise) +**/ inline bool __attribute__((__always_inline__)) I2C_slave_get_reg_size(const I2C_SLAVE * slave) { return slave->cfg.reg_size; } -/*! \brief Get I2C current register address (addr may passed this way in procedures if contigous accesses) - * \attribute inline - * \param [in] slave - pointer to the I2C slave structure - * \return current register map address - */ +/*!\brief Get I2C current register address (addr may passed this way in procedures if contigous accesses) +** \attribute inline +** \param [in] slave - pointer to the I2C slave structure +** \return current register map address +**/ inline uint16_t __attribute__((__always_inline__)) I2C_slave_get_reg_addr(const I2C_SLAVE * slave) { return slave->reg_addr; } + /*************************/ /*** I2C BUS FUNCTIONS ***/ /*************************/ -/*! \brief Enable I2c module on arduino board (including pull-ups, - * enabling of ACK, and setting clock frequency) - * \param [in] speed - I2C bus speed in KHz - * \return nothing - */ +/*!\brief Enable I2c module on arduino board (including pull-ups, + * enabling of ACK, and setting clock frequency) +** \param [in] speed - I2C bus speed in KHz +** \return nothing +**/ void I2C_init(const uint16_t speed); -/*! \brief Disable I2c module on arduino board (releasing pull-ups, and TWI control) - * \return nothing - */ +/*!\brief Disable I2c module on arduino board (releasing pull-ups, and TWI control) +** \return nothing +**/ void I2C_uninit(); -/*! \brief Change I2C frequency - * \param [in] speed - I2C bus speed in KHz - * \return true if change is successful (false otherwise) - */ -bool I2C_set_speed(const uint16_t speed); +/*!\brief Change I2C frequency +** \param [in] speed - I2C bus speed in KHz (max 400KHz on AVR) +** \return Configured bus speed +**/ +uint16_t I2C_set_speed(const uint16_t speed); -/*! \brief Change I2C ack timeout - * \param [in] timeout - I2C ack timeout (500 ms max) - * \return true if change is successful (false otherwise) - */ -bool I2C_set_timeout(const uint16_t timeout); +/*!\brief Change I2C ack timeout +** \param [in] timeout - I2C ack timeout (500 ms max) +** \return Configured timeout +**/ +uint16_t I2C_set_timeout(const uint16_t timeout); -/*! \brief Change I2C message retries (in case of failure) - * \param [in] retries - I2C number of retries (max of 8) - * \return true if change is successful (false otherwise) - */ -bool I2C_set_retries(const uint8_t retries); +/*!\brief Change I2C message retries (in case of failure) +** \param [in] retries - I2C number of retries (max of 8) +** \return Configured number of retries +**/ +uint8_t I2C_set_retries(const uint8_t retries); -/*! \brief Get I2C busy status - * \return true if busy - */ +/*!\brief Get I2C busy status +** \return true if busy +**/ bool I2C_is_busy(void); -/*! \brief This function writes the provided data to the address specified. - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_addr - register address in register map - * \param [in] data - pointer to the first byte of a block of data to write - * \param [in] bytes - indicates how many bytes of data to write - * \return I2C_STATUS status of write attempt - */ +/*!\brief This function writes the provided data to the address specified. +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_addr - register address in register map +** \param [in] data - pointer to the first byte of a block of data to write +** \param [in] bytes - indicates how many bytes of data to write +** \return I2C_STATUS status of write attempt +**/ I2C_STATUS I2C_write(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes); -/*! \brief This inline is a wrapper to I2C_write in case of contigous operations - * \attribute inline - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] data - pointer to the first byte of a block of data to write - * \param [in] bytes - indicates how many bytes of data to write - * \return I2C_STATUS status of write attempt - */ +/*!\brief This inline is a wrapper to I2C_write in case of contigous operations +** \attribute inline +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] data - pointer to the first byte of a block of data to write +** \param [in] bytes - indicates how many bytes of data to write +** \return I2C_STATUS status of write attempt +**/ inline I2C_STATUS __attribute__((__always_inline__)) I2C_write_next(I2C_SLAVE * slave, uint8_t * data, const uint16_t bytes) { // TODO: implement read next so that it doesn't have to send start register address again return I2C_write(slave, slave->reg_addr, data, bytes); } -/*! \brief This function reads data from the address specified and stores this - * data in the area provided by the pointer. - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] reg_addr - register address in register map - * \param [in, out] data - pointer to the first byte of a block of data to read - * \param [in] bytes - indicates how many bytes of data to read - * \return I2C_STATUS status of read attempt - */ +/*!\brief This function reads data from the address specified and stores this + * data in the area provided by the pointer. +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] reg_addr - register address in register map +** \param [in, out] data - pointer to the first byte of a block of data to read +** \param [in] bytes - indicates how many bytes of data to read +** \return I2C_STATUS status of read attempt +**/ I2C_STATUS I2C_read(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes); -/*! \brief This inline is a wrapper to I2C_read in case of contigous operations - * \attribute inline - * \param [in, out] slave - pointer to the I2C slave structure - * \param [in] data - pointer to the first byte of a block of data to read - * \param [in] bytes - indicates how many bytes of data to read - * \return I2C_STATUS status of read attempt - */ +/*!\brief This inline is a wrapper to I2C_read in case of contigous operations +** \attribute inline +** \param [in, out] slave - pointer to the I2C slave structure +** \param [in] data - pointer to the first byte of a block of data to read +** \param [in] bytes - indicates how many bytes of data to read +** \return I2C_STATUS status of read attempt +**/ inline I2C_STATUS __attribute__((__always_inline__)) I2C_read_next(I2C_SLAVE * slave, uint8_t * data, const uint16_t bytes) { // TODO: implement read next so that it doesn't have to send start register address again return I2C_read(slave, slave->reg_addr, data, bytes); } @@ -240,38 +241,38 @@ inline I2C_STATUS __attribute__((__always_inline__)) I2C_read_next(I2C_SLAVE * s /*** cI2C LOW LEVEL FUNCTIONS ***/ /*** THAT MAY BE USEFUL FOR DVPT ***/ /***********************************/ -/*! \brief I2C bus reset (Release SCL and SDA lines and re-enable module) - * \return nothing - */ +/*!\brief I2C bus reset (Release SCL and SDA lines and re-enable module) +** \return nothing +**/ void I2C_reset(void); -/*! \brief Send start condition - * \return true if start condition acknowledged (false otherwise) - */ +/*!\brief Send start condition +** \return true if start condition acknowledged (false otherwise) +**/ bool I2C_start(void); -/*! \brief Send stop condition - * \return true if stop condition acknowledged (false otherwise) - */ +/*!\brief Send stop condition +** \return true if stop condition acknowledged (false otherwise) +**/ bool I2C_stop(void); -/*! \brief Send byte on bus - * \param [in] dat - data to be sent - * \return true if data sent acknowledged (false otherwise) - */ +/*!\brief Send byte on bus +** \param [in] dat - data to be sent +** \return true if data sent acknowledged (false otherwise) +**/ bool I2C_wr8(const uint8_t dat); -/*! \brief Receive byte from bus - * \param [in] ack - true if wait for ack - * \return true if data reception acknowledged (false otherwise) - */ +/*!\brief Receive byte from bus +** \param [in] ack - true if wait for ack +** \return true if data reception acknowledged (false otherwise) +**/ uint8_t I2C_rd8(const bool ack); -/*! \brief Send I2C address - * \param [in] slave - pointer to the I2C slave structure - * \param [in] rw - read/write transaction - * \return true if I2C chip address sent acknowledged (false otherwise) - */ +/*!\brief Send I2C address +** \param [in] slave - pointer to the I2C slave structure +** \param [in] rw - read/write transaction +** \return true if I2C chip address sent acknowledged (false otherwise) +**/ bool I2C_sndAddr(I2C_SLAVE * slave, const I2C_RW rw);