1 /*
2  * Copyright (c) 2015 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <zephyr.h>
9 #include <sys/printk.h>
10 #include <device.h>
11 #include <drivers/i2c.h>
12 
13 /**
14  * @file Sample app using the Fujitsu MB85RC256V FRAM through I2C.
15  */
16 
17 #define FRAM_I2C_ADDR	0x50
18 
write_bytes(const struct device * i2c_dev,uint16_t addr,uint8_t * data,uint32_t num_bytes)19 static int write_bytes(const struct device *i2c_dev, uint16_t addr,
20 		       uint8_t *data, uint32_t num_bytes)
21 {
22 	uint8_t wr_addr[2];
23 	struct i2c_msg msgs[2];
24 
25 	/* FRAM address */
26 	wr_addr[0] = (addr >> 8) & 0xFF;
27 	wr_addr[1] = addr & 0xFF;
28 
29 	/* Setup I2C messages */
30 
31 	/* Send the address to write to */
32 	msgs[0].buf = wr_addr;
33 	msgs[0].len = 2U;
34 	msgs[0].flags = I2C_MSG_WRITE;
35 
36 	/* Data to be written, and STOP after this. */
37 	msgs[1].buf = data;
38 	msgs[1].len = num_bytes;
39 	msgs[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
40 
41 	return i2c_transfer(i2c_dev, &msgs[0], 2, FRAM_I2C_ADDR);
42 }
43 
read_bytes(const struct device * i2c_dev,uint16_t addr,uint8_t * data,uint32_t num_bytes)44 static int read_bytes(const struct device *i2c_dev, uint16_t addr,
45 		      uint8_t *data, uint32_t num_bytes)
46 {
47 	uint8_t wr_addr[2];
48 	struct i2c_msg msgs[2];
49 
50 	/* Now try to read back from FRAM */
51 
52 	/* FRAM address */
53 	wr_addr[0] = (addr >> 8) & 0xFF;
54 	wr_addr[1] = addr & 0xFF;
55 
56 	/* Setup I2C messages */
57 
58 	/* Send the address to read from */
59 	msgs[0].buf = wr_addr;
60 	msgs[0].len = 2U;
61 	msgs[0].flags = I2C_MSG_WRITE;
62 
63 	/* Read from device. STOP after this. */
64 	msgs[1].buf = data;
65 	msgs[1].len = num_bytes;
66 	msgs[1].flags = I2C_MSG_READ | I2C_MSG_STOP;
67 
68 	return i2c_transfer(i2c_dev, &msgs[0], 2, FRAM_I2C_ADDR);
69 }
70 
main(void)71 void main(void)
72 {
73 	const struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));
74 	uint8_t cmp_data[16];
75 	uint8_t data[16];
76 	int i, ret;
77 
78 	if (!device_is_ready(i2c_dev)) {
79 		printk("I2C: Device is not ready.\n");
80 		return;
81 	}
82 
83 	/* Do one-byte read/write */
84 
85 	data[0] = 0xAE;
86 	ret = write_bytes(i2c_dev, 0x00, &data[0], 1);
87 	if (ret) {
88 		printk("Error writing to FRAM! error code (%d)\n", ret);
89 		return;
90 	} else {
91 		printk("Wrote 0xAE to address 0x00.\n");
92 	}
93 
94 	data[0] = 0x86;
95 	ret = write_bytes(i2c_dev, 0x01, &data[0], 1);
96 	if (ret) {
97 		printk("Error writing to FRAM! error code (%d)\n", ret);
98 		return;
99 	} else {
100 		printk("Wrote 0x86 to address 0x01.\n");
101 	}
102 
103 	data[0] = 0x00;
104 	ret = read_bytes(i2c_dev, 0x00, &data[0], 1);
105 	if (ret) {
106 		printk("Error reading from FRAM! error code (%d)\n", ret);
107 		return;
108 	} else {
109 		printk("Read 0x%X from address 0x00.\n", data[0]);
110 	}
111 
112 	data[1] = 0x00;
113 	ret = read_bytes(i2c_dev, 0x01, &data[0], 1);
114 	if (ret) {
115 		printk("Error reading from FRAM! error code (%d)\n", ret);
116 		return;
117 	} else {
118 		printk("Read 0x%X from address 0x01.\n", data[0]);
119 	}
120 
121 	/* Do multi-byte read/write */
122 
123 	/* get some random data, and clear out data[] */
124 	for (i = 0; i < sizeof(cmp_data); i++) {
125 		cmp_data[i] = k_cycle_get_32() & 0xFF;
126 		data[i] = 0x00;
127 	}
128 
129 	/* write them to the FRAM */
130 	ret = write_bytes(i2c_dev, 0x00, cmp_data, sizeof(cmp_data));
131 	if (ret) {
132 		printk("Error writing to FRAM! error code (%d)\n", ret);
133 		return;
134 	} else {
135 		printk("Wrote %zu bytes to address 0x00.\n", sizeof(cmp_data));
136 	}
137 
138 	ret = read_bytes(i2c_dev, 0x00, data, sizeof(data));
139 	if (ret) {
140 		printk("Error reading from FRAM! error code (%d)\n", ret);
141 		return;
142 	} else {
143 		printk("Read %zu bytes from address 0x00.\n", sizeof(data));
144 	}
145 
146 	ret = 0;
147 	for (i = 0; i < sizeof(cmp_data); i++) {
148 		/* uncomment below if you want to see all the bytes */
149 		/* printk("0x%X ?= 0x%X\n", cmp_data[i], data[i]); */
150 		if (cmp_data[i] != data[i]) {
151 			printk("Data comparison failed @ %d.\n", i);
152 			ret = -EIO;
153 		}
154 	}
155 	if (ret == 0) {
156 		printk("Data comparison successful.\n");
157 	}
158 }
159