Skip to content

Conversation

@nandojve
Copy link
Member

@nandojve nandojve commented Jan 9, 2026

Summary

Add USB Device Controller (UDC) driver for SAM4S/E UDP peripheral, enabling USB device_next stack support for these MCUs.

  • New UDC driver: drivers/usb/udc/udc_sam_udp.c
  • UDP supports only Full-Speed (12 Mbps)
  • PIO-based transfers

Test Plan

  • CDC ACM sample tested on sam4s_xplained
  • Enumeration works on FS modes
  • usbtest validation passed on sam4s_xplained and sam4e_xpro
  • Data transfer bidirectional working

Add support for driver-specific endpoint configuration validation by
calling the driver's ep_try_config callback in udc_ep_try_config().

This allows drivers to apply additional restrictions beyond the basic
checks, such as:
- Reserving high-capacity endpoints for isochronous transfers
- Enforcing hardware-specific endpoint allocation rules
- Validating endpoint configurations against hardware limitations

The callback is invoked after the basic capability check passes,
with the endpoint configuration temporarily filled with the
requested values. The original configuration is restored after the
callback returns.

Signed-off-by: Gerson Fernando Budke <[email protected]>
Add devicetree nodes for the UDP peripheral on SAM4S and SAM4E SoCs,
along with the corresponding devicetree binding.

The UDP controller is present at:
- SAM4S: 0x40034000, IRQ 34
- SAM4E: 0x40084000, IRQ 35

Both variants share the same compatible "atmel,sam-udp" and feature:
- 8 hardware endpoints (EP0-EP7)
- 1 bidirectional endpoint (EP0 for control)
- 5 IN endpoints, 4 OUT endpoints
- Full-speed USB 2.0 (12 Mbps)

Signed-off-by: Gerson Fernando Budke <[email protected]>
Add a new USB Device Controller (UDC) driver for Atmel SAM4S, SAM4E,
and SAM3S microcontrollers with the UDP (USB Device Port) peripheral.
This driver replaces the deprecated legacy USB stack before removal.

Hardware Specifications:
- USB 2.0 Full-Speed only (12 Mbps)
- 8 hardware endpoints (EP0-EP7)
- 2668 bytes embedded DPRAM/FIFO
- No DMA - all transfers via PIO
- Integrated transceiver with pull-up on DDP
- Dual-bank (ping-pong) support on EP1,2,4,5,6,7

Endpoint Configuration (per datasheet Table 40-1):
- EP0: Control, no dual-bank, 64 bytes
- EP1,2: Bulk/Iso/Int, dual-bank, 64 bytes each bank
- EP3: Bulk/Int, no dual-bank, 64 bytes
- EP4,5: Bulk/Iso/Int, dual-bank, 512 bytes each bank
- EP6,7: Bulk/Iso/Int, dual-bank, 64 bytes each bank

Key Implementation Details:

1. Dual-Bank Pipelining (IN transfers):
- Track filled banks with tx_banks counter (0-2)
- Set TXPKTRDY after each bank fill per datasheet 40.6.2.2
- Pre-fill second bank while first is transmitting

2. OUT Processing:
- Bulk/Int/Iso endpoints processed directly in ISR
- EP0 uses thread-based processing for control transfer flexibility
- Bank alternation tracking for dual-bank endpoints

3. Clock Management:
- PLLB configured for 48MHz USB clock (UDPCK)
- Proper suspend/resume with clock gating
- Transceiver disable during disconnect for power saving

4. CSR Register Handling:
- Special "write 1 to preserve" bits handled correctly
- Polling after set/clear for MCK/UDPCK synchronization
- RX_DATA_BK0, RX_DATA_BK1, RXSETUP, STALLSENT, TXCOMP preserved

5. Endpoint Allocation Strategy:
- EP4/EP5 (512-byte) reserved for isochronous via ep_try_config
- Odd endpoints (1,3,5,7) for IN, even (2,4,6) for OUT
- EP0 truly bidirectional for control transfers

Performance:
- Achieves ~800-900 KB/s throughput
- Near USB Full-Speed theoretical maximum (~1.2 MB/s)
- All testusb tests (0-29) passing

Tested on sam4s_xplained board with Linux testusb utility.

Signed-off-by: Gerson Fernando Budke <[email protected]>
Add Atmel USB UDP configurations:
 - pinctrl
 - devicetree
 - yaml config

Signed-off-by: Gerson Fernando Budke <[email protected]>
Add CONFIG_SOC_ATMEL_SAM_PRES to allow configuring the Master Clock
(MCK) prescaler. This is needed for SAM4E which requires a prescaler
of 2 to achieve the correct clock frequency.

Changes:
- Add SOC_ATMEL_SAM_PRES Kconfig option with default of 2 for SAM4E
  and 1 for other SAM series
- Fix SOC_ATMEL_SAM_PLLA_MULA default for SAM4E from 9 to 19
  to achieve 120MHz: 12MHz * 20 / 2 = 120MHz
- Use CONFIG_SOC_ATMEL_SAM_PRES in SoC init for SAM4E, SAM4S, SAMX7X

Signed-off-by: Gerson Fernando Budke <[email protected]>
SAM4E doesn't have PLLB, so the USB clock must be derived from PLLA
which is shared with the system clock.

Use PMC_MCKR_CSS_PLLB_CLK to detect PLLB availability at compile time:
- SAM4S (has PLLB): Use dedicated PLLB, 96MHz / 2 = 48MHz
- SAM4E (no PLLB): Use PLLA, ~240MHz / 5 = 48MHz

For SAM4E, PLLA is already configured by the SoC init code for the
system clock, so we just verify it's locked and configure the USB
divider. On shutdown, we don't disable PLLA since it's needed for
the system clock.

Signed-off-by: Gerson Fernando Budke <[email protected]>
Add Atmel USB UDP configurations:
 - pinctrl
 - devicetree
 - yaml config

Signed-off-by: Gerson Fernando Budke <[email protected]>
@zephyrbot zephyrbot added platform: Microchip SAM Microchip SAM Platform (formerly Atmel SAM) area: Boards/SoCs area: USB Universal Serial Bus area: Devicetree Binding PR modifies or adds a Device Tree binding labels Jan 9, 2026
@nandojve nandojve added this to the v4.4.0 milestone Jan 9, 2026
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 9, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Boards/SoCs area: Devicetree Binding PR modifies or adds a Device Tree binding area: USB Universal Serial Bus platform: Microchip SAM Microchip SAM Platform (formerly Atmel SAM)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants