🔌 hal::usb
USB 2.0 Full Speed - Device/Host/OTG Controller
~420 satır
~25 function
STM32F4/F7/H7
📖 Overview
USB modülü, USB 2.0 Full Speed (12 Mbps) iletişimi sağlar. CDC (Virtual COM), HID (Keyboard/Mouse), MSC (Mass Storage) device classları ile PC bağlantısı kurar. Host mode ile USB flash disk, keyboard okuma structlabilir. IoT data logging, debug console, firmware update ve user interface for kritiktir.
🔑 Key Features
- USB 2.0 Full Speed: 12 Mbps (Low Speed 1.5 Mbps de desteklenir)
- Device Mode: PC'ye bağlanarak virtual device olur
- Host Mode: USB periferalleri bağlanabilir (flash, keyboard)
- OTG Support: Device ve Host modları arasında dinamik geçiş
- Device Classes: CDC, HID, MSC, Audio, Custom
- DMA Support: High-speed data transfer
- VBUS Detection: USB cable takılma algılama
- Self/Bus Powered: Güç yönetimi esnekliği
🚀 Quick Start
import hal::usb, hal::gpio
// USB pins: PA11 (D-), PA12 (D+)
gpio.pin_init(gpio.PORT_A, 11, do
mode: gpio.MODE_AF,
af: gpio.AF10_USB
end)
gpio.pin_init(gpio.PORT_A, 12, do
mode: gpio.MODE_AF,
af: gpio.AF10_USB
end)
// Initialize USB CDC (Virtual COM Port)
usb.init_cdc(do
vid: 0x0483, // ST Microelectronics VID
pid: 0x5740, // CDC PID
manufacturer: "BERK Embedded",
product: "Virtual COM Port"
end)
// Connect to PC
usb.connect()
// Wait for enumeration
loop do
if usb.is_configured() do
break
end
end
io.yazdir_satır("USB connected!")
// Send data to PC
usb.cdc_write("Hello from BERK!\r\n")
📦 Types and Enums'lar
// USB Mode
enum Mode {
DEVICE, // Device mode (slave)
HOST, // Host mode (master)
OTG // On-The-Go (dynamic)
}
// Device Classes
enum DeviceClass {
CDC, // Communication Device Class (Virtual COM)
HID, // Human Interface Device (Keyboard/Mouse)
MSC, // Mass Storage Class (USB Disk)
AUDIO, // Audio Class
CUSTOM // Custom class
}
// USB Speed
enum Speed {
LOW_SPEED, // 1.5 Mbps
FULL_SPEED, // 12 Mbps
HIGH_SPEED // 480 Mbps (USB 2.0 HS only)
}
// Power Mode
enum PowerMode {
SELF_POWERED, // External power supply
BUS_POWERED // Powered from USB cable (max 500 mA)
}
struct USBConfig do
mode: Mode = DEVICE,
device_class: DeviceClass = CDC,
speed: Speed = FULL_SPEED,
power_mode: PowerMode = BUS_POWERED,
max_power_ma: int = 100,
vid: int16 = 0x0483,
pid: int16 = 0x5740
end
💡 Example 1: USB CDC Virtual COM Port (Debug Console)
Problem: PC ile seri haberleşme for UART yerine USB kullanmak
import hal::usb
let usb_rx_buffer: Array<int8> = Array.yeni(256)
let usb_rx_index: int = 0
function usb_console_init() do
usb.init_cdc(do
vid: 0x0483,
pid: 0x5740,
manufacturer: "BERK",
product: "Debug Console",
serial_number: "BERK-001"
end)
// Set receive callback
usb.cdc_set_rx_callback(usb_console_rx_handler)
usb.connect()
// Wait for enumeration
loop do
if usb.is_configured() do
break
end
delay_ms(100)
end
usb.cdc_write("\r\n=== BERK Embedded Debug Console ===\r\n")
usb.cdc_write("Type 'help' for commands\r\n> ")
end
function usb_console_rx_handler(data: Array<int8>) do
for byte forde data do
if byte == 13 do // Enter key
// Process command
usb.cdc_write("\r\n")
let cmd = String.from_bytes(usb_rx_buffer, usb_rx_index)
usb_console_process_command(cmd)
usb_rx_index = 0
usb.cdc_write("> ")
else if byte == 8 veya byte == 127 do // Backspace
if usb_rx_index > 0 do
usb_rx_index = usb_rx_index - 1
usb.cdc_write("\b \b") // Erase character
end
else do
if usb_rx_index < 256 do
usb_rx_buffer[usb_rx_index] = byte
usb_rx_index = usb_rx_index + 1
usb.cdc_write_byte(byte) // Echo
end
end
end
end
function usb_console_process_command(cmd: String) do
match cmd do
"help" => do
usb.cdc_write("Commands:\r\n")
usb.cdc_write(" help - Show this help\r\n")
usb.cdc_write(" status - System status\r\n")
usb.cdc_write(" reset - Reset system\r\n")
end,
"status" => do
usb.cdc_write("CPU: STM32F407\r\n")
usb.cdc_write("Clock: 168 MHz\r\n")
usb.cdc_write("Uptime: " + systick.get_ms().metne() + " ms\r\n")
end,
"reset" => do
usb.cdc_write("Resetting...\r\n")
delay_ms(100)
nvic.system_reset()
end,
_ => do
usb.cdc_write("Unknown command: " + cmd + "\r\n")
end
end
end
Kullanım: PC'de PuTTY/TeraTerm ile /dev/ttyACM0 veya COM3 açın. 115200 baud ayarı gereksiz (USB CDC).
💡 Example 2: USB HID Keyboard Emulation
Problem: MCU'yu USB klavye gibi göstermek (otomatik yazma)
import hal::usb
function usb_keyboard_init() do
usb.init_hid(do
vid: 0x0483,
pid: 0x5750,
manufacturer: "BERK",
product: "USB Keyboard",
hid_type: usb.HID_KEYBOARD
end)
usb.connect()
// Wait for enumeration
loop do
if usb.is_configured() do
break
end
delay_ms(100)
end
end
function keyboard_press(key: int8) do
// HID keyboard report: [modifier, reserved, key1-6]
let report: Array<int8> = [0, 0, key, 0, 0, 0, 0, 0]
// Send key press
usb.hid_send_report(report)
delay_ms(50)
// Send key release
report[2] = 0
usb.hid_send_report(report)
delay_ms(50)
end
function keyboard_type_string(text: String) do
for karakter forde text do
// Convert ASCII to HID keycode
let keycode = ascii_to_hid_keycode(karakter)
keyboard_press(keycode)
end
end
function ana() do
usb_keyboard_init()
io.yazdir_satır("USB Keyboard ready")
// Wait for button press
loop do
if button_pressed() do
// Type "Hello World!" on host PC
keyboard_type_string("Hello World!")
keyboard_press(0x28) // Enter key
delay_ms(1000)
end
end
end
Result: PC'ye takıldığında gerçek klavye gibi algılanır. Otomatik yazma, macro sistemi.
💡 Example 3: USB MSC - Mass Storage (USB Disk Emulation)
Problem: SD card'ı USB flash disk gibi göstermek
import hal::usb, hal::sdio
function usb_msc_init() do
// Initialize SD card
sdio.init()
// Get SD card info
let sd_info = sdio.get_card_info()
io.yazdir_satır("SD Card: " + (sd_info.capacity / 1024 / 1024).metne() + " MB")
// Initialize USB MSC
usb.init_msc(do
vid: 0x0483,
pid: 0x5720,
product: "BERK USB Disk",
block_count: sd_info.block_count,
block_size: sd_info.block_size,
read_callback: msc_read_block,
write_callback: msc_write_block
end)
usb.connect()
io.yazdir_satır("USB Mass Storage ready")
end
function msc_read_block(block_num: int, buffer: Array<int8>) -> bool do
// Read block from SD card
return sdio.read_blocks(block_num, 1, buffer)
end
function msc_write_block(block_num: int, data: Array<int8>) -> bool do
// Write block to SD card
return sdio.write_blocks(block_num, 1, data)
end
function ana() do
usb_msc_init()
loop do
// Handle USB events
usb.poll()
// LED blink when active
if usb.is_active() do
led_toggle()
end
delay_ms(100)
end
end
Kullanım: PC'ye takıldığında USB flash disk gibi görünür. Dosya kopyalama çalışır.
📚 API Reference
Core Functions
// USB Initialization
function init_cdc(config: CDCConfig)
function init_hid(config: HIDConfig)
function init_msc(config: MSCConfig)
// Connection
function connect()
function disconnect()
function is_configured() -> bool
// CDC Functions
function cdc_write(data: String)
function cdc_write_bytes(data: Array<int8>)
function cdc_read() -> Array<int8>
function cdc_set_rx_callback(callback: function(Array<int8>))
// HID Functions
function hid_send_report(report: Array<int8>)
function hid_get_report() -> Array<int8>
// Status
function get_state() -> USBState
function is_active() -> bool
function poll() // Process USB events
⚠️ Important Notes:
- 48 MHz Clock: USB for tam 48 MHz clock gerekli (tolerance ±0.25%)
- VID/PID: Production'da kendi VID/PID'nizi alın (USB-IF'den)
- Enumeration Time: PC tanıma süresi 1-3 saniye sürebilir
- Interrupt Priority: USB interrupt yüksek öncelikli olmalı
🖥️ Platform Support
| Platform | USB Support | Speed | Endpoints |
|---|---|---|---|
| STM32F1 | ✅ FS | 12 Mbps | 8 EP |
| STM32F4 | ✅ FS/HS | 12/480 Mbps | 6 EP (FS), 8 EP (HS) |
| STM32F7 | ✅ FS/HS | 12/480 Mbps | 6 EP (FS), 8 EP (HS) |
| STM32H7 | ✅ FS/HS | 12/480 Mbps | 9 EP |
✅ Best Practices
- ✅ CDC for debug: UART yerine USB CDC kullan (kablo gereksinimi aynı)
- ✅ HID for UI: Basit kontrol for HID keyboard/mouse kullan
- ✅ MSC for data: Log dosyaları for MSC kullan (FAT32)
- ✅ Disconnect before reset: Reset öncesi usb.disconnect() çağır
- ❌ Float operations: USB interrupt'ta floating-point kullanma
- ❌ Long callbacks: USB callback'leri kısa tutun (<1 ms)
🔗 Related Modules
- hal::clock - 48 MHz USB clock configuration
- hal::gpio - USB D+/D- pin setup
- hal::sdio - SD card for USB MSC backend
- hal::dma - DMA for high-speed USB transfers