Unify i2c_master headers (#24846)
* Unify i2c_master headers * More documentation improvements * Reorganise PAL mode defaults
This commit is contained in:
parent
291d154d7b
commit
ef29a46c87
5 changed files with 225 additions and 136 deletions
|
@ -16,17 +16,22 @@ You can then call the I2C API by including `i2c_master.h` in your code.
|
||||||
|
|
||||||
## I2C Addressing {#note-on-i2c-addresses}
|
## I2C Addressing {#note-on-i2c-addresses}
|
||||||
|
|
||||||
All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting
|
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.
|
||||||
the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed
|
|
||||||
on datasheets and the internet will be represented as 7 bits occupying the lower 7 bits and will need to be
|
|
||||||
shifted to the left (more significant) by one bit. This is easy to do via the bitwise shift operator `<< 1`.
|
|
||||||
|
|
||||||
You 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`:
|
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.
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define MY_I2C_ADDRESS (0x18 << 1)
|
#define MY_I2C_ADDRESS (0x18 << 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or, you can shift the address ahead of time:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define MY_I2C_ADDRESS 0x30
|
||||||
|
```
|
||||||
|
|
||||||
See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details.
|
See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details.
|
||||||
|
|
||||||
## AVR Configuration {#avr-configuration}
|
## AVR Configuration {#avr-configuration}
|
||||||
|
@ -40,9 +45,9 @@ The following defines can be used to configure the I2C master driver:
|
||||||
No further setup is required - just connect the `SDA` and `SCL` pins of your I2C devices to the matching pins on the MCU:
|
No further setup is required - just connect the `SDA` and `SCL` pins of your I2C devices to the matching pins on the MCU:
|
||||||
|
|
||||||
|MCU |`SCL`|`SDA`|
|
|MCU |`SCL`|`SDA`|
|
||||||
|------------------|-----|-----|
|
|-------------|-----|-----|
|
||||||
|ATmega16/32U4 |`D0` |`D1` |
|
|ATmega16/32U4|`D0` |`D1` |
|
||||||
|AT90USB64/128 |`D0` |`D1` |
|
|AT90USB64/128|`D0` |`D1` |
|
||||||
|ATmega32A |`C0` |`C1` |
|
|ATmega32A |`C0` |`C1` |
|
||||||
|ATmega328/P |`C5` |`C4` |
|
|ATmega328/P |`C5` |`C4` |
|
||||||
|
|
||||||
|
@ -52,7 +57,7 @@ The ATmega16/32U2 does not possess I2C functionality, and so cannot use this dri
|
||||||
|
|
||||||
## ChibiOS/ARM Configuration {#arm-configuration}
|
## ChibiOS/ARM Configuration {#arm-configuration}
|
||||||
|
|
||||||
You'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.
|
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.
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
|
@ -83,15 +88,19 @@ To enable I2C, modify your board's `halconf.h` to enable I2C, then modify your b
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|`config.h` Overrride |Description |Default|
|
|`config.h` Override|Description |Default|
|
||||||
|------------------------|--------------------------------------------------------------|-------|
|
|-------------------|-------------------------------------------------------------|-------|
|
||||||
|`I2C_DRIVER` |I2C peripheral to use - I2C1 -> `I2CD1`, I2C2 -> `I2CD2` etc. |`I2CD1`|
|
|`I2C_DRIVER` |I2C peripheral to use - I2C1 -> `I2CD1`, I2C2 -> `I2CD2` etc.|`I2CD1`|
|
||||||
|`I2C1_SCL_PIN` |The pin definition for SCL |`B6` |
|
|`I2C1_SCL_PIN` |The pin to use for SCL |`B6` |
|
||||||
|`I2C1_SCL_PAL_MODE` |The alternate function mode for SCL |`4` |
|
|`I2C1_SCL_PAL_MODE`|The alternate function mode for SCL |`4` |
|
||||||
|`I2C1_SDA_PIN` |The pin definition for SDA |`B7` |
|
|`I2C1_SDA_PIN` |The pin to use for SDA |`B7` |
|
||||||
|`I2C1_SDA_PAL_MODE` |The alternate function mode for SDA |`4` |
|
|`I2C1_SDA_PAL_MODE`|The alternate function mode for SDA |`4` |
|
||||||
|
|
||||||
The following configuration values depend on the specific MCU in use.
|
::: tip
|
||||||
|
Currently only a single I2C peripheral is supported, therefore the `I2C1_*` defines are used for configuration regardless of the selected peripheral.
|
||||||
|
:::
|
||||||
|
|
||||||
|
The following configuration values are dependent on the ChibiOS I2C LLD, which is dictated by the microcontroller.
|
||||||
|
|
||||||
### I2Cv1 {#arm-configuration-i2cv1}
|
### I2Cv1 {#arm-configuration-i2cv1}
|
||||||
|
|
||||||
|
@ -168,6 +177,29 @@ Send multiple bytes to the selected I2C device.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### `i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-transmit-p}
|
||||||
|
|
||||||
|
Send multiple bytes from PROGMEM to the selected I2C device.
|
||||||
|
|
||||||
|
On ARM devices, this function is simply an alias for `i2c_transmit(address, data, length, timeout)`.
|
||||||
|
|
||||||
|
#### Arguments {#api-i2c-transmit-p-arguments}
|
||||||
|
|
||||||
|
- `uint8_t address`
|
||||||
|
The 7-bit I2C address of the device.
|
||||||
|
- `const uint8_t* data`
|
||||||
|
A pointer to the data to transmit.
|
||||||
|
- `uint16_t length`
|
||||||
|
The number of bytes to write. Take care not to overrun the length of `data`.
|
||||||
|
- `uint16_t timeout`
|
||||||
|
The time in milliseconds to wait for a response from the target device.
|
||||||
|
|
||||||
|
#### Return Value {#api-i2c-transmit-p-return}
|
||||||
|
|
||||||
|
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-receive}
|
### `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-receive}
|
||||||
|
|
||||||
Receive multiple bytes from the selected I2C device.
|
Receive multiple bytes from the selected I2C device.
|
||||||
|
@ -177,7 +209,7 @@ Receive multiple bytes from the selected I2C device.
|
||||||
- `uint8_t address`
|
- `uint8_t address`
|
||||||
The 7-bit I2C address of the device.
|
The 7-bit I2C address of the device.
|
||||||
- `uint8_t* data`
|
- `uint8_t* data`
|
||||||
A pointer to the buffer to read into.
|
A pointer to a buffer to read into.
|
||||||
- `uint16_t length`
|
- `uint16_t length`
|
||||||
The number of bytes to read. Take care not to overrun the length of `data`.
|
The number of bytes to read. Take care not to overrun the length of `data`.
|
||||||
- `uint16_t timeout`
|
- `uint16_t timeout`
|
||||||
|
@ -191,7 +223,7 @@ Receive multiple bytes from the selected I2C device.
|
||||||
|
|
||||||
### `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}
|
### `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}
|
||||||
|
|
||||||
Writes to a register with an 8-bit address on the I2C device.
|
Write to a register with an 8-bit address on the I2C device.
|
||||||
|
|
||||||
#### Arguments {#api-i2c-write-register-arguments}
|
#### Arguments {#api-i2c-write-register-arguments}
|
||||||
|
|
||||||
|
@ -214,7 +246,7 @@ Writes to a register with an 8-bit address on the I2C device.
|
||||||
|
|
||||||
### `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}
|
### `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}
|
||||||
|
|
||||||
Writes to a register with a 16-bit address (big endian) on the I2C device.
|
Write to a register with a 16-bit address (big endian) on the I2C device.
|
||||||
|
|
||||||
#### Arguments {#api-i2c-write-register16-arguments}
|
#### Arguments {#api-i2c-write-register16-arguments}
|
||||||
|
|
||||||
|
@ -237,7 +269,7 @@ Writes to a register with a 16-bit address (big endian) on the I2C device.
|
||||||
|
|
||||||
### `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}
|
### `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}
|
||||||
|
|
||||||
Reads from a register with an 8-bit address on the I2C device.
|
Read from a register with an 8-bit address on the I2C device.
|
||||||
|
|
||||||
#### Arguments {#api-i2c-read-register-arguments}
|
#### Arguments {#api-i2c-read-register-arguments}
|
||||||
|
|
||||||
|
@ -260,7 +292,7 @@ Reads from a register with an 8-bit address on the I2C device.
|
||||||
|
|
||||||
### `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}
|
### `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}
|
||||||
|
|
||||||
Reads from a register with a 16-bit address (big endian) on the I2C device.
|
Read from a register with a 16-bit address (big endian) on the I2C device.
|
||||||
|
|
||||||
#### Arguments {#api-i2c-read-register16-arguments}
|
#### Arguments {#api-i2c-read-register16-arguments}
|
||||||
|
|
||||||
|
@ -283,16 +315,16 @@ Reads from a register with a 16-bit address (big endian) on the I2C device.
|
||||||
|
|
||||||
### `i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout)` {#api-i2c-ping-address}
|
### `i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout)` {#api-i2c-ping-address}
|
||||||
|
|
||||||
Pings the I2C bus for a specific address.
|
Ping the I2C bus for a specific address.
|
||||||
|
|
||||||
On 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 (unsuccessful response to ping attempt).
|
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).
|
||||||
|
|
||||||
This function is weakly defined, meaning it can be overridden if necessary for your particular use case.
|
This function is weakly defined, meaning it can be overridden if necessary for your particular use case.
|
||||||
|
|
||||||
#### Arguments {#api-i2c-ping-address-arguments}
|
#### Arguments {#api-i2c-ping-address-arguments}
|
||||||
|
|
||||||
- `uint8_t address`
|
- `uint8_t address`
|
||||||
The 7-bit I2C address of the device (ie. without the read/write bit - this will be set automatically).
|
The 7-bit I2C address of the device.
|
||||||
- `uint16_t timeout`
|
- `uint16_t timeout`
|
||||||
The time in milliseconds to wait for a response from the target device.
|
The time in milliseconds to wait for a response from the target device.
|
||||||
|
|
||||||
|
|
141
drivers/i2c_master.h
Normal file
141
drivers/i2c_master.h
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
// Copyright 2025 QMK
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \defgroup i2c_master I2C Master API
|
||||||
|
*
|
||||||
|
* \brief API to communicate with I2C devices.
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int16_t i2c_status_t;
|
||||||
|
|
||||||
|
#define I2C_STATUS_SUCCESS (0)
|
||||||
|
#define I2C_STATUS_ERROR (-1)
|
||||||
|
#define I2C_STATUS_TIMEOUT (-2)
|
||||||
|
|
||||||
|
#define I2C_TIMEOUT_IMMEDIATE (0)
|
||||||
|
#define I2C_TIMEOUT_INFINITE (0xFFFF)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize the I2C driver. This function must be called only once, before any of the below functions can be called.
|
||||||
|
*
|
||||||
|
* This function is weakly defined, meaning it can be overridden if necessary for your particular use case.
|
||||||
|
*/
|
||||||
|
void i2c_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send multiple bytes to the selected I2C device.
|
||||||
|
*
|
||||||
|
* \param address The 7-bit I2C address of the device.
|
||||||
|
* \param data A pointer to the data to transmit.
|
||||||
|
* \param length The number of bytes to write. Take care not to overrun the length of `data`.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
|
||||||
|
|
||||||
|
#if defined(__AVR__) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* \brief Send multiple bytes from PROGMEM to the selected I2C device.
|
||||||
|
*
|
||||||
|
* On ARM devices, this function is simply an alias for i2c_transmit(address, data, length, timeout).
|
||||||
|
*
|
||||||
|
* \param address The 7-bit I2C address of the device.
|
||||||
|
* \param data A pointer to the data to transmit.
|
||||||
|
* \param length The number of bytes to write. Take care not to overrun the length of `data`.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
|
||||||
|
#else
|
||||||
|
# define i2c_transmit_P(address, data, length, timeout) i2c_transmit(address, data, length, timeout)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Receive multiple bytes from the selected I2C device.
|
||||||
|
*
|
||||||
|
* \param address The 7-bit I2C address of the device.
|
||||||
|
* \param data A pointer to a buffer to read into.
|
||||||
|
* \param length The number of bytes to read. Take care not to overrun the length of `data`.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write to a register with an 8-bit address on the I2C device.
|
||||||
|
*
|
||||||
|
* \param devaddr The 7-bit I2C address of the device.
|
||||||
|
* \param regaddr The register address to write to.
|
||||||
|
* \param data A pointer to the data to transmit.
|
||||||
|
* \param length The number of bytes to write. Take care not to overrun the length of `data`.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write to a register with a 16-bit address (big endian) on the I2C device.
|
||||||
|
*
|
||||||
|
* \param devaddr The 7-bit I2C address of the device.
|
||||||
|
* \param regaddr The register address to write to.
|
||||||
|
* \param data A pointer to the data to transmit.
|
||||||
|
* \param length The number of bytes to write. Take care not to overrun the length of `data`.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read from a register with an 8-bit address on the I2C device.
|
||||||
|
*
|
||||||
|
* \param devaddr The 7-bit I2C address of the device.
|
||||||
|
* \param regaddr The register address to read from.
|
||||||
|
* \param data A pointer to a buffer to read into.
|
||||||
|
* \param length The number of bytes to read. Take care not to overrun the length of `data`.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read from a register with a 16-bit address (big endian) on the I2C device.
|
||||||
|
*
|
||||||
|
* \param devaddr The 7-bit I2C address of the device.
|
||||||
|
* \param regaddr The register address to read from.
|
||||||
|
* \param data A pointer to a buffer to read into.
|
||||||
|
* \param length The number of bytes to read. Take care not to overrun the length of `data`.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Ping the I2C bus for a specific address.
|
||||||
|
*
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
* This function is weakly defined, meaning it can be overridden if necessary for your particular use case.
|
||||||
|
*
|
||||||
|
* \param address The 7-bit I2C address of the device.
|
||||||
|
* \param timeout The time in milliseconds to wait for a response from the target device.
|
||||||
|
*
|
||||||
|
* \return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
|
||||||
|
*/
|
||||||
|
i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout);
|
||||||
|
|
||||||
|
/** \} */
|
|
@ -1,41 +0,0 @@
|
||||||
/* Copyright (C) 2019 Elia Ritterbusch
|
|
||||||
+
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
/* Library made by: g4lvanix
|
|
||||||
* GitHub repository: https://github.com/g4lvanix/I2C-master-lib
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef int16_t i2c_status_t;
|
|
||||||
|
|
||||||
#define I2C_STATUS_SUCCESS (0)
|
|
||||||
#define I2C_STATUS_ERROR (-1)
|
|
||||||
#define I2C_STATUS_TIMEOUT (-2)
|
|
||||||
|
|
||||||
#define I2C_TIMEOUT_IMMEDIATE (0)
|
|
||||||
#define I2C_TIMEOUT_INFINITE (0xFFFF)
|
|
||||||
|
|
||||||
void i2c_init(void);
|
|
||||||
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout);
|
|
|
@ -29,17 +29,37 @@
|
||||||
#include "i2c_master.h"
|
#include "i2c_master.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "chibios_config.h"
|
#include "chibios_config.h"
|
||||||
#include <string.h>
|
|
||||||
#include <ch.h>
|
#include <ch.h>
|
||||||
#include <hal.h>
|
#include <hal.h>
|
||||||
|
|
||||||
|
#ifndef I2C_DRIVER
|
||||||
|
# define I2C_DRIVER I2CD1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef I2C1_SCL_PIN
|
#ifndef I2C1_SCL_PIN
|
||||||
# define I2C1_SCL_PIN B6
|
# define I2C1_SCL_PIN B6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef I2C1_SCL_PAL_MODE
|
||||||
|
# ifdef USE_GPIOV1
|
||||||
|
# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN
|
||||||
|
# else
|
||||||
|
# define I2C1_SCL_PAL_MODE 4
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef I2C1_SDA_PIN
|
#ifndef I2C1_SDA_PIN
|
||||||
# define I2C1_SDA_PIN B7
|
# define I2C1_SDA_PIN B7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef I2C1_SDA_PAL_MODE
|
||||||
|
# ifdef USE_GPIOV1
|
||||||
|
# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN
|
||||||
|
# else
|
||||||
|
# define I2C1_SDA_PAL_MODE 4
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_I2CV1
|
#ifdef USE_I2CV1
|
||||||
# ifndef I2C1_OPMODE
|
# ifndef I2C1_OPMODE
|
||||||
# define I2C1_OPMODE OPMODE_I2C
|
# define I2C1_OPMODE OPMODE_I2C
|
||||||
|
@ -70,27 +90,6 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef I2C_DRIVER
|
|
||||||
# define I2C_DRIVER I2CD1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GPIOV1
|
|
||||||
# ifndef I2C1_SCL_PAL_MODE
|
|
||||||
# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN
|
|
||||||
# endif
|
|
||||||
# ifndef I2C1_SDA_PAL_MODE
|
|
||||||
# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
// The default PAL alternate modes are used to signal that the pins are used for I2C
|
|
||||||
# ifndef I2C1_SCL_PAL_MODE
|
|
||||||
# define I2C1_SCL_PAL_MODE 4
|
|
||||||
# endif
|
|
||||||
# ifndef I2C1_SDA_PAL_MODE
|
|
||||||
# define I2C1_SDA_PAL_MODE 4
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const I2CConfig i2cconfig = {
|
static const I2CConfig i2cconfig = {
|
||||||
#if defined(USE_I2CV1_CONTRIB)
|
#if defined(USE_I2CV1_CONTRIB)
|
||||||
I2C1_CLOCK_SPEED,
|
I2C1_CLOCK_SPEED,
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
/* Copyright 2018 Jack Humbert
|
|
||||||
* Copyright 2018 Yiancar
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This library follows the convention of the AVR i2c_master library.
|
|
||||||
* As a result addresses are expected to be already shifted (addr << 1).
|
|
||||||
* I2CD1 is the default driver which corresponds to pins B6 and B7. This
|
|
||||||
* can be changed.
|
|
||||||
* Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
|
|
||||||
* STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef int16_t i2c_status_t;
|
|
||||||
|
|
||||||
#define I2C_STATUS_SUCCESS (0)
|
|
||||||
#define I2C_STATUS_ERROR (-1)
|
|
||||||
#define I2C_STATUS_TIMEOUT (-2)
|
|
||||||
|
|
||||||
void i2c_init(void);
|
|
||||||
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
|
||||||
i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout);
|
|
Loading…
Add table
Add a link
Reference in a new issue