Skip to content

Commit bb29418

Browse files
committed
Initial commit.
0 parents  commit bb29418

File tree

9 files changed

+353
-0
lines changed

9 files changed

+353
-0
lines changed

.clang-format

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Standard: Cpp11
2+
BasedOnStyle: Google
3+
IndentWidth: 4
4+
ColumnLimit: 0
5+
KeepEmptyLinesAtTheStartOfBlocks: true
6+
AllowShortIfStatementsOnASingleLine: Always

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
patreon: sitronlabs

LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Sitron Labs
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
667 KB
Binary file not shown.

keywords.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pi3usb9281c KEYWORD1
2+
setup KEYWORD2
3+
detect KEYWORD2
4+
reset KEYWORD2
5+
device_attach_wait KEYWORD2
6+
device_type_get KEYWORD2
7+
switch_state_set KEYWORD2
8+
register_read KEYWORD2
9+
register_write KEYWORD2

library.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "Sitron_Labs_PI3USB9281C_Arduino_Library",
3+
"version": "0.1.0",
4+
"description": "Arduino library for the Diodes Incorporated (previously Pericom) PI3USB9281C USB device detection IC.",
5+
"keywords": "sitron labs,sitron,labs,arduino,library,i2c,interface,usb,device,charger,detection,pericom,diodes,diodes incorporated,pi3usb9281,pi3usb9281a,pi3usb9281c",
6+
"repository": {
7+
"type": "git",
8+
"url": "https:\/\/github.com\/sitronlabs\/SitronLabs_Diodes_PI3USB9281C_Arduino_Library.git"
9+
},
10+
"frameworks": "arduino",
11+
"platforms": "*",
12+
"dependencies": [],
13+
"build": {
14+
"includeDir": "src"
15+
}
16+
}

library.properties

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=Sitron Labs PI3USB9281C Arduino Library
2+
version=0.1.0
3+
author=Sitron Labs
4+
maintainer=Sitron Labs <[email protected]>
5+
sentence=Arduino library for the Diodes Incorporated (previously Pericom) PI3USB9281C USB device detection IC.
6+
paragraph=
7+
category=Other
8+
url=https://github.com/sitronlabs/SitronLabs_Diodes_PI3USB9281C_Arduino_Library
9+
architectures=*
10+
depends=

