Ejemplo n.º 1
0
EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
    uint8_t bf = 0;
    uint32_t flags = 0;

    //check which buffer must be filled
    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
        // Double buffered
        if (LPC_USB->EPINUSE & EP(endpoint)) {
            bf = 1;
        } else {
            bf = 0;
        }
    }

    // if isochronous endpoint, T = 1
    if(endpointState[endpoint].options & ISOCHRONOUS)
    {
        flags |= CMDSTS_T;
    }

    //Active the endpoint for reading
    ep[PHY_TO_LOG(endpoint)].out[bf] = CMDSTS_A | CMDSTS_NBYTES(maximumSize) \
                                       | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out) | flags;
    return EP_PENDING;
}
Ejemplo n.º 2
0
USBHAL::USBHAL(void) {
    NVIC_DisableIRQ(USB_IRQ);
    
    // fill in callback array
    epCallback[0] = &USBHAL::EP1_OUT_callback;
    epCallback[1] = &USBHAL::EP1_IN_callback;
    epCallback[2] = &USBHAL::EP2_OUT_callback;
    epCallback[3] = &USBHAL::EP2_IN_callback;
    epCallback[4] = &USBHAL::EP3_OUT_callback;
    epCallback[5] = &USBHAL::EP3_IN_callback;
    epCallback[6] = &USBHAL::EP4_OUT_callback;
    epCallback[7] = &USBHAL::EP4_IN_callback;

    // nUSB_CONNECT output
    LPC_IOCON->PIO0_6 = 0x00000001;

    // Enable clocks (USB registers, USB RAM)
    LPC_SYSCON->SYSAHBCLKCTRL |= CLK_USB | CLK_USBRAM;

    // Ensure device disconnected (DCON not set)
    LPC_USB->DEVCMDSTAT = 0;

    // to ensure that the USB host sees the device as
    // disconnected if the target CPU is reset.
    wait(0.3);

    // Reserve space in USB RAM for endpoint command/status list
    // Must be 256 byte aligned
    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 256);
    ep = (EP_COMMAND_STATUS *)usbRamPtr;
    usbRamPtr += (sizeof(EP_COMMAND_STATUS) * NUMBER_OF_LOGICAL_ENDPOINTS);
    LPC_USB->EPLISTSTART = (uint32_t)(ep) & 0xffffff00;

    // Reserve space in USB RAM for Endpoint 0
    // Must be 64 byte aligned
    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 64);
    ct = (CONTROL_TRANSFER *)usbRamPtr;
    usbRamPtr += sizeof(CONTROL_TRANSFER);
    LPC_USB->DATABUFSTART =(uint32_t)(ct) & 0xffc00000;

    // Setup command/status list for EP0
    ep[0].out[0] = 0;
    ep[0].in[0] =  0;
    ep[0].out[1] = CMDSTS_ADDRESS_OFFSET((uint32_t)ct->setup);

    // Route all interrupts to IRQ, some can be routed to
    // USB_FIQ if you wish.
    LPC_USB->INTROUTING = 0;

    // Set device address 0, enable USB device, no remote wakeup
    devCmdStat = DEV_ADDR(0) | DEV_EN | DSUS;
    LPC_USB->DEVCMDSTAT = devCmdStat;

    // Enable interrupts for device events and EP0
    LPC_USB->INTEN = DEV_INT | EP(EP0IN) | EP(EP0OUT) | FRAME_INT;
    instance = this;

    //attach IRQ handler and enable interrupts
    NVIC_SetVector(USB_IRQ, (uint32_t)&_usbisr);
}
Ejemplo n.º 3
0
void USBHAL::EP0read(void) {
    // Start an endpoint 0 read

    // The USB ISR will call USBDevice_EP0out() when a packet has been read,
    // the USBDevice layer then calls USBBusInterface_EP0getReadResult() to
    // read the data.

    ep[0].out[0] = CMDSTS_A |CMDSTS_NBYTES(MAX_PACKET_SIZE_EP0) \
                   | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out);
}
Ejemplo n.º 4
0
void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
    // Start and endpoint 0 write

    // The USB ISR will call USBDevice_EP0in() when the data has
    // been written, the USBDevice layer then calls
    // USBBusInterface_EP0getWriteResult() to complete the transaction.

    // Copy data
    USBMemCopy(ct->in, buffer, size);

    // Start transfer
    ep[0].in[0] = CMDSTS_A | CMDSTS_NBYTES(size) \
                  | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->in);
}
Ejemplo n.º 5
0
EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
    uint32_t flags = 0;
    uint32_t bf;

    // Validate parameters
    if (data == NULL) {
        return EP_INVALID;
    }

    if (endpoint > LAST_PHYSICAL_ENDPOINT) {
        return EP_INVALID;
    }

    if ((endpoint==EP0IN) || (endpoint==EP0OUT)) {
        return EP_INVALID;
    }

    if (size > endpointState[endpoint].maxPacket) {
        return EP_INVALID;
    }

    if (LPC_USB->EPBUFCFG & EP(endpoint)) {
        // Double buffered
        if (LPC_USB->EPINUSE & EP(endpoint)) {
            bf = 1;
        } else {
            bf = 0;
        }
    } else {
        // Single buffered
        bf = 0;
    }

    // Check if already active
    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) {
        return EP_INVALID;
    }

    // Check if stalled
    if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) {
        return EP_STALLED;
    }

    // Copy data to USB RAM
    USBMemCopy((uint8_t *)endpointState[endpoint].buffer[bf], data, size);

    // Add options
    if (endpointState[endpoint].options & RATE_FEEDBACK_MODE) {
        flags |= CMDSTS_RF;
    }

    if (endpointState[endpoint].options & ISOCHRONOUS) {
        flags |= CMDSTS_T;
    }

    // Add transfer
    ep[PHY_TO_LOG(endpoint)].in[bf] = CMDSTS_ADDRESS_OFFSET( \
                                      endpointState[endpoint].buffer[bf]) \
                                      | CMDSTS_NBYTES(size) | CMDSTS_A | flags;

    return EP_PENDING;
}
Ejemplo n.º 6
0
USBHAL::USBHAL(void) {
    NVIC_DisableIRQ(USB_IRQ);

    // fill in callback array
    epCallback[0] = &USBHAL::EP1_OUT_callback;
    epCallback[1] = &USBHAL::EP1_IN_callback;
    epCallback[2] = &USBHAL::EP2_OUT_callback;
    epCallback[3] = &USBHAL::EP2_IN_callback;
    epCallback[4] = &USBHAL::EP3_OUT_callback;
    epCallback[5] = &USBHAL::EP3_IN_callback;
    epCallback[6] = &USBHAL::EP4_OUT_callback;
    epCallback[7] = &USBHAL::EP4_IN_callback;

#if defined(TARGET_LPC1549)
    /* Set USB PLL input to system oscillator */
    LPC_SYSCON->USBPLLCLKSEL = 0x01;

    /* Setup USB PLL  (FCLKIN = 12MHz) * 4 = 48MHz
       MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
       FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
       FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
    LPC_SYSCON->USBPLLCTRL = (0x3 | (1UL << 6));

    /* Powerup USB PLL */  
    LPC_SYSCON->PDRUNCFG &= ~(CLK_USB);

    /* Wait for PLL to lock */
    while(!(LPC_SYSCON->USBPLLSTAT & 0x01));

    /* enable USB main clock */
    LPC_SYSCON->USBCLKSEL = 0x02;
    LPC_SYSCON->USBCLKDIV = 1;

    /* Enable AHB clock to the USB block. */
    LPC_SYSCON->SYSAHBCLKCTRL1 |= CLK_USB;

    /* power UP USB Phy */
    LPC_SYSCON->PDRUNCFG &= ~(1UL << 9);

    /* Reset USB block */
    LPC_SYSCON->PRESETCTRL1 |= (CLK_USB);
    LPC_SYSCON->PRESETCTRL1 &= ~(CLK_USB);

#else
    #if defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501)
    // USB_VBUS input with pull-down
    LPC_IOCON->PIO0_3 = 0x00000009;
    #endif

    // nUSB_CONNECT output
    LPC_IOCON->PIO0_6 = 0x00000001;

    // Enable clocks (USB registers, USB RAM)
    LPC_SYSCON->SYSAHBCLKCTRL |= CLK_USB | CLK_USBRAM;

    // Ensure device disconnected (DCON not set)
    LPC_USB->DEVCMDSTAT = 0;
#endif
    // to ensure that the USB host sees the device as
    // disconnected if the target CPU is reset.
    wait(0.3);

    // Reserve space in USB RAM for endpoint command/status list
    // Must be 256 byte aligned
    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 256);
    ep = (EP_COMMAND_STATUS *)usbRamPtr;
    usbRamPtr += (sizeof(EP_COMMAND_STATUS) * NUMBER_OF_LOGICAL_ENDPOINTS);
    LPC_USB->EPLISTSTART = (uint32_t)(ep) & 0xffffff00;

    // Reserve space in USB RAM for Endpoint 0
    // Must be 64 byte aligned
    usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 64);
    ct = (CONTROL_TRANSFER *)usbRamPtr;
    usbRamPtr += sizeof(CONTROL_TRANSFER);
    LPC_USB->DATABUFSTART =(uint32_t)(ct) & 0xffc00000;

    // Setup command/status list for EP0
    ep[0].out[0] = 0;
    ep[0].in[0] =  0;
    ep[0].out[1] = CMDSTS_ADDRESS_OFFSET((uint32_t)ct->setup);

    // Route all interrupts to IRQ, some can be routed to
    // USB_FIQ if you wish.
    LPC_USB->INTROUTING = 0;

    // Set device address 0, enable USB device, no remote wakeup
    devCmdStat = DEV_ADDR(0) | DEV_EN | DSUS;
    LPC_USB->DEVCMDSTAT = devCmdStat;

    // Enable interrupts for device events and EP0
    LPC_USB->INTEN = DEV_INT | EP(EP0IN) | EP(EP0OUT) | FRAME_INT;
    instance = this;

    //attach IRQ handler and enable interrupts
    NVIC_SetVector(USB_IRQ, (uint32_t)&_usbisr);
}