🔌 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

🚀 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

🔗 Related Modules

🔙 HAL Modules | 🌐 Turkish