src/pi3usb9281c.cpp

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/* Self header */
2+
#include "pi3usb9281c.h"
3+
4+
/* Config */
5+
#ifndef CONFIG_PI3USB9281C_LOG_FUNCTION
6+
#define CONFIG_PI3USB9281C_LOG_FUNCTION(...) (void)0 //!< Replace by { Serial.printf(__VA_ARGS__); Serial.println(); } to output on serial port
7+
#endif
8+
9+
/**
10+
*
11+
* @param[in] i2c_library
12+
* @param[in] i2c_address
13+
* @param[in] pin_enb
14+
*/
15+
int pi3usb9281c::setup(TwoWire& i2c_library, const uint8_t i2c_address, const int pin_enb) {
16+
17+
/* Ensure i2c address is valid */
18+
if (i2c_address != 0x25) {
19+
return -EINVAL;
20+
}
21+
22+
/* Save parameters */
23+
m_i2c_library = &i2c_library;
24+
m_i2c_address = i2c_address;
25+
26+
/* Enable */
27+
pinMode(pin_enb, OUTPUT);
28+
digitalWrite(pin_enb, LOW);
29+
30+
/* Return success */
31+
return 0;
32+
}
33+
34+
/**
35+
*
36+
*/
37+
bool pi3usb9281c::detect(void) {
38+
uint8_t reg_id;
39+
if (register_read(PI3USB9281C_REGISTER_ID, &reg_id) < 0 || reg_id != 0b00011000) {
40+
return false;
41+
} else {
42+
return true;
43+
}
44+
}
45+
46+
/**
47+
*
48+
*/
49+
int pi3usb9281c::reset(void) {
50+
51+
/* */
52+
uint8_t reg_reset = 0x01;
53+
if (register_write(PI3USB9281C_REGISTER_RESET, reg_reset) < 0) {
54+
return -EIO;
55+
}
56+
57+
/* Return success */
58+
return 0;
59+
}
60+
61+
/**
62+
* @param[in] timeout_ms
63+
* @return
64+
*/
65+
int pi3usb9281c::device_attach_wait(const uint32_t timeout_ms) {
66+
67+
/* While timeout has not expired */
68+
for (uint32_t time_start = millis();;) {
69+
70+
/* Watch for timeout */
71+
if (millis() - time_start >= timeout_ms) {
72+
return -ETIMEDOUT;
73+
}
74+
75+
/* Read interrupt flags */
76+
uint8_t reg_interrupt = 0;
77+
if (register_read(PI3USB9281C_REGISTER_INTERRUPT, &reg_interrupt) < 0) {
78+
return -EIO;
79+
}
80+
81+
/* Check accessory attached interrupt flag */
82+
if (reg_interrupt & 0b1) {
83+
84+
/* Clear interrupt flag */
85+
reg_interrupt = 0b1;
86+
if (register_write(PI3USB9281C_REGISTER_INTERRUPT, reg_interrupt) < 0) {
87+
return -EIO;
88+
}
89+
90+
/* Return success */
91+
return 0;
92+
}
93+
}
94+
}
95+
96+
/**
97+
*
98+
*/
99+
int pi3usb9281c::device_type_get(enum pi3usb9281c_device_type* const type) {
100+
101+
/* Read registers */
102+
uint8_t reg_device_type = 0;
103+
uint8_t reg_charger_type = 0;
104+
if ((register_read(PI3USB9281C_REGISTER_DEVICE_TYPE, &reg_device_type) < 0) ||
105+
(register_read(PI3USB9281C_REGISTER_CHARGER_STATUS, &reg_charger_type) < 0)) {
106+
CONFIG_PI3USB9281C_LOG_FUNCTION("Failed to read device type!");
107+
return -EIO;
108+
}
109+
110+
/* */
111+
if (reg_charger_type & (1 << 4)) {
112+
*type = PI3USB9281C_DEVICE_TYPE_CHARGER_2_4A;
113+
} else if (reg_charger_type & (1 << 3)) {
114+
*type = PI3USB9281C_DEVICE_TYPE_CHARGER_2A;
115+
} else if (reg_charger_type & (1 << 2)) {
116+
*type = PI3USB9281C_DEVICE_TYPE_CHARGER_1A;
117+
} else if ((reg_charger_type & 0b11) == 0b11) {
118+
*type = PI3USB9281C_DEVICE_TYPE_CARKIT2;
119+
} else if ((reg_charger_type & 0b11) == 0b10) {
120+
*type = PI3USB9281C_DEVICE_TYPE_CARKIT1;
121+
} else if (reg_device_type & (1 << 6)) {
122+
*type = PI3USB9281C_DEVICE_TYPE_USB_DCP;
123+
} else if (reg_device_type & (1 << 5)) {
124+
*type = PI3USB9281C_DEVICE_TYPE_USB_CDP;
125+
} else if (reg_device_type & (1 << 2)) {
126+
*type = PI3USB9281C_DEVICE_TYPE_USB_SDP;
127+
} else {
128+
*type = PI3USB9281C_DEVICE_TYPE_UNKNOWN;
129+
}
130+
131+
/* Return success */
132+
return 0;
133+
}
134+
135+
/**
136+
*
137+
*/
138+
int pi3usb9281c::switch_state_set(const enum pi3usb9281c_switch_state state) {
139+
140+
/* Ensure state is valid */
141+
if (state != PI3USB9281C_SWITCH_STATE_AUTO &&
142+
state != PI3USB9281C_SWITCH_STATE_MANUAL_OPEN &&
143+
state != PI3USB9281C_SWITCH_STATE_MANUAL_CLOSED) {
144+
return -EINVAL;
145+
}
146+
147+
/* Write registers */
148+
uint8_t reg_control = 0b00011011 | (state == PI3USB9281C_SWITCH_STATE_AUTO ? 1 << 2 : 0);
149+
uint8_t reg_manual_switch = 0b00000000 | (state == PI3USB9281C_SWITCH_STATE_MANUAL_CLOSED ? 0b00100111 : 0);
150+
if (register_write(PI3USB9281C_REGISTER_CONTROL, reg_control) < 0 ||
151+
register_write(PI3USB9281C_REGISTER_MANUAL_SWITCH, reg_manual_switch) < 0) {
152+
return -EIO;
153+
}
154+
155+
/* Return success */
156+
return 0;
157+
}
158+
159+
/**
160+
* Reads the contents of the given register.
161+
* @param[in] reg_address The address of the register.
162+
* @param[out] reg_content A pointer to a variable that will be updated with the contents of the register.
163+
* @return 0 in case of success, or a negative error code otherwise.
164+
*/
165+
int pi3usb9281c::register_read(const enum pi3usb9281c_register reg_address, uint8_t* const reg_content) {
166+
int res;
167+
168+
/* Ensure library has been configured */
169+
if (m_i2c_library == NULL) {
170+
return -EINVAL;
171+
}
172+
173+
/* Send register address */
174+
m_i2c_library->beginTransmission(m_i2c_address);
175+
m_i2c_library->write(reg_address);
176+
res = m_i2c_library->endTransmission(false);
177+
if (res != 0) {
178+
return -EIO;
179+
}
180+
181+
/* Read data */
182+
m_i2c_library->requestFrom(m_i2c_address, (uint8_t)1, (uint8_t) true);
183+
res = m_i2c_library->available();
184+
if (res == 0) {
185+
return -EIO;
186+
}
187+
*reg_content = m_i2c_library->read();
188+
189+
/* Return success */
190+
return 0;
191+
}
192+
193+
/**
194+
* Updates the content of the given register.
195+
* @param[in] reg_address The address of the register.
196+
* @param[in] reg_content The new content of the register.
197+
* @return 0 in case of success, or a negative error code otherwise.
198+
*/
199+
int pi3usb9281c::register_write(const enum pi3usb9281c_register reg_address, const uint8_t reg_content) {
200+
int res;
201+
202+
/* Ensure library has been configured */
203+
if (m_i2c_library == NULL) {
204+
return -EINVAL;
205+
}
206+
207+
/* Send register address and data */
208+
m_i2c_library->beginTransmission(m_i2c_address);
209+
m_i2c_library->write(reg_address);
210+
m_i2c_library->write(reg_content);
211+
res = m_i2c_library->endTransmission(true);
212+
if (res != 0) {
213+
return -EIO;
214+
}
215+
216+
/* Return success */
217+
return 0;
218+
}

