@@ -107,6 +107,13 @@ static int udc_ambiq_tx(const struct device *dev, uint8_t ep, struct net_buf *bu
107
107
if (buf == NULL ) {
108
108
status = am_hal_usb_ep_xfer (priv -> usb_handle , ep , NULL , 0 );
109
109
} else {
110
+ #if defined(CONFIG_UDC_AMBIQ_HANDLE_CACHE )
111
+ /* Cache management if cache and DMA is enabled */
112
+ if ((ep != USB_CONTROL_EP_OUT ) &&
113
+ !buf_in_nocache ((uintptr_t )buf -> data , buf -> size )) {
114
+ sys_cache_data_flush_range (buf -> data , buf -> size );
115
+ }
116
+ #endif
110
117
status = am_hal_usb_ep_xfer (priv -> usb_handle , ep , buf -> data , buf -> len );
111
118
}
112
119
@@ -123,7 +130,6 @@ static int udc_ambiq_rx(const struct device *dev, uint8_t ep, struct net_buf *bu
123
130
{
124
131
struct udc_ambiq_data * priv = udc_get_private (dev );
125
132
struct udc_ep_config * ep_cfg = udc_get_ep_cfg (dev , ep );
126
- struct udc_ep_config * cfg = udc_get_ep_cfg (dev , USB_CONTROL_EP_OUT );
127
133
uint32_t status ;
128
134
uint16_t rx_size = buf -> size ;
129
135
@@ -133,10 +139,24 @@ static int udc_ambiq_rx(const struct device *dev, uint8_t ep, struct net_buf *bu
133
139
}
134
140
udc_ep_set_busy (ep_cfg , true);
135
141
136
- /* Make sure that OUT transaction size triggered doesn't exceed EP's MPS */
137
- if ((ep != USB_CONTROL_EP_OUT ) && (cfg -> mps < rx_size )) {
138
- rx_size = cfg -> mps ;
142
+ #ifndef CONFIG_UDC_AMBIQ_DMA1_MODE
143
+ /*
144
+ * Make sure that OUT transaction size triggered doesn't exceed EP's MPS,
145
+ * as the USB IP has no way to detect end on transaction when last packet
146
+ * is not a short packet. Except for UDC_AMBIQ_DMA1_MODE, where such
147
+ * detection is available.
148
+ */
149
+ if ((ep != USB_CONTROL_EP_OUT ) && (ep_cfg -> mps < rx_size )) {
150
+ rx_size = ep_cfg -> mps ;
151
+ }
152
+ #endif
153
+
154
+ #if CONFIG_UDC_AMBIQ_HANDLE_CACHE
155
+ /* Cache management if cache and DMA is enabled */
156
+ if ((ep != USB_CONTROL_EP_OUT ) && !buf_in_nocache ((uintptr_t )buf -> data , buf -> size )) {
157
+ sys_cache_data_invd_range (buf -> data , buf -> size );
139
158
}
159
+ #endif
140
160
141
161
status = am_hal_usb_ep_xfer (priv -> usb_handle , ep , buf -> data , rx_size );
142
162
if (status != AM_HAL_STATUS_SUCCESS ) {
@@ -212,7 +232,7 @@ static void udc_ambiq_ep0_setup_callback(const struct device *dev, uint8_t *usb_
212
232
}
213
233
214
234
static void udc_ambiq_ep_xfer_complete_callback (const struct device * dev , uint8_t ep_addr ,
215
- uint16_t xfer_len , am_hal_usb_xfer_code_e code ,
235
+ uint32_t xfer_len , am_hal_usb_xfer_code_e code ,
216
236
void * param )
217
237
{
218
238
struct net_buf * buf ;
@@ -470,14 +490,18 @@ static int udc_ambiq_disable(const struct device *dev)
470
490
return 0 ;
471
491
}
472
492
493
+ #define DEFINE_ISR_PARAM_DEF (x , _ ) CONCAT(uint32_t int_status, x)
494
+ #define DEFINE_ISR_PARAM_PTR (x , _ ) CONCAT(&int_status, x)
495
+ #define DEFINE_ISR_PARAM (x , _ ) CONCAT(int_status, x)
496
+
473
497
static void udc_ambiq_usb_isr (const struct device * dev )
474
498
{
475
499
struct udc_ambiq_data * priv = udc_get_private (dev );
476
- uint32_t int_status [ 3 ] ;
477
-
478
- am_hal_usb_intr_status_get ( priv -> usb_handle , & int_status [ 0 ], & int_status [ 1 ],
479
- & int_status [ 2 ]);
480
- am_hal_usb_interrupt_service ( priv -> usb_handle , int_status [ 0 ], int_status [ 1 ], int_status [ 2 ] );
500
+ LISTIFY ( CONFIG_UDC_AMBIQ_ISR_PARAM_COUNT , DEFINE_ISR_PARAM_DEF , (;)) ;
501
+ am_hal_usb_intr_status_get ( priv -> usb_handle , LISTIFY ( CONFIG_UDC_AMBIQ_ISR_PARAM_COUNT ,
502
+ DEFINE_ISR_PARAM_PTR , (,)));
503
+ am_hal_usb_interrupt_service (
504
+ priv -> usb_handle , LISTIFY ( CONFIG_UDC_AMBIQ_ISR_PARAM_COUNT , DEFINE_ISR_PARAM , (,)) );
481
505
}
482
506
483
507
static int usb_power_rails_set (const struct device * dev , bool on )
@@ -516,11 +540,54 @@ static int usb_power_rails_set(const struct device *dev, bool on)
516
540
return 0 ;
517
541
}
518
542
543
+ #if CONFIG_SOC_SERIES_APOLLO5X
544
+ static int init_apollo5x (const struct udc_ambiq_data * priv )
545
+ {
546
+ uint32_t am_ret = AM_HAL_STATUS_SUCCESS ;
547
+ am_hal_clkmgr_board_info_t board ;
548
+ am_hal_usb_phyclksrc_e phyclksrc ;
549
+
550
+ /* Decide PHY clock source according to USB speed and board configuration*/
551
+ am_hal_clkmgr_board_info_get (& board );
552
+ if (priv -> usb_speed == AM_HAL_USB_SPEED_FULL ) {
553
+ phyclksrc = AM_HAL_USB_PHYCLKSRC_HFRC_24M ;
554
+ } else if (board .sXtalHs .ui32XtalHsFreq == 48000000 ) {
555
+ phyclksrc = AM_HAL_USB_PHYCLKSRC_XTAL_HS_DIV2 ;
556
+ } else if (board .sXtalHs .ui32XtalHsFreq == 24000000 ) {
557
+ phyclksrc = AM_HAL_USB_PHYCLKSRC_XTAL_HS ;
558
+ } else if (board .ui32ExtRefClkFreq == 48000000 ) {
559
+ phyclksrc = AM_HAL_USB_PHYCLKSRC_EXTREFCLK ;
560
+ } else if (board .ui32ExtRefClkFreq == 24000000 ) {
561
+ phyclksrc = AM_HAL_USB_PHYCLKSRC_EXTREFCLK_DIV2 ;
562
+ } else {
563
+ phyclksrc = AM_HAL_USB_PHYCLKSRC_PLL ;
564
+ }
565
+
566
+ if (phyclksrc == AM_HAL_USB_PHYCLKSRC_PLL ) {
567
+ am_ret = am_hal_clkmgr_clock_config (AM_HAL_CLKMGR_CLK_ID_SYSPLL , 24000000 , NULL );
568
+ if (am_ret != AM_HAL_STATUS_SUCCESS ) {
569
+ LOG_WRN ("Unable to configure SYSPLL for USB. Fallback to HFRC clock "
570
+ "source" );
571
+ phyclksrc = AM_HAL_USB_PHYCLKSRC_HFRC_24M ;
572
+ }
573
+ }
574
+
575
+ am_hal_usb_set_phy_clk_source (priv -> usb_handle , phyclksrc );
576
+ am_hal_usb_phy_clock_enable (priv -> usb_handle , true, priv -> usb_speed );
577
+
578
+ return 0 ;
579
+ }
580
+ #endif
581
+
519
582
static int udc_ambiq_init (const struct device * dev )
520
583
{
521
584
struct udc_ambiq_data * priv = udc_get_private (dev );
522
585
const struct udc_ambiq_config * cfg = dev -> config ;
523
586
uint32_t ret = 0 ;
587
+ #if CONFIG_UDC_AMBIQ_DEB_ENABLE
588
+ uint8_t idx ;
589
+ uint32_t mask ;
590
+ #endif
524
591
525
592
/* Create USB */
526
593
if (am_hal_usb_initialize (0 , (void * )& priv -> usb_handle ) != AM_HAL_STATUS_SUCCESS ) {
@@ -542,10 +609,51 @@ static int udc_ambiq_init(const struct device *dev)
542
609
am_hal_usb_hardware_unreset ();
543
610
/* Release USB PHY reset */
544
611
am_hal_usb_disable_phy_reset_override ();
612
+
613
+ #if CONFIG_SOC_SERIES_APOLLO5X
614
+ ret = init_apollo5x (priv );
615
+ if (ret ) {
616
+ return ret ;
617
+ }
618
+ #endif
619
+
620
+ #if CONFIG_UDC_AMBIQ_DEB_ENABLE
621
+ idx = 1 ;
622
+ mask = CONFIG_UDC_AMBIQ_DEB_ENABLE & 0xFFFF ;
623
+ while (mask ) {
624
+ if (mask & 0x1 ) {
625
+ am_hal_usb_enable_ep_double_buffer (priv -> usb_handle , idx ,
626
+ AM_HAL_USB_OUT_DIR , true);
627
+ }
628
+ idx ++ ;
629
+ mask >>= 1 ;
630
+ }
631
+
632
+ idx = 1 ;
633
+ mask = (CONFIG_UDC_AMBIQ_DEB_ENABLE >> 16 ) & 0xFFFF ;
634
+ while (mask ) {
635
+ if (mask & 0x1 ) {
636
+ am_hal_usb_enable_ep_double_buffer (priv -> usb_handle , idx , AM_HAL_USB_IN_DIR ,
637
+ true);
638
+ }
639
+ idx ++ ;
640
+ mask >>= 1 ;
641
+ }
642
+ #endif
643
+
545
644
/* Set USB Speed */
546
645
am_hal_usb_set_dev_speed (priv -> usb_handle , priv -> usb_speed );
547
646
/* Enable USB interrupt */
548
647
am_hal_usb_intr_usb_enable (priv -> usb_handle , USB_INTRUSB_Reset_Msk );
648
+ /* Configure DMA Modes */
649
+ #if CONFIG_UDC_AMBIQ_DMA1_MODE
650
+ am_hal_usb_set_xfer_mode (priv -> usb_handle , AM_HAL_USB_OUT_DMA_MODE_1 );
651
+ am_hal_usb_set_xfer_mode (priv -> usb_handle , AM_HAL_USB_IN_DMA_MODE_1 );
652
+ #elif CONFIG_UDC_AMBIQ_DMA0_MODE
653
+ am_hal_usb_set_xfer_mode (priv -> usb_handle , AM_HAL_USB_OUT_DMA_MODE_0 );
654
+ am_hal_usb_set_xfer_mode (priv -> usb_handle , AM_HAL_USB_IN_DMA_MODE_0 );
655
+ #endif
656
+
549
657
/* Enable Control Endpoints */
550
658
if (udc_ep_enable_internal (dev , USB_CONTROL_EP_OUT , USB_EP_TYPE_CONTROL , EP0_MPS , 0 )) {
551
659
LOG_ERR ("Failed to enable control endpoint" );
@@ -582,6 +690,10 @@ static int udc_ambiq_shutdown(const struct device *dev)
582
690
cfg -> irq_disable_func (dev );
583
691
/* Assert USB PHY reset */
584
692
am_hal_usb_enable_phy_reset_override ();
693
+ #if CONFIG_SOC_SERIES_APOLLO5X
694
+ /* Release USB PHY Clock*/
695
+ am_hal_usb_phy_clock_enable (priv -> usb_handle , false, priv -> usb_speed );
696
+ #endif
585
697
/* Disable the USB power rails */
586
698
ret = usb_power_rails_set (dev , false);
587
699
if (ret ) {
@@ -911,7 +1023,7 @@ static const struct udc_api udc_ambiq_api = {
911
1023
} \
912
1024
\
913
1025
static void udc_ambiq_ep_xfer_complete_callback_##n( \
914
- uint8_t ep_addr, uint16_t xfer_len, am_hal_usb_xfer_code_e code, void *param) \
1026
+ uint8_t ep_addr, uint32_t xfer_len, am_hal_usb_xfer_code_e code, void *param) \
915
1027
{ \
916
1028
udc_ambiq_ep_xfer_complete_callback(DEVICE_DT_INST_GET(n), ep_addr, xfer_len, \
917
1029
code, param); \
@@ -926,7 +1038,8 @@ static const struct udc_api udc_ambiq_api = {
926
1038
am_hal_usb_register_ep0_setup_received_callback(priv->usb_handle, \
927
1039
udc_ambiq_ep0_setup_callback_##n); \
928
1040
am_hal_usb_register_ep_xfer_complete_callback( \
929
- priv->usb_handle, udc_ambiq_ep_xfer_complete_callback_##n); \
1041
+ priv->usb_handle, (am_hal_usb_ep_xfer_complete_callback) \
1042
+ udc_ambiq_ep_xfer_complete_callback_##n); \
930
1043
} \
931
1044
static void udc_ambiq_thread_##n(void *dev, void *arg1, void *arg2) \
932
1045
{ \
0 commit comments