1
0
Fork 0
mirror of https://github.com/SMFSW/cI2C synced 2025-07-04 20:46:56 +02:00

v0.3: bugfixes and refactoring

This commit is contained in:
SMFSW 2017-01-22 18:32:00 +01:00
parent 588c8106a3
commit 4728577666
11 changed files with 536 additions and 350 deletions

117
examples/ci2c_advanced/ci2c_advanced.ino Normal file → Executable file
View file

@ -1,38 +1,53 @@
/*
Master i2c (advanced)
Redirecting write & read slave functions in setup (to custom functions following template)
Redirecting slave write & read functions in setup (to custom functions following typedef)
Read and Write operations are then called using the same functions
Function to get Chip ID are device dependant (and will probably only work on FUJITSU devices)
This example code is in the public domain.
created Jan 12 2017
latest mod Jan 16 2017
latest mod Jan 22 2017
by SMFSW
*/
#include <ci2c.h>
I2C_SLAVE FRAM;
const uint8_t blank = 0xEE; // blank tab filling value for test
I2C_SLAVE FRAM; // slave declaration
void setup() {
uint8_t str[3];
memset(&str, blank, sizeof(str));
Serial.begin(115200); // start serial for output
I2C_init(I2C_LOW); // init with low speed (400KHz)
I2C_slave_init(&FRAM, 0x50, I2C_16B_REG);
I2C_slave_set_rw_func(&FRAM, I2C_rd_advanced, 0);
I2C_slave_set_rw_func(&FRAM, I2C_wr_advanced, 1);
I2C_slave_set_rw_func(&FRAM, I2C_wr_advanced, I2C_WRITE);
I2C_slave_set_rw_func(&FRAM, I2C_rd_advanced, I2C_READ);
I2C_get_chip_id(&FRAM, &str[0]);
Serial.println();
//for (uint8_t i = 0; i < sizeof(str); i++) { Serial.print(str[i], HEX); } // print hex values
Serial.print("\nManufacturer ID: ");
Serial.print((str[0] << 4) + (str[1] >> 4), HEX);
Serial.print("\nProduct ID: ");
Serial.print(((str[1] & 0x0F) << 8) + str[2], HEX);
}
void loop() {
const uint16_t reg_addr = 0;
uint8_t str[7];
memset(&str, 0xEE, sizeof(str));
I2C_read(&FRAM, reg_addr, &str[0], sizeof(str)); // Addr 0, 2bytes Addr size, str, read chars for size of str
memset(&str, blank, sizeof(str));
I2C_read(&FRAM, reg_addr, &str[0], sizeof(str)); // FRAM, Addr 0, str, read chars for size of str
Serial.println();
for (uint8_t i = 0; i < sizeof(str); i++)
{
Serial.print(str[i], HEX); // receive a byte as character
Serial.print(str[i], HEX); // print hex values
Serial.print(" ");
}
@ -41,21 +56,18 @@ void loop() {
/*! \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 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] nb_bytes - indicates how many bytes of data to write
*! \return Boolean indicating success/fail of write attempt
* \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_advanced(I2C_SLAVE * slave, uint16_t reg_addr, uint8_t * data, uint16_t nb_bytes)
bool I2C_wr_advanced(I2C_SLAVE * slave, uint16_t reg_addr, uint8_t * data, uint16_t bytes)
{
uint16_t ct_w;
slave->reg_addr = reg_addr;
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave->cfg.addr << 1) == false) { return false; }
if (I2C_sndAddr(slave, I2C_WRITE) == false) { return false; }
if (slave->cfg.reg_size)
{
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
@ -65,7 +77,7 @@ static bool I2C_wr_advanced(I2C_SLAVE * slave, uint16_t reg_addr, uint8_t * data
if (I2C_snd8((uint8_t) reg_addr) == false) { return false; }
}
for (ct_w = 0; ct_w < nb_bytes; ct_w++)
for (uint16_t cnt = 0; cnt < bytes; cnt++)
{
if (I2C_snd8(*(data++)) == false) { return false; }
slave->reg_addr++;
@ -78,44 +90,34 @@ static bool I2C_wr_advanced(I2C_SLAVE * slave, uint16_t reg_addr, uint8_t * data
/*! \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 to init
*! \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] nb_bytes - indicates how many bytes of data to read
*! \return Boolean indicating success/fail of read attempt
* \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_advanced(I2C_SLAVE * slave, uint16_t reg_addr, uint8_t * data, uint16_t nb_bytes)
bool I2C_rd_advanced(I2C_SLAVE * slave, uint16_t reg_addr, uint8_t * data, uint16_t bytes)
{
uint16_t ct_r;
slave->reg_addr = reg_addr;
if (nb_bytes == 0) { nb_bytes++; }
if (bytes == 0) { bytes = 1; }
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave->cfg.addr << 1) == false) { return false; }
if (slave->cfg.reg_size)
{
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave, I2C_WRITE) == false) { return false; }
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
{
if (I2C_snd8((uint8_t) (reg_addr >> 8)) == false) { return false; }
}
if (I2C_snd8((uint8_t) reg_addr) == false) { return false; }
if (I2C_start() == false) { return false; }
if (I2C_sndAddr((slave->cfg.addr << 1) | 0x01) == false) { return false; }
}
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave, I2C_READ) == false) { return false; }
for (ct_r = 0; ct_r < nb_bytes; ct_r++)
for (uint16_t cnt = 0; cnt < bytes; cnt++)
{
if (ct_r == (nb_bytes - 1))
{
if (I2C_rcv8(false) == false) { return false; }
}
else
{
if (I2C_rcv8(true) == false) { return false; }
}
if (I2C_rcv8((cnt == (bytes - 1)) ? false : true) == false) { return false; }
*data++ = TWDR;
slave->reg_addr++;
}
@ -125,3 +127,32 @@ static bool I2C_rd_advanced(I2C_SLAVE * slave, uint16_t reg_addr, uint8_t * data
return true;
}
/*! \brief This procedure calls appropriate functions to get chip ID of FUJITSU devices.
* \param [in, out] slave - pointer to the I2C slave structure
* \param [in, out] data - pointer to the first byte of a block of data to read
* \return Boolean indicating success/fail of read attempt
*/
bool I2C_get_chip_id(I2C_SLAVE * slave, uint8_t * data)
{
const uint16_t bytes = 3;
I2C_SLAVE FRAM_ID;
I2C_slave_init(&FRAM_ID, 0xF8 >> 1, I2C_16B_REG); // Dummy slave init for I2C_sndAddr
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(&FRAM_ID, I2C_WRITE) == false) { return false; }
if (I2C_snd8(slave->cfg.addr << 1) == false) { return false; }
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(&FRAM_ID, I2C_READ) == false) { return false; }
for (uint16_t cnt = 0; cnt < bytes; cnt++)
{
if (I2C_rcv8((cnt == (bytes - 1)) ? false : true) == false) { return false; }
*data++ = TWDR;
}
if (I2C_stop() == false) { return false; }
return true;
}