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:
parent
588c8106a3
commit
4728577666
11 changed files with 536 additions and 350 deletions
117
examples/ci2c_advanced/ci2c_advanced.ino
Normal file → Executable file
117
examples/ci2c_advanced/ci2c_advanced.ino
Normal file → Executable 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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue