@@ -238,7 +238,13 @@ typedef struct {
238238 uint8_t hxfr ;
239239 }sndfifo_owner ;
240240
241+ #if CFG_TUSB_MCU == OPT_MCU_RP2040
242+ // currently has undefined reference to `__atomic_test_and_set' with rp2040 on Arduino with gcc 14.2
243+ // temporarily use native semaphore instead. TODO rework osal semaphore/mutex later on
244+ semaphore_t busy ; // busy transferring
245+ #else
241246 atomic_flag busy ; // busy transferring
247+ #endif
242248
243249#if OSAL_MUTEX_REQUIRED
244250 OSAL_MUTEX_DEF (spi_mutexdef );
@@ -257,6 +263,25 @@ static tuh_configure_max3421_t _tuh_cfg = {
257263 .pinctl = 0 , // default: negative edge interrupt
258264};
259265
266+ #if CFG_TUSB_MCU == OPT_MCU_RP2040
267+ TU_ATTR_ALWAYS_INLINE static inline bool usb_xfer_test_and_set (void ) {
268+ return !sem_try_acquire (& _hcd_data .busy );
269+ }
270+
271+ TU_ATTR_ALWAYS_INLINE static inline void usb_xfer_clear (void ) {
272+ sem_release (& _hcd_data .busy );
273+ }
274+
275+ #else
276+ TU_ATTR_ALWAYS_INLINE static inline bool usb_xfer_test_and_set (void ) {
277+ return atomic_flag_test_and_set (& _hcd_data .busy );
278+ }
279+
280+ TU_ATTR_ALWAYS_INLINE static inline void usb_xfer_clear (void ) {
281+ atomic_flag_clear (& _hcd_data .busy );
282+ }
283+ #endif
284+
260285//--------------------------------------------------------------------+
261286// API: SPI transfer with MAX3421E
262287// - spi_cs_api(), spi_xfer_api(), int_api(): must be implemented by application
@@ -511,6 +536,10 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
511536 tu_memclr (& _hcd_data , sizeof (_hcd_data ));
512537 _hcd_data .peraddr = 0xff ; // invalid
513538
539+ #if CFG_TUSB_MCU == OPT_MCU_RP2040
540+ sem_init (& _hcd_data .busy , 1 , 1 );
541+ #endif
542+
514543#if OSAL_MUTEX_REQUIRED
515544 _hcd_data .spi_mutex = osal_mutex_create (& _hcd_data .spi_mutexdef );
516545#endif
@@ -568,6 +597,10 @@ bool hcd_deinit(uint8_t rhport) {
568597 _hcd_data .spi_mutex = NULL ;
569598 #endif
570599
600+ #if CFG_TUSB_MCU == OPT_MCU_RP2040
601+ sem_reset (& _hcd_data .busy , 1 );
602+ #endif
603+
571604 return true;
572605}
573606
@@ -754,7 +787,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf
754787 ep -> state = EP_STATE_ATTEMPT_1 ;
755788
756789 // carry out transfer if not busy
757- if (!atomic_flag_test_and_set ( & _hcd_data . busy )) {
790+ if (!usb_xfer_test_and_set ( )) {
758791 xact_generic (rhport , ep , true, false);
759792 }
760793
@@ -791,7 +824,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]
791824 ep -> state = EP_STATE_ATTEMPT_1 ;
792825
793826 // carry out transfer if not busy
794- if (!atomic_flag_test_and_set ( & _hcd_data . busy )) {
827+ if (!usb_xfer_test_and_set ( )) {
795828 xact_setup (rhport , ep , false);
796829 }
797830
@@ -876,7 +909,7 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re
876909 xact_generic (rhport , next_ep , true, in_isr );
877910 }else {
878911 // no more pending
879- atomic_flag_clear ( & _hcd_data . busy );
912+ usb_xfer_clear ( );
880913 }
881914}
882915
@@ -915,7 +948,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
915948 xact_generic (rhport , next_ep , true, in_isr );
916949 } else {
917950 // no more pending in this frame -> clear busy
918- atomic_flag_clear ( & _hcd_data . busy );
951+ usb_xfer_clear ( );
919952 }
920953 return ;
921954
@@ -1026,7 +1059,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
10261059 }
10271060
10281061 // start usb transfer if not busy
1029- if (ep_retry != NULL && !atomic_flag_test_and_set ( & _hcd_data . busy )) {
1062+ if (ep_retry != NULL && !usb_xfer_test_and_set ( )) {
10301063 xact_generic (rhport , ep_retry , true, in_isr );
10311064 }
10321065 }
0 commit comments