3939
4040#if (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || CFG_TUSB_MCU == OPT_MCU_PIC32MK )
4141
42- #define TU_PIC_HAS_MMU 1
43- #define TU_PIC_HAS_HW_RMW 1
4442#define TU_PIC_INT_SIZE 4
4543
4644#elif (CFG_TUSB_MCU == OPT_MCU_PIC24 || CFG_TUSB_MCU == OPT_MCU_DSPIC33 )
4745
48- #define TU_PIC_HAS_MMU 0
49- #define TU_PIC_HAS_HW_RMW 0
5046#define TU_PIC_INT_SIZE 2
5147
5248#else
5652#endif
5753
5854
59- #if TU_PIC_HAS_MMU
55+ #if TU_PIC_INT_SIZE == 4
6056
6157#ifndef KVA_TO_PA
6258#define KVA_TO_PA (kva ) ((uint32_t)(kva) & 0x1fffffff)
8985 TOK_PID_SETUP = 0xDu ,
9086};
9187
88+ // The BDT is 8 bytes on 32bit PICs and 4 bytes on 8/16bit PICs
89+ #if TU_PIC_INT_SIZE == 4
9290typedef struct TU_ATTR_PACKED
9391{
9492 union {
@@ -119,6 +117,37 @@ typedef struct TU_ATTR_PACKED
119117} buffer_descriptor_t ;
120118
121119TU_VERIFY_STATIC ( sizeof (buffer_descriptor_t ) == 8 , "size is not correct" );
120+ #else
121+ typedef struct TU_ATTR_PACKED
122+ {
123+ union {
124+ uint16_t head ;
125+
126+ struct {
127+ uint16_t : 10 ;
128+ uint16_t tok_pid : 4 ;
129+ uint16_t data : 1 ;
130+ uint16_t own : 1 ;
131+ };
132+ struct {
133+ uint16_t : 10 ;
134+ uint16_t bdt_stall : 1 ;
135+ uint16_t dts : 1 ;
136+ uint16_t ninc : 1 ;
137+ uint16_t keep : 1 ;
138+ };
139+
140+ struct {
141+ uint16_t bc : 10 ;
142+ uint16_t : 6 ;
143+ };
144+ };
145+ uint8_t * addr ;
146+ } buffer_descriptor_t ;
147+
148+ TU_VERIFY_STATIC ( sizeof (buffer_descriptor_t ) == 4 , "size is not correct" );
149+ #endif
150+
122151
123152typedef struct TU_ATTR_PACKED
124153{
@@ -142,7 +171,11 @@ typedef struct
142171 union {
143172 /* [#EP][OUT,IN][EVEN,ODD] */
144173 buffer_descriptor_t bdt [16 ][2 ][2 ];
145- uint16_t bda [512 ];
174+ #if TU_PIC_INT_SIZE == 4
175+ uint16_t bda [256 ];
176+ #else
177+ uint8_t bda [256 ];
178+ #endif
146179 };
147180 TU_ATTR_ALIGNED (4 ) union {
148181 endpoint_state_t endpoint [16 ][2 ];
@@ -158,7 +191,11 @@ typedef struct
158191// BDT(Buffer Descriptor Table) must be 256-byte aligned
159192CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED (512 ) volatile static dcd_data_t _dcd ;
160193
194+ #if TU_PIC_INT_SIZE == 4
161195TU_VERIFY_STATIC ( sizeof (_dcd .bdt ) == 512 , "size is not correct" );
196+ #else
197+ TU_VERIFY_STATIC ( sizeof (_dcd .bdt ) == 256 , "size is not correct" );
198+ #endif
162199
163200#if TU_PIC_INT_SIZE == 4
164201typedef uint32_t ep_reg_t ;
@@ -172,7 +209,12 @@ static inline volatile void *ep_addr(uint8_t rhport, uint8_t ep_num) {
172209#else
173210 volatile void * ep_reg_base = & U1EP0 ;
174211#endif
175- return ep_reg_base + 0x10 * ep_num ;
212+ #if TU_PIC_INT_SIZE == 4
213+ const size_t offset = 0x10 ;
214+ #else
215+ const size_t offset = 0x2 ;
216+ #endif
217+ return ep_reg_base + offset * ep_num ;
176218}
177219
178220static inline ep_reg_t ep_read (uint8_t rhport , uint8_t ep_num ) {
@@ -186,7 +228,7 @@ static inline void ep_write(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
186228}
187229
188230static inline void ep_clear (uint8_t rhport , uint8_t ep_num , ep_reg_t val ) {
189- #if TU_PIC_HAS_HW_RMW
231+ #if TU_PIC_INT_SIZE == 4
190232 volatile ep_reg_t * ep_clr = (ep_addr (rhport , ep_num ) + 0x4 );
191233 * ep_clr = val ;
192234#else
@@ -197,7 +239,7 @@ static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
197239}
198240
199241static inline void ep_set (uint8_t rhport , uint8_t ep_num , ep_reg_t val ) {
200- #if TU_PIC_HAS_HW_RMW
242+ #if TU_PIC_INT_SIZE == 4
201243 volatile ep_reg_t * ep_s = (ep_addr (rhport , ep_num ) + 0x8 );
202244 * ep_s = val ;
203245#else
@@ -278,7 +320,7 @@ static void prepare_next_setup_packet(uint8_t rhport)
278320 _dcd .bdt [0 ][1 ][in_odd ].data = 1 ;
279321 _dcd .bdt [0 ][1 ][in_odd ^ 1 ].data = 0 ;
280322 dcd_edpt_xfer (rhport , tu_edpt_addr (0 , TUSB_DIR_OUT ),
281- _dcd .setup_packet , sizeof (_dcd .setup_packet ));
323+ _dcd .setup_packet , sizeof (_dcd .setup_packet ));
282324}
283325
284326static void process_stall (uint8_t rhport )
@@ -298,7 +340,7 @@ static void process_stall(uint8_t rhport)
298340
299341static void process_tokdne (uint8_t rhport )
300342{
301- uint32_t s = U1STAT ;
343+ ep_reg_t s = U1STAT ;
302344
303345 U1IR = _U1IR_TRNIF_MASK ;
304346
@@ -321,7 +363,11 @@ static void process_tokdne(uint8_t rhport)
321363 ep -> odd = odd ^ 1 ;
322364 if (pid == TOK_PID_SETUP ) {
323365 dcd_event_setup_received (rhport , (uint8_t * )PA_TO_KVA1 (bd -> addr ), true);
366+ #if TU_PIC_INT_SIZE == 4
324367 U1CONCLR = _U1CON_PKTDIS_TOKBUSY_MASK ;
368+ #else
369+ U1CONbits .PKTDIS = 0 ;
370+ #endif
325371 return ;
326372 }
327373
@@ -341,8 +387,8 @@ static void process_tokdne(uint8_t rhport)
341387 }
342388 const unsigned length = ep -> length ;
343389 dcd_event_xfer_complete (rhport ,
344- tu_edpt_addr (epnum , dir ),
345- length - remaining , XFER_RESULT_SUCCESS , true);
390+ tu_edpt_addr (epnum , dir ),
391+ length - remaining , XFER_RESULT_SUCCESS , true);
346392 if (0 == epnum && 0 == length ) {
347393 /* After completion a ZLP of control transfer,
348394 * it prepares for the next steup transfer. */
@@ -358,11 +404,16 @@ static void process_tokdne(uint8_t rhport)
358404
359405static void process_bus_reset (uint8_t rhport )
360406{
407+ #if TU_PIC_INT_SIZE == 4
361408 U1PWRCCLR = _U1PWRC_USUSPEND_MASK ;
362409 U1CONSET = _U1CON_PPBRST_MASK ;
410+ #else
411+ U1PWRCbits .USUSPND = 0 ;
412+ U1CONbits .PPBRST = 1 ;
413+ #endif
363414 U1ADDR = 0 ;
364415
365- U1IE = _U1IE_URSTIE_DETACHIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK |
416+ U1IE = _U1IE_URSTIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK |
366417 _U1IE_UERRIE_MASK | _U1IE_STALLIE_MASK ;
367418
368419 U1EP0 = _U1EP0_EPHSHK_MASK | _U1EP0_EPRXEN_MASK | _U1EP0_EPTXEN_MASK ;
@@ -386,7 +437,11 @@ static void process_bus_reset(uint8_t rhport)
386437 tu_memclr (_dcd .endpoint [1 ], sizeof (_dcd .endpoint ) - sizeof (_dcd .endpoint [0 ]));
387438 _dcd .addr = 0 ;
388439 prepare_next_setup_packet (rhport );
440+ #if TU_PIC_INT_SIZE == 4
389441 U1CONCLR = _U1CON_PPBRST_MASK ;
442+ #else
443+ U1CONbits .PPBRST = 0 ;
444+ #endif
390445 dcd_event_bus_reset (rhport , TUSB_SPEED_FULL , true);
391446}
392447
@@ -399,9 +454,15 @@ static void process_bus_sleep(uint8_t rhport)
399454static void process_bus_resume (uint8_t rhport )
400455{
401456 // Enable suspend & disable resume interrupt
457+ #if TU_PIC_INT_SIZE == 4
402458 U1PWRCCLR = _U1PWRC_USUSPEND_MASK ;
403459 U1IECLR = _U1IE_RESUMEIE_MASK ;
404460 U1IESET = _U1IE_IDLEIE_MASK ;
461+ #else
462+ U1PWRCbits .USUSPND = 0 ;
463+ U1IEbits .RESUMEIE = 0 ;
464+ U1IEbits .IDLEIE = 1 ;
465+ #endif
405466
406467 dcd_event_bus_signal (rhport , DCD_EVENT_RESUME , true);
407468}
@@ -418,26 +479,29 @@ void dcd_init(uint8_t rhport)
418479 TRISBbits .TRISB6 = 1 ;
419480#endif
420481
421- #if (CFG_TUSB_MCU == OPT_MCU_PIC32MX ) || (CFG_TUSB_MCU == OPT_MCU_PIC32MM )
482+ tu_memclr (& _dcd , sizeof (_dcd ));
483+
484+ #if TU_PIC_INT_SIZE == 4
422485 U1PWRCSET = _U1PWRC_USBPWR_MASK ;
423- #elif CFG_TUSB_MCU == OPT_MCU_PIC32MK
424- // TODO
425- #elif (CFG_TUSB_MCU == OPT_MCU_PIC24 ) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33 )
486+ #else
426487 U1PWRCbits .USBPWR = 1 ;
427488#endif
428-
429- tu_memclr (& _dcd , sizeof (_dcd ));
430-
489+
490+ #if TU_PIC_INT_SIZE == 4
431491 uint32_t bdt_phys = KVA_TO_PA ((uintptr_t )_dcd .bdt );
432492
433493 U1BDTP1 = (uint8_t )(bdt_phys >> 8 );
434494 U1BDTP2 = (uint8_t )(bdt_phys >> 16 );
435495 U1BDTP3 = (uint8_t )(bdt_phys >> 24 );
496+ #else
497+ U1BDTP1 = (uint8_t )((uint16_t )(void * )_dcd .bdt >> 8 );
436498
437- U1IE = _U1IE_URSTIE_DETACHIE_MASK ;
499+ U1CNFG1bits .PPB = 2 ;
500+ #endif
438501
439- dcd_connect ( rhport ) ;
502+ U1IE = _U1IE_URSTIE_MASK ;
440503
504+ dcd_connect (rhport );
441505}
442506
443507void dcd_int_enable (uint8_t rhport )
@@ -459,18 +523,30 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
459523
460524void dcd_remote_wakeup (uint8_t rhport )
461525{
526+ #if TU_PIC_INT_SIZE == 4
462527 U1CONSET = _U1CON_RESUME_MASK ;
463-
528+ #else
529+ U1CONbits .RESUME = 1 ;
530+ #endif
464531 unsigned cnt = 25000000 / 1000 ;
465532 while (cnt -- ) asm volatile ("nop" );
466533
534+ #if TU_PIC_INT_SIZE == 4
467535 U1CONCLR = _U1CON_RESUME_MASK ;
536+ #else
537+ U1CONbits .RESUME = 0 ;
538+ #endif
468539}
469540
470541void dcd_connect (uint8_t rhport )
471542{
472- while (!U1CONbits .USBEN )
543+ while (!U1CONbits .USBEN ) {
544+ #if TU_PIC_INT_SIZE == 4
473545 U1CONSET = _U1CON_USBEN_SOFEN_MASK ;
546+ #else
547+ U1CONbits .USBEN = 1 ;
548+ #endif
549+ }
474550}
475551
476552void dcd_disconnect (uint8_t rhport )
@@ -502,14 +578,14 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
502578
503579 ep -> max_packet_size = tu_edpt_packet_size (ep_desc );
504580
581+
505582 unsigned val = _U1EP0_EPCONDIS_MASK ;
506583 val |= (xfer != TUSB_XFER_ISOCHRONOUS ) ? _U1EP0_EPHSHK_MASK : 0 ;
507584 val |= dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK ;
508585
509- volatile void * ep_reg_base = & U1EP0 ;
510- volatile uint32_t * reg_ep = (ep_reg_base + 0x10 * epn );
511-
512- * reg_ep |= val ;
586+ ep_reg_t tmp = ep_read (rhport , epn );
587+ tmp |= val ;
588+ ep_write (rhport , epn , tmp );
513589
514590 if (xfer != TUSB_XFER_ISOCHRONOUS ) {
515591 bd [odd ].dts = 1 ;
@@ -569,6 +645,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
569645
570646bool dcd_edpt_xfer (uint8_t rhport , uint8_t ep_addr , uint8_t * buffer , uint16_t total_bytes )
571647{
648+
572649 const unsigned epn = tu_edpt_number (ep_addr );
573650 const unsigned dir = tu_edpt_dir (ep_addr );
574651 endpoint_state_t * ep = & _dcd .endpoint [epn ][dir ];
@@ -593,7 +670,6 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
593670 }
594671 bd -> bc = total_bytes >= mps ? mps : total_bytes ;
595672 bd -> addr = (uint8_t * )KVA_TO_PA (buffer );
596- // __DSB();
597673 bd -> own = 1 ; /* This bit must be set last */
598674
599675 if (ie ) intr_enable (rhport );
@@ -673,7 +749,7 @@ void dcd_int_handler(uint8_t rhport)
673749 U1IR = is ; /* discard any pending events */
674750 }
675751
676- if (is & _U1IR_URSTIF_DETACHIF_MASK ) {
752+ if (is & _U1IR_URSTIF_MASK ) {
677753 U1IR = is ; /* discard any pending events */
678754 process_bus_reset (rhport );
679755 }
@@ -705,7 +781,6 @@ void dcd_int_handler(uint8_t rhport)
705781 }
706782
707783 intr_clear (rhport );
708-
709784}
710785
711786#endif
0 commit comments