-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwirewrapper_advanced.ino
More file actions
148 lines (117 loc) · 4.73 KB
/
wirewrapper_advanced.ino
File metadata and controls
148 lines (117 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
Master i2c (advanced)
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 23 2017
latest mod May 13 2018
by SMFSW
*/
#include <WireWrapper.h>
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_FM); // init with Fast Mode (400KHz)
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);
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, 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); // print hex values
Serial.print(" ");
}
delay(5000);
}
/*! \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
*/
bool I2C_wr_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, const uint16_t bytes)
{
if (bytes == 0) { return false; }
Wire.beginTransmission(slave->cfg.addr);
if ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if writing next
{
slave->reg_addr = reg_addr;
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
{
if (Wire.write((uint8_t) (reg_addr >> 8)) == 0) { return false; }
}
if (Wire.write((uint8_t) reg_addr) == 0) { return false; }
}
for (uint16_t cnt = 0; cnt < bytes; cnt++)
{
if (Wire.write(*(data++)) == 0) { return false; }
slave->reg_addr++;
}
if (Wire.endTransmission() != 0) { return false; }
return true;
}
/*! \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
*/
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 ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if reading next
{
slave->reg_addr = reg_addr;
Wire.beginTransmission(slave->cfg.addr);
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
{
if (Wire.write((uint8_t) (reg_addr >> 8)) == 0) { return false; }
}
if (Wire.write((uint8_t) reg_addr) == 0) { return false; }
if (Wire.endTransmission(false) != 0) { return false; }
}
if (Wire.requestFrom((int) slave->cfg.addr, (int) bytes) == 0) { return false; }
for (uint16_t cnt = 0; cnt < bytes; cnt++)
{
*data++ = Wire.read();
slave->reg_addr++;
}
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 int16_t bytes = 3;
I2C_SLAVE FRAM_ID;
I2C_slave_init(&FRAM_ID, 0xF8 >> 1, I2C_16B_REG); // Dummy slave init for I2C_sndAddr
Wire.beginTransmission(FRAM_ID.cfg.addr);
if (Wire.write(slave->cfg.addr << 1) == 0) { return false; }
if (Wire.endTransmission(false) != 0) { return false; }
if (Wire.requestFrom((int) FRAM_ID.cfg.addr, (int) bytes) == 0) { return false; }
for (uint16_t cnt = 0; cnt < bytes; cnt++)
{ *data++ = Wire.read(); }
return true;
}