@@ -161,6 +161,22 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr);
161
161
//--------------------------------------------------------------------+
162
162
// USBH-HCD API
163
163
//--------------------------------------------------------------------+
164
+
165
+ //If your system requires separation of virtual and physical memory, implement
166
+ //tuh_get_phys_addr and tuh_get_virt_addr in your application.
167
+ TU_ATTR_WEAK void * tuh_get_phys_addr (void * virtual_address );
168
+ TU_ATTR_WEAK void * tuh_get_virt_addr (void * physical_address );
169
+ TU_ATTR_ALWAYS_INLINE static void * _phys_addr (void * virtual_address )
170
+ {
171
+ if (tuh_get_phys_addr ) return tuh_get_phys_addr (virtual_address );
172
+ return virtual_address ;
173
+ }
174
+ TU_ATTR_ALWAYS_INLINE static void * _virt_addr (void * physical_address )
175
+ {
176
+ if (tuh_get_virt_addr ) return tuh_get_virt_addr (physical_address );
177
+ return physical_address ;
178
+ }
179
+
164
180
// Initialization according to 5.1.1.4
165
181
bool hcd_init (uint8_t rhport )
166
182
{
@@ -170,7 +186,7 @@ bool hcd_init(uint8_t rhport)
170
186
tu_memclr (& ohci_data , sizeof (ohci_data_t ));
171
187
for (uint8_t i = 0 ; i < 32 ; i ++ )
172
188
{ // assign all interrupt pointers to period head ed
173
- ohci_data .hcca .interrupt_table [i ] = (uint32_t ) & ohci_data .period_head_ed ;
189
+ ohci_data .hcca .interrupt_table [i ] = (uint32_t ) _phys_addr ( & ohci_data .period_head_ed ) ;
174
190
}
175
191
176
192
ohci_data .control [0 ].ed .skip = 1 ;
@@ -198,9 +214,9 @@ bool hcd_init(uint8_t rhport)
198
214
while ( OHCI_REG -> command_status_bit .controller_reset ) {} // should not take longer than 10 us
199
215
200
216
//------------- init ohci registers -------------//
201
- OHCI_REG -> control_head_ed = (uint32_t ) & ohci_data .control [0 ].ed ;
202
- OHCI_REG -> bulk_head_ed = (uint32_t ) & ohci_data .bulk_head_ed ;
203
- OHCI_REG -> hcca = (uint32_t ) & ohci_data .hcca ;
217
+ OHCI_REG -> control_head_ed = (uint32_t ) _phys_addr ( & ohci_data .control [0 ].ed ) ;
218
+ OHCI_REG -> bulk_head_ed = (uint32_t ) _phys_addr ( & ohci_data .bulk_head_ed ) ;
219
+ OHCI_REG -> hcca = (uint32_t ) _phys_addr ( & ohci_data .hcca ) ;
204
220
205
221
OHCI_REG -> interrupt_disable = OHCI_REG -> interrupt_enable ; // disable all interrupts
206
222
OHCI_REG -> interrupt_status = OHCI_REG -> interrupt_status ; // clear current set bits
@@ -327,8 +343,8 @@ static void gtd_init(ohci_gtd_t* p_td, uint8_t* data_ptr, uint16_t total_bytes)
327
343
p_td -> delay_interrupt = OHCI_INT_ON_COMPLETE_NO ;
328
344
p_td -> condition_code = OHCI_CCODE_NOT_ACCESSED ;
329
345
330
- p_td -> current_buffer_pointer = data_ptr ;
331
- p_td -> buffer_end = total_bytes ? (data_ptr + total_bytes - 1 ) : data_ptr ;
346
+ p_td -> current_buffer_pointer = _phys_addr ( data_ptr ) ;
347
+ p_td -> buffer_end = total_bytes ? (_phys_addr ( data_ptr + total_bytes - 1 )) : ( uint8_t * ) p_td -> current_buffer_pointer ;
332
348
}
333
349
334
350
static ohci_ed_t * ed_from_addr (uint8_t dev_addr , uint8_t ep_addr )
@@ -364,7 +380,7 @@ static ohci_ed_t * ed_find_free(void)
364
380
static void ed_list_insert (ohci_ed_t * p_pre , ohci_ed_t * p_ed )
365
381
{
366
382
p_ed -> next = p_pre -> next ;
367
- p_pre -> next = (uint32_t ) p_ed ;
383
+ p_pre -> next = (uint32_t ) _phys_addr ( p_ed ) ;
368
384
}
369
385
370
386
static void ed_list_remove_by_addr (ohci_ed_t * p_head , uint8_t dev_addr )
@@ -373,7 +389,7 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr)
373
389
374
390
while ( p_prev -> next )
375
391
{
376
- ohci_ed_t * ed = (ohci_ed_t * ) p_prev -> next ;
392
+ ohci_ed_t * ed = (ohci_ed_t * ) _virt_addr (( void * ) p_prev -> next ) ;
377
393
378
394
if (ed -> dev_addr == dev_addr )
379
395
{
@@ -384,14 +400,14 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr)
384
400
p_prev -> next = ed -> next ;
385
401
386
402
// point the removed ED's next pointer to list head to make sure HC can always safely move away from this ED
387
- ed -> next = (uint32_t ) p_head ;
403
+ ed -> next = (uint32_t ) _phys_addr ( p_head ) ;
388
404
ed -> used = 0 ;
389
405
ed -> skip = 0 ;
390
406
continue ;
391
407
}
392
408
393
409
// check next valid since we could remove it
394
- if (p_prev -> next ) p_prev = (ohci_ed_t * ) p_prev -> next ;
410
+ if (p_prev -> next ) p_prev = (ohci_ed_t * ) _virt_addr (( void * ) p_prev -> next ) ;
395
411
}
396
412
}
397
413
@@ -410,11 +426,11 @@ static void td_insert_to_ed(ohci_ed_t* p_ed, ohci_gtd_t * p_gtd)
410
426
// tail is always NULL
411
427
if ( tu_align16 (p_ed -> td_head .address ) == 0 )
412
428
{ // TD queue is empty --> head = TD
413
- p_ed -> td_head .address |= (uint32_t ) p_gtd ;
429
+ p_ed -> td_head .address |= (uint32_t ) _phys_addr ( p_gtd ) ;
414
430
}
415
431
else
416
432
{ // TODO currently only support queue up to 2 TD each endpoint at a time
417
- ((ohci_gtd_t * ) tu_align16 (p_ed -> td_head .address ))-> next = (uint32_t ) p_gtd ;
433
+ ((ohci_gtd_t * ) tu_align16 (( uint32_t ) _virt_addr (( void * ) p_ed -> td_head .address ))) -> next = (uint32_t ) _phys_addr ( p_gtd ) ;
418
434
}
419
435
}
420
436
@@ -470,7 +486,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
470
486
qtd -> delay_interrupt = 0 ;
471
487
472
488
//------------- Attach TDs list to Control Endpoint -------------//
473
- ed -> td_head .address = (uint32_t ) qtd ;
489
+ ed -> td_head .address = (uint32_t ) _phys_addr ( qtd ) ;
474
490
475
491
OHCI_REG -> command_status_bit .control_list_filled = 1 ;
476
492
@@ -496,7 +512,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
496
512
gtd -> data_toggle = GTD_DT_DATA1 ; // Both Data and Ack stage start with DATA1
497
513
gtd -> delay_interrupt = 0 ;
498
514
499
- ed -> td_head .address = (uint32_t ) gtd ;
515
+ ed -> td_head .address = (uint32_t ) _phys_addr ( gtd ) ;
500
516
501
517
OHCI_REG -> command_status_bit .control_list_filled = 1 ;
502
518
}else
@@ -544,16 +560,17 @@ static ohci_td_item_t* list_reverse(ohci_td_item_t* td_head)
544
560
545
561
while (td_head != NULL )
546
562
{
563
+ td_head = _virt_addr (td_head );
547
564
uint32_t next = td_head -> next ;
548
565
549
566
// make current's item become reverse's first item
550
567
td_head -> next = (uint32_t ) td_reverse_head ;
551
- td_reverse_head = td_head ;
568
+ td_reverse_head = _phys_addr ( td_head ) ;
552
569
553
570
td_head = (ohci_td_item_t * ) next ; // advance to next item
554
571
}
555
572
556
- return td_reverse_head ;
573
+ return _virt_addr ( td_reverse_head ) ;
557
574
}
558
575
559
576
static inline bool gtd_is_control (ohci_gtd_t const * const p_qtd )
@@ -624,7 +641,7 @@ static void done_queue_isr(uint8_t hostid)
624
641
hcd_event_xfer_complete (ed -> dev_addr , tu_edpt_addr (ed -> ep_number , dir ), xferred_bytes , event , true);
625
642
}
626
643
627
- td_head = (ohci_td_item_t * ) td_head -> next ;
644
+ td_head = (ohci_td_item_t * ) _virt_addr (( void * ) td_head -> next ) ;
628
645
}
629
646
}
630
647
0 commit comments