src/pi3usb9281c.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#ifndef PI3USB9281C_H
2+
#define PI3USB9281C_H
3+
4+
/* Arduino libraries */
5+
#include <Arduino.h>
6+
#include <Wire.h>
7+
8+
/* C/C++ libraries */
9+
#include <errno.h>
10+
#include <stddef.h>
11+
#include <stdint.h>
12+
13+
/**
14+
*
15+
*/
16+
enum pi3usb9281c_register {
17+
PI3USB9281C_REGISTER_ID = 0x01,
18+
PI3USB9281C_REGISTER_CONTROL = 0x02,
19+
PI3USB9281C_REGISTER_INTERRUPT = 0x03,
20+
PI3USB9281C_REGISTER_INTERRUPT_MASK = 0x05,
21+
PI3USB9281C_REGISTER_DEVICE_TYPE = 0x0A,
22+
PI3USB9281C_REGISTER_VBUS_DETECT = 0x0B,
23+
PI3USB9281C_REGISTER_CHARGER_STATUS = 0x0E,
24+
PI3USB9281C_REGISTER_MANUAL_SWITCH = 0x13,
25+
PI3USB9281C_REGISTER_RESET = 0x1B,
26+
PI3USB9281C_REGISTER_VBUS = 0x1D,
27+
};
28+
29+
/**
30+
* List of different switch states for the D+ and D- signals
31+
*/
32+
enum pi3usb9281c_switch_state {
33+
PI3USB9281C_SWITCH_STATE_AUTO,
34+
PI3USB9281C_SWITCH_STATE_MANUAL_OPEN,
35+
PI3USB9281C_SWITCH_STATE_MANUAL_CLOSED,
36+
};
37+
38+
/**
39+
* List of different USB devices the IC can detect
40+
*/
41+
enum pi3usb9281c_device_type {
42+
PI3USB9281C_DEVICE_TYPE_UNKNOWN,
43+
PI3USB9281C_DEVICE_TYPE_USB_SDP, //!< Standard Downstream Port, up to 500mA
44+
PI3USB9281C_DEVICE_TYPE_USB_CDP, //!< Charging Downstream Port, up to 1.5A
45+
PI3USB9281C_DEVICE_TYPE_USB_DCP, //!< Dedicated Charging Port, beyond 1.5A
46+
PI3USB9281C_DEVICE_TYPE_CHARGER_1A, //!< 1.0 Amps charger
47+
PI3USB9281C_DEVICE_TYPE_CHARGER_2A, //!< 2.0 Amps charger
48+
PI3USB9281C_DEVICE_TYPE_CHARGER_2_4A, //!< 2.4 Amps charger
49+
PI3USB9281C_DEVICE_TYPE_CARKIT1, //!<
50+
PI3USB9281C_DEVICE_TYPE_CARKIT2, //!<
51+
};
52+
53+
/**
54+
*
55+
*/
56+
class pi3usb9281c {
57+
public:
58+
int setup(TwoWire &i2c_library, const uint8_t i2c_address, const int pin_res);
59+
bool detect(void);
60+
int reset(void);
61+
int device_attach_wait(const uint32_t timeout_ms);
62+
int device_type_get(enum pi3usb9281c_device_type *const type);
63+
int switch_state_set(const enum pi3usb9281c_switch_state state);
64+
int register_read(const enum pi3usb9281c_register reg_address, uint8_t *const reg_content);
65+
int register_write(const enum pi3usb9281c_register reg_address, const uint8_t reg_content);
66+
67+
protected:
68+
TwoWire *m_i2c_library = NULL;
69+
uint8_t m_i2c_address = 0;
70+
};
71+
72+
#endif

0 commit comments

Comments
 (0)