-
Notifications
You must be signed in to change notification settings - Fork 271
/
Copy pathport_scan.c
311 lines (244 loc) · 7.03 KB
/
port_scan.c
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
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/* Copyright (C) 2015-2019 by Jacob Alexander
*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This file 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this file. If not, see <http://www.gnu.org/licenses/>.
*/
// ----- Defines -----
// Compile-modes
// See capabilities.kll for details
#define None 0
#define USBSwap 1
#define USBInterSwap 2
#define USBHubSwap 3
// ----- Includes -----
// Compiler Includes
#include <Lib/ScanLib.h>
// Project Includes
#include <cli.h>
#include <kll.h>
#include <kll_defs.h>
#include <latency.h>
#include <led.h>
#include <print.h>
#include <Lib/gpio.h>
// USB Includes
#if defined(_avr_at_)
#include <avr/usb_keyboard_serial.h>
#elif defined(_kinetis_) || defined(_sam_)
#include <arm/usb_dev.h>
#endif
// Interconnect Includes
#if Port_SwapMode_define == USBInterSwap
#include <connect_scan.h>
#endif
// Local Includes
#include "port_scan.h"
// ----- Structs -----
// ----- Function Declarations -----
// CLI Functions
void cliFunc_portCross( char* args );
void cliFunc_portUART ( char* args );
void cliFunc_portUSB ( char* args );
// ----- Variables -----
uint32_t Port_lastcheck_ms;
uint32_t Port_attempt;
// GPIOs used for swapping
#if Port_SwapMode_define == USBSwap || Port_SwapMode_define == USBInterSwap
static const GPIO_Pin usb_swap_pin1 = Port_SwapUSBPin1_define;
#endif
#if Port_SwapMode_define == USBHubSwap
static const GPIO_Pin usb_swap_pin2 = Port_SwapUSBPin2_define;
static const GPIO_Pin usb_swap_pin3 = Port_SwapUSBPin3_define;
static const GPIO_Pin usb_swap_pin4 = Port_SwapUSBPin4_define;
#endif
#if Port_SwapMode_define == USBInterSwap
static const GPIO_Pin uart_swap_pin1 = Port_SwapInterpPin1_define;;
#endif
#if Port_SwapMode_define == USBInterSwap
static const GPIO_Pin uart_cross_pin1 = Port_CrossInterPin1_define;
#endif
// Scan Module command dictionary
CLIDict_Entry( portCross, "Cross interconnect pins." );
CLIDict_Entry( portUSB, "Swap USB ports manually, forces usb and interconnect to re-negotiate if necessary." );
CLIDict_Entry( portUART, "Swap interconnect ports." );
CLIDict_Def( portCLIDict, "Port Swap Module Commands" ) = {
#if Port_SwapMode_define == USBInterSwap
CLIDict_Item( portCross ),
CLIDict_Item( portUART ),
#endif
CLIDict_Item( portUSB ),
{ 0, 0, 0 } // Null entry for dictionary end
};
// Latency measurement resource
static uint8_t portLatencyResource;
// ----- Functions -----
void Port_usb_swap()
{
#if Port_SwapMode_define == USBSwap || Port_SwapMode_define == USBInterSwap
info_printNL("USB Port Swap");
// USB Swap
GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveToggle, GPIO_Config_None );
// Re-initialize usb
// Call usb_configured() to check if usb is ready
usb_reinit();
#else
warn_printNL("Unsupported");
#endif
}
void Port_uart_swap()
{
#if Port_SwapMode_define == USBInterSwap
info_printNL("Interconnect Line Swap");
// UART Swap
GPIO_Ctrl( uart_swap_pin1, GPIO_Type_DriveToggle, GPIO_Config_None );
#else
warn_printNL("Unsupported");
#endif
}
void Port_cross()
{
#if Port_SwapMode_define == USBInterSwap
info_printNL("Interconnect Line Cross");
// UART Tx/Rx cross-over
GPIO_Ctrl( uart_cross_pin1, GPIO_Type_DriveToggle, GPIO_Config_None );
// Reset interconnects
Connect_reset();
#else
warn_printNL("Unsupported");
#endif
}
// Setup
inline void Port_setup()
{
// Register Scan CLI dictionary
CLI_registerDictionary( portCLIDict, portCLIDictName );
#if Port_SwapMode_define == USBSwap
// USB Swap
// Start, disabled
GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveLow, GPIO_Config_None );
#elif Port_SwapMode_define == USBInterSwap
// USB Swap
// Start, disabled
GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveLow, GPIO_Config_None );
// UART Tx/Rx cross-over
// Start, disabled
GPIO_Ctrl( uart_cross_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
GPIO_Ctrl( uart_cross_pin1, GPIO_Type_DriveLow, GPIO_Config_None );
// UART Swap
// Start, disabled
GPIO_Ctrl( uart_swap_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
GPIO_Ctrl( uart_swap_pin1, GPIO_Type_DriveLow, GPIO_Config_None );
#else
warn_printNL("Unsupported");
#endif
// Starting point for automatic port swapping
Port_lastcheck_ms = systick_millis_count;
Port_attempt = 0;
// Allocate latency measurement resource
portLatencyResource = Latency_add_resource("PortSwap", LatencyOption_Ticks);
}
// Port State processing loop
inline uint8_t Port_scan()
{
// Latency measurement start
Latency_start_time( portLatencyResource );
// TODO Add in interconnect line cross
#define USBPortSwapDelay_ms 1000
// Wait 1000 ms before checking
// Only check for swapping after delay
uint32_t wait_ms = systick_millis_count - Port_lastcheck_ms;
if ( wait_ms > USBPortSwapDelay_ms + Port_attempt * USBPortSwapDelay_ms / 4 )
{
// Update timeout
Port_lastcheck_ms = systick_millis_count;
// USB not initialized, attempt to swap
if ( !usb_configured() )
{
Port_usb_swap();
Port_attempt++;
}
}
// Latency measurement end
Latency_end_time( portLatencyResource );
return 0;
}
// ----- Capabilities -----
void Port_uart_capability( TriggerMacro *trigger, uint8_t state, uint8_t stateType, uint8_t *args )
{
CapabilityState cstate = KLL_CapabilityState( state, stateType );
switch ( cstate )
{
case CapabilityState_Last:
// Only use capability on release
break;
case CapabilityState_Debug:
// Display capability name
print("Port_uart_capability()");
return;
default:
return;
}
Port_uart_swap();
}
void Port_usb_capability( TriggerMacro *trigger, uint8_t state, uint8_t stateType, uint8_t *args )
{
CapabilityState cstate = KLL_CapabilityState( state, stateType );
switch ( cstate )
{
case CapabilityState_Last:
// Only use capability on release
break;
case CapabilityState_Debug:
// Display capability name
print("Port_usb_capability()");
return;
default:
return;
}
Port_usb_swap();
}
void Port_cross_capability( TriggerMacro *trigger, uint8_t state, uint8_t stateType, uint8_t *args )
{
CapabilityState cstate = KLL_CapabilityState( state, stateType );
switch ( cstate )
{
case CapabilityState_Last:
// Only use capability on release
break;
case CapabilityState_Debug:
// Display capability name
print("Port_cross_capability()");
return;
default:
return;
}
Port_cross();
}
// ----- CLI Command Functions -----
void cliFunc_portUART( char* args )
{
print( NL );
Port_uart_swap();
}
void cliFunc_portUSB( char* args )
{
print( NL );
Port_usb_swap();
}
void cliFunc_portCross( char* args )
{
print( NL );
Port_cross();
}