|
@@ -26,35 +26,57 @@
|
26
|
26
|
|
27
|
27
|
/*
|
28
|
28
|
* Read a single byte from the FUSB302B
|
|
29
|
+ *
|
|
30
|
+ * cfg: The FUSB302B to communicate with
|
|
31
|
+ * addr: The memory address from which to read
|
|
32
|
+ *
|
|
33
|
+ * Returns the value read from addr.
|
29
|
34
|
*/
|
30
|
|
-static uint8_t fusb_read_byte(uint8_t addr)
|
|
35
|
+static uint8_t fusb_read_byte(struct pdb_fusb_config *cfg, uint8_t addr)
|
31
|
36
|
{
|
32
|
37
|
uint8_t buf;
|
33
|
|
- i2cMasterTransmit(&I2CD2, FUSB302B_ADDR, &addr, 1, &buf, 1);
|
|
38
|
+ i2cMasterTransmit(cfg->i2cp, cfg->addr, &addr, 1, &buf, 1);
|
34
|
39
|
return buf;
|
35
|
40
|
}
|
36
|
41
|
|
37
|
42
|
/*
|
38
|
43
|
* Read multiple bytes from the FUSB302B
|
|
44
|
+ *
|
|
45
|
+ * cfg: The FUSB302B to communicate with
|
|
46
|
+ * addr: The memory address from which to read
|
|
47
|
+ * size: The number of bytes to read
|
|
48
|
+ * buf: The buffer into which data will be read
|
39
|
49
|
*/
|
40
|
|
-static void fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf)
|
|
50
|
+static void fusb_read_buf(struct pdb_fusb_config *cfg, uint8_t addr,
|
|
51
|
+ uint8_t size, uint8_t *buf)
|
41
|
52
|
{
|
42
|
|
- i2cMasterTransmit(&I2CD2, FUSB302B_ADDR, &addr, 1, buf, size);
|
|
53
|
+ i2cMasterTransmit(cfg->i2cp, cfg->addr, &addr, 1, buf, size);
|
43
|
54
|
}
|
44
|
55
|
|
45
|
56
|
/*
|
46
|
57
|
* Write a single byte to the FUSB302B
|
|
58
|
+ *
|
|
59
|
+ * cfg: The FUSB302B to communicate with
|
|
60
|
+ * addr: The memory address to which we will write
|
|
61
|
+ * byte: The value to write
|
47
|
62
|
*/
|
48
|
|
-static void fusb_write_byte(uint8_t addr, uint8_t byte)
|
|
63
|
+static void fusb_write_byte(struct pdb_fusb_config *cfg, uint8_t addr,
|
|
64
|
+ uint8_t byte)
|
49
|
65
|
{
|
50
|
66
|
uint8_t buf[2] = {addr, byte};
|
51
|
|
- i2cMasterTransmit(&I2CD2, FUSB302B_ADDR, buf, 2, NULL, 0);
|
|
67
|
+ i2cMasterTransmit(cfg->i2cp, cfg->addr, buf, 2, NULL, 0);
|
52
|
68
|
}
|
53
|
69
|
|
54
|
70
|
/*
|
55
|
71
|
* Write multiple bytes to the FUSB302B
|
|
72
|
+ *
|
|
73
|
+ * cfg: The FUSB302B to communicate with
|
|
74
|
+ * addr: The memory address to which we will write
|
|
75
|
+ * size: The number of bytes to write
|
|
76
|
+ * buf: The buffer to write
|
56
|
77
|
*/
|
57
|
|
-static void fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf)
|
|
78
|
+static void fusb_write_buf(struct pdb_fusb_config *cfg, uint8_t addr,
|
|
79
|
+ uint8_t size, const uint8_t *buf)
|
58
|
80
|
{
|
59
|
81
|
uint8_t txbuf[size + 1];
|
60
|
82
|
|
|
@@ -64,7 +86,7 @@ static void fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf)
|
64
|
86
|
txbuf[i + 1] = buf[i];
|
65
|
87
|
}
|
66
|
88
|
|
67
|
|
- i2cMasterTransmit(&I2CD2, FUSB302B_ADDR, txbuf, size + 1, NULL, 0);
|
|
89
|
+ i2cMasterTransmit(cfg->i2cp, cfg->addr, txbuf, size + 1, NULL, 0);
|
68
|
90
|
}
|
69
|
91
|
|
70
|
92
|
void fusb_send_message(struct pdb_fusb_config *cfg, const union pd_msg *msg)
|
|
@@ -95,9 +117,9 @@ void fusb_send_message(struct pdb_fusb_config *cfg, const union pd_msg *msg)
|
95
|
117
|
sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len;
|
96
|
118
|
|
97
|
119
|
/* Write all three parts of the message to the TX FIFO */
|
98
|
|
- fusb_write_buf(FUSB_FIFOS, 5, sop_seq);
|
99
|
|
- fusb_write_buf(FUSB_FIFOS, msg_len, msg->bytes);
|
100
|
|
- fusb_write_buf(FUSB_FIFOS, 4, eop_seq);
|
|
120
|
+ fusb_write_buf(cfg, FUSB_FIFOS, 5, sop_seq);
|
|
121
|
+ fusb_write_buf(cfg, FUSB_FIFOS, msg_len, msg->bytes);
|
|
122
|
+ fusb_write_buf(cfg, FUSB_FIFOS, 4, eop_seq);
|
101
|
123
|
|
102
|
124
|
i2cReleaseBus(cfg->i2cp);
|
103
|
125
|
}
|
|
@@ -112,21 +134,21 @@ uint8_t fusb_read_message(struct pdb_fusb_config *cfg, union pd_msg *msg)
|
112
|
134
|
/* If this isn't an SOP message, return error.
|
113
|
135
|
* Because of our configuration, we should be able to assume this means the
|
114
|
136
|
* buffer is empty, and not try to read past a non-SOP message. */
|
115
|
|
- if ((fusb_read_byte(FUSB_FIFOS) & FUSB_FIFO_RX_TOKEN_BITS)
|
|
137
|
+ if ((fusb_read_byte(cfg, FUSB_FIFOS) & FUSB_FIFO_RX_TOKEN_BITS)
|
116
|
138
|
!= FUSB_FIFO_RX_SOP) {
|
117
|
|
- i2cReleaseBus(&I2CD2);
|
|
139
|
+ i2cReleaseBus(cfg->i2cp);
|
118
|
140
|
return 1;
|
119
|
141
|
}
|
120
|
142
|
/* Read the message header into msg */
|
121
|
|
- fusb_read_buf(FUSB_FIFOS, 2, msg->bytes);
|
|
143
|
+ fusb_read_buf(cfg, FUSB_FIFOS, 2, msg->bytes);
|
122
|
144
|
/* Get the number of data objects */
|
123
|
145
|
numobj = PD_NUMOBJ_GET(msg);
|
124
|
146
|
/* If there is at least one data object, read the data objects */
|
125
|
147
|
if (numobj > 0) {
|
126
|
|
- fusb_read_buf(FUSB_FIFOS, numobj * 4, msg->bytes + 2);
|
|
148
|
+ fusb_read_buf(cfg, FUSB_FIFOS, numobj * 4, msg->bytes + 2);
|
127
|
149
|
}
|
128
|
150
|
/* Throw the CRC32 in the garbage, since the PHY already checked it. */
|
129
|
|
- fusb_read_buf(FUSB_FIFOS, 4, garbage);
|
|
151
|
+ fusb_read_buf(cfg, FUSB_FIFOS, 4, garbage);
|
130
|
152
|
|
131
|
153
|
i2cReleaseBus(cfg->i2cp);
|
132
|
154
|
return 0;
|
|
@@ -137,7 +159,7 @@ void fusb_send_hardrst(struct pdb_fusb_config *cfg)
|
137
|
159
|
i2cAcquireBus(cfg->i2cp);
|
138
|
160
|
|
139
|
161
|
/* Send a hard reset */
|
140
|
|
- fusb_write_byte(FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
|
|
162
|
+ fusb_write_byte(cfg, FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
|
141
|
163
|
|
142
|
164
|
i2cReleaseBus(cfg->i2cp);
|
143
|
165
|
}
|
|
@@ -147,44 +169,44 @@ void fusb_setup(struct pdb_fusb_config *cfg)
|
147
|
169
|
i2cAcquireBus(cfg->i2cp);
|
148
|
170
|
|
149
|
171
|
/* Fully reset the FUSB302B */
|
150
|
|
- fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES);
|
|
172
|
+ fusb_write_byte(cfg, FUSB_RESET, FUSB_RESET_SW_RES);
|
151
|
173
|
|
152
|
174
|
/* Turn on all power */
|
153
|
|
- fusb_write_byte(FUSB_POWER, 0x0F);
|
|
175
|
+ fusb_write_byte(cfg, FUSB_POWER, 0x0F);
|
154
|
176
|
|
155
|
177
|
/* Set interrupt masks */
|
156
|
|
- fusb_write_byte(FUSB_MASK1, 0x00);
|
157
|
|
- fusb_write_byte(FUSB_MASKA, 0x00);
|
158
|
|
- fusb_write_byte(FUSB_MASKB, 0x00);
|
159
|
|
- fusb_write_byte(FUSB_CONTROL0, 0x04);
|
|
178
|
+ fusb_write_byte(cfg, FUSB_MASK1, 0x00);
|
|
179
|
+ fusb_write_byte(cfg, FUSB_MASKA, 0x00);
|
|
180
|
+ fusb_write_byte(cfg, FUSB_MASKB, 0x00);
|
|
181
|
+ fusb_write_byte(cfg, FUSB_CONTROL0, 0x04);
|
160
|
182
|
|
161
|
183
|
/* Enable automatic retransmission */
|
162
|
|
- fusb_write_byte(FUSB_CONTROL3, 0x07);
|
|
184
|
+ fusb_write_byte(cfg, FUSB_CONTROL3, 0x07);
|
163
|
185
|
|
164
|
186
|
/* Flush the RX buffer */
|
165
|
|
- fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
|
187
|
+ fusb_write_byte(cfg, FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
166
|
188
|
|
167
|
189
|
/* Measure CC1 */
|
168
|
|
- fusb_write_byte(FUSB_SWITCHES0, 0x07);
|
|
190
|
+ fusb_write_byte(cfg, FUSB_SWITCHES0, 0x07);
|
169
|
191
|
chThdSleepMicroseconds(250);
|
170
|
|
- uint8_t cc1 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
|
192
|
+ uint8_t cc1 = fusb_read_byte(cfg, FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
171
|
193
|
|
172
|
194
|
/* Measure CC2 */
|
173
|
|
- fusb_write_byte(FUSB_SWITCHES0, 0x0B);
|
|
195
|
+ fusb_write_byte(cfg, FUSB_SWITCHES0, 0x0B);
|
174
|
196
|
chThdSleepMicroseconds(250);
|
175
|
|
- uint8_t cc2 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
|
197
|
+ uint8_t cc2 = fusb_read_byte(cfg, FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
176
|
198
|
|
177
|
199
|
/* Select the correct CC line for BMC signaling; also enable AUTO_CRC */
|
178
|
200
|
if (cc1 > cc2) {
|
179
|
|
- fusb_write_byte(FUSB_SWITCHES1, 0x25);
|
180
|
|
- fusb_write_byte(FUSB_SWITCHES0, 0x07);
|
|
201
|
+ fusb_write_byte(cfg, FUSB_SWITCHES1, 0x25);
|
|
202
|
+ fusb_write_byte(cfg, FUSB_SWITCHES0, 0x07);
|
181
|
203
|
} else {
|
182
|
|
- fusb_write_byte(FUSB_SWITCHES1, 0x26);
|
183
|
|
- fusb_write_byte(FUSB_SWITCHES0, 0x0B);
|
|
204
|
+ fusb_write_byte(cfg, FUSB_SWITCHES1, 0x26);
|
|
205
|
+ fusb_write_byte(cfg, FUSB_SWITCHES0, 0x0B);
|
184
|
206
|
}
|
185
|
207
|
|
186
|
208
|
/* Reset the PD logic */
|
187
|
|
- fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET);
|
|
209
|
+ fusb_write_byte(cfg, FUSB_RESET, FUSB_RESET_PD_RESET);
|
188
|
210
|
|
189
|
211
|
i2cReleaseBus(cfg->i2cp);
|
190
|
212
|
}
|
|
@@ -194,7 +216,7 @@ void fusb_get_status(struct pdb_fusb_config *cfg, union fusb_status *status)
|
194
|
216
|
i2cAcquireBus(cfg->i2cp);
|
195
|
217
|
|
196
|
218
|
/* Read the interrupt and status flags into status */
|
197
|
|
- fusb_read_buf(FUSB_STATUS0A, 7, status->bytes);
|
|
219
|
+ fusb_read_buf(cfg, FUSB_STATUS0A, 7, status->bytes);
|
198
|
220
|
|
199
|
221
|
i2cReleaseBus(cfg->i2cp);
|
200
|
222
|
}
|
|
@@ -204,7 +226,7 @@ enum fusb_typec_current fusb_get_typec_current(struct pdb_fusb_config *cfg)
|
204
|
226
|
i2cAcquireBus(cfg->i2cp);
|
205
|
227
|
|
206
|
228
|
/* Read the BC_LVL into a variable */
|
207
|
|
- enum fusb_typec_current bc_lvl = fusb_read_byte(FUSB_STATUS0)
|
|
229
|
+ enum fusb_typec_current bc_lvl = fusb_read_byte(cfg, FUSB_STATUS0)
|
208
|
230
|
& FUSB_STATUS0_BC_LVL;
|
209
|
231
|
|
210
|
232
|
i2cReleaseBus(cfg->i2cp);
|
|
@@ -217,11 +239,11 @@ void fusb_reset(struct pdb_fusb_config *cfg)
|
217
|
239
|
i2cAcquireBus(cfg->i2cp);
|
218
|
240
|
|
219
|
241
|
/* Flush the TX buffer */
|
220
|
|
- fusb_write_byte(FUSB_CONTROL0, 0x44);
|
|
242
|
+ fusb_write_byte(cfg, FUSB_CONTROL0, 0x44);
|
221
|
243
|
/* Flush the RX buffer */
|
222
|
|
- fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
|
244
|
+ fusb_write_byte(cfg, FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
223
|
245
|
/* Reset the PD logic */
|
224
|
|
- fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET);
|
|
246
|
+ fusb_write_byte(cfg, FUSB_RESET, FUSB_RESET_PD_RESET);
|
225
|
247
|
|
226
|
248
|
i2cReleaseBus(cfg->i2cp);
|
227
|
249
|
}
|