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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <stdint.h>
#include <hal/I2C.h>
#include <hal/I2CTypes.h>
namespace frc {
/**
* I2C bus interface class.
*
* This class is intended to be used by sensor (and other I2C device) drivers.
* It probably should not be used directly.
*
* The Onboard I2C port is subject to system lockups. See <a
* href="https://docs.wpilib.org/en/stable/docs/yearly-overview/known-issues.html#onboard-i2c-causing-system-lockups">
* WPILib Known Issues</a> page for details.
*/
class I2C {
public:
/**
* I2C connection ports.
*/
enum Port {
/// Onboard I2C port.
kOnboard = 0,
/// MXP (roboRIO MXP) I2C port.
kMXP
};
/**
* Constructor.
*
* @param port The I2C port to which the device is connected.
* @param deviceAddress The address of the device on the I2C bus.
*/
I2C(Port port, int deviceAddress);
I2C(I2C&&) = default;
I2C& operator=(I2C&&) = default;
/**
* Returns I2C port.
*
* @return I2C port.
*/
Port GetPort() const;
/**
* Returns I2C device address.
*
* @return I2C device address.
*/
int GetDeviceAddress() const;
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction. If you intend to write multiple bytes in the same
* transaction and do not plan to receive anything back, use writeBulk()
* instead. Calling this with a receiveSize of 0 will result in an error.
*
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool Transaction(uint8_t* dataToSend, int sendSize, uint8_t* dataReceived,
int receiveSize);
/**
* Attempt to address a device on the I2C bus.
*
* This allows you to figure out if there is a device on the I2C bus that
* responds to the address specified in the constructor.
*
* @return Transfer Aborted... false for success, true for aborted.
*/
bool AddressOnly();
/**
* Execute a write transaction with the device.
*
* Write a single byte to a register on a device and wait until the
* transaction is complete.
*
* @param registerAddress The address of the register on the device to be
* written.
* @param data The byte to write to the register on the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool Write(int registerAddress, uint8_t data);
/**
* Execute a bulk write transaction with the device.
*
* Write multiple bytes to a device and wait until the
* transaction is complete.
*
* @param data The data to write to the register on the device.
* @param count The number of bytes to be written.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool WriteBulk(uint8_t* data, int count);
/**
* Execute a read transaction with the device.
*
* Read bytes from a device.
* Most I2C devices will auto-increment the register pointer internally
* allowing you to read consecutive registers on a device in a single
* transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param data A pointer to the array of bytes to store the data
* read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool Read(int registerAddress, int count, uint8_t* data);
/**
* Execute a read only transaction with the device.
*
* Read bytes from a device. This method does not write any data to prompt the
* device.
*
* @param buffer A pointer to the array of bytes to store the data read from
* the device.
* @param count The number of bytes to read in the transaction.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool ReadOnly(int count, uint8_t* buffer);
/**
* Verify that a device's registers contain expected values.
*
* Most devices will have a set of registers that contain a known value that
* can be used to identify them. This allows an I2C device driver to easily
* verify that the device contains the expected value.
*
* @pre The device must support and be configured to use register
* auto-increment.
*
* @param registerAddress The base register to start reading from the device.
* @param count The size of the field to be verified.
* @param expected A buffer containing the values expected from the
* device.
*/
bool VerifySensor(int registerAddress, int count, const uint8_t* expected);
private:
hal::Handle<HAL_I2CPort, HAL_CloseI2C, HAL_I2C_kInvalid> m_port;
int m_deviceAddress;
};
} // namespace frc