1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 13 /**************************************************************************/ 14 /**************************************************************************/ 15 /** */ 16 /** USBX Component */ 17 /** */ 18 /** OHCI Controller Driver */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 24 /**************************************************************************/ 25 /* */ 26 /* COMPONENT DEFINITION RELEASE */ 27 /* */ 28 /* ux_hcd_ohci.h PORTABLE C */ 29 /* 6.1.12 */ 30 /* AUTHOR */ 31 /* */ 32 /* Chaoqiong Xiao, Microsoft Corporation */ 33 /* */ 34 /* DESCRIPTION */ 35 /* */ 36 /* This file contains all the header and extern functions used by the */ 37 /* USBX host OHCI Controller. */ 38 /* */ 39 /* RELEASE HISTORY */ 40 /* */ 41 /* DATE NAME DESCRIPTION */ 42 /* */ 43 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 44 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 45 /* resulting in version 6.1 */ 46 /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ 47 /* used unsigned defines, */ 48 /* resulting in version 6.1.2 */ 49 /* 08-02-2021 Chaoqiong Xiao Modified comment(s), */ 50 /* added extern "C" keyword */ 51 /* for compatibility with C++, */ 52 /* resulting in version 6.1.8 */ 53 /* 01-31-2022 Xiuwen Cai Modified comment(s), */ 54 /* fixed HcPeriodicStart value,*/ 55 /* resulting in version 6.1.10 */ 56 /* 07-29-2022 Yajun Xia Modified comment(s), */ 57 /* fixed OHCI PRSC issue, */ 58 /* resulting in version 6.1.12 */ 59 /* */ 60 /**************************************************************************/ 61 62 #ifndef UX_HCD_OHCI_H 63 #define UX_HCD_OHCI_H 64 65 /* Determine if a C++ compiler is being used. If so, ensure that standard 66 C is used to process the API information. */ 67 68 #ifdef __cplusplus 69 70 /* Yes, C++ compiler is present. Use standard C. */ 71 extern "C" { 72 73 #endif 74 75 76 /* Define generic OHCI constants. */ 77 78 #define UX_OHCI_CONTROLLER 1 79 #define UX_OHCI_MAX_PAYLOAD 4096 80 #define UX_OHCI_FRAME_DELAY 4u 81 82 83 /* Define OHCI HCOR register mapping. */ 84 85 #define OHCI_HC_REVISION 0x00 86 #define OHCI_HC_CONTROL 0x01 87 #define OHCI_HC_COMMAND_STATUS 0x02 88 #define OHCI_HC_INTERRUPT_STATUS 0x03 89 #define OHCI_HC_INTERRUPT_ENABLE 0x04 90 #define OHCI_HC_INTERRUPT_DISABLE 0x05 91 #define OHCI_HC_HCCA 0x06 92 #define OHCI_HC_PERIOD_CURRENT_ED 0x07 93 #define OHCI_HC_CONTROL_HEAD_ED 0x08 94 #define OHCI_HC_CONTROL_CURRENT_ED 0x09 95 #define OHCI_HC_BULK_HEAD_ED 0x0a 96 #define OHCI_HC_BULK_CURRENT_ED 0x0b 97 #define OHCI_HC_DONE_HEAD 0x0c 98 #define OHCI_HC_FM_INTERVAL 0x0d 99 #define OHCI_HC_FM_REMAINING 0x0e 100 #define OHCI_HC_FM_NUMBER 0x0f 101 #define OHCI_HC_PERIODIC_START 0x10 102 #define OHCI_HC_LS_THRESHOLD 0x11 103 #define OHCI_HC_RH_DESCRIPTOR_A 0x12 104 #define OHCI_HC_RH_DESCRIPTOR_B 0x13 105 #define OHCI_HC_RH_STATUS 0x14 106 #define OHCI_HC_RH_PORT_STATUS 0x15 107 108 109 /* Define OHCI control register values. */ 110 111 #define OHCI_HC_CR_CBSR_0 0x00000000u 112 #define OHCI_HC_CR_CBSR_1 0x00000001u 113 #define OHCI_HC_CR_CBSR_2 0x00000002u 114 #define OHCI_HC_CR_CBSR_3 0x00000003u 115 #define OHCI_HC_CR_PLE 0x00000004u 116 #define OHCI_HC_CR_IE 0x00000008u 117 #define OHCI_HC_CR_CLE 0x00000010u 118 #define OHCI_HC_CR_BLE 0x00000020u 119 #define OHCI_HC_CR_RESET 0x00000000u 120 #define OHCI_HC_CR_RESUME 0x00000040u 121 #define OHCI_HC_CR_OPERATIONAL 0x00000080u 122 #define OHCI_HC_CR_SUSPEND 0x000000c0u 123 #define OHCI_HC_CR_IR 0x00000100u 124 #define OHCI_HC_CR_RWC 0x00000200u 125 #define OHCI_HC_CR_RWE 0x00000400u 126 127 #define OHCI_HC_CONTROL_VALUE (OHCI_HC_CR_CBSR_3 | OHCI_HC_CR_OPERATIONAL | OHCI_HC_CR_PLE | OHCI_HC_CR_IE | OHCI_HC_CR_CLE | OHCI_HC_CR_BLE) 128 129 130 /* Define OHCI HCOR command/status bitmaps. */ 131 132 #define OHCI_HC_CS_HCR 0x00000001u 133 #define OHCI_HC_CS_CLF 0x00000002u 134 #define OHCI_HC_CS_BLF 0x00000004u 135 136 137 #define OHCI_HC_RH_PSM 0x00000100u 138 #define OHCI_HC_RH_NPS 0x00000200u 139 #define OHCI_HC_RH_DT 0x00000400u 140 #define OHCI_HC_RH_OCPM 0x00000800u 141 #define OHCI_HC_RH_NOCP 0x00001000u 142 #define OHCI_HC_RH_POTPGT 24u 143 144 #define OHCI_HC_RS_LPS 0x00000001u 145 #define OHCI_HC_RS_OCI 0x00000002u 146 #define OHCI_HC_RS_DRWE 0x00008000u 147 #define OHCI_HC_RS_LPSC 0x00010000u 148 #define OHCI_HC_RS_OCIC 0x00020000u 149 #define OHCI_HC_RS_CRWE 0x80000000u 150 151 #define OHCI_HC_PS_CCS 0x00000001u 152 #define OHCI_HC_PS_CPE 0x00000001u 153 #define OHCI_HC_PS_PES 0x00000002u 154 #define OHCI_HC_PS_PSS 0x00000004u 155 #define OHCI_HC_PS_POCI 0x00000008u 156 #define OHCI_HC_PS_PRS 0x00000010u 157 #define OHCI_HC_PS_PPS 0x00000100u 158 #define OHCI_HC_PS_LSDA 0x00000200u 159 #define OHCI_HC_PS_CSC 0x00010000u 160 #define OHCI_HC_PS_PESC 0x00020000u 161 #define OHCI_HC_PS_PSSC 0x00040000u 162 #define OHCI_HC_PS_OCIC 0x00080000u 163 #define OHCI_HC_PS_PRSC 0x00100000u 164 165 166 /* Define OHCI interrupt status register definitions. */ 167 168 #define OHCI_HC_INT_SO 0x00000001u 169 #define OHCI_HC_INT_WDH 0x00000002u 170 #define OHCI_HC_INT_SF 0x00000004u 171 #define OHCI_HC_INT_RD 0x00000008u 172 #define OHCI_HC_INT_UE 0x00000010u 173 #define OHCI_HC_INT_FNO 0x00000020u 174 #define OHCI_HC_INT_RHSC 0x00000040u 175 #define OHCI_HC_INT_OC 0x40000000u 176 177 #define OHCI_HC_INT_MIE 0x80000000u 178 179 180 #define OHCI_HC_INTERRUPT_ENABLE_NORMAL (OHCI_HC_INT_WDH | OHCI_HC_INT_RD | OHCI_HC_INT_UE | OHCI_HC_INT_RHSC | OHCI_HC_INT_MIE) 181 182 #define OHCI_HC_INTERRUPT_DISABLE_ALL (OHCI_HC_INT_SO | \ 183 OHCI_HC_INT_WDH | \ 184 OHCI_HC_INT_SF | \ 185 OHCI_HC_INT_RD | \ 186 OHCI_HC_INT_UE | \ 187 OHCI_HC_INT_FNO | \ 188 OHCI_HC_INT_RHSC | \ 189 OHCI_HC_INT_OC | \ 190 OHCI_HC_INT_MIE) 191 192 193 /* Define OHCI frame interval definition. */ 194 195 #define OHCI_HC_FM_INTERVAL_CLEAR 0x8000ffffu 196 #define OHCI_HC_FM_INTERVAL_SET 0x27780000u 197 #define OHCI_HC_FM_INTERVAL_FI_MASK 0x00003fffu 198 199 200 /* Define OHCI static definition. */ 201 202 #define UX_OHCI_AVAILABLE_BANDWIDTH 6000u 203 #define UX_OHCI_INIT_DELAY 1000 204 #define UX_OHCI_RESET_RETRY 1000 205 #define UX_OHCI_RESET_DELAY 10 206 #define UX_OHCI_PORT_RESET_RETRY 10 207 #define UX_OHCI_PORT_RESET_DELAY 10 208 209 210 /* Define OHCI initialization values. */ 211 212 #define UX_OHCI_COMMAND_STATUS_RESET 0 213 #define UX_OHCI_INIT_RESET_DELAY 10 214 215 /* Define OHCI completion code errors. */ 216 217 #define UX_OHCI_NO_ERROR 0x00 218 #define UX_OHCI_ERROR_CRC 0x01 219 #define UX_OHCI_ERROR_BIT_STUFFING 0x02 220 #define UX_OHCI_ERROR_DATA_TOGGLE 0x03 221 #define UX_OHCI_ERROR_STALL 0x04 222 #define UX_OHCI_ERROR_DEVICE_NOT_RESPONDING 0x05 223 #define UX_OHCI_ERROR_PID_FAILURE 0x06 224 #define UX_OHCI_ERROR_PID_UNEXPECTED 0x07 225 #define UX_OHCI_ERROR_DATA_OVERRRUN 0x08 226 #define UX_OHCI_ERROR_DATA_UNDERRUN 0x09 227 #define UX_OHCI_ERROR_BUFFER_OVERRRUN 0x0c 228 #define UX_OHCI_ERROR_BUFFER_UNDERRUN 0x0d 229 #define UX_OHCI_NOT_ACCESSED 0x0e 230 231 #define UX_OHCI_PRSC_EVENT 0x1u 232 233 #define UX_OHCI_PRSC_EVENT_TIMEOUT 100 234 235 /* Define OHCI HCCA structure. */ 236 237 typedef struct UX_HCD_OHCI_HCCA_STRUCT 238 { 239 240 struct UX_OHCI_ED_STRUCT 241 *ux_hcd_ohci_hcca_ed[32]; 242 USHORT ux_hcd_ohci_hcca_frame_number; 243 USHORT ux_hcd_ohci_hcca_reserved1; 244 struct UX_OHCI_TD_STRUCT 245 *ux_hcd_ohci_hcca_done_head; 246 UCHAR ux_hcd_ohci_hcca_reserved2[116]; 247 } UX_HCD_OHCI_HCCA; 248 249 250 /* Define OHCI HCD structure. */ 251 252 typedef struct UX_HCD_OHCI_STRUCT 253 { 254 255 struct UX_HCD_STRUCT 256 *ux_hcd_ohci_hcd_owner; 257 struct UX_HCD_OHCI_HCCA_STRUCT 258 *ux_hcd_ohci_hcca; 259 ULONG *ux_hcd_ohci_hcor; 260 UINT ux_hcd_ohci_nb_root_hubs; 261 struct UX_OHCI_TD_STRUCT 262 *ux_hcd_ohci_done_head; 263 struct UX_OHCI_ED_STRUCT 264 *ux_hcd_ohci_ed_list; 265 struct UX_OHCI_TD_STRUCT 266 *ux_hcd_ohci_td_list; 267 struct UX_OHCI_ISO_TD_STRUCT 268 *ux_hcd_ohci_iso_td_list; 269 UX_EVENT_FLAGS_GROUP 270 ux_hcd_ohci_event_flags_group; 271 } UX_HCD_OHCI; 272 273 274 /* Define OHCI ED structure. */ 275 276 typedef struct UX_OHCI_ED_STRUCT 277 { 278 279 ULONG ux_ohci_ed_dw0; 280 struct UX_OHCI_TD_STRUCT 281 *ux_ohci_ed_tail_td; 282 struct UX_OHCI_TD_STRUCT 283 *ux_ohci_ed_head_td; 284 struct UX_OHCI_ED_STRUCT 285 *ux_ohci_ed_next_ed; 286 struct UX_OHCI_ED_STRUCT 287 *ux_ohci_ed_previous_ed; 288 ULONG ux_ohci_ed_status; 289 struct UX_ENDPOINT_STRUCT 290 *ux_ohci_ed_endpoint; 291 ULONG ux_ohci_ed_frame; 292 } UX_OHCI_ED; 293 294 295 /* Define OHCI ED bitmap. */ 296 297 #define UX_OHCI_ED_LOW_SPEED 0x00002000u 298 #define UX_OHCI_ED_SKIP 0x00004000u 299 #define UX_OHCI_ED_ISOCHRONOUS 0x00008000u 300 #define UX_OHCI_ED_MPS 0x0000ffffu 301 302 #define UX_OHCI_ED_HALTED 0x00000001u 303 #define UX_OHCI_ED_TOGGLE_CARRY 0x00000002u 304 #define UX_OHCI_ED_MASK_TD (~0x00000003u) 305 306 #define UX_OHCI_ED_OUT 0x0800u 307 #define UX_OHCI_ED_IN 0x1000u 308 309 310 /* Define OHCI TD structure. */ 311 312 typedef struct UX_OHCI_TD_STRUCT 313 { 314 ULONG ux_ohci_td_dw0; 315 UCHAR * ux_ohci_td_cbp; 316 struct UX_OHCI_TD_STRUCT 317 *ux_ohci_td_next_td; 318 UCHAR * ux_ohci_td_be; 319 ULONG ux_ohci_td_reserved_1[4]; 320 struct UX_TRANSFER_STRUCT 321 *ux_ohci_td_transfer_request; 322 struct UX_OHCI_TD_STRUCT 323 *ux_ohci_td_next_td_transfer_request; 324 struct UX_OHCI_ED_STRUCT 325 *ux_ohci_td_ed; 326 ULONG ux_ohci_td_length; 327 ULONG ux_ohci_td_status; 328 ULONG ux_ohci_td_reserved_2[3]; 329 } UX_OHCI_TD; 330 331 332 /* Define OHCI TD bitmap. */ 333 334 #define UX_OHCI_TD_OUT 0x00080000u 335 #define UX_OHCI_TD_IN 0x00100000u 336 #define UX_OHCI_TD_DEFAULT_DW0 0xf0000000u 337 #define UX_OHCI_TD_DATA0 0x02000000u 338 #define UX_OHCI_TD_DATA1 0x03000000u 339 #define UX_OHCI_TD_R 0x00040000u 340 341 #define UX_OHCI_TD_SETUP_PHASE 0x00010000u 342 #define UX_OHCI_TD_DATA_PHASE 0x00020000u 343 #define UX_OHCI_TD_STATUS_PHASE 0x00040000u 344 #define UX_OHCI_TD_CC 28u 345 346 347 /* Define OHCI ISOCHRONOUS TD structure. */ 348 349 typedef struct UX_OHCI_ISO_TD_STRUCT 350 { 351 352 ULONG ux_ohci_iso_td_dw0; 353 UCHAR * ux_ohci_iso_td_bp0; 354 struct UX_OHCI_TD_STRUCT 355 *ux_ohci_iso_td_next_td; 356 UCHAR * ux_ohci_iso_td_be; 357 USHORT ux_ohci_iso_td_offset_psw[8]; 358 struct UX_TRANSFER_STRUCT 359 *ux_ohci_iso_td_transfer_request; 360 struct UX_OHCI_TD_STRUCT 361 *ux_ohci_iso_td_next_td_transfer_request; 362 struct UX_OHCI_ED_STRUCT 363 *ux_ohci_iso_td_ed; 364 ULONG ux_ohci_iso_td_length; 365 ULONG ux_ohci_iso_td_status; 366 ULONG ux_ohci_iso_td_reserved[3]; 367 } UX_OHCI_ISO_TD; 368 369 370 /* Define OHCI ISOCHRONOUS TD bitmap. */ 371 372 #define UX_OHCI_ISO_TD_BASE 0xfffff000u 373 #define UX_OHCI_ISO_TD_OFFSET 0x00000fffu 374 #define UX_OHCI_ISO_TD_PSW_CC 0x0000e000u 375 #define UX_OHCI_ISO_TD_FC 24u 376 377 378 /* Define OHCI function prototypes. */ 379 380 UINT _ux_hcd_ohci_asynchronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint); 381 UINT _ux_hcd_ohci_asynchronous_endpoint_destroy(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint); 382 UINT _ux_hcd_ohci_controller_disable(UX_HCD_OHCI *hcd_ohci); 383 VOID _ux_hcd_ohci_done_queue_process(UX_HCD_OHCI *hcd_ohci); 384 UX_OHCI_ED *_ux_hcd_ohci_ed_obtain(UX_HCD_OHCI *hcd_ohci); 385 UINT _ux_hcd_ohci_endpoint_error_clear(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint); 386 UINT _ux_hcd_ohci_endpoint_reset(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint); 387 UINT _ux_hcd_ohci_entry(UX_HCD *hcd, UINT function, VOID *parameter); 388 UINT _ux_hcd_ohci_frame_number_get(UX_HCD_OHCI *hcd_ohci, ULONG *frame_number); 389 VOID _ux_hcd_ohci_frame_number_set(UX_HCD_OHCI *hcd_ohci, ULONG frame_number); 390 UINT _ux_hcd_ohci_initialize(UX_HCD *hcd); 391 UINT _ux_hcd_ohci_interrupt_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint); 392 VOID _ux_hcd_ohci_interrupt_handler(VOID); 393 UINT _ux_hcd_ohci_isochronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint); 394 UX_OHCI_ISO_TD *_ux_hcd_ohci_isochronous_td_obtain(UX_HCD_OHCI *hcd_ohci); 395 UX_OHCI_ED *_ux_hcd_ohci_least_traffic_list_get(UX_HCD_OHCI *hcd_ohci); 396 VOID _ux_hcd_ohci_next_td_clean(UX_OHCI_TD *td); 397 UINT _ux_hcd_ohci_periodic_endpoint_destroy(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint); 398 UINT _ux_hcd_ohci_periodic_tree_create(UX_HCD_OHCI *hcd_ohci); 399 UINT _ux_hcd_ohci_port_disable(UX_HCD_OHCI *hcd_ohci, ULONG port_index); 400 UINT _ux_hcd_ohci_port_enable(UX_HCD_OHCI *hcd_ohci, ULONG port_index); 401 UINT _ux_hcd_ohci_port_reset(UX_HCD_OHCI *hcd_ohci, ULONG port_index); 402 UINT _ux_hcd_ohci_port_resume(UX_HCD_OHCI *hcd_ohci, UINT port_index); 403 ULONG _ux_hcd_ohci_port_status_get(UX_HCD_OHCI *hcd_ohci, ULONG port_index); 404 UINT _ux_hcd_ohci_port_suspend(UX_HCD_OHCI *hcd_ohci, ULONG port_index); 405 UINT _ux_hcd_ohci_power_down_port(UX_HCD_OHCI *hcd_ohci, ULONG port_index); 406 UINT _ux_hcd_ohci_power_on_port(UX_HCD_OHCI *hcd_ohci, ULONG port_index); 407 VOID _ux_hcd_ohci_power_root_hubs(UX_HCD_OHCI *hcd_ohci); 408 ULONG _ux_hcd_ohci_register_read(UX_HCD_OHCI *hcd_ohci, ULONG ohci_register); 409 VOID _ux_hcd_ohci_register_write(UX_HCD_OHCI *hcd_ohci, ULONG ohci_register, ULONG value); 410 UX_OHCI_TD *_ux_hcd_ohci_regular_td_obtain(UX_HCD_OHCI *hcd_ohci); 411 UINT _ux_hcd_ohci_request_bulk_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request); 412 UINT _ux_hcd_ohci_request_control_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request); 413 UINT _ux_hcd_ohci_request_interrupt_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request); 414 UINT _ux_hcd_ohci_request_isochronous_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request); 415 UINT _ux_hcd_ohci_request_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request); 416 UINT _ux_hcd_ohci_transfer_abort(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request); 417 VOID _ux_hcd_ohci_transfer_request_process(UX_TRANSFER *transfer_request); 418 419 #define ux_hcd_ohci_initialize _ux_hcd_ohci_initialize 420 #define ux_hcd_ohci_interrupt_handler _ux_hcd_ohci_interrupt_handler 421 422 /* Determine if a C++ compiler is being used. If so, complete the standard 423 C conditional started above. */ 424 #ifdef __cplusplus 425 } 426 #endif 427 428 #endif 429 430