cI2C/examples/ci2c_advanced/ci2c_advanced.ino

161 lines
5.2 KiB
Arduino
Raw Normal View History

2017-01-16 19:22:03 +01:00
/*
Master i2c (advanced)
2017-01-22 18:32:00 +01:00
Redirecting slave write & read functions in setup (to custom functions following typedef)
2017-01-16 19:22:03 +01:00
Read and Write operations are then called using the same functions
2017-01-22 18:32:00 +01:00
Function to get Chip ID are device dependant (and will probably only work on FUJITSU devices)
2017-01-16 19:22:03 +01:00
This example code is in the public domain.
created Jan 12 2017
latest mod Nov 30 2017
2017-01-16 19:22:03 +01:00
by SMFSW
*/
#include <ci2c.h>
2017-01-22 18:32:00 +01:00
const uint8_t blank = 0xEE; // blank tab filling value for test
I2C_SLAVE FRAM; // slave declaration
2017-01-16 19:22:03 +01:00
void setup() {
2017-01-22 18:32:00 +01:00
uint8_t str[3];
memset(&str, blank, sizeof(str));
2017-01-16 19:22:03 +01:00
Serial.begin(115200); // start serial for output
2017-02-02 00:03:07 +01:00
I2C_init(I2C_FM); // init with Fast Mode (400KHz)
2017-01-16 19:22:03 +01:00
I2C_slave_init(&FRAM, 0x50, I2C_16B_REG);
I2C_slave_set_rw_func(&FRAM, (ci2c_fct_ptr) I2C_wr_advanced, I2C_WRITE);
I2C_slave_set_rw_func(&FRAM, (ci2c_fct_ptr) I2C_rd_advanced, I2C_READ);
2017-01-22 18:32:00 +01:00
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);
2017-01-16 19:22:03 +01:00
}
void loop() {
const uint16_t reg_addr = 0;
uint8_t str[7];
2017-01-22 18:32:00 +01:00
memset(&str, blank, sizeof(str));
I2C_read(&FRAM, reg_addr, &str[0], sizeof(str)); // FRAM, Addr 0, str, read chars for size of str
2017-01-16 19:22:03 +01:00
Serial.println();
for (uint8_t i = 0; i < sizeof(str); i++)
{
2017-01-22 18:32:00 +01:00
Serial.print(str[i], HEX); // print hex values
2017-01-16 19:22:03 +01:00
Serial.print(" ");
}
delay(5000);
}
/*! \brief This procedure calls appropriate functions to perform a proper send transaction on I2C bus.
2017-01-22 18:32:00 +01:00
* \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
2017-01-16 19:22:03 +01:00
*/
bool I2C_wr_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes)
2017-01-16 19:22:03 +01:00
{
if (bytes == 0) { return false; }
2017-01-16 19:22:03 +01:00
if (I2C_start() == false) { return false; }
2017-01-22 18:32:00 +01:00
if (I2C_sndAddr(slave, I2C_WRITE) == false) { return false; }
if ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if writing next
2017-01-16 19:22:03 +01:00
{
slave->reg_addr = reg_addr;
2017-01-16 19:22:03 +01:00
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
{
2017-02-02 00:03:07 +01:00
if (I2C_wr8((uint8_t) (reg_addr >> 8)) == false) { return false; }
2017-01-16 19:22:03 +01:00
}
2017-02-02 00:03:07 +01:00
if (I2C_wr8((uint8_t) reg_addr) == false) { return false; }
2017-01-16 19:22:03 +01:00
}
2017-01-22 18:32:00 +01:00
for (uint16_t cnt = 0; cnt < bytes; cnt++)
2017-01-16 19:22:03 +01:00
{
2017-02-02 00:03:07 +01:00
if (I2C_wr8(*(data++)) == false) { return false; }
2017-01-16 19:22:03 +01:00
slave->reg_addr++;
}
if (I2C_stop() == false) { return false; }
return true;
}
/*! \brief This procedure calls appropriate functions to perform a proper receive transaction on I2C bus.
2017-01-22 18:32:00 +01:00
* \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
2017-01-16 19:22:03 +01:00
*/
bool I2C_rd_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes)
2017-01-16 19:22:03 +01:00
{
if (bytes == 0) { return false; }
2017-01-16 19:22:03 +01:00
if ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if reading next
2017-01-16 19:22:03 +01:00
{
slave->reg_addr = reg_addr;
2017-01-22 18:32:00 +01:00
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave, I2C_WRITE) == false) { return false; }
2017-01-16 19:22:03 +01:00
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
{
2017-02-02 00:03:07 +01:00
if (I2C_wr8((uint8_t) (reg_addr >> 8)) == false) { return false; }
2017-01-16 19:22:03 +01:00
}
2017-02-02 00:03:07 +01:00
if (I2C_wr8((uint8_t) reg_addr) == false) { return false; }
2017-01-16 19:22:03 +01:00
}
2017-01-22 18:32:00 +01:00
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave, I2C_READ) == false) { return false; }
2017-01-16 19:22:03 +01:00
2017-01-22 18:32:00 +01:00
for (uint16_t cnt = 0; cnt < bytes; cnt++)
2017-01-16 19:22:03 +01:00
{
2017-02-02 00:03:07 +01:00
if (I2C_rd8((cnt == (bytes - 1)) ? false : true) == false) { return false; }
2017-01-16 19:22:03 +01:00
*data++ = TWDR;
slave->reg_addr++;
}
if (I2C_stop() == false) { return false; }
return true;
}
2017-01-22 18:32:00 +01:00
/*! \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; }
2017-02-02 00:03:07 +01:00
if (I2C_wr8(slave->cfg.addr << 1) == false) { return false; }
2017-01-22 18:32:00 +01:00
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(&FRAM_ID, I2C_READ) == false) { return false; }
for (uint16_t cnt = 0; cnt < bytes; cnt++)
{
2017-02-02 00:03:07 +01:00
if (I2C_rd8((cnt == (bytes - 1)) ? false : true) == false) { return false; }
2017-01-22 18:32:00 +01:00
*data++ = TWDR;
}
if (I2C_stop() == false) { return false; }
return true;
}