qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

i2c.md (13773B)


      1 # I2C Master Driver {#i2c-master-driver}
      2 
      3 The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
      4 
      5 ## Usage {#usage}
      6 
      7 In 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 
      9 However, if you need to use the driver standalone, add the following to your `rules.mk`:
     10 
     11 ```make
     12 I2C_DRIVER_REQUIRED = yes
     13 ```
     14 
     15 You can then call the I2C API by including `i2c_master.h` in your code.
     16 
     17 ## I2C Addressing {#note-on-i2c-addresses}
     18 
     19 I2C addresses listed on datasheets and the internet are usually represented as a 7-bit value. The eighth bit (the least significant bit) controls whether the operation is a read or a write.
     20 
     21 All of the address parameters expected by the driver API should therefore be pushed to the upper 7 bits of the address byte; the driver will take care of setting the read/write bit as appropriate.
     22 
     23 This is easy to do via the bitwise left shift operator. For example, if your device has an address of `0x18` you might create a define for convenience:
     24 
     25 ```c
     26 #define MY_I2C_ADDRESS (0x18 << 1)
     27 ```
     28 
     29 Or, you can shift the address ahead of time:
     30 
     31 ```c
     32 #define MY_I2C_ADDRESS 0x30
     33 ```
     34 
     35 See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details.
     36 
     37 ## AVR Configuration {#avr-configuration}
     38 
     39 The following defines can be used to configure the I2C master driver:
     40 
     41 |`config.h` Override|Description          |Default |
     42 |-------------------|---------------------|--------|
     43 |`F_SCL`            |Clock frequency in Hz|`400000`|
     44 
     45 No further setup is required - just connect the `SDA` and `SCL` pins of your I2C devices to the matching pins on the MCU:
     46 
     47 |MCU          |`SCL`|`SDA`|
     48 |-------------|-----|-----|
     49 |ATmega16/32U4|`D0` |`D1` |
     50 |AT90USB64/128|`D0` |`D1` |
     51 |ATmega32A    |`C0` |`C1` |
     52 |ATmega328/P  |`C5` |`C4` |
     53 
     54 ::: tip
     55 The ATmega16/32U2 does not possess I2C functionality, and so cannot use this driver.
     56 :::
     57 
     58 ## ChibiOS/ARM Configuration {#arm-configuration}
     59 
     60 You'll need to determine which pins can be used for I2C -- as an example, STM32 parts generally have multiple I2C peripherals, labeled I2C1, I2C2, I2C3 etc.
     61 
     62 To enable I2C, modify your board's `halconf.h` to enable I2C, then modify your board's `mcuconf.h` to enable the peripheral you've chosen:
     63 
     64 ::: code-group
     65 ```c [halconf.h]
     66 #pragma once
     67 
     68 #define HAL_USE_I2C TRUE // [!code focus]
     69 
     70 #include_next <halconf.h>
     71 ```
     72 ```c [mcuconf.h]
     73 #pragma once
     74 
     75 #include_next <mcuconf.h>
     76 
     77 #undef STM32_I2C_USE_I2C2 // [!code focus]
     78 #define STM32_I2C_USE_I2C2 TRUE // [!code focus]
     79 ```
     80 :::
     81 
     82 |`mcuconf.h` Setting         |Description                                                                       |Default|
     83 |----------------------------|----------------------------------------------------------------------------------|-------|
     84 |`STM32_I2C_BUSY_TIMEOUT`    |Time in milliseconds until the I2C command is aborted if no response is received  |`50`   |
     85 |`STM32_I2C_XXX_IRQ_PRIORITY`|Interrupt priority for hardware driver XXX (THIS IS AN EXPERT SETTING)            |`10`   |
     86 |`STM32_I2C_USE_DMA`         |Enable/Disable the ability of the MCU to offload the data transfer to the DMA unit|`TRUE` |
     87 |`STM32_I2C_XXX_DMA_PRIORITY`|Priority of DMA unit for hardware driver XXX (THIS IS AN EXPERT SETTING)          |`1`    |
     88 
     89 Configuration-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.
     90 
     91 |`config.h` Override|Description                                                  |Default|
     92 |-------------------|-------------------------------------------------------------|-------|
     93 |`I2C_DRIVER`       |I2C peripheral to use - I2C1 -> `I2CD1`, I2C2 -> `I2CD2` etc.|`I2CD1`|
     94 |`I2C1_SCL_PIN`     |The pin to use for SCL                                       |`B6`   |
     95 |`I2C1_SCL_PAL_MODE`|The alternate function mode for SCL                          |`4`    |
     96 |`I2C1_SDA_PIN`     |The pin to use for SDA                                       |`B7`   |
     97 |`I2C1_SDA_PAL_MODE`|The alternate function mode for SDA                          |`4`    |
     98 
     99 ::: tip
    100 Currently only a single I2C peripheral is supported, therefore the `I2C1_*` defines are used for configuration regardless of the selected peripheral.
    101 :::
    102 
    103 The following configuration values are dependent on the ChibiOS I2C LLD, which is dictated by the microcontroller.
    104 
    105 ### I2Cv1 {#arm-configuration-i2cv1}
    106 
    107 * STM32F1xx
    108 * STM32F2xx
    109 * STM32F4xx
    110 * STM32L0xx
    111 * STM32L1xx
    112 
    113 See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#7_I2Cv1_configuration_structure) for the I2Cv1 configuration structure.
    114 
    115 |`config.h` Override|Default         |
    116 |-------------------|----------------|
    117 |`I2C1_OPMODE`      |`OPMODE_I2C`    |
    118 |`I2C1_CLOCK_SPEED` |`100000`        |
    119 |`I2C1_DUTY_CYCLE`  |`STD_DUTY_CYCLE`|
    120 
    121 ### I2Cv2 {#arm-configuration-i2cv2}
    122 
    123 * STM32F0xx
    124 * STM32F3xx
    125 * STM32F7xx
    126 * STM32L4xx
    127 
    128 See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#8_I2Cv2_I2Cv3_configuration_structure) for the I2Cv2 configuration structure.
    129 
    130 |`config.h` Override  |Default|
    131 |---------------------|-------|
    132 |`I2C1_TIMINGR_PRESC` |`0U`   |
    133 |`I2C1_TIMINGR_SCLDEL`|`7U`   |
    134 |`I2C1_TIMINGR_SDADEL`|`0U`   |
    135 |`I2C1_TIMINGR_SCLH`  |`38U`  |
    136 |`I2C1_TIMINGR_SCLL`  |`129U` |
    137 
    138 ## API {#api}
    139 
    140 ### `void i2c_init(void)` {#api-i2c-init}
    141 
    142 Initialize the I2C driver. This function must be called only once, before any of the below functions can be called.
    143 
    144 This function is weakly defined, meaning it can be overridden if necessary for your particular use case:
    145 
    146 ```c
    147 void i2c_init(void) {
    148     gpio_set_pin_input(B6); // Try releasing special pins for a short time
    149     gpio_set_pin_input(B7);
    150     wait_ms(10); // Wait for the release to happen
    151 
    152     palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function
    153     palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function
    154 }
    155 ```
    156 
    157 ---
    158 
    159 ### `i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-transmit}
    160 
    161 Send multiple bytes to the selected I2C device.
    162 
    163 #### Arguments {#api-i2c-transmit-arguments}
    164 
    165  - `uint8_t address`  
    166    The 7-bit I2C address of the device.
    167  - `const uint8_t* data`  
    168    A pointer to the data to transmit.
    169  - `uint16_t length`  
    170    The number of bytes to write. Take care not to overrun the length of `data`.
    171  - `uint16_t timeout`  
    172    The time in milliseconds to wait for a response from the target device.
    173 
    174 #### Return Value {#api-i2c-transmit-return}
    175 
    176 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    177 
    178 ---
    179 
    180 ### `i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-transmit-p}
    181 
    182 Send multiple bytes from PROGMEM to the selected I2C device.
    183 
    184 On ARM devices, this function is simply an alias for `i2c_transmit(address, data, length, timeout)`.
    185 
    186 #### Arguments {#api-i2c-transmit-p-arguments}
    187 
    188  - `uint8_t address`  
    189    The 7-bit I2C address of the device.
    190  - `const uint8_t* data`  
    191    A pointer to the data to transmit.
    192  - `uint16_t length`  
    193    The number of bytes to write. Take care not to overrun the length of `data`.
    194  - `uint16_t timeout`  
    195    The time in milliseconds to wait for a response from the target device.
    196 
    197 #### Return Value {#api-i2c-transmit-p-return}
    198 
    199 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    200 
    201 ---
    202 
    203 ### `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-receive}
    204 
    205 Receive multiple bytes from the selected I2C device.
    206 
    207 #### Arguments {#api-i2c-receive-arguments}
    208 
    209  - `uint8_t address`  
    210    The 7-bit I2C address of the device.
    211  - `uint8_t* data`  
    212    A pointer to a buffer to read into.
    213  - `uint16_t length`  
    214    The number of bytes to read. Take care not to overrun the length of `data`.
    215  - `uint16_t timeout`  
    216    The time in milliseconds to wait for a response from the target device.
    217 
    218 #### Return Value {#api-i2c-receive-return}
    219 
    220 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    221 
    222 ---
    223 
    224 ### `i2c_status_t i2c_transmit_and_receive(uint8_t address, const uint8_t* tx_data, uint16_t tx_length, uint8_t* rx_data, uint16_t rx_length, uint16_t timeout)` {#api-i2c-transmit-and-receive}
    225 
    226 Send and receive multiple bytes from the selected I2C device.
    227 
    228 #### Arguments {#api-i2c-transmit-and-receive-arguments}
    229 
    230  - `uint8_t address`
    231    The 7-bit I2C address of the device.
    232  - `const uint8_t* tx_data`
    233    A pointer to the data to transmit.
    234  - `uint16_t tx_length`
    235    The number of bytes to write. Take care not to overrun the length of `tx_data`.
    236  - `uint8_t* rx_data`
    237    A pointer to a buffer to read into.
    238  - `uint16_t rx_length`
    239    The number of bytes to read. Take care not to overrun the length of `data`.
    240  - `uint16_t timeout`
    241    The time in milliseconds to wait for a response from the target device.
    242 
    243 #### Return Value {#api-i2c-transmit-and-receive-return}
    244 
    245 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    246 
    247 ---
    248 
    249 ### `i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-write-register}
    250 
    251 Write to a register with an 8-bit address on the I2C device.
    252 
    253 #### Arguments {#api-i2c-write-register-arguments}
    254 
    255  - `uint8_t devaddr`  
    256    The 7-bit I2C address of the device.
    257  - `uint8_t regaddr`  
    258    The register address to write to.
    259  - `const uint8_t* data`  
    260    A pointer to the data to transmit.
    261  - `uint16_t length`  
    262    The number of bytes to write. Take care not to overrun the length of `data`.
    263  - `uint16_t timeout`  
    264    The time in milliseconds to wait for a response from the target device.
    265 
    266 #### Return Value {#api-i2c-write-register-return}
    267 
    268 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    269 
    270 ---
    271 
    272 ### `i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-write-register16}
    273 
    274 Write to a register with a 16-bit address (big endian) on the I2C device.
    275 
    276 #### Arguments {#api-i2c-write-register16-arguments}
    277 
    278  - `uint8_t devaddr`  
    279    The 7-bit I2C address of the device.
    280  - `uint16_t regaddr`  
    281    The register address to write to.
    282  - `const uint8_t* data`  
    283    A pointer to the data to transmit.
    284  - `uint16_t length`  
    285    The number of bytes to write. Take care not to overrun the length of `data`.
    286  - `uint16_t timeout`  
    287    The time in milliseconds to wait for a response from the target device.
    288 
    289 #### Return Value {#api-i2c-write-register16-return}
    290 
    291 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    292 
    293 ---
    294 
    295 ### `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}
    296 
    297 Read from a register with an 8-bit address on the I2C device.
    298 
    299 #### Arguments {#api-i2c-read-register-arguments}
    300 
    301  - `uint8_t devaddr`  
    302    The 7-bit I2C address of the device.
    303  - `uint8_t regaddr`  
    304    The register address to read from.
    305  - `uint8_t data`  
    306    A pointer to a buffer to read into.
    307  - `uint16_t length`  
    308    The number of bytes to read. Take care not to overrun the length of `data`.
    309  - `uint16_t timeout`  
    310    The time in milliseconds to wait for a response from the target device.
    311 
    312 #### Return Value {#api-i2c-read-register-return}
    313 
    314 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    315 
    316 ---
    317 
    318 ### `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}
    319 
    320 Read from a register with a 16-bit address (big endian) on the I2C device.
    321 
    322 #### Arguments {#api-i2c-read-register16-arguments}
    323 
    324  - `uint8_t devaddr`  
    325    The 7-bit I2C address of the device.
    326  - `uint16_t regaddr`  
    327    The register address to read from.
    328  - `uint8_t* data`  
    329    A pointer to a buffer to read into.
    330  - `uint16_t length`  
    331    The number of bytes to read. Take care not to overrun the length of `data`.
    332  - `uint16_t timeout`  
    333    The time in milliseconds to wait for a response from the target device.
    334 
    335 #### Return Value {#api-i2c-read-register16-return}
    336 
    337 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
    338 
    339 ---
    340 
    341 ### `i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout)` {#api-i2c-ping-address}
    342 
    343 Ping the I2C bus for a specific address.
    344 
    345 On ChibiOS a "best effort" attempt is made by reading a single byte from register 0 at the given 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 (unsuccessful response to ping attempt).
    346 
    347 This function is weakly defined, meaning it can be overridden if necessary for your particular use case.
    348 
    349 #### Arguments {#api-i2c-ping-address-arguments}
    350 
    351  - `uint8_t address`  
    352    The 7-bit I2C address of the device.
    353  - `uint16_t timeout`  
    354    The time in milliseconds to wait for a response from the target device.
    355 
    356 #### Return Value {#api-i2c-ping-address-return}
    357 
    358 `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.