This repository has been archived by the owner on Jan 7, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
example-i2c.c
108 lines (86 loc) · 3.02 KB
/
example-i2c.c
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
/* Copyright 2019 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */
#include <metal/cpu.h>
#include <metal/i2c.h>
#include <metal/io.h>
#include <metal/machine.h>
#include <metal/uart.h>
#include <stdio.h>
#include <time.h>
/* PmodAD2, PmodTmp2 sensor modules are connected to I2C0 bus */
#define TEMP_SENSOR_I2C_ADDR 0x4B
#define TEMP_SENSOR_ID 0xCB
#define ADC_I2C_ADDR 0x28
#define I2C_BAUDRATE 100000
/* Return values */
#define RET_OK 0
#define RET_NOK 1
/* Buffer length macros */
#define LEN0 0
#define LEN1 1
#define LEN2 2
/* 1s delay macro */
#define WAIT_1S(timeout) \
timeout = time(NULL) + 1; \
while (timeout > time(NULL)) \
;
int main(void) {
unsigned int temp, volt;
unsigned char buf[LEN2];
time_t timeout;
struct metal_i2c *i2c;
printf("%s %s \n", __DATE__, __TIME__);
printf("I2C demo test..\n");
i2c = metal_i2c_get_device(0);
if (i2c == NULL) {
printf("I2C not available \n");
return RET_NOK;
}
metal_i2c_init(i2c, I2C_BAUDRATE, METAL_I2C_MASTER);
/* Attempt to read ADT7420 Chip ID */
buf[0] = 0x0B;
metal_i2c_write(i2c, TEMP_SENSOR_I2C_ADDR, LEN1, buf, METAL_I2C_STOP_DISABLE);
metal_i2c_read(i2c, TEMP_SENSOR_I2C_ADDR, LEN1, buf, METAL_I2C_STOP_ENABLE);
/* Verify Chip ID */
if (buf[0] == TEMP_SENSOR_ID) {
printf("PmodTmp2 module detected \n");
} else {
printf("Failed to detect PmodTmp2 module \n");
return RET_NOK;
}
/* Attempt to access AD7991, configure to convert on Vin0. */
buf[0] = 0x10;
if (metal_i2c_write(i2c, ADC_I2C_ADDR, LEN1, buf, METAL_I2C_STOP_ENABLE) !=
RET_OK) {
printf("Failed to detect PmodAD2 module \n");
return RET_NOK;
} else {
printf("PmodAD2 module detected \n");
}
/* Loop and print data from slaves every 1s */
while (1) {
/* Slave access using read / write APIs */
buf[0] = 0x0;
metal_i2c_write(i2c, TEMP_SENSOR_I2C_ADDR, LEN1, buf,
METAL_I2C_STOP_DISABLE);
metal_i2c_read(i2c, TEMP_SENSOR_I2C_ADDR, LEN2, buf, METAL_I2C_STOP_ENABLE);
/* Get temperature value from received data */
temp = ((unsigned int)buf[0] << 8 | buf[1]) >> 7;
metal_i2c_read(i2c, ADC_I2C_ADDR, LEN2, buf, METAL_I2C_STOP_ENABLE);
/* Convert data to represent ADC values in mV */
volt = (((unsigned int)buf[0] << 8 | buf[1]) & 0xFFF) * 0.806;
printf("temp: %u volts : %u \n", temp, volt);
/* Slave access using transfer API */
buf[0] = 0x0;
metal_i2c_transfer(i2c, TEMP_SENSOR_I2C_ADDR, buf, LEN1, buf, LEN2);
/* Get temperature value from received data */
temp = ((unsigned int)buf[0] << 8 | buf[1]) >> 7;
metal_i2c_transfer(i2c, ADC_I2C_ADDR, buf, LEN0, buf, LEN2);
/* Convert data to represent ADC values in mV */
volt = (((unsigned int)buf[0] << 8 | buf[1]) & 0xFFF) * 0.806;
printf("temp: %u volts : %u \n", temp, volt);
/* Wait 1s */
WAIT_1S(timeout);
}
return RET_OK;
}