Skip to content

Commit 14c98dd

Browse files
committed
minor ehci rename, move code around
1 parent 0da273e commit 14c98dd

File tree

1 file changed

+91
-90
lines changed

1 file changed

+91
-90
lines changed

src/portable/ehci/ehci.c

Lines changed: 91 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -126,53 +126,29 @@ static inline void print_intr(uint32_t intr) {
126126
//--------------------------------------------------------------------+
127127
// PROTOTYPE
128128
//--------------------------------------------------------------------+
129-
static inline ehci_link_t* get_period_head(uint8_t rhport, uint32_t interval_ms)
130-
{
131-
(void) rhport;
132-
return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
133-
}
134-
135-
static inline ehci_qhd_t* qhd_control(uint8_t dev_addr)
136-
{
137-
return &ehci_data.control[dev_addr].qhd;
138-
}
139-
140-
static inline ehci_qhd_t* qhd_async_head(uint8_t rhport)
141-
{
142-
(void) rhport;
143-
// control qhd of dev0 is used as async head
144-
return qhd_control(0);
145-
}
146129

147-
static inline ehci_qtd_t* qtd_control(uint8_t dev_addr)
148-
{
149-
return &ehci_data.control[dev_addr].qtd;
150-
}
130+
// weak dcache for non-cacheable MCU
131+
TU_ATTR_WEAK void hcd_dcache_clean(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; }
132+
TU_ATTR_WEAK void hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; }
133+
TU_ATTR_WEAK void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; }
151134

135+
TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms);
136+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport);
152137

153-
static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
154-
static inline ehci_qhd_t* qhd_find_free (void);
155-
static inline ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
138+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr);
139+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
140+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_find_free (void);
141+
static ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
156142
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
157143
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd);
158144

159-
static inline ehci_qtd_t* qtd_find_free (void);
145+
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr);
146+
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_find_free (void);
160147
static void qtd_init (ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes);
161148

162149
static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
163150
static inline ehci_link_t* list_next (ehci_link_t const *p_link);
164-
165-
TU_ATTR_WEAK void hcd_dcache_clean(void const* addr, uint32_t data_size) {
166-
(void) addr; (void) data_size;
167-
}
168-
169-
TU_ATTR_WEAK void hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
170-
(void) addr; (void) data_size;
171-
}
172-
173-
TU_ATTR_WEAK void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
174-
(void) addr; (void) data_size;
175-
}
151+
static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr);
176152

177153
//--------------------------------------------------------------------+
178154
// HCD API
@@ -274,7 +250,7 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
274250
}
275251

276252
// Remove from async list
277-
list_remove_qhd_by_daddr((ehci_link_t *) qhd_async_head(rhport), daddr);
253+
list_remove_qhd_by_daddr((ehci_link_t *) list_get_async_head(rhport), daddr);
278254

279255
// Remove from all interval period list
280256
for(uint8_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++) {
@@ -286,37 +262,42 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
286262
}
287263

288264
static void init_periodic_list(uint8_t rhport) {
265+
(void) rhport;
266+
289267
// Build the polling interval tree with 1 ms, 2 ms, 4 ms and 8 ms (framesize) only
290268
for ( uint32_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++ ) {
291269
ehci_data.period_head_arr[i].int_smask = 1; // queue head in period list must have smask non-zero
292270
ehci_data.period_head_arr[i].qtd_overlay.halted = 1; // dummy node, always inactive
293271
}
294272

295-
ehci_link_t * const framelist = ehci_data.period_framelist;
296-
ehci_link_t * const period_1ms = get_period_head(rhport, 1u);
297-
273+
// TODO EHCI_FRAMELIST_SIZE with other size than 8
298274
// all links --> period_head_arr[0] (1ms)
299275
// 0, 2, 4, 6 etc --> period_head_arr[1] (2ms)
300276
// 1, 5 --> period_head_arr[2] (4ms)
301277
// 3 --> period_head_arr[3] (8ms)
302278

303-
// TODO EHCI_FRAMELIST_SIZE with other size than 8
279+
ehci_link_t * const framelist = ehci_data.period_framelist;
280+
ehci_link_t * const head_1ms = (ehci_link_t *) &ehci_data.period_head_arr[0];
281+
ehci_link_t * const head_2ms = (ehci_link_t *) &ehci_data.period_head_arr[1];
282+
ehci_link_t * const head_4ms = (ehci_link_t *) &ehci_data.period_head_arr[2];
283+
ehci_link_t * const head_8ms = (ehci_link_t *) &ehci_data.period_head_arr[3];
284+
304285
for (uint32_t i = 0; i < FRAMELIST_SIZE; i++) {
305-
framelist[i].address = (uint32_t) period_1ms;
286+
framelist[i].address = (uint32_t) head_1ms;
306287
framelist[i].type = EHCI_QTYPE_QHD;
307288
}
308289

309290
for (uint32_t i = 0; i < FRAMELIST_SIZE; i += 2) {
310-
list_insert(framelist + i, get_period_head(rhport, 2u), EHCI_QTYPE_QHD);
291+
list_insert(framelist + i, head_2ms, EHCI_QTYPE_QHD);
311292
}
312293

313294
for (uint32_t i = 1; i < FRAMELIST_SIZE; i += 4) {
314-
list_insert(framelist + i, get_period_head(rhport, 4u), EHCI_QTYPE_QHD);
295+
list_insert(framelist + i, head_4ms, EHCI_QTYPE_QHD);
315296
}
316297

317-
list_insert(framelist + 3, get_period_head(rhport, 8u), EHCI_QTYPE_QHD);
298+
list_insert(framelist + 3, head_8ms, EHCI_QTYPE_QHD);
318299

319-
period_1ms->terminate = 1;
300+
head_1ms->terminate = 1;
320301
}
321302

