1 /* Copyright (c) 2010-2011 mbed.org, MIT License
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4 * and associated documentation files (the "Software"), to deal in the Software without
5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
9 * The above copyright notice and this permission notice shall be included in all copies or
10 * substantial portions of the Software.
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include "ohci_wrapp_RZ_A1.h"
23 #include "ohci_wrapp_RZ_A1_local.h"
24 #include "rza_io_regrw.h"
25 #include "usb_host_setting.h"
27 /* ------------------ HcControl Register --------------------- */
28 #define OR_CONTROL_PLE (0x00000004)
29 #define OR_CONTROL_IE (0x00000008)
30 #define OR_CONTROL_CLE (0x00000010)
31 #define OR_CONTROL_BLE (0x00000020)
32 /* ----------------- HcCommandStatus Register ----------------- */
33 #define OR_CMD_STATUS_HCR (0x00000001)
34 #define OR_CMD_STATUS_CLF (0x00000002)
35 #define OR_CMD_STATUS_BLF (0x00000004)
36 #define OR_CMD_STATUS_OCR (0x00000008)
37 /* --------------- HcInterruptStatus Register ----------------- */
38 #define OR_INTR_STATUS_WDH (0x00000002)
39 #define OR_INTR_STATUS_RHSC (0x00000040)
40 /* --------------- HcInterruptEnable Register ----------------- */
41 #define OR_INTR_ENABLE_WDH (0x00000002)
42 #define OR_INTR_ENABLE_RHSC (0x00000040)
43 /* -------------- HcRhPortStatus[1:NDP] Register -------------- */
44 #define OR_RH_PORT_CSC (0x00010000)
45 #define OR_RH_PORT_LSDA (0x00000200)
46 #define OR_RH_PORT_PRS (0x00000010)
47 #define OR_RH_PORT_POCI (0x00000008)
48 #define OR_RH_PORT_CCS (0x00000001)
50 #define ED_FORMAT (0x00008000) /* Format */
51 #define ED_SKIP (0x00004000) /* Skip this ep in queue */
52 #define ED_TOGLE_CARRY (0x00000002)
53 #define ED_HALTED (0x00000001)
55 #define TD_SETUP (0x00000000) /* Direction of Setup Packet */
56 #define TD_OUT (0x00080000) /* Direction Out */
57 #define TD_TOGGLE_0 (0x02000000) /* Toggle 0 */
58 #define TD_TOGGLE_1 (0x03000000) /* Toggle 1 */
60 /* -------------- USB Standard Requests -------------- */
61 #define GET_STATUS (0x00)
62 #define SET_FEATURE (0x03)
63 #define SET_ADDRESS (0x05)
65 #define TD_CTL_MSK_DP (0x00180000)
66 #define TD_CTL_MSK_T (0x03000000)
67 #define TD_CTL_MSK_CC (0xF0000000)
68 #define TD_CTL_MSK_EC (0x0C000000)
69 #define TD_CTL_SHFT_CC (28)
70 #define TD_CTL_SHFT_EC (26)
71 #define TD_CTL_SHFT_T (24)
72 #define ED_SHFT_TOGLE_CARRY (1)
73 #define SIG_GEN_LIST_REQ (1)
74 #if (ISO_TRANS_MAX_NUM > 0)
75 #define TD_PSW_MSK_CC (0xF000)
76 #define TD_PSW_SHFT_CC (12)
77 #define TD_CTL_MSK_FC (0x07000000)
78 #define TD_CTL_SHFT_FC (24)
81 #define CTL_TRANS_TIMEOUT (1000)
82 #define BLK_TRANS_TIMEOUT (5)
83 #define TOTAL_SEM_NUM (5 + (2 * INT_TRANS_MAX_NUM) + (2 * ISO_TRANS_MAX_NUM))
85 #define PORT_LOW_SPEED (0x00000200)
86 #define PORT_HIGH_SPEED (0x00000400)
87 #define PORT_NUM (16 + 1) /* num + root(1) */
89 typedef struct tag_hctd
{
90 uint32_t control
; /* Transfer descriptor control */
91 uint8_t *currBufPtr
; /* Physical address of current buffer pointer */
92 struct tag_hctd
*nextTD
; /* Physical pointer to next Transfer Descriptor */
93 uint8_t *bufEnd
; /* Physical address of end of buffer */
96 #if (ISO_TRANS_MAX_NUM > 0)
98 typedef struct tag_hcisotd
{
99 uint32_t control
; /* Transfer descriptor control */
100 uint8_t *bufferPage0
; /* Buffer Page 0 */
101 struct tag_hcisotd
*nextTD
; /* Physical pointer to next Transfer Descriptor */
102 uint8_t *bufEnd
; /* Physical address of end of buffer */
103 uint16_t offsetPSW
[PSW_NUM
]; /* Offset/PSW */
107 typedef struct tag_hced
{
108 uint32_t control
; /* Endpoint descriptor control */
109 uint32_t tailTD
; /* Physical address of tail in Transfer descriptor list */
110 uint32_t headTD
; /* Physcial address of head in Transfer descriptor list */
111 struct tag_hced
*nextED
; /* Physical address of next Endpoint descriptor */
114 typedef struct tag_hcca
{
115 uint32_t IntTable
[32]; /* Interrupt Table */
116 uint32_t FrameNumber
; /* Frame Number */
117 uint32_t DoneHead
; /* Done Head */
118 volatile uint8_t Reserved
[116]; /* Reserved for future use */
119 volatile uint8_t Unknown
[4]; /* Unused */
122 typedef struct tag_usb_ohci_reg
{
123 volatile uint32_t HcRevision
;
124 volatile uint32_t HcControl
;
125 volatile uint32_t HcCommandStatus
;
126 volatile uint32_t HcInterruptStatus
;
127 volatile uint32_t HcInterruptEnable
;
128 volatile uint32_t HcInterruptDisable
;
129 volatile uint32_t HcHCCA
;
130 volatile uint32_t HcPeriodCurrentED
;
131 volatile uint32_t HcControlHeadED
;
132 volatile uint32_t HcControlCurrentED
;
133 volatile uint32_t HcBulkHeadED
;
134 volatile uint32_t HcBulkCurrentED
;
135 volatile uint32_t HcDoneHead
;
136 volatile uint32_t HcFmInterval
;
137 volatile uint32_t HcFmRemaining
;
138 volatile uint32_t HcFmNumber
;
139 volatile uint32_t HcPeriodicStart
;
140 volatile uint32_t HcLSThreshold
;
141 volatile uint32_t HcRhDescriptorA
;
142 volatile uint32_t HcRhDescriptorB
;
143 volatile uint32_t HcRhStatus
;
144 volatile uint32_t HcRhPortStatus1
;
147 typedef struct tag_genelal_ed
{
149 osSemaphoreId semid_wait
;
150 osSemaphoreId semid_list
;
151 void *p_curr_td
; /* pointer of hctd_t or hcisotd_t */
156 uint8_t *p_start_buf
;
157 #if (ISO_TRANS_MAX_NUM > 0)
162 typedef struct tag_tdinfo
{
167 uint16_t speed
; /* 1:Speed = Low */
171 typedef struct tag_split_trans
{
172 uint16_t root_devadr
;
177 uint32_t port_sts_bits
[PORT_NUM
];
180 static void callback_task(void const * argument
);
181 static void control_ed_task(void const * argument
);
182 static void bulk_ed_task(void const * argument
);
183 static void int_ed_task(void const * argument
);
184 static int32_t int_trans_doing(hced_t
*p_ed
, uint32_t index
);
185 static int32_t chk_genelal_ed(genelal_ed_t
*p_g_ed
);
186 static void chk_genelal_td_done(genelal_ed_t
*p_g_ed
);
187 static void chk_split_trans_setting(genelal_ed_t
*p_g_ed
);
188 static void set_split_trans_setting(void);
189 static void control_trans(genelal_ed_t
*p_g_ed
);
190 static void bulk_trans(genelal_ed_t
*p_g_ed
);
191 static void int_trans_setting(genelal_ed_t
*p_g_ed
, uint32_t index
);
192 static uint32_t chk_cycle(hced_t
*p_ed
);
193 static void int_trans(genelal_ed_t
*p_g_ed
);
194 static void get_td_info(genelal_ed_t
*p_g_ed
, tdinfo_t
*p_td_info
);
195 static void set_togle(uint32_t pipe
, hctd_t
*p_td
, hced_t
*p_ed
);
196 #if (ISO_TRANS_MAX_NUM > 0)
197 static void iso_ed_task(void const * argument
);
198 static int32_t iso_trans_doing(hced_t
*p_ed
, uint32_t index
);
199 static void chk_iso_td_done(genelal_ed_t
*p_g_ed
);
200 static int32_t chk_iso_ed(genelal_ed_t
*p_g_ed
);
201 static void iso_trans_setting(genelal_ed_t
*p_g_ed
, uint32_t index
);
202 static uint32_t iso_chk_starting_frame(genelal_ed_t
*p_g_ed
);
203 static void iso_trans(genelal_ed_t
*p_g_ed
);
205 static void connect_check(void);
207 extern USB_HOST_CFG_PIPETBL_t usb_host_blk_ep_tbl1
[];
208 extern USB_HOST_CFG_PIPETBL_t usb_host_int_ep_tbl1
[];
209 #if (ISO_TRANS_MAX_NUM > 0)
210 extern USB_HOST_CFG_PIPETBL_t usb_host_iso_ep_tbl1
[];
213 static usb_ohci_reg_t usb_reg
;
214 static usb_ohci_reg_t
*p_usb_reg
= &usb_reg
;
215 static usbisr_fnc_t
*p_usbisr_cb
= NULL
;
216 static osSemaphoreId semid_cb
= NULL
;
217 static uint32_t connect_change
= 0xFFFFFFFF;
218 static uint32_t init_end
= 0;
219 static genelal_ed_t ctl_ed
;
220 static genelal_ed_t blk_ed
;
221 static genelal_ed_t int_ed
[INT_TRANS_MAX_NUM
];
222 static split_trans_t split_ctl
;
224 #if (ISO_TRANS_MAX_NUM > 0)
225 static genelal_ed_t iso_ed
[ISO_TRANS_MAX_NUM
];
228 osSemaphoreDef(ohciwrapp_sem_01
);
229 osSemaphoreDef(ohciwrapp_sem_02
);
230 osSemaphoreDef(ohciwrapp_sem_03
);
231 osSemaphoreDef(ohciwrapp_sem_04
);
232 osSemaphoreDef(ohciwrapp_sem_05
);
233 osSemaphoreDef(ohciwrapp_sem_06
);
234 osSemaphoreDef(ohciwrapp_sem_07
);
235 #if (INT_TRANS_MAX_NUM >= 2)
236 osSemaphoreDef(ohciwrapp_sem_08
);
237 osSemaphoreDef(ohciwrapp_sem_09
);
239 #if (INT_TRANS_MAX_NUM >= 3)
240 osSemaphoreDef(ohciwrapp_sem_10
);
241 osSemaphoreDef(ohciwrapp_sem_11
);
243 #if (INT_TRANS_MAX_NUM >= 4)
244 osSemaphoreDef(ohciwrapp_sem_12
);
245 osSemaphoreDef(ohciwrapp_sem_13
);
247 #if (ISO_TRANS_MAX_NUM >= 1)
248 osSemaphoreDef(ohciwrapp_sem_14
);
249 osSemaphoreDef(ohciwrapp_sem_15
);
251 #if (ISO_TRANS_MAX_NUM >= 2)
252 osSemaphoreDef(ohciwrapp_sem_16
);
253 osSemaphoreDef(ohciwrapp_sem_17
);
256 osThreadDef(callback_task
, osPriorityHigh
, 512);
257 osThreadDef(control_ed_task
, osPriorityNormal
, 512);
258 osThreadDef(bulk_ed_task
, osPriorityNormal
, 512);
259 static void int_ed_task_1(void const * argument
) {
260 int_ed_task(argument
);
262 osThreadDef(int_ed_task_1
, osPriorityNormal
, 512);
263 #if (INT_TRANS_MAX_NUM >= 2)
264 static void int_ed_task_2(void const * argument
) {
265 int_ed_task(argument
);
267 osThreadDef(int_ed_task_2
, osPriorityNormal
, 512);
269 #if (INT_TRANS_MAX_NUM >= 3)
270 static void int_ed_task_3(void const * argument
) {
271 int_ed_task(argument
);
273 osThreadDef(int_ed_task_3
, osPriorityNormal
, 512);
275 #if (INT_TRANS_MAX_NUM >= 4)
276 static void int_ed_task_4(void const * argument
) {
277 int_ed_task(argument
);
279 osThreadDef(int_ed_task_4
, osPriorityNormal
, 512);
282 #if (ISO_TRANS_MAX_NUM >= 1)
283 static void iso_ed_task_1(void const * argument
) {
284 iso_ed_task(argument
);
286 osThreadDef(iso_ed_task_1
, osPriorityNormal
, 512);
288 #if (ISO_TRANS_MAX_NUM >= 2)
289 static void iso_ed_task_2(void const * argument
) {
290 iso_ed_task(argument
);
292 osThreadDef(iso_ed_task_2
, osPriorityNormal
, 512);
295 void ohciwrapp_init(usbisr_fnc_t
*p_usbisr_fnc
) {
296 static const osSemaphoreDef_t
* const sem_def_tbl
[TOTAL_SEM_NUM
] = {
297 osSemaphore(ohciwrapp_sem_01
), osSemaphore(ohciwrapp_sem_02
), osSemaphore(ohciwrapp_sem_03
)
298 , osSemaphore(ohciwrapp_sem_04
), osSemaphore(ohciwrapp_sem_05
), osSemaphore(ohciwrapp_sem_06
)
299 , osSemaphore(ohciwrapp_sem_07
)
300 #if (INT_TRANS_MAX_NUM >= 2)
301 , osSemaphore(ohciwrapp_sem_08
), osSemaphore(ohciwrapp_sem_09
)
303 #if (INT_TRANS_MAX_NUM >= 3)
304 , osSemaphore(ohciwrapp_sem_10
), osSemaphore(ohciwrapp_sem_11
)
306 #if (INT_TRANS_MAX_NUM >= 4)
307 , osSemaphore(ohciwrapp_sem_12
), osSemaphore(ohciwrapp_sem_13
)
309 #if (ISO_TRANS_MAX_NUM >= 1)
310 , osSemaphore(ohciwrapp_sem_14
), osSemaphore(ohciwrapp_sem_15
)
312 #if (ISO_TRANS_MAX_NUM >= 2)
313 , osSemaphore(ohciwrapp_sem_16
), osSemaphore(ohciwrapp_sem_17
)
316 static const osThreadDef_t
* const int_tsk_def_tbl
[INT_TRANS_MAX_NUM
] = {
317 osThread(int_ed_task_1
)
318 #if (INT_TRANS_MAX_NUM >= 2)
319 , osThread(int_ed_task_2
)
321 #if (INT_TRANS_MAX_NUM >= 3)
322 , osThread(int_ed_task_3
)
324 #if (INT_TRANS_MAX_NUM >= 4)
325 , osThread(int_ed_task_4
)
328 #if (ISO_TRANS_MAX_NUM > 0)
329 static const osThreadDef_t
* const iso_tsk_def_tbl
[ISO_TRANS_MAX_NUM
] = {
330 osThread(iso_ed_task_1
)
331 #if (ISO_TRANS_MAX_NUM >= 2)
332 , osThread(iso_ed_task_2
)
340 /* Disables interrupt for usb */
341 GIC_DisableIRQ(USBIXUSBIX
);
343 #if (USB_HOST_CH == 0)
345 GPIOP4
&= ~0x0002; /* Outputs low level */
346 GPIOPMC4
&= ~0x0002; /* Port mode */
347 GPIOPM4
&= ~0x0002; /* Output mode */
350 p_usbisr_cb
= p_usbisr_fnc
;
351 #if (USB_HOST_HISPEED == 0)
352 g_usbx_host_SupportUsbDeviceSpeed
= USB_HOST_FULL_SPEED
;
354 g_usbx_host_SupportUsbDeviceSpeed
= USB_HOST_HIGH_SPEED
;
356 p_usb_reg
->HcRevision
= 0x00000010;
357 p_usb_reg
->HcControl
= 0x00000000;
358 p_usb_reg
->HcCommandStatus
= 0x00000000;
359 p_usb_reg
->HcInterruptStatus
= 0x00000000;
360 p_usb_reg
->HcInterruptEnable
= 0x00000000;
361 p_usb_reg
->HcInterruptDisable
= 0x00000000;
362 p_usb_reg
->HcHCCA
= 0x00000000;
363 p_usb_reg
->HcPeriodCurrentED
= 0x00000000;
364 p_usb_reg
->HcControlHeadED
= 0x00000000;
365 p_usb_reg
->HcControlCurrentED
= 0x00000000;
366 p_usb_reg
->HcBulkHeadED
= 0x00000000;
367 p_usb_reg
->HcBulkCurrentED
= 0x00000000;
368 p_usb_reg
->HcDoneHead
= 0x00000000;
369 p_usb_reg
->HcFmInterval
= 0x00002EDF;
370 p_usb_reg
->HcFmRemaining
= 0x00002EDF;
371 p_usb_reg
->HcFmNumber
= 0x00000000;
372 p_usb_reg
->HcPeriodicStart
= 0x00000000;
373 p_usb_reg
->HcLSThreshold
= 0x00000628;
374 p_usb_reg
->HcRhDescriptorA
= 0xFF000901;
375 p_usb_reg
->HcRhDescriptorB
= 0x00020000;
376 p_usb_reg
->HcRhStatus
= 0x00000000;
377 p_usb_reg
->HcRhPortStatus1
= 0x00000000;
379 #if (USB_HOST_CH == 0)
380 GPIOP4
|= 0x0002; /* P4_1 Outputs high level */
382 GPIOP4
&= ~0x0002; /* P4_1 Outputs low level */
389 (void)memset(&ctl_ed
, 0, sizeof(ctl_ed
));
390 (void)memset(&blk_ed
, 0, sizeof(blk_ed
));
391 (void)memset(&int_ed
[0], 0, sizeof(int_ed
));
392 #if (ISO_TRANS_MAX_NUM > 0)
393 (void)memset(&iso_ed
[0], 0, sizeof(iso_ed
));
397 semid_cb
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
399 (void)osThreadCreate(osThread(callback_task
), 0);
401 /* control transfer */
402 ctl_ed
.semid_wait
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
404 ctl_ed
.semid_list
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
406 ctl_ed
.tskid
= osThreadCreate(osThread(control_ed_task
), 0);
409 blk_ed
.semid_wait
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
411 blk_ed
.semid_list
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
413 blk_ed
.tskid
= osThreadCreate(osThread(bulk_ed_task
), 0);
415 /* interrupt transfer */
416 for (cnt
= 0; cnt
< INT_TRANS_MAX_NUM
; cnt
++) {
417 int_ed
[cnt
].semid_wait
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
419 int_ed
[cnt
].semid_list
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
421 int_ed
[cnt
].tskid
= osThreadCreate(int_tsk_def_tbl
[cnt
], (void *)cnt
);
424 #if (ISO_TRANS_MAX_NUM > 0)
425 /* isochronous transfer */
426 for (cnt
= 0; cnt
< ISO_TRANS_MAX_NUM
; cnt
++) {
427 iso_ed
[cnt
].semid_wait
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
429 iso_ed
[cnt
].semid_list
= osSemaphoreCreate(sem_def_tbl
[index
], 0);
431 iso_ed
[cnt
].tskid
= osThreadCreate(iso_tsk_def_tbl
[cnt
], (void *)cnt
);
438 uint32_t ohciwrapp_reg_r(uint32_t reg_ofs
) {
443 return *(uint32_t *)((uint8_t *)p_usb_reg
+ reg_ofs
);
446 void ohciwrapp_reg_w(uint32_t reg_ofs
, uint32_t set_data
) {
456 case OHCI_REG_CONTROL
:
457 last_data
= p_usb_reg
->HcControl
;
458 p_usb_reg
->HcControl
= (set_data
& 0x000007FF);
459 if ((last_data
& OR_CONTROL_CLE
) != (set_data
& OR_CONTROL_CLE
)) {
461 if ((set_data
& OR_CONTROL_CLE
) != 0) {
462 (void)osSemaphoreRelease(ctl_ed
.semid_list
);
464 if (ctl_ed
.trans_wait
== 1) {
465 ctl_ed
.trans_wait
= 0;
466 (void)osSemaphoreRelease(ctl_ed
.semid_wait
);
468 (void)osSemaphoreWait(ctl_ed
.semid_list
, osWaitForever
);
471 if ((last_data
& OR_CONTROL_BLE
) != (set_data
& OR_CONTROL_BLE
)) {
473 if ((set_data
& OR_CONTROL_BLE
) != 0) {
474 (void)osSemaphoreRelease(blk_ed
.semid_list
);
476 if (blk_ed
.trans_wait
== 1) {
477 blk_ed
.trans_wait
= 0;
478 (void)osSemaphoreRelease(blk_ed
.semid_wait
);
480 (void)osSemaphoreWait(blk_ed
.semid_list
, osWaitForever
);
483 #if (ISO_TRANS_MAX_NUM > 0)
484 if ((last_data
& OR_CONTROL_IE
) != (set_data
& OR_CONTROL_IE
)) {
486 for (cnt
= 0; cnt
< ISO_TRANS_MAX_NUM
; cnt
++) {
487 if ((set_data
& OR_CONTROL_IE
) != 0) {
488 (void)osSemaphoreRelease(iso_ed
[cnt
].semid_list
);
490 if (iso_ed
[cnt
].trans_wait
== 1) {
491 iso_ed
[cnt
].trans_wait
= 0;
492 (void)osSemaphoreRelease(iso_ed
[cnt
].semid_wait
);
494 (void)osSemaphoreWait(iso_ed
[cnt
].semid_list
, osWaitForever
);
499 if ((last_data
& OR_CONTROL_PLE
) != (set_data
& OR_CONTROL_PLE
)) {
501 for (cnt
= 0; cnt
< INT_TRANS_MAX_NUM
; cnt
++) {
502 if ((set_data
& OR_CONTROL_PLE
) != 0) {
503 (void)osSemaphoreRelease(int_ed
[cnt
].semid_list
);
505 if (int_ed
[cnt
].trans_wait
== 1) {
506 int_ed
[cnt
].trans_wait
= 0;
507 (void)osSemaphoreRelease(int_ed
[cnt
].semid_wait
);
509 (void)osSemaphoreWait(int_ed
[cnt
].semid_list
, osWaitForever
);
514 case OHCI_REG_COMMANDSTATUS
:
515 if ((set_data
& OR_CMD_STATUS_HCR
) != 0) { /* HostController Reset */
516 p_usb_reg
->HcCommandStatus
|= OR_CMD_STATUS_HCR
;
517 if (usbx_api_host_init(16, g_usbx_host_SupportUsbDeviceSpeed
, USBHCLOCK_X1_48MHZ
) == USB_HOST_ATTACH
) {
518 ohciwrapp_loc_Connect(1);
520 p_usb_reg
->HcCommandStatus
&= ~OR_CMD_STATUS_HCR
;
522 if ((set_data
& OR_CMD_STATUS_CLF
) != 0) {
523 p_usb_reg
->HcCommandStatus
|= OR_CMD_STATUS_CLF
;
524 osSignalSet(ctl_ed
.tskid
, SIG_GEN_LIST_REQ
);
526 if ((set_data
& OR_CMD_STATUS_BLF
) != 0) {
527 p_usb_reg
->HcCommandStatus
|= OR_CMD_STATUS_BLF
;
528 osSignalSet(blk_ed
.tskid
, SIG_GEN_LIST_REQ
);
530 if ((set_data
& OR_CMD_STATUS_OCR
) != 0) {
531 p_usb_reg
->HcCommandStatus
|= OR_CMD_STATUS_OCR
;
533 p_usb_reg
->HcCommandStatus
&= ~OR_CMD_STATUS_OCR
;
536 case OHCI_REG_INTERRUPTSTATUS
:
537 if (((p_usb_reg
->HcInterruptStatus
& OR_INTR_STATUS_WDH
) != 0)
538 && ((set_data
& OR_INTR_STATUS_WDH
) != 0)) {
539 if (p_usb_reg
->HcDoneHead
!= 0x00000000) {
540 p_hcca
= (hcca_t
*)p_usb_reg
->HcHCCA
;
541 p_hcca
->DoneHead
= p_usb_reg
->HcDoneHead
;
542 p_usb_reg
->HcDoneHead
= 0x00000000;
543 p_usb_reg
->HcInterruptStatus
|= OR_INTR_STATUS_WDH
;
544 (void)osSemaphoreRelease(semid_cb
);
546 p_usb_reg
->HcInterruptStatus
&= ~OR_INTR_STATUS_WDH
;
549 if ((set_data
& OR_INTR_STATUS_RHSC
) != 0) {
550 p_usb_reg
->HcInterruptStatus
&= ~OR_INTR_STATUS_RHSC
;
553 case OHCI_REG_INTERRUPTENABLE
:
554 case OHCI_REG_INTERRUPTDISABLE
:
556 case OHCI_REG_CONTROLHEADED
:
557 case OHCI_REG_CONTROLCURRENTED
:
558 case OHCI_REG_BULKHEADED
:
559 case OHCI_REG_BULKCURRENTED
:
560 case OHCI_REG_FMINTERVAL
:
561 case OHCI_REG_FMREMAINING
:
562 case OHCI_REG_PERIODICSTART
:
563 case OHCI_REG_LSTHRESHOLD
:
564 case OHCI_REG_RHDESCRIPTORA
:
565 case OHCI_REG_RHDESCRIPTORB
:
566 case OHCI_REG_RHSTATUS
:
567 *(uint32_t *)((uint8_t *)p_usb_reg
+ reg_ofs
) = set_data
;
569 case OHCI_REG_RHPORTSTATUS1
:
570 p_usb_reg
->HcRhPortStatus1
&= ~(set_data
& 0xFFFF0000);
571 if ((set_data
& OR_RH_PORT_PRS
) != 0) { /* Set Port Reset */
572 p_usb_reg
->HcRhPortStatus1
|= OR_RH_PORT_PRS
;
573 usbx_host_UsbBusReset();
574 p_usb_reg
->HcRhPortStatus1
&= ~OR_RH_PORT_PRS
;
577 case OHCI_REG_REVISION
:
578 case OHCI_REG_PERIODCURRENTED
:
579 case OHCI_REG_DONEHEADED
:
580 case OHCI_REG_FMNUMBER
:
587 static void callback_task(void const * argument
) {
588 usbisr_fnc_t
*p_wk_cb
= p_usbisr_cb
;
590 if (p_wk_cb
== NULL
) {
595 osSemaphoreWait(semid_cb
, osWaitForever
);
596 if (connect_change
!= 0xFFFFFFFF) {
597 connect_change
= 0xFFFFFFFF;
604 static void control_ed_task(void const * argument
) {
606 osSignalWait(SIG_GEN_LIST_REQ
, osWaitForever
);
607 (void)osSemaphoreWait(ctl_ed
.semid_list
, osWaitForever
);
608 while ((p_usb_reg
->HcControl
& OR_CONTROL_CLE
) != 0) {
609 if ((p_usb_reg
->HcControlCurrentED
== 0)
610 && ((p_usb_reg
->HcCommandStatus
& OR_CMD_STATUS_CLF
) != 0)) {
611 p_usb_reg
->HcControlCurrentED
= p_usb_reg
->HcControlHeadED
;
612 p_usb_reg
->HcCommandStatus
&= ~OR_CMD_STATUS_CLF
;
614 if (p_usb_reg
->HcControlCurrentED
!= 0) {
615 ctl_ed
.p_curr_ed
= (hced_t
*)p_usb_reg
->HcControlCurrentED
;
616 if (chk_genelal_ed(&ctl_ed
) != 0) {
617 control_trans(&ctl_ed
);
618 p_usb_reg
->HcCommandStatus
|= OR_CMD_STATUS_CLF
;
620 p_usb_reg
->HcControlCurrentED
= (uint32_t)ctl_ed
.p_curr_ed
->nextED
;
625 if ((p_usb_reg
->HcCommandStatus
& OR_CMD_STATUS_CLF
) != 0) {
626 osSignalSet(ctl_ed
.tskid
, SIG_GEN_LIST_REQ
);
628 (void)osSemaphoreRelease(ctl_ed
.semid_list
);
632 static void bulk_ed_task(void const * argument
) {
634 osSignalWait(SIG_GEN_LIST_REQ
, osWaitForever
);
635 (void)osSemaphoreWait(blk_ed
.semid_list
, osWaitForever
);
636 while ((p_usb_reg
->HcControl
& OR_CONTROL_BLE
) != 0) {
637 if ((p_usb_reg
->HcBulkCurrentED
== 0)
638 && ((p_usb_reg
->HcCommandStatus
& OR_CMD_STATUS_BLF
) != 0)) {
639 p_usb_reg
->HcBulkCurrentED
= p_usb_reg
->HcBulkHeadED
;
640 p_usb_reg
->HcCommandStatus
&= ~OR_CMD_STATUS_BLF
;
642 if (p_usb_reg
->HcBulkCurrentED
!= 0) {
643 blk_ed
.p_curr_ed
= (hced_t
*)p_usb_reg
->HcBulkCurrentED
;
644 if (chk_genelal_ed(&blk_ed
) != 0) {
646 p_usb_reg
->HcCommandStatus
|= OR_CMD_STATUS_BLF
;
648 p_usb_reg
->HcBulkCurrentED
= (uint32_t)blk_ed
.p_curr_ed
->nextED
;
653 if ((p_usb_reg
->HcCommandStatus
& OR_CMD_STATUS_BLF
) != 0) {
654 osSignalSet(blk_ed
.tskid
, SIG_GEN_LIST_REQ
);
656 (void)osSemaphoreRelease(blk_ed
.semid_list
);
660 static void int_ed_task(void const * argument
) {
661 genelal_ed_t
*p_int_ed
= &int_ed
[(uint32_t)argument
];
663 uint32_t wait_cnt
= 0;
668 (void)osSemaphoreWait(p_int_ed
->semid_list
, osWaitForever
);
669 if (p_int_ed
->p_curr_ed
== NULL
) {
670 for (cnt
= 0; (cnt
< 32) && ((p_usb_reg
->HcControl
& OR_CONTROL_PLE
) != 0)
671 && (p_int_ed
->p_curr_ed
== NULL
); cnt
++) {
672 p_hcca
= (hcca_t
*)p_usb_reg
->HcHCCA
;
673 p_ed
= (hced_t
*)p_hcca
->IntTable
[cnt
];
674 while ((p_ed
!= NULL
) && ((p_usb_reg
->HcControl
& OR_CONTROL_PLE
) != 0)
675 && (p_int_ed
->p_curr_ed
== NULL
)) {
676 if (int_trans_doing(p_ed
, (uint32_t)argument
) == 0) {
677 p_int_ed
->p_curr_ed
= p_ed
;
678 if (chk_genelal_ed(p_int_ed
) != 0) {
679 int_trans_setting(p_int_ed
, (uint32_t)argument
);
681 p_int_ed
->p_curr_ed
= NULL
;
688 if (p_int_ed
->p_curr_ed
!= NULL
) {
689 while ((p_usb_reg
->HcControl
& OR_CONTROL_PLE
) != 0) {
690 if (chk_genelal_ed(p_int_ed
) != 0) {
692 (void)osSemaphoreWait(p_int_ed
->semid_wait
, osWaitForever
);
693 usbx_host_stop_transfer(p_int_ed
->pipe_no
);
694 wait_cnt
= p_int_ed
->cycle_time
;
699 p_int_ed
->p_curr_ed
= NULL
;
705 (void)osSemaphoreRelease(p_int_ed
->semid_list
);
706 if (p_int_ed
->p_curr_ed
== NULL
) {
714 static int32_t int_trans_doing(hced_t
*p_ed
, uint32_t index
) {
718 for (cnt
= 0; cnt
< INT_TRANS_MAX_NUM
; cnt
++) {
719 if ((index
!= cnt
) && (int_ed
[cnt
].p_curr_ed
== p_ed
)) {
727 static int32_t chk_genelal_ed(genelal_ed_t
*p_g_ed
){
729 hced_t
*p_ed
= p_g_ed
->p_curr_ed
;
731 if (((p_ed
->control
& ED_SKIP
) != 0)
732 || ((p_ed
->control
& ED_FORMAT
) != 0)
733 || ((p_ed
->headTD
& ED_HALTED
) != 0)
734 || ((p_ed
->tailTD
& 0xFFFFFFF0) == (p_ed
->headTD
& 0xFFFFFFF0))) {
736 } else if ((p_ed
->control
& 0x0000007F) > 10) {
737 p_ed
->headTD
|= ED_HALTED
;
739 p_g_ed
->p_curr_td
= (void *)(p_ed
->headTD
& 0xFFFFFFF0);
740 if (p_g_ed
->p_curr_td
== NULL
) {
741 p_ed
->headTD
|= ED_HALTED
;
743 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
745 p_g_ed
->p_start_buf
= p_td
->currBufPtr
;
753 static void chk_genelal_td_done(genelal_ed_t
*p_g_ed
) {
755 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
756 uint32_t ConditionCode
= RZA_IO_RegRead_32(&p_td
->control
, TD_CTL_SHFT_CC
, TD_CTL_MSK_CC
);
758 if ((ConditionCode
!= TD_CC_NOT_ACCESSED_1
) && (ConditionCode
!= TD_CC_NOT_ACCESSED_2
)) {
759 p_g_ed
->p_curr_ed
->headTD
= ((uint32_t)p_td
->nextTD
& 0xFFFFFFF0)
760 | (p_g_ed
->p_curr_ed
->headTD
& 0x0000000F);
761 p_td
->nextTD
= (hctd_t
*)p_usb_reg
->HcDoneHead
;
762 p_usb_reg
->HcDoneHead
= (uint32_t)p_g_ed
->p_curr_td
;
763 if ((p_usb_reg
->HcInterruptStatus
& OR_INTR_STATUS_WDH
) == 0) {
764 p_hcca
= (hcca_t
*)p_usb_reg
->HcHCCA
;
765 p_hcca
->DoneHead
= p_usb_reg
->HcDoneHead
;
766 p_usb_reg
->HcDoneHead
= 0x00000000;
767 p_usb_reg
->HcInterruptStatus
|= OR_INTR_STATUS_WDH
;
768 (void)osSemaphoreRelease(semid_cb
);
773 static void chk_split_trans_setting(genelal_ed_t
*p_g_ed
) {
776 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
778 /* Hi-Speed mode only */
779 if (g_usbx_host_UsbDeviceSpeed
!= USB_HOST_HIGH_SPEED
) {
783 if (RZA_IO_RegRead_32(&p_td
->control
, TD_CTL_SHFT_CC
, TD_CTL_MSK_CC
) != TD_CC_NOERROR
) {
787 get_td_info(p_g_ed
, &td_info
);
788 p_buf
= p_g_ed
->p_start_buf
;
790 if (td_info
.direction
== 0) {
791 uint8_t bRequest
= p_buf
[1];
792 uint16_t wValue
= (p_buf
[3] << 8) + p_buf
[2];
793 uint16_t wIndx
= (p_buf
[5] << 8) + p_buf
[4];
796 if ((td_info
.devadr
== 0) && (bRequest
== SET_ADDRESS
)) {
798 usbx_host_get_devadd(USB_HOST_DEVICE_0
, &devadd
);
799 usbx_host_set_devadd(wValue
, &devadd
);
800 if (split_ctl
.root_devadr
== 0) {
801 split_ctl
.root_devadr
= wValue
; /* New Address */
803 } else if ((td_info
.devadr
== split_ctl
.root_devadr
) && (bRequest
== SET_FEATURE
)
804 && (wValue
== 0x0004) && (split_ctl
.root_devadr
!= 0)) {
805 /* SET_FEATURE PORT_RESET */
806 split_ctl
.reset_port
= (wIndx
& 0x00FF);
807 } else if ((td_info
.devadr
== split_ctl
.root_devadr
) && (bRequest
== GET_STATUS
)) {
809 split_ctl
.get_port
= wIndx
;
810 split_ctl
.seq_cnt
= 1;
814 } else if (td_info
.direction
== 2) {
815 if ((td_info
.devadr
== split_ctl
.root_devadr
) && (split_ctl
.seq_cnt
== 1)) {
816 if (split_ctl
.get_port
< PORT_NUM
) {
817 split_ctl
.port_sts_bits
[split_ctl
.get_port
] = (p_buf
[1] << 8) + p_buf
[0];
819 split_ctl
.seq_cnt
= 0;
826 static void set_split_trans_setting(void) {
830 if ((split_ctl
.root_devadr
!= 0) && (split_ctl
.reset_port
!= 0) && (split_ctl
.reset_port
< PORT_NUM
)) {
831 usbx_host_get_devadd(USB_HOST_DEVICE_0
, &devadd
);
832 RZA_IO_RegWrite_16(&devadd
, split_ctl
.root_devadr
, USB_DEVADDn_UPPHUB_SHIFT
, USB_DEVADDn_UPPHUB
);
833 RZA_IO_RegWrite_16(&devadd
, split_ctl
.reset_port
, USB_DEVADDn_HUBPORT_SHIFT
, USB_DEVADDn_HUBPORT
);
834 if ((split_ctl
.port_sts_bits
[split_ctl
.reset_port
] & PORT_HIGH_SPEED
) != 0) {
835 port_speed
= USB_HOST_HIGH_SPEED
;
836 } else if ((split_ctl
.port_sts_bits
[split_ctl
.reset_port
] & PORT_LOW_SPEED
) != 0) {
837 port_speed
= USB_HOST_LOW_SPEED
;
839 port_speed
= USB_HOST_FULL_SPEED
;
841 RZA_IO_RegWrite_16(&devadd
, port_speed
, USB_DEVADDn_USBSPD_SHIFT
, USB_DEVADDn_USBSPD
);
842 usbx_host_set_devadd(USB_HOST_DEVICE_0
, &devadd
);
843 split_ctl
.reset_port
= 0;
847 static void control_trans(genelal_ed_t
*p_g_ed
) {
848 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
852 get_td_info(p_g_ed
, &td_info
);
854 if (g_usbx_host_UsbDeviceSpeed
== USB_HOST_HIGH_SPEED
) {
855 if (td_info
.devadr
== 0) {
856 set_split_trans_setting();
859 /* When a non-Hi-Speed, the communication speed is determined from the TD. */
860 usbx_host_get_devadd(USB_HOST_DEVICE_0
, &devadd
);
861 if (td_info
.speed
== 1) {
862 RZA_IO_RegWrite_16(&devadd
, USB_HOST_LOW_SPEED
, USB_DEVADDn_USBSPD_SHIFT
, USB_DEVADDn_USBSPD
);
864 RZA_IO_RegWrite_16(&devadd
, USB_HOST_FULL_SPEED
, USB_DEVADDn_USBSPD_SHIFT
, USB_DEVADDn_USBSPD
);
866 usbx_host_set_devadd(td_info
.devadr
, &devadd
);
869 USB20X
.DCPMAXP
= (td_info
.devadr
<< 12) + td_info
.msp
;
870 if (td_info
.direction
== 0) {
871 g_usbx_host_CmdStage
= (USB_HOST_STAGE_SETUP
| USB_HOST_CMD_IDLE
);
872 } else if (td_info
.count
!= 0) {
873 g_usbx_host_CmdStage
= (USB_HOST_STAGE_DATA
| USB_HOST_CMD_IDLE
);
875 g_usbx_host_CmdStage
= (USB_HOST_STAGE_STATUS
| USB_HOST_CMD_IDLE
);
877 g_usbx_host_pipe_status
[USB_HOST_PIPE0
] = USB_HOST_PIPE_WAIT
;
878 p_g_ed
->pipe_no
= USB_HOST_PIPE0
;
880 p_g_ed
->trans_wait
= 1;
882 if (td_info
.direction
== 0) {
883 uint16_t Req
= (p_td
->currBufPtr
[1] << 8) + p_td
->currBufPtr
[0];
884 uint16_t Val
= (p_td
->currBufPtr
[3] << 8) + p_td
->currBufPtr
[2];
885 uint16_t Indx
= (p_td
->currBufPtr
[5] << 8) + p_td
->currBufPtr
[4];
886 uint16_t Len
= (p_td
->currBufPtr
[7] << 8) + p_td
->currBufPtr
[6];
888 g_usbx_host_data_pointer
[USB_HOST_PIPE0
] = p_td
->bufEnd
;
889 usbx_host_SetupStage(Req
, Val
, Indx
, Len
);
890 } else if (td_info
.direction
== 1) {
891 usbx_host_CtrlWriteStart(td_info
.count
, p_td
->currBufPtr
);
893 usbx_host_CtrlReadStart(td_info
.count
, p_td
->currBufPtr
);
896 (void)osSemaphoreWait(p_g_ed
->semid_wait
, CTL_TRANS_TIMEOUT
);
897 if (p_g_ed
->trans_wait
== 1) {
898 p_g_ed
->trans_wait
= 0;
899 RZA_IO_RegWrite_32(&p_td
->control
, TD_CC_DEVICENOTRESPONDING
, TD_CTL_SHFT_CC
, TD_CTL_MSK_CC
);
902 g_usbx_host_CmdStage
&= (~USB_HOST_CMD_FIELD
);
903 g_usbx_host_CmdStage
|= USB_HOST_CMD_IDLE
;
904 g_usbx_host_pipe_status
[USB_HOST_PIPE0
] = USB_HOST_PIPE_IDLE
;
907 static void bulk_trans(genelal_ed_t
*p_g_ed
) {
908 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
909 hced_t
*p_ed
= p_g_ed
->p_curr_ed
;
911 USB_HOST_CFG_PIPETBL_t
*user_table
= &usb_host_blk_ep_tbl1
[0];
914 get_td_info(p_g_ed
, &td_info
);
917 wk_table
[1] = USB_HOST_ENDPOINT_DESC
;
918 wk_table
[2] = td_info
.endpoint_no
;
919 if (td_info
.direction
== 2) {
920 wk_table
[2] |= USB_HOST_EP_IN
;
922 wk_table
[3] = USB_HOST_EP_BULK
;
923 wk_table
[4] = (uint8_t)td_info
.msp
;
924 wk_table
[5] = (uint8_t)(td_info
.msp
>> 8);
925 p_g_ed
->pipe_no
= user_table
->pipe_number
;
926 usbx_api_host_SetEndpointTable(td_info
.devadr
, user_table
, wk_table
);
928 set_togle(p_g_ed
->pipe_no
, p_td
, p_ed
);
930 p_g_ed
->trans_wait
= 1;
931 if (td_info
.direction
== 1) {
932 usbx_host_start_send_transfer(p_g_ed
->pipe_no
, td_info
.count
, p_td
->currBufPtr
);
934 usbx_host_start_receive_transfer(p_g_ed
->pipe_no
, td_info
.count
, p_td
->currBufPtr
);
937 (void)osSemaphoreWait(p_g_ed
->semid_wait
, BLK_TRANS_TIMEOUT
);
938 usbx_host_stop_transfer(p_g_ed
->pipe_no
);
941 static void int_trans_setting(genelal_ed_t
*p_g_ed
, uint32_t index
) {
942 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
943 hced_t
*p_ed
= p_g_ed
->p_curr_ed
;
945 USB_HOST_CFG_PIPETBL_t
*user_table
= &usb_host_int_ep_tbl1
[index
];
950 get_td_info(p_g_ed
, &td_info
);
953 wk_table
[1] = USB_HOST_ENDPOINT_DESC
;
954 wk_table
[2] = td_info
.endpoint_no
;
955 if (td_info
.direction
== 2) {
956 wk_table
[2] |= USB_HOST_EP_IN
;
958 wk_table
[3] = USB_HOST_EP_INT
;
959 wk_table
[4] = (uint8_t)td_info
.msp
;
960 wk_table
[5] = (uint8_t)(td_info
.msp
>> 8);
961 cycle_time
= chk_cycle(p_ed
);
962 p_g_ed
->cycle_time
= cycle_time
;
963 user_table
->pipe_cycle
= 0;
964 while (cycle_time
> 1) {
966 user_table
->pipe_cycle
++;
968 if (g_usbx_host_UsbDeviceSpeed
== USB_HOST_HIGH_SPEED
) {
969 usbx_host_get_devadd(td_info
.devadr
, &devadd
);
970 if (RZA_IO_RegRead_16(&devadd
, USB_DEVADDn_USBSPD_SHIFT
, USB_DEVADDn_USBSPD
) == USB_HOST_HIGH_SPEED
) {
971 user_table
->pipe_cycle
+= 3;
972 if (user_table
->pipe_cycle
> 7) {
973 user_table
->pipe_cycle
= 7;
978 p_g_ed
->pipe_no
= user_table
->pipe_number
;
979 usbx_api_host_SetEndpointTable(td_info
.devadr
, user_table
, wk_table
);
981 set_togle(p_g_ed
->pipe_no
, p_td
, p_ed
);
984 static uint32_t chk_cycle(hced_t
*p_ed
) {
986 uint32_t hit_cnt
= 0;
987 uint32_t cycle_time
= 1;
991 p_hcca
= (hcca_t
*)p_usb_reg
->HcHCCA
;
993 for (cnt
= 0; cnt
< 32; cnt
++) {
994 p_wk_ed
= (hced_t
*)p_hcca
->IntTable
[cnt
];
995 while (p_wk_ed
!= NULL
) {
996 if (p_wk_ed
== p_ed
) {
1000 p_wk_ed
= p_wk_ed
->nextED
;
1005 } else if (hit_cnt
< 4) {
1007 } else if (hit_cnt
< 8) {
1009 } else if (hit_cnt
< 16) {
1011 } else if (hit_cnt
< 32) {
1020 static void int_trans(genelal_ed_t
*p_g_ed
) {
1021 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
1024 get_td_info(p_g_ed
, &td_info
);
1025 p_g_ed
->trans_wait
= 1;
1026 if (td_info
.direction
== 1) {
1027 usbx_host_start_send_transfer(p_g_ed
->pipe_no
, td_info
.count
, p_td
->currBufPtr
);
1029 usbx_host_start_receive_transfer(p_g_ed
->pipe_no
, td_info
.count
, p_td
->currBufPtr
);
1033 static void get_td_info(genelal_ed_t
*p_g_ed
, tdinfo_t
*p_td_info
) {
1034 hced_t
*p_ed
= p_g_ed
->p_curr_ed
;
1036 p_td_info
->endpoint_no
= (uint8_t)((p_ed
->control
>> 7) & 0x0000000F);
1037 p_td_info
->msp
= (p_ed
->control
>> 16) & 0x000007FF;
1038 p_td_info
->devadr
= p_ed
->control
& 0x0000000F;
1039 p_td_info
->speed
= (p_ed
->control
>> 13) & 0x00000001;
1040 p_td_info
->direction
= (p_ed
->control
>> 11) & 0x00000003;
1042 if ((p_ed
->control
& ED_FORMAT
) == 0) {
1043 hctd_t
*p_td
= (hctd_t
*)p_g_ed
->p_curr_td
;
1045 if ((p_td_info
->direction
== 0) || (p_td_info
->direction
== 3)) {
1046 if ((p_td
->control
& TD_CTL_MSK_DP
) == TD_SETUP
) {
1047 p_td_info
->direction
= 0;
1048 } else if ((p_td
->control
& TD_CTL_MSK_DP
) == TD_OUT
) {
1049 p_td_info
->direction
= 1;
1051 p_td_info
->direction
= 2;
1054 if (p_td
->currBufPtr
!= NULL
) {
1055 p_td_info
->count
= (uint32_t)p_td
->bufEnd
- (uint32_t)p_td
->currBufPtr
+ 1;
1057 p_td_info
->count
= 0;
1060 #if (ISO_TRANS_MAX_NUM > 0)
1061 hcisotd_t
*p_isotd
= (hcisotd_t
*)p_g_ed
->p_curr_td
;
1063 if ((p_td_info
->direction
== 0) || (p_td_info
->direction
== 3)) {
1064 if ((p_isotd
->control
& TD_CTL_MSK_DP
) == TD_SETUP
) {
1065 p_td_info
->direction
= 0;
1066 } else if ((p_isotd
->control
& TD_CTL_MSK_DP
) == TD_OUT
) {
1067 p_td_info
->direction
= 1;
1069 p_td_info
->direction
= 2;
1076 static void set_togle(uint32_t pipe
, hctd_t
*p_td
, hced_t
*p_ed
) {
1077 if ((p_td
->control
& TD_CTL_MSK_T
) == TD_TOGGLE_0
) {
1078 usbx_host_set_sqclr(pipe
);
1079 } else if ((p_td
->control
& TD_CTL_MSK_T
) == TD_TOGGLE_1
) {
1080 usbx_host_set_sqset(pipe
);
1081 } else if ((p_ed
->headTD
& ED_TOGLE_CARRY
) == 0) {
1082 usbx_host_set_sqclr(pipe
);
1084 usbx_host_set_sqset(pipe
);
1088 #if (ISO_TRANS_MAX_NUM > 0)
1089 static void iso_ed_task(void const * argument
) {
1090 genelal_ed_t
*p_iso_ed
= &iso_ed
[(uint32_t)argument
];
1091 uint32_t wait_cnt
= 0;
1092 uint32_t wait_time
= 0;
1097 (void)osSemaphoreWait(p_iso_ed
->semid_list
, osWaitForever
);
1098 if (p_iso_ed
->p_curr_ed
== NULL
) {
1099 p_hcca
= (hcca_t
*)p_usb_reg
->HcHCCA
;
1100 p_ed
= (hced_t
*)p_hcca
->IntTable
[0];
1101 while ((p_ed
!= NULL
) && ((p_usb_reg
->HcControl
& OR_CONTROL_IE
) != 0)
1102 && (p_iso_ed
->p_curr_ed
== NULL
)) {
1103 if (iso_trans_doing(p_ed
, (uint32_t)argument
) == 0) {
1104 p_iso_ed
->p_curr_ed
= p_ed
;
1105 if (chk_iso_ed(p_iso_ed
) != 0) {
1106 iso_trans_setting(p_iso_ed
, (uint32_t)argument
);
1108 p_iso_ed
->p_curr_ed
= NULL
;
1111 p_ed
= p_ed
->nextED
;
1113 p_iso_ed
->psw_idx
= 0;
1115 if (p_iso_ed
->p_curr_ed
!= NULL
) {
1116 while ((p_usb_reg
->HcControl
& OR_CONTROL_IE
) != 0) {
1117 if (chk_iso_ed(p_iso_ed
) != 0) {
1118 wait_time
= iso_chk_starting_frame(p_iso_ed
);
1119 if (wait_time
!= 0) {
1121 p_usb_reg
->HcFmNumber
+= wait_time
;
1122 p_usb_reg
->HcFmNumber
&= 0x0000FFFF;
1124 p_iso_ed
->psw_idx
= 0;
1125 iso_trans(p_iso_ed
);
1126 (void)osSemaphoreWait(p_iso_ed
->semid_wait
, osWaitForever
);
1127 usbx_host_stop_transfer(p_iso_ed
->pipe_no
);
1133 p_iso_ed
->p_curr_ed
= NULL
;
1139 (void)osSemaphoreRelease(p_iso_ed
->semid_list
);
1140 if (p_iso_ed
->p_curr_ed
== NULL
) {
1148 static int32_t iso_trans_doing(hced_t
*p_ed
, uint32_t index
) {
1152 for (cnt
= 0; cnt
< ISO_TRANS_MAX_NUM
; cnt
++) {
1153 if ((index
!= cnt
) && (iso_ed
[cnt
].p_curr_ed
== p_ed
)) {
1161 static void chk_iso_td_done(genelal_ed_t
*p_g_ed
) {
1163 hcisotd_t
*p_isotd
= (hcisotd_t
*)p_g_ed
->p_curr_td
;
1164 uint32_t ConditionCode
= RZA_IO_RegRead_32(&p_isotd
->control
, TD_CTL_SHFT_CC
, TD_CTL_MSK_CC
);
1166 if ((ConditionCode
!= TD_CC_NOT_ACCESSED_1
) && (ConditionCode
!= TD_CC_NOT_ACCESSED_2
)) {
1167 p_g_ed
->p_curr_ed
->headTD
= ((uint32_t)p_isotd
->nextTD
& 0xFFFFFFF0)
1168 | (p_g_ed
->p_curr_ed
->headTD
& 0x0000000F);
1169 p_isotd
->nextTD
= (hcisotd_t
*)p_usb_reg
->HcDoneHead
;
1170 p_usb_reg
->HcDoneHead
= (uint32_t)p_g_ed
->p_curr_td
;
1171 if ((p_usb_reg
->HcInterruptStatus
& OR_INTR_STATUS_WDH
) == 0) {
1172 p_hcca
= (hcca_t
*)p_usb_reg
->HcHCCA
;
1173 p_hcca
->DoneHead
= p_usb_reg
->HcDoneHead
;
1174 p_usb_reg
->HcDoneHead
= 0x00000000;
1175 p_usb_reg
->HcInterruptStatus
|= OR_INTR_STATUS_WDH
;
1176 (void)osSemaphoreRelease(semid_cb
);
1181 static int32_t chk_iso_ed(genelal_ed_t
*p_g_ed
){
1183 hced_t
*p_ed
= p_g_ed
->p_curr_ed
;
1185 if (((p_ed
->control
& ED_SKIP
) != 0)
1186 || ((p_ed
->control
& ED_FORMAT
) == 0)
1187 || ((p_ed
->headTD
& ED_HALTED
) != 0)
1188 || ((p_ed
->tailTD
& 0xFFFFFFF0) == (p_ed
->headTD
& 0xFFFFFFF0))) {
1190 } else if ((p_ed
->control
& 0x0000007F) > 10) {
1191 p_ed
->headTD
|= ED_HALTED
;
1193 p_g_ed
->p_curr_td
= (void *)(p_ed
->headTD
& 0xFFFFFFF0);
1194 if (p_g_ed
->p_curr_td
== NULL
) {
1195 p_ed
->headTD
|= ED_HALTED
;
1197 hcisotd_t
*p_isotd
= (hcisotd_t
*)p_g_ed
->p_curr_td
;
1199 p_g_ed
->p_start_buf
= p_isotd
->bufferPage0
;
1207 static void iso_trans_setting(genelal_ed_t
*p_g_ed
, uint32_t index
) {
1209 USB_HOST_CFG_PIPETBL_t
*user_table
= &usb_host_iso_ep_tbl1
[index
];
1210 uint8_t wk_table
[6];
1213 get_td_info(p_g_ed
, &td_info
);
1216 wk_table
[1] = USB_HOST_ENDPOINT_DESC
;
1217 wk_table
[2] = td_info
.endpoint_no
;
1218 if (td_info
.direction
== 2) {
1219 wk_table
[2] |= USB_HOST_EP_IN
;
1221 wk_table
[3] = USB_HOST_EP_ISO
;
1222 wk_table
[4] = (uint8_t)td_info
.msp
;
1223 wk_table
[5] = (uint8_t)(td_info
.msp
>> 8);
1224 p_g_ed
->cycle_time
= 1;
1225 user_table
->pipe_cycle
= 0;
1226 if (g_usbx_host_UsbDeviceSpeed
== USB_HOST_HIGH_SPEED
) {
1227 usbx_host_get_devadd(td_info
.devadr
, &devadd
);
1228 if (RZA_IO_RegRead_16(&devadd
, USB_DEVADDn_USBSPD_SHIFT
, USB_DEVADDn_USBSPD
) == USB_HOST_HIGH_SPEED
) {
1229 user_table
->pipe_cycle
+= 3;
1233 p_g_ed
->pipe_no
= user_table
->pipe_number
;
1234 usbx_api_host_SetEndpointTable(td_info
.devadr
, user_table
, wk_table
);
1237 static uint32_t iso_chk_starting_frame(genelal_ed_t
*p_g_ed
) {
1238 hcisotd_t
*p_isotd
= (hcisotd_t
*)p_g_ed
->p_curr_td
;
1239 uint32_t starting_frame
= p_isotd
->control
& 0x0000FFFF;
1240 uint32_t wait_time
= 0;
1242 if ((p_g_ed
->psw_idx
== 0) && (starting_frame
> p_usb_reg
->HcFmNumber
)) {
1243 wait_time
= starting_frame
- p_usb_reg
->HcFmNumber
;
1249 static void iso_trans(genelal_ed_t
*p_g_ed
) {
1250 hcisotd_t
*p_isotd
= (hcisotd_t
*)p_g_ed
->p_curr_td
;
1255 if (((uint32_t)p_isotd
->offsetPSW
[p_g_ed
->psw_idx
] & 0x00001000) == 0) {
1256 buff_addr
= (uint32_t)p_isotd
->bufferPage0
& 0xFFFFF000;
1258 buff_addr
= (uint32_t)p_isotd
->bufEnd
& 0xFFFFF000;
1260 buff_addr
|= (uint32_t)p_isotd
->offsetPSW
[p_g_ed
->psw_idx
] & 0x00000FFF;
1262 if (p_g_ed
->psw_idx
< RZA_IO_RegRead_32(&p_isotd
->control
, TD_CTL_SHFT_FC
, TD_CTL_MSK_FC
)) {
1263 data_size
= p_isotd
->offsetPSW
[p_g_ed
->psw_idx
+ 1] - p_isotd
->offsetPSW
[p_g_ed
->psw_idx
];
1265 data_size
= (uint32_t)p_isotd
->bufEnd
- buff_addr
+ 1;
1267 p_isotd
->offsetPSW
[p_g_ed
->psw_idx
] = (uint16_t)data_size
;
1269 get_td_info(p_g_ed
, &td_info
);
1270 p_g_ed
->trans_wait
= 1;
1271 if (td_info
.direction
== 1) {
1272 usbx_host_start_send_transfer(p_g_ed
->pipe_no
, data_size
, (uint8_t *)buff_addr
);
1274 usbx_host_start_receive_transfer(p_g_ed
->pipe_no
, data_size
, (uint8_t *)buff_addr
);
1279 static void connect_check(void) {
1282 uint16_t devadd
= 0;
1283 uint32_t wk_HcRhPortStatus1
= p_usb_reg
->HcRhPortStatus1
;
1285 if (usbx_host_CheckAttach() == USB_HOST_ATTACH
) {
1289 if ((((wk_HcRhPortStatus1
& OR_RH_PORT_CCS
) == 0) && (type
== 0))
1290 || (((wk_HcRhPortStatus1
& OR_RH_PORT_CCS
) != 0) && (type
!= 0))) {
1295 usbx_host_UsbDetach();
1296 wk_HcRhPortStatus1
&= ~OR_RH_PORT_CCS
;
1298 usbx_host_UsbAttach();
1299 stat
= usbx_host_UsbBusReset();
1300 RZA_IO_RegWrite_16(&devadd
, 0, USB_DEVADDn_UPPHUB_SHIFT
, USB_DEVADDn_UPPHUB
);
1301 RZA_IO_RegWrite_16(&devadd
, 0, USB_DEVADDn_HUBPORT_SHIFT
, USB_DEVADDn_HUBPORT
);
1302 if (stat
== USB_HOST_HSMODE
) {
1303 wk_HcRhPortStatus1
&= ~OR_RH_PORT_LSDA
;
1304 RZA_IO_RegWrite_16(&USB20X
.SOFCFG
, 0, USB_SOFCFG_TRNENSEL_SHIFT
, USB_SOFCFG_TRNENSEL
);
1305 g_usbx_host_UsbDeviceSpeed
= USB_HOST_HIGH_SPEED
;
1306 } else if (stat
== USB_HOST_FSMODE
) {
1307 wk_HcRhPortStatus1
&= ~OR_RH_PORT_LSDA
;
1308 RZA_IO_RegWrite_16(&USB20X
.SOFCFG
, 0, USB_SOFCFG_TRNENSEL_SHIFT
, USB_SOFCFG_TRNENSEL
);
1309 g_usbx_host_UsbDeviceSpeed
= USB_HOST_FULL_SPEED
;
1311 wk_HcRhPortStatus1
|= OR_RH_PORT_LSDA
;
1312 RZA_IO_RegWrite_16(&USB20X
.SOFCFG
, 1, USB_SOFCFG_TRNENSEL_SHIFT
, USB_SOFCFG_TRNENSEL
);
1313 g_usbx_host_UsbDeviceSpeed
= USB_HOST_LOW_SPEED
;
1315 RZA_IO_RegWrite_16(&devadd
, g_usbx_host_UsbDeviceSpeed
, USB_DEVADDn_USBSPD_SHIFT
, USB_DEVADDn_USBSPD
);
1316 usbx_host_init_pipe_status();
1317 usbx_host_set_devadd(USB_HOST_DEVICE_0
, &devadd
);
1318 wk_HcRhPortStatus1
|= OR_RH_PORT_CCS
;
1320 wk_HcRhPortStatus1
|= OR_RH_PORT_CSC
;
1321 p_usb_reg
->HcRhPortStatus1
= wk_HcRhPortStatus1
;
1322 p_usb_reg
->HcInterruptStatus
|= OR_INTR_STATUS_RHSC
;
1323 (void)memset(&split_ctl
, 0, sizeof(split_ctl
));
1326 void ohciwrapp_loc_Connect(uint32_t type
) {
1329 connect_change
= type
;
1331 if (ctl_ed
.trans_wait
== 1) {
1332 ohciwrapp_loc_TransEnd(ctl_ed
.pipe_no
, TD_CC_DEVICENOTRESPONDING
);
1334 if (blk_ed
.trans_wait
== 1) {
1335 ohciwrapp_loc_TransEnd(blk_ed
.pipe_no
, TD_CC_DEVICENOTRESPONDING
);
1337 for (cnt
= 0; cnt
< INT_TRANS_MAX_NUM
; cnt
++) {
1338 if (int_ed
[cnt
].trans_wait
== 1) {
1339 ohciwrapp_loc_TransEnd(int_ed
[cnt
].pipe_no
, TD_CC_DEVICENOTRESPONDING
);
1342 #if (ISO_TRANS_MAX_NUM > 0)
1343 for (cnt
= 0; cnt
< ISO_TRANS_MAX_NUM
; cnt
++) {
1344 if (iso_ed
[cnt
].trans_wait
== 1) {
1345 hced_t
*p_ed
= iso_ed
[cnt
].p_curr_ed
;
1347 p_ed
->headTD
|= ED_HALTED
;
1348 ohciwrapp_loc_TransEnd(iso_ed
[cnt
].pipe_no
, TD_CC_DEVICENOTRESPONDING
);
1353 (void)osSemaphoreRelease(semid_cb
);
1356 void ohciwrapp_loc_TransEnd(uint32_t pipe
, uint32_t ConditionCode
) {
1357 uint32_t periodic
= 0;
1361 genelal_ed_t
*p_wait_ed
= NULL
;
1363 if (ctl_ed
.pipe_no
== pipe
) {
1364 p_wait_ed
= &ctl_ed
;
1365 } else if (blk_ed
.pipe_no
== pipe
) {
1366 p_wait_ed
= &blk_ed
;
1368 #if (ISO_TRANS_MAX_NUM > 0)
1369 if (p_wait_ed
== NULL
) {
1370 for (cnt
= 0; cnt
< ISO_TRANS_MAX_NUM
; cnt
++) {
1371 if (iso_ed
[cnt
].pipe_no
== pipe
) {
1372 p_wait_ed
= &iso_ed
[cnt
];
1378 if (p_wait_ed
== NULL
) {
1379 for (cnt
= 0; cnt
< INT_TRANS_MAX_NUM
; cnt
++) {
1380 if (int_ed
[cnt
].pipe_no
== pipe
) {
1381 p_wait_ed
= &int_ed
[cnt
];
1389 if (p_wait_ed
== NULL
) {
1392 p_ed
= p_wait_ed
->p_curr_ed
;
1397 if ((p_ed
->control
& ED_FORMAT
) == 0) {
1398 hctd_t
*p_td
= (hctd_t
*)p_wait_ed
->p_curr_td
;
1401 if (ConditionCode
== TD_CC_NOERROR
) {
1403 RZA_IO_RegWrite_32(&p_td
->control
, 0, TD_CTL_SHFT_EC
, TD_CTL_MSK_EC
);
1405 /* CurrentBufferPointer */
1406 p_td
->currBufPtr
+= ((uint32_t)p_td
->bufEnd
- (uint32_t)p_td
->currBufPtr
+ 1) - g_usbx_host_data_count
[pipe
];
1409 RZA_IO_RegWrite_32(&p_td
->control
, 3, TD_CTL_SHFT_EC
, TD_CTL_MSK_EC
);
1413 sqmon
= usbx_host_get_sqmon(pipe
);
1414 RZA_IO_RegWrite_32(&p_td
->control
, sqmon
, TD_CTL_SHFT_T
, TD_CTL_MSK_T
);
1416 p_ed
->headTD
&= ~ED_TOGLE_CARRY
;
1418 p_ed
->headTD
|= ED_TOGLE_CARRY
;
1422 RZA_IO_RegWrite_32(&p_td
->control
, ConditionCode
, TD_CTL_SHFT_CC
, TD_CTL_MSK_CC
);
1424 if (p_wait_ed
== &ctl_ed
) {
1425 chk_split_trans_setting(&ctl_ed
);
1427 chk_genelal_td_done(p_wait_ed
);
1429 if (periodic
!= 0) {
1430 if (chk_genelal_ed(p_wait_ed
) != 0) {
1431 int_trans(p_wait_ed
);
1433 p_wait_ed
->trans_wait
= 0;
1434 (void)osSemaphoreRelease(p_wait_ed
->semid_wait
);
1437 p_wait_ed
->trans_wait
= 0;
1438 (void)osSemaphoreRelease(p_wait_ed
->semid_wait
);
1442 #if (ISO_TRANS_MAX_NUM > 0)
1443 hcisotd_t
*p_isotd
= (hcisotd_t
*)p_wait_ed
->p_curr_td
;
1444 uint32_t next_trans
= 0;
1446 if (p_isotd
!= NULL
) {
1447 usbx_host_stop_transfer(pipe
);
1448 if (p_usb_reg
->HcFmNumber
< 0x0000FFFF) {
1449 p_usb_reg
->HcFmNumber
++;
1451 p_usb_reg
->HcFmNumber
= 0;
1454 /* Size of packet */
1455 p_isotd
->offsetPSW
[p_wait_ed
->psw_idx
] -= g_usbx_host_data_count
[pipe
];
1458 RZA_IO_RegWrite_32(&p_isotd
->control
, ConditionCode
, TD_CTL_SHFT_CC
, TD_CTL_MSK_CC
);
1459 RZA_IO_RegWrite_16(&p_isotd
->offsetPSW
[p_wait_ed
->psw_idx
],
1460 (uint16_t)ConditionCode
, TD_PSW_SHFT_CC
, TD_PSW_MSK_CC
);
1462 if (usbx_host_CheckAttach() != USB_HOST_ATTACH
) {
1463 p_ed
->headTD
|= ED_HALTED
;
1465 if (p_wait_ed
->psw_idx
>= RZA_IO_RegRead_32(&p_isotd
->control
, TD_CTL_SHFT_FC
, TD_CTL_MSK_FC
)) {
1466 p_wait_ed
->psw_idx
= 0;
1467 chk_iso_td_done(p_wait_ed
);
1469 p_wait_ed
->psw_idx
++;
1471 if (chk_iso_ed(p_wait_ed
) != 0) {
1472 if (iso_chk_starting_frame(p_wait_ed
) == 0) {
1473 iso_trans(p_wait_ed
);
1477 if (next_trans
== 0) {
1478 p_wait_ed
->trans_wait
= 0;
1479 (void)osSemaphoreRelease(p_wait_ed
->semid_wait
);