Open FFBoard
Open source force feedback firmware
dwc2_info.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2
3import ctypes
4import argparse
5import click
6import pandas as pd
7
8# hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4
9# Note: FS is FullSpeed, HS is HighSpeed
10dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4']
11dwc2_reg_value = {
12 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020],
13 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030],
14 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030],
15 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030],
16 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030],
17 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x03F403E8, 0x17F00030],
18 'ST F412/76x FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030],
19 'ST F723/L4P5 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030],
20 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x03EED2E8, 0x23F00030],
21 'ST F76x HS': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030],
22 'ST H743/H750': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x03B8D2E8, 0xE3F00030],
23 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030],
24 'ST U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30],
25 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x027A01E5, 0xDBF08030],
26 'GD32VF103': [0x1000, 0, 0, 0, 0, 0],
27}
28
29# Combine dwc2_info with dwc2_reg_list
30# dwc2_info = {
31# 'BCM2711 (Pi4)': {
32# 'GUID': 0x2708A000,
33# 'GSNPSID': 0x4F54280A,
34# 'GHWCFG1': 0,
35# 'GHWCFG2': 0x228DDD50,
36# 'GHWCFG3': 0xFF000E8,
37# 'GHWCFG4': 0x1FF00020
38# },
39dwc2_info = {key: {field: value for field, value in zip(dwc2_reg_list, values)} for key, values in dwc2_reg_value.items()}
40
41
42class GHWCFG2(ctypes.LittleEndianStructure):
43 _fields_ = [
44 ("op_mode", ctypes.c_uint32, 3),
45 ("arch", ctypes.c_uint32, 2),
46 ("single_point", ctypes.c_uint32, 1),
47 ("hs_phy_type", ctypes.c_uint32, 2),
48 ("fs_phy_type", ctypes.c_uint32, 2),
49 ("num_dev_ep", ctypes.c_uint32, 4),
50 ("num_host_ch", ctypes.c_uint32, 4),
51 ("period_channel_support", ctypes.c_uint32, 1),
52 ("enable_dynamic_fifo", ctypes.c_uint32, 1),
53 ("mul_proc_intrpt", ctypes.c_uint32, 1),
54 ("reserved21", ctypes.c_uint32, 1),
55 ("nptx_q_depth", ctypes.c_uint32, 2),
56 ("ptx_q_depth", ctypes.c_uint32, 2),
57 ("token_q_depth", ctypes.c_uint32, 5),
58 ("otg_enable_ic_usb", ctypes.c_uint32, 1)
59 ]
60
61
62class GHWCFG3(ctypes.LittleEndianStructure):
63 _fields_ = [
64 ("xfer_size_width", ctypes.c_uint32, 4),
65 ("packet_size_width", ctypes.c_uint32, 3),
66 ("otg_enable", ctypes.c_uint32, 1),
67 ("i2c_enable", ctypes.c_uint32, 1),
68 ("vendor_ctrl_itf", ctypes.c_uint32, 1),
69 ("optional_feature_removed", ctypes.c_uint32, 1),
70 ("synch_reset", ctypes.c_uint32, 1),
71 ("otg_adp_support", ctypes.c_uint32, 1),
72 ("otg_enable_hsic", ctypes.c_uint32, 1),
73 ("battery_charger_support", ctypes.c_uint32, 1),
74 ("lpm_mode", ctypes.c_uint32, 1),
75 ("dfifo_depth", ctypes.c_uint32, 16)
76 ]
77
78
79class GHWCFG4(ctypes.LittleEndianStructure):
80 _fields_ = [
81 ("num_dev_period_in_ep", ctypes.c_uint32, 4),
82 ("partial_powerdown", ctypes.c_uint32, 1),
83 ("ahb_freq_min", ctypes.c_uint32, 1),
84 ("hibernation", ctypes.c_uint32, 1),
85 ("extended_hibernation", ctypes.c_uint32, 1),
86 ("reserved8", ctypes.c_uint32, 1),
87 ("enhanced_lpm_support1", ctypes.c_uint32, 1),
88 ("service_interval_flow", ctypes.c_uint32, 1),
89 ("ipg_isoc_support", ctypes.c_uint32, 1),
90 ("acg_support", ctypes.c_uint32, 1),
91 ("enhanced_lpm_support", ctypes.c_uint32, 1),
92 ("phy_data_width", ctypes.c_uint32, 2),
93 ("ctrl_ep_num", ctypes.c_uint32, 4),
94 ("iddg_filter", ctypes.c_uint32, 1),
95 ("vbus_valid_filter", ctypes.c_uint32, 1),
96 ("a_valid_filter", ctypes.c_uint32, 1),
97 ("b_valid_filter", ctypes.c_uint32, 1),
98 ("session_end_filter", ctypes.c_uint32, 1),
99 ("dedicated_fifos", ctypes.c_uint32, 1),
100 ("num_dev_in_eps", ctypes.c_uint32, 4),
101 ("dma_desc_enable", ctypes.c_uint32, 1),
102 ("dma_desc_dynamic", ctypes.c_uint32, 1)
103 ]
104
105# mapping for specific fields in GHWCFG2
106GHWCFG2_field = {
107 'op_mode': {
108 0: "HNP SRP",
109 1: "SRP",
110 2: "noHNP noSRP",
111 3: "SRP Device",
112 4: "noOTG Device",
113 5: "SRP Host",
114 6: "noOTG Host"
115 },
116 'arch': {
117 0: "Slave only",
118 1: "DMA external",
119 2: "DMA internal"
120 },
121 'single_point': {
122 0: "hub",
123 1: "n/a"
124 },
125 'hs_phy_type': {
126 0: "n/a",
127 1: "UTMI+",
128 2: "ULPI",
129 3: "UTMI+/ULPI"
130 },
131 'fs_phy_type': {
132 0: "n/a",
133 1: "Dedicated",
134 2: "Shared UTMI+",
135 3: "Shared ULPI"
136 },
137 'nptx_q_depth': {
138 0: "2",
139 1: "4",
140 2: "8",
141 },
142 'ptx_q_depth': {
143 0: "2",
144 1: "4",
145 2: "8",
146 3: "16"
147 },
148}
149
150# mapping for specific fields in GHWCFG4
151GHWCFG4_field = {
152 'phy_data_width': {
153 0: "8 bit",
154 1: "16 bit",
155 2: "8/16 bit",
156 3: "Reserved"
157 },
158 }
159
160def main():
161 """Render dwc2_info to Markdown table"""
162
163 parser = argparse.ArgumentParser()
164 args = parser.parse_args()
165
166 # Create an empty list to hold the dictionaries
167 md_table = []
168
169 # Iterate over the dwc2_info dictionary and extract fields
170 for device, reg_values in dwc2_info.items():
171 md_item = {"Device": device}
172 for r_name, r_value in reg_values.items():
173 md_item[r_name] = f"0x{r_value:08X}"
174
175 if r_name == 'GSNPSID':
176 # Get dwc2 specs version
177 major = ((r_value >> 8) >> 4) & 0x0F
178 minor = (r_value >> 4) & 0xFF
179 patch = chr((r_value & 0x0F) + ord('a') - 0xA)
180 md_item[f' - specs version'] = f"{major:X}.{minor:02X}{patch}"
181 elif r_name in globals():
182 # Get bit-field values which exist as ctypes structures
183 class_hdl = globals()[r_name]
184 ghwcfg = class_hdl.from_buffer_copy(r_value.to_bytes(4, byteorder='little'))
185 for field_name, field_type, _ in class_hdl._fields_:
186 field_value = getattr(ghwcfg, field_name)
187 if class_hdl == GHWCFG2 and field_name in GHWCFG2_field:
188 field_value = GHWCFG2_field[field_name].get(field_value, f"Unknown ({field_value})")
189 if class_hdl == GHWCFG4 and field_name in GHWCFG4_field:
190 field_value = GHWCFG4_field[field_name].get(field_value, f"Unknown ({field_value})")
191
192 md_item[f' - {field_name}'] = field_value
193
194 md_table.append(md_item)
195
196 # Create a Pandas DataFrame from the list of dictionaries
197 df = pd.DataFrame(md_table).set_index('Device')
198
199 # Transpose the DataFrame to switch rows and columns
200 df = df.T
201 #print(df)
202
203 # Write the Markdown table to a file
204 with open('dwc2_info.md', 'w') as md_file:
205 md_file.write(df.to_markdown())
206 md_file.write('\n')
207
208
209if __name__ == '__main__':
210 main()
def main()
Definition: dwc2_info.py:160