1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
|
/*
* fusb302 usb phy driver for type-c and PD
*
* Copyright (C) 2015, 2016 Fairchild Semiconductor Corporation
*
* 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
* 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. Seee 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/>.
*
*/
#include "core.h"
#include "TypeC.h"
#include "PDProtocol.h"
#include "PDPolicy.h"
#include "TypeC_Types.h"
#include "PD_Types.h"
#ifdef FSC_DEBUG
#include "version.h"
#endif // FSC_DEBUG
extern FSC_BOOL PolicyHasContract;
extern doDataObject_t USBPDContract;
extern SourceOrSink sourceOrSink;
extern USBTypeCCurrent SinkCurrent;
/*
* Call this function to initialize the core.
*/
void core_initialize(void)
{
InitializeTypeCVariables(); // Initialize the TypeC variables for the state machine
InitializePDProtocolVariables(); // Initialize the USB PD variables
InitializePDPolicyVariables(); // Initialize the USB PD variables
InitializeTypeC();
}
/*
* Call this function to enable or disable the core Type-C State Machine.
* TRUE -> enable the core state machine
* FALSE -> disable the core state machine
*/
void core_enable_typec(FSC_BOOL enable)
{
if (enable == TRUE) EnableTypeCStateMachine();
else DisableTypeCStateMachine();
}
/*
* Call this function to run the state machines.
*/
void core_state_machine(void)
{
StateMachineTypeC();
}
/*
* Call this function every 100us for the core's timers.
*/
void core_tick(void)
{
TypeCTick();
ProtocolTick();
PolicyTick();
#ifdef FSC_DEBUG
LogTickAt100us();
#endif // FSC_DEBUG
}
#ifdef FSC_DEBUG
/*
* Call this function to get the lower 8-bits of the core revision number.
*/
FSC_U8 core_get_rev_lower(void)
{
return FSC_TYPEC_CORE_FW_REV_LOWER;
}
/*
* Call this function to get the middle 8-bits of the core revision number.
*/
FSC_U8 core_get_rev_middle(void)
{
return FSC_TYPEC_CORE_FW_REV_MIDDLE;
}
/*
* Call this function to get the upper 8-bits of the core revision number.
*/
FSC_U8 core_get_rev_upper(void)
{
return FSC_TYPEC_CORE_FW_REV_UPPER;
}
#endif // FSC_DEBUG
void core_set_vbus_transition_time(FSC_U32 time_ms)
{
SetVbusTransitionTime(time_ms);
}
#ifdef FSC_DEBUG
void core_configure_port_type(FSC_U8 config)
{
ConfigurePortType(config);
}
void core_enable_pd(FSC_BOOL enable)
{
if (enable == TRUE) EnableUSBPD();
else DisableUSBPD();
}
#ifdef FSC_HAVE_SRC
void core_set_source_caps(FSC_U8* buf)
{
WriteSourceCapabilities(buf);
}
void core_get_source_caps(FSC_U8* buf)
{
ReadSourceCapabilities(buf);
}
#endif // FSC_HAVE_SRC
#ifdef FSC_HAVE_SNK
void core_set_sink_caps(FSC_U8* buf)
{
WriteSinkCapabilities(buf);
}
void core_get_sink_caps(FSC_U8* buf)
{
ReadSinkCapabilities(buf);
}
void core_set_sink_req(FSC_U8* buf)
{
WriteSinkRequestSettings(buf);
}
void core_get_sink_req(FSC_U8* buf)
{
ReadSinkRequestSettings(buf);
}
#endif // FSC_HAVE_SNK
void core_send_hard_reset(void)
{
SendUSBPDHardReset();
}
void core_process_pd_buffer_read(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
ProcessPDBufferRead(InBuffer, OutBuffer);
}
void core_process_typec_pd_status(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
ProcessTypeCPDStatus(InBuffer, OutBuffer);
}
void core_process_typec_pd_control(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
ProcessTypeCPDControl(InBuffer, OutBuffer);
}
void core_process_local_register_request(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
ProcessLocalRegisterRequest(InBuffer, OutBuffer);
}
void core_process_set_typec_state(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
ProcessSetTypeCState(InBuffer, OutBuffer);
}
void core_process_read_typec_state_log(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
ProcessReadTypeCStateLog(InBuffer, OutBuffer);
}
void core_process_read_pd_state_log(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
ProcessReadPDStateLog(InBuffer, OutBuffer);
}
void core_set_alternate_modes(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
setAlternateModes(InBuffer[3]);
}
void core_set_manual_retries(FSC_U8* InBuffer, FSC_U8* OutBuffer)
{
setManualRetries(InBuffer[4]);
}
FSC_U8 core_get_alternate_modes(void)
{
return getAlternateModes();
}
FSC_U8 core_get_manual_retries(void)
{
return getManualRetries();
}
void core_set_state_unattached(void)
{
SetStateUnattached();
}
FSC_U16 core_get_advertised_current(void)
{
FSC_U16 current = 0; // Current advertisement in mA
if(sourceOrSink == SINK)
{
if(PolicyHasContract) // If there is a PD contract
{
current = USBPDContract.FVRDO.OpCurrent * 10; // Return contracted current in mA
}
else // We check Type-C current
{
switch(SinkCurrent)
{
/* Note for Default: This can be
* 500mA for USB 2.0
* 900mA for USB 3.1
* Up to 1.5A for USB BC 1.2
*/
case utccDefault:
current = 500;
break;
case utcc1p5A:
current = 1500;
break;
case utcc3p0A:
current = 3000;
break;
case utccNone:
default:
current = 0;
break;
}
}
}
return current;
}
void core_reset_pd(void)
{
EnableUSBPD();
USBPDEnable(TRUE, sourceOrSink);
}
void core_requestPRSwap(void)
{
PDTransmitHeader.NumDataObjects = 0;
PDTransmitHeader.MessageType = CMTPR_Swap;
USBPDTxFlag = TRUE;
}
void core_requestDRSwap(void)
{
PDTransmitHeader.NumDataObjects = 0;
PDTransmitHeader.MessageType = CMTDR_Swap;
USBPDTxFlag = TRUE;
}
#endif // FSC_DEBUG
|