322303
bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
@@ -345,7 +326,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
345326
EHCI_INT_MASK_NXP_PERIODIC | EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_FRAMELIST_ROLLOVER;
346327

347328
//------------- Asynchronous List -------------//
348-
ehci_qhd_t * const async_head = qhd_async_head(rhport);
329+
ehci_qhd_t * const async_head = list_get_async_head(rhport);
349330
tu_memclr(async_head, sizeof(ehci_qhd_t));
350331

351332
async_head->next.address = (uint32_t) async_head; // circular list, next is itself
@@ -426,11 +407,11 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
426407
{
427408
case TUSB_XFER_CONTROL:
428409
case TUSB_XFER_BULK:
429-
list_head = (ehci_link_t*) qhd_async_head(rhport);
410+
list_head = (ehci_link_t*) list_get_async_head(rhport);
430411
break;
431412

432413
case TUSB_XFER_INTERRUPT:
433-
list_head = get_period_head(rhport, p_qhd->interval_ms);
414+
list_head = list_get_period_head(rhport, p_qhd->interval_ms);
434415
break;
435416

436417
case TUSB_XFER_ISOCHRONOUS:
@@ -439,10 +420,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
439420

440421
default: break;
441422
}
442-
443423
TU_ASSERT(list_head);
444424

445-
// TODO might need to disable async/period list
446425
list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD);
447426

448427
hcd_dcache_clean(p_qhd, sizeof(ehci_qhd_t));
@@ -622,8 +601,8 @@ void async_list_xfer_complete_isr(ehci_qhd_t * const async_head)
622601
TU_ATTR_ALWAYS_INLINE static inline
623602
void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
624603
{
625-
uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
626-
ehci_link_t next_link = * get_period_head(rhport, interval_ms);
604+
uint32_t const period_1ms_addr = (uint32_t) list_get_period_head(rhport, 1u);
605+
ehci_link_t next_link = *list_get_period_head(rhport, interval_ms);
627606

628607
while (!next_link.terminate) {
629608
if (interval_ms > 1 && period_1ms_addr == tu_align32(next_link.address)) {
@@ -721,7 +700,7 @@ TU_ATTR_ALWAYS_INLINE static inline
721700
void xfer_error_isr(uint8_t rhport)
722701
{
723702
//------------- async list -------------//
724-
ehci_qhd_t * const async_head = qhd_async_head(rhport);
703+
ehci_qhd_t * const async_head = list_get_async_head(rhport);
725704
ehci_qhd_t *p_qhd = async_head;
726705
do
727706
{
@@ -731,10 +710,10 @@ void xfer_error_isr(uint8_t rhport)
731710
}while(p_qhd != async_head); // async list traversal, stop if loop around
732711

733712
//------------- TODO refractor period list -------------//
734-
uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
713+
uint32_t const period_1ms_addr = (uint32_t) list_get_period_head(rhport, 1u);
735714
for (uint32_t interval_ms=1; interval_ms <= FRAMELIST_SIZE; interval_ms *= 2)
736715
{
737-
ehci_link_t next_item = * get_period_head(rhport, interval_ms);
716+
ehci_link_t next_item = *list_get_period_head(rhport, interval_ms);
738717

739718
// TODO abstract max loop guard for period
740719
while( !next_item.terminate &&
@@ -801,7 +780,7 @@ void hcd_int_handler(uint8_t rhport)
801780

802781
//------------- some QTD/SITD/ITD with IOC set is completed -------------//
803782
if (int_status & EHCI_INT_MASK_NXP_ASYNC) {
804-
async_list_xfer_complete_isr(qhd_async_head(rhport));
783+
async_list_xfer_complete_isr(list_get_async_head(rhport));
805784
regs->status = EHCI_INT_MASK_NXP_ASYNC; // Acknowledge
806785
}
807786

@@ -828,42 +807,70 @@ void hcd_int_handler(uint8_t rhport)
828807
}
829808

830809
//--------------------------------------------------------------------+
831-
// HELPER
810+
// List Managing Helper
832811
//--------------------------------------------------------------------+
833812

813+
// Get head of periodic list
814+
TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms) {
815+
(void) rhport;
816+
return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
817+
}
834818

835-
//------------- queue head helper -------------//
836-
static inline ehci_qhd_t* qhd_find_free (void)
819+
// Get head of async list
820+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport) {
821+
(void) rhport;
822+
return qhd_control(0); // control qhd of dev0 is used as async head
823+
}
824+
825+
// insert at head
826+
static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
837827
{
838-
for (uint32_t i=0; i<QHD_MAX; i++)
839-
{
828+
new->address = current->address;
829+
current->address = ((uint32_t) new) | (new_type << 1);
830+
}
831+
832+
static inline ehci_link_t* list_next(ehci_link_t const *p_link)
833+
{
834+
return (ehci_link_t*) tu_align32(p_link->address);
835+
}
836+
837+
//--------------------------------------------------------------------+
838+
// Queue Header helper
839+
//--------------------------------------------------------------------+
840+
841+
// Get queue head for control transfer (always available)
842+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr) {
843+
return &ehci_data.control[dev_addr].qhd;
844+
}
845+
846+
// Find a free queue head
847+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_find_free(void) {
848+
for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
840849
if ( !ehci_data.qhd_pool[i].used ) return &ehci_data.qhd_pool[i];
841850
}
842-
843851
return NULL;
844852
}
845853

846-
static inline ehci_qhd_t* qhd_next(ehci_qhd_t const * p_qhd)
847-
{
848-
return (ehci_qhd_t*) tu_align32(p_qhd->next.address);
854+
// Next queue head link
855+
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_next(ehci_qhd_t const *p_qhd) {
856+
return (ehci_qhd_t *) tu_align32(p_qhd->next.address);
849857
}
850858

851-
static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
852-
{
853-
ehci_qhd_t* qhd_pool = ehci_data.qhd_pool;
859+
// Get queue head from address
860+
static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) {
861+
ehci_qhd_t *qhd_pool = ehci_data.qhd_pool;
854862

855-
for(uint32_t i=0; i<QHD_MAX; i++)
856-
{
863+
for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
857864
if ( (qhd_pool[i].dev_addr == dev_addr) &&
858-
ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) )
859-
{
865+
ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) ) {
860866
return &qhd_pool[i];
861867
}
862868
}
863869

864870
return NULL;
865871
}
866872

873+
// Init queue head with endpoint descriptor
867874
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
868875
{
869876
// address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise)
@@ -938,6 +945,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
938945
}
939946
}
940947

948+
// Attach a TD to queue head
941949
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
942950
qhd->attached_qtd = qtd;
943951
qhd->attached_buffer = qtd->buffer[0];
@@ -949,9 +957,16 @@ static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
949957
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
950958
}
951959

960+
//--------------------------------------------------------------------+
961+
// Queue TD helper
962+
//--------------------------------------------------------------------+
963+
964+
// Get TD for control transfer (always available)
965+
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr) {
966+
return &ehci_data.control[dev_addr].qtd;
967+
}
952968

953-
//------------- TD helper -------------//
954-
static inline ehci_qtd_t *qtd_find_free(void) {
969+
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t *qtd_find_free(void) {
955970
for (uint32_t i = 0; i < QTD_MAX; i++) {
956971
if (!ehci_data.qtd_pool[i].used) return &ehci_data.qtd_pool[i];
957972
}
@@ -979,18 +994,4 @@ static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes)
979994
}
980995
}
981996

982-
//------------- List Managing Helper -------------//
983-
984-
// insert at head
985-
static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
986-
{
987-
new->address = current->address;
988-
current->address = ((uint32_t) new) | (new_type << 1);
989-
}
990-
991-
static inline ehci_link_t* list_next(ehci_link_t const *p_link)
992-
{
993-
return (ehci_link_t*) tu_align32(p_link->address);
994-
}
995-
996997
#endif

0 commit comments

Comments
 (0)