|
| 1 | +[](https://www.sitronlabs.com/) |
| 2 | +[](https://discord.gg/btnVDeWhfW) |
| 3 | + |
| 4 | + |
| 5 | +[](https://www.ardu-badge.com/Sitron%20Labs%20PI3USB9281C%20Arduino%20Library) |
| 6 | +[](https://registry.platformio.org/libraries/sitronlabs/Sitron_Labs_PI3USB9281C_Arduino_Library) |
| 7 | + |
| 8 | +# Sitron Labs Diodes PI3USB9281C Arduino Library |
| 9 | + |
| 10 | +Arduino library for interfacing with the Diodes Incorporated (previously Pericom) PI3USB9281C USB device detection IC. |
| 11 | + |
| 12 | +## Description |
| 13 | + |
| 14 | +The PI3USB9281C is a USB charger and device detection IC that can identify various types of USB ports and charging devices. It can detect Standard Downstream Ports (SDP), Charging Downstream Ports (CDP), Dedicated Charging Ports (DCP), various charger types (1A, 2A, 2.4A), and CarKit accessories. The IC also provides control over D+/D- switch routing and monitors device attachment events. This library provides a simple interface to access these features via I2C. |
| 15 | + |
| 16 | +## Installation |
| 17 | + |
| 18 | +### Arduino IDE |
| 19 | + |
| 20 | +Install via the Arduino Library Manager by searching for "Sitron Labs PI3USB9281C". |
| 21 | + |
| 22 | +Alternatively, install manually: |
| 23 | +1. Download or clone this repository |
| 24 | +2. Place it in your Arduino `libraries` folder |
| 25 | +3. Restart the Arduino IDE |
| 26 | + |
| 27 | +### PlatformIO |
| 28 | + |
| 29 | +Install via the PlatformIO Library Manager by searching for "Sitron Labs PI3USB9281C". |
| 30 | + |
| 31 | +Alternatively, add the library manually to your `platformio.ini` file: |
| 32 | + |
| 33 | +```ini |
| 34 | +lib_deps = |
| 35 | + https://github.com/sitronlabs/SitronLabs_Diodes_PI3USB9281C_Arduino_Library.git |
| 36 | +``` |
| 37 | + |
| 38 | +## Hardware Connections |
| 39 | + |
| 40 | +Connect the PI3USB9281C to your Arduino using I2C: |
| 41 | + |
| 42 | +- VCC → 3.3V or 5V (check your board's specifications) |
| 43 | +- GND → GND |
| 44 | +- SDA → SDA (I2C Data) |
| 45 | +- SCL → SCL (I2C Clock) |
| 46 | +- ENB → Any digital pin (enable pin, active LOW) |
| 47 | +- INT → NC (unused by this library) |
| 48 | + |
| 49 | +The I2C address is fixed at 0x25. |
| 50 | + |
| 51 | +## Usage |
| 52 | + |
| 53 | +### Basic Device Detection |
| 54 | + |
| 55 | +```cpp |
| 56 | +#include <Wire.h> |
| 57 | +#include <pi3usb9281c.h> |
| 58 | + |
| 59 | +// Create device object |
| 60 | +pi3usb9281c device; |
| 61 | + |
| 62 | +// I2C address (fixed at 0x25) |
| 63 | +const uint8_t I2C_ADDRESS = 0x25; |
| 64 | + |
| 65 | +// Enable pin |
| 66 | +const int PIN_ENB = 2; |
| 67 | + |
| 68 | +void setup() { |
| 69 | + Serial.begin(9600); |
| 70 | + |
| 71 | + // Initialize I2C |
| 72 | + Wire.begin(); |
| 73 | + |
| 74 | + // Setup the PI3USB9281C (I2C library, I2C address, enable pin) |
| 75 | + if (device.setup(Wire, I2C_ADDRESS, PIN_ENB) != 0) { |
| 76 | + Serial.println("Failed to setup PI3USB9281C"); |
| 77 | + return; |
| 78 | + } |
| 79 | + |
| 80 | + // Detect the device |
| 81 | + if (!device.detect()) { |
| 82 | + Serial.println("PI3USB9281C not detected"); |
| 83 | + return; |
| 84 | + } |
| 85 | + |
| 86 | + // Perform software reset |
| 87 | + device.reset(); |
| 88 | + delay(100); |
| 89 | + |
| 90 | + // Set switch to automatic mode |
| 91 | + device.switch_state_set(PI3USB9281C_SWITCH_STATE_AUTO); |
| 92 | + |
| 93 | + Serial.println("PI3USB9281C initialized"); |
| 94 | +} |
| 95 | + |
| 96 | +void loop() { |
| 97 | + // Check for device attachment (non-blocking) |
| 98 | + int attach_status = device.device_attach_get(); |
| 99 | + |
| 100 | + if (attach_status == 1) { |
| 101 | + Serial.println("Device attached!"); |
| 102 | + |
| 103 | + // Get device type |
| 104 | + enum pi3usb9281c_device_type type; |
| 105 | + if (device.device_type_get(&type) == 0) { |
| 106 | + switch (type) { |
| 107 | + case PI3USB9281C_DEVICE_TYPE_USB_SDP: |
| 108 | + Serial.println("USB Standard Downstream Port (up to 500mA)"); |
| 109 | + break; |
| 110 | + case PI3USB9281C_DEVICE_TYPE_USB_CDP: |
| 111 | + Serial.println("USB Charging Downstream Port (up to 1.5A)"); |
| 112 | + break; |
| 113 | + case PI3USB9281C_DEVICE_TYPE_USB_DCP: |
| 114 | + Serial.println("USB Dedicated Charging Port (beyond 1.5A)"); |
| 115 | + break; |
| 116 | + case PI3USB9281C_DEVICE_TYPE_CHARGER_1A: |
| 117 | + Serial.println("1.0 Amps charger"); |
| 118 | + break; |
| 119 | + case PI3USB9281C_DEVICE_TYPE_CHARGER_2A: |
| 120 | + Serial.println("2.0 Amps charger"); |
| 121 | + break; |
| 122 | + case PI3USB9281C_DEVICE_TYPE_CHARGER_2_4A: |
| 123 | + Serial.println("2.4 Amps charger"); |
| 124 | + break; |
| 125 | + case PI3USB9281C_DEVICE_TYPE_CARKIT1: |
| 126 | + Serial.println("CarKit type 1 accessory"); |
| 127 | + break; |
| 128 | + case PI3USB9281C_DEVICE_TYPE_CARKIT2: |
| 129 | + Serial.println("CarKit type 2 accessory"); |
| 130 | + break; |
| 131 | + default: |
| 132 | + Serial.println("Unknown device type"); |
| 133 | + break; |
| 134 | + } |
| 135 | + } |
| 136 | + } else if (attach_status < 0) { |
| 137 | + Serial.println("Error reading device status"); |
| 138 | + } |
| 139 | + |
| 140 | + delay(100); |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +### Waiting for Device Attachment |
| 145 | + |
| 146 | +```cpp |
| 147 | +#include <Wire.h> |
| 148 | +#include <pi3usb9281c.h> |
| 149 | + |
| 150 | +pi3usb9281c device; |
| 151 | +const uint8_t I2C_ADDRESS = 0x25; |
| 152 | +const int PIN_ENB = 2; |
| 153 | + |
| 154 | +void setup() { |
| 155 | + Serial.begin(9600); |
| 156 | + Wire.begin(); |
| 157 | + |
| 158 | + device.setup(Wire, I2C_ADDRESS, PIN_ENB); |
| 159 | + device.detect(); |
| 160 | + device.reset(); |
| 161 | + delay(100); |
| 162 | + device.switch_state_set(PI3USB9281C_SWITCH_STATE_AUTO); |
| 163 | +} |
| 164 | + |
| 165 | +void loop() { |
| 166 | + Serial.println("Waiting for device attachment..."); |
| 167 | + |
| 168 | + // Wait for device attachment (blocking, with timeout) |
| 169 | + if (device.device_attach_wait(5000) == 0) { |
| 170 | + Serial.println("Device attached!"); |
| 171 | + |
| 172 | + enum pi3usb9281c_device_type type; |
| 173 | + if (device.device_type_get(&type) == 0) { |
| 174 | + // Process device type... |
| 175 | + } |
| 176 | + } else { |
| 177 | + Serial.println("Timeout waiting for device"); |
| 178 | + } |
| 179 | + |
| 180 | + delay(1000); |
| 181 | +} |
| 182 | +``` |
| 183 | + |
| 184 | +## API Reference |
| 185 | + |
| 186 | +### setup(TwoWire &i2c_library, uint8_t i2c_address, int pin_enb) |
| 187 | + |
| 188 | +Initializes the PI3USB9281C device. |
| 189 | + |
| 190 | +- `i2c_library`: I2C library instance to use (typically `Wire`) |
| 191 | +- `i2c_address`: I2C address (must be 0x25) |
| 192 | +- `pin_enb`: GPIO pin number connected to the device's enable pin (active LOW) |
| 193 | + |
| 194 | +Returns 0 on success, or -EINVAL if the I2C address is invalid. |
| 195 | + |
| 196 | +### detect(void) |
| 197 | + |
| 198 | +Detects if a PI3USB9281C device is present by reading the device ID register. |
| 199 | + |
| 200 | +Returns true if device is detected, false otherwise. |
| 201 | + |
| 202 | +### reset(void) |
| 203 | + |
| 204 | +Performs a software reset of the device. |
| 205 | + |
| 206 | +Returns 0 on success, or a negative error code on I2C communication failure. |
| 207 | + |
| 208 | +### device_attach_get(void) |
| 209 | + |
| 210 | +Checks for device attachment (non-blocking). Reads the interrupt register once to check for device attachment and clears the interrupt flag if a device is attached. |
| 211 | + |
| 212 | +Returns 1 if device attached, 0 if no device attached, or -EIO on I2C error. |
| 213 | + |
| 214 | +### device_attach_wait(uint32_t timeout_ms) |
| 215 | + |
| 216 | +Waits for a device attachment event (blocking). Polls the interrupt register until a device is attached or the timeout expires. |
| 217 | + |
| 218 | +- `timeout_ms`: Maximum time to wait in milliseconds |
| 219 | + |
| 220 | +Returns 0 on device attached, -ETIMEDOUT on timeout, or -EIO on I2C error. |
| 221 | + |
| 222 | +### device_type_get(pi3usb9281c_device_type *type) |
| 223 | + |
| 224 | +Gets the type of attached USB device or charger. |
| 225 | + |
| 226 | +- `type`: Output parameter for the detected device type |
| 227 | + |
| 228 | +Returns 0 on success, or -EIO on I2C communication error. |
| 229 | + |
| 230 | +**Device types:** |
| 231 | +- `PI3USB9281C_DEVICE_TYPE_USB_SDP`: Standard Downstream Port (up to 500mA) |
| 232 | +- `PI3USB9281C_DEVICE_TYPE_USB_CDP`: Charging Downstream Port (up to 1.5A) |
| 233 | +- `PI3USB9281C_DEVICE_TYPE_USB_DCP`: Dedicated Charging Port (beyond 1.5A) |
| 234 | +- `PI3USB9281C_DEVICE_TYPE_CHARGER_1A`: 1.0 Amps charger |
| 235 | +- `PI3USB9281C_DEVICE_TYPE_CHARGER_2A`: 2.0 Amps charger |
| 236 | +- `PI3USB9281C_DEVICE_TYPE_CHARGER_2_4A`: 2.4 Amps charger |
| 237 | +- `PI3USB9281C_DEVICE_TYPE_CARKIT1`: CarKit type 1 accessory |
| 238 | +- `PI3USB9281C_DEVICE_TYPE_CARKIT2`: CarKit type 2 accessory |
| 239 | +- `PI3USB9281C_DEVICE_TYPE_UNKNOWN`: Unknown device type |
| 240 | + |
| 241 | +### switch_state_set(pi3usb9281c_switch_state state) |
| 242 | + |
| 243 | +Controls the state of the D+/D- switch. |
| 244 | + |
| 245 | +- `state`: Desired switch state |
| 246 | + - `PI3USB9281C_SWITCH_STATE_AUTO`: Automatic control based on detected device type |
| 247 | + - `PI3USB9281C_SWITCH_STATE_MANUAL_OPEN`: Force switch to disconnected state |
| 248 | + - `PI3USB9281C_SWITCH_STATE_MANUAL_CLOSED`: Force switch to connected state |
| 249 | + |
| 250 | +Returns 0 on success, -EINVAL for invalid state, or -EIO on I2C error. |
| 251 | + |
| 252 | +## Specifications |
| 253 | + |
| 254 | +- I2C address: 0x25 (fixed) |
| 255 | +- Communication interface: I2C |
| 256 | +- Enable pin: Active LOW |
| 257 | +- Detected USB port types: SDP, CDP, DCP |
| 258 | +- Detected charger types: 1A, 2A, 2.4A |
| 259 | +- Detected accessories: CarKit type 1 and type 2 |
| 260 | +- Switch control: Automatic or manual (open/closed) |
| 261 | + |
0 commit comments