summaryrefslogtreecommitdiff
path: root/docs/drivers/i2c.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/drivers/i2c.md')
-rw-r--r--docs/drivers/i2c.md290
1 files changed, 290 insertions, 0 deletions
diff --git a/docs/drivers/i2c.md b/docs/drivers/i2c.md
new file mode 100644
index 0000000000..10949ed59e
--- /dev/null
+++ b/docs/drivers/i2c.md
@@ -0,0 +1,290 @@
1# I2C Master Driver {#i2c-master-driver}
2
3The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
4
5## Usage {#usage}
6
7In most cases, the I2C Master driver code is automatically included if you are using a feature or driver which requires it, such as [OLED](../features/oled_driver).
8
9However, if you need to use the driver standalone, add the following to your `rules.mk`:
10
11```make
12I2C_DRIVER_REQUIRED = yes
13```
14
15You can then call the I2C API by including `i2c_master.h` in your code.
16
17## I2C Addressing {#note-on-i2c-addresses}
18
19All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting
20the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed
21on datasheets and the internet will be represented as 7 bits occupying the lower 7 bits and will need to be
22shifted to the left (more significant) by one bit. This is easy to do via the bitwise shift operator `<< 1`.
23
24You can either do this on each call to the functions below, or once in your definition of the address. For example, if your device has an address of `0x18`:
25
26```c
27#define MY_I2C_ADDRESS (0x18 << 1)
28```
29
30See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details.
31
32## AVR Configuration {#avr-configuration}
33
34The following defines can be used to configure the I2C master driver:
35
36|`config.h` Override|Description |Default |
37|-------------------|---------------------|--------|
38|`F_SCL` |Clock frequency in Hz|`400000`|
39
40No further setup is required - just connect the `SDA` and `SCL` pins of your I2C devices to the matching pins on the MCU:
41
42|MCU |`SCL`|`SDA`|
43|------------------|-----|-----|
44|ATmega16/32U4 |`D0` |`D1` |
45|AT90USB64/128 |`D0` |`D1` |
46|ATmega32A |`C0` |`C1` |
47|ATmega328/P |`C5` |`C4` |
48
49::: tip
50The ATmega16/32U2 does not possess I2C functionality, and so cannot use this driver.
51:::
52
53## ChibiOS/ARM Configuration {#arm-configuration}
54
55You'll need to determine which pins can be used for I2C -- a an example, STM32 parts generally have multiple I2C peripherals, labeled I2C1, I2C2, I2C3 etc.
56
57To enable I2C, modify your board's `halconf.h` to enable I2C:
58
59```c
60#define HAL_USE_I2C TRUE
61```
62
63Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example:
64
65```c
66#undef STM32_I2C_USE_I2C2
67#define STM32_I2C_USE_I2C2 TRUE
68```
69
70|`mcuconf.h` Setting |Description |Default|
71|----------------------------|----------------------------------------------------------------------------------|-------|
72|`STM32_I2C_BUSY_TIMEOUT` |Time in milliseconds until the I2C command is aborted if no response is received |`50` |
73|`STM32_I2C_XXX_IRQ_PRIORITY`|Interrupt priority for hardware driver XXX (THIS IS AN EXPERT SETTING) |`10` |
74|`STM32_I2C_USE_DMA` |Enable/Disable the ability of the MCU to offload the data transfer to the DMA unit|`TRUE` |
75|`STM32_I2C_XXX_DMA_PRIORITY`|Priority of DMA unit for hardware driver XXX (THIS IS AN EXPERT SETTING) |`1` |
76
77Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303.
78
79|`config.h` Overrride |Description |Default|
80|------------------------|--------------------------------------------------------------|-------|
81|`I2C_DRIVER` |I2C peripheral to use - I2C1 -> `I2CD1`, I2C2 -> `I2CD2` etc. |`I2CD1`|
82|`I2C1_SCL_PIN` |The pin definition for SCL |`B6` |
83|`I2C1_SCL_PAL_MODE` |The alternate function mode for SCL |`4` |
84|`I2C1_SDA_PIN` |The pin definition for SDA |`B7` |
85|`I2C1_SDA_PAL_MODE` |The alternate function mode for SDA |`4` |
86
87The following configuration values depend on the specific MCU in use.
88
89### I2Cv1 {#arm-configuration-i2cv1}
90
91* STM32F1xx
92* STM32F2xx
93* STM32F4xx
94* STM32L0xx
95* STM32L1xx
96
97See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#7_I2Cv1_configuration_structure) for the I2Cv1 configuration structure.
98
99|`config.h` Override|Default |
100|-------------------|----------------|
101|`I2C1_OPMODE` |`OPMODE_I2C` |
102|`I2C1_CLOCK_SPEED` |`100000` |
103|`I2C1_DUTY_CYCLE` |`STD_DUTY_CYCLE`|
104
105### I2Cv2 {#arm-configuration-i2cv2}
106
107* STM32F0xx
108* STM32F3xx
109* STM32F7xx
110* STM32L4xx
111
112See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#8_I2Cv2_I2Cv3_configuration_structure) for the I2Cv2 configuration structure.
113
114|`config.h` Override |Default|
115|---------------------|-------|
116|`I2C1_TIMINGR_PRESC` |`0U` |
117|`I2C1_TIMINGR_SCLDEL`|`7U` |
118|`I2C1_TIMINGR_SDADEL`|`0U` |
119|`I2C1_TIMINGR_SCLH` |`38U` |
120|`I2C1_TIMINGR_SCLL` |`129U` |
121
122## API {#api}
123
124### `void i2c_init(void)` {#api-i2c-init}
125
126Initialize the I2C driver. This function must be called only once, before any of the below functions can be called.
127
128This function is weakly defined, meaning it can be overridden if necessary for your particular use case:
129
130```c
131void i2c_init(void) {
132 gpio_set_pin_input(B6); // Try releasing special pins for a short time
133 gpio_set_pin_input(B7);
134 wait_ms(10); // Wait for the release to happen
135
136 palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function
137 palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function
138}
139```
140
141---
142
143### `i2c_status_t i2c_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout)` {#api-i2c-transmit}
144
145Send multiple bytes to the selected I2C device.
146
147#### Arguments {#api-i2c-transmit-arguments}
148
149 - `uint8_t address`
150 The 7-bit I2C address of the device.
151 - `uint8_t *data`
152 A pointer to the data to transmit.
153 - `uint16_t length`
154 The number of bytes to write. Take care not to overrun the length of `data`.
155 - `uint16_t timeout`
156 The time in milliseconds to wait for a response from the target device.
157
158#### Return Value {#api-i2c-transmit-return}
159
160`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
161
162---
163
164### `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-receive}
165
166Receive multiple bytes from the selected I2C device.
167
168#### Arguments {#api-i2c-receive-arguments}
169
170 - `uint8_t address`
171 The 7-bit I2C address of the device.
172 - `uint8_t *data`
173 A pointer to the buffer to read into.
174 - `uint16_t length`
175 The number of bytes to read. Take care not to overrun the length of `data`.
176 - `uint16_t timeout`
177 The time in milliseconds to wait for a response from the target device.
178
179#### Return Value {#api-i2c-receive-return}
180
181`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
182
183---
184
185### `i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-write-register}
186
187Writes to a register with an 8-bit address on the I2C device.
188
189#### Arguments {#api-i2c-write-register-arguments}
190
191 - `uint8_t devaddr`
192 The 7-bit I2C address of the device.
193 - `uint8_t regaddr`
194 The register address to write to.
195 - `uint8_t *data`
196 A pointer to the data to transmit.
197 - `uint16_t length`
198 The number of bytes to write. Take care not to overrun the length of `data`.
199 - `uint16_t timeout`
200 The time in milliseconds to wait for a response from the target device.
201
202#### Return Value {#api-i2c-write-register-return}
203
204`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
205
206---
207
208### `i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-write-register16}
209
210Writes to a register with a 16-bit address (big endian) on the I2C device.
211
212#### Arguments {#api-i2c-write-register16-arguments}
213
214 - `uint8_t devaddr`
215 The 7-bit I2C address of the device.
216 - `uint16_t regaddr`
217 The register address to write to.
218 - `uint8_t *data`
219 A pointer to the data to transmit.
220 - `uint16_t length`
221 The number of bytes to write. Take care not to overrun the length of `data`.
222 - `uint16_t timeout`
223 The time in milliseconds to wait for a response from the target device.
224
225#### Return Value {#api-i2c-write-register16-return}
226
227`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
228
229---
230
231### `i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-read-register}
232
233Reads from a register with an 8-bit address on the I2C device.
234
235#### Arguments {#api-i2c-read-register-arguments}
236
237 - `uint8_t devaddr`
238 The 7-bit I2C address of the device.
239 - `uint8_t regaddr`
240 The register address to read from.
241 - `uint16_t length`
242 The number of bytes to read. Take care not to overrun the length of `data`.
243 - `uint16_t timeout`
244 The time in milliseconds to wait for a response from the target device.
245
246#### Return Value {#api-i2c-read-register-return}
247
248`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
249
250---
251
252### `i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-read-register16}
253
254Reads from a register with a 16-bit address (big endian) on the I2C device.
255
256#### Arguments {#api-i2c-read-register16-arguments}
257
258 - `uint8_t devaddr`
259 The 7-bit I2C address of the device.
260 - `uint16_t regaddr`
261 The register address to read from.
262 - `uint16_t length`
263 The number of bytes to read. Take care not to overrun the length of `data`.
264 - `uint16_t timeout`
265 The time in milliseconds to wait for a response from the target device.
266
267#### Return Value {#api-i2c-read-register16-return}
268
269`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
270
271---
272
273### `i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout)` {#api-i2c-ping-address}
274
275Pings the I2C bus for a specific address.
276
277On ChibiOS a "best effort" attempt is made by reading a single byte from register 0 at the requested address. This should generally work except for I2C devices that do not not respond to a register 0 read request, which will result in a false negative result (unsucessful response to ping attempt).
278
279This function is weakly defined, meaning it can be overridden if necessary for your particular use case:
280
281#### Arguments
282
283 - `uint8_t address`
284 The 7-bit I2C address of the device (ie. without the read/write bit - this will be set automatically).
285 - `uint16_t timeout`
286 The time in milliseconds to wait for a response from the target device.
287
288#### Return Value
289
290`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.