lm4f: Add functions for controlling USB interrupts
Add functions to enable and disable USB interrupts, and document how to use these functions to run usbd_poll() from the usb ISR. Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
parent
ad048f7d5a
commit
9d46103ced
@ -382,6 +382,41 @@
|
||||
/** Controller type */
|
||||
#define USB_PP_TYPE_MASK (0x0F << 0)
|
||||
|
||||
/* =============================================================================
|
||||
* Convenience enums
|
||||
* ---------------------------------------------------------------------------*/
|
||||
enum usb_interrupt {
|
||||
USB_INT_DISCON = USB_IM_DISCON,
|
||||
USB_INT_SOF = USB_IM_SOF,
|
||||
USB_INT_RESET = USB_IM_RESET,
|
||||
USB_INT_RESUME = USB_IM_RESUME,
|
||||
USB_INT_SUSPEND = USB_IM_SUSPEND,
|
||||
};
|
||||
|
||||
enum usb_ep_interrupt {
|
||||
USB_EP0_INT = USB_EP0,
|
||||
USB_EP1_INT = USB_EP1,
|
||||
USB_EP2_INT = USB_EP2,
|
||||
USB_EP3_INT = USB_EP3,
|
||||
USB_EP4_INT = USB_EP4,
|
||||
USB_EP5_INT = USB_EP5,
|
||||
USB_EP6_INT = USB_EP6,
|
||||
USB_EP7_INT = USB_EP7,
|
||||
};
|
||||
/* =============================================================================
|
||||
* Function prototypes
|
||||
* ---------------------------------------------------------------------------*/
|
||||
BEGIN_DECLS
|
||||
|
||||
void usb_enable_interrupts(enum usb_interrupt ints,
|
||||
enum usb_ep_interrupt rx_ints,
|
||||
enum usb_ep_interrupt tx_ints);
|
||||
void usb_disable_interrupts(enum usb_interrupt ints,
|
||||
enum usb_ep_interrupt rx_ints,
|
||||
enum usb_ep_interrupt tx_ints);
|
||||
|
||||
END_DECLS
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* LIBOPENCM3_LM4F_USB_H */
|
@ -40,6 +40,47 @@
|
||||
* usbd_dev = usbd_init(&lm4f_usb_driver, ...);
|
||||
* @endcode
|
||||
*
|
||||
* <b>Polling or interrupt-driven? </b>
|
||||
*
|
||||
* The LM4F USB driver will work fine regardless of whether it is called from an
|
||||
* interrupt service routine, or from the main program loop.
|
||||
*
|
||||
* Polling USB from the main loop requires calling @ref usbd_poll() from the
|
||||
* main program loop.
|
||||
* For example:
|
||||
* @code{.c}
|
||||
* // Main program loop
|
||||
* while(1) {
|
||||
* usbd_poll(usb_dev);
|
||||
* do_other_stuff();
|
||||
* ...
|
||||
* @endcode
|
||||
*
|
||||
* Running @ref usbd_poll() from an interrupt has the advantage that it is only
|
||||
* called when needed, saving CPU cycles for the main program.
|
||||
*
|
||||
* RESET, DISCON, RESUME, and SUSPEND interrupts must be enabled, along with the
|
||||
* interrupts for any endpoint that is used. The EP0_TX interrupt must be
|
||||
* enabled for the control endpoint to function correctly.
|
||||
* For example, if EP1IN and EP2OUT are used, then the EP0_TX, EP1_TX, and
|
||||
* EP2_RX interrupts should be enabled:
|
||||
* @code{.c}
|
||||
* // Enable USB interrupts for EP0, EP1IN, and EP2OUT
|
||||
* ints = USB_INT_RESET | USB_INT_DISCON | USB_INT_RESUME |
|
||||
* USB_INT_SUSPEND;
|
||||
* usb_enable_interrupts(ints, USB_EP2_INT, USB_EP0_INT | USB_EP1_INT);
|
||||
* // Route the interrupts through the NVIC
|
||||
* nvic_enable_irq(NVIC_USB0_IRQ);
|
||||
* @endcode
|
||||
*
|
||||
* The USB ISR only has to call @ref usbd_poll().
|
||||
*
|
||||
* @code{.c}
|
||||
* void usb0_isr(void)
|
||||
* {
|
||||
* usbd_poll(usb_dev);
|
||||
* }
|
||||
* @endcode
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -70,6 +111,58 @@
|
||||
|
||||
const struct _usbd_driver lm4f_usb_driver;
|
||||
|
||||
/**
|
||||
* \brief Enable Specific USB Interrupts
|
||||
*
|
||||
* Enable any combination of interrupts. Interrupts may be OR'ed together to
|
||||
* enable them with one call. For example, to enable both the RESUME and RESET
|
||||
* interrupts, pass (USB_INT_RESUME | USB_INT_RESET)
|
||||
*
|
||||
* Note that the NVIC must be enabled and properly configured for the interrupt
|
||||
* to be routed to the CPU.
|
||||
*
|
||||
* @param[in] ints Interrupts which to enable. Any combination of interrupts may
|
||||
* be specified by OR'ing then together
|
||||
* @param[in] rx_ints Endpoints for which to generate an interrupt when a packet
|
||||
* packet is received.
|
||||
* @param[in] tx_ints Endpoints for which to generate an interrupt when a packet
|
||||
* packet is finished transmitting.
|
||||
*/
|
||||
void usb_enable_interrupts(enum usb_interrupt ints,
|
||||
enum usb_ep_interrupt rx_ints,
|
||||
enum usb_ep_interrupt tx_ints)
|
||||
{
|
||||
USB_IE |= ints;
|
||||
USB_RXIE |= rx_ints;
|
||||
USB_TXIE |= tx_ints;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable Specific USB Interrupts
|
||||
*
|
||||
* Disable any combination of interrupts. Interrupts may be OR'ed together to
|
||||
* enable them with one call. For example, to disable both the RESUME and RESET
|
||||
* interrupts, pass (USB_INT_RESUME | USB_INT_RESET)
|
||||
*
|
||||
* Note that the NVIC must be enabled and properly configured for the interrupt
|
||||
* to be routed to the CPU.
|
||||
*
|
||||
* @param[in] ints Interrupts which to disable. Any combination of interrupts
|
||||
* may be specified by OR'ing then together
|
||||
* @param[in] rx_ints Endpoints for which to stop generating an interrupt when a
|
||||
* packet packet is received.
|
||||
* @param[in] tx_ints Endpoints for which to stop generating an interrupt when a
|
||||
* packet packet is finished transmitting.
|
||||
*/
|
||||
void usb_disable_interrupts(enum usb_interrupt ints,
|
||||
enum usb_ep_interrupt rx_ints,
|
||||
enum usb_ep_interrupt tx_ints)
|
||||
{
|
||||
USB_IE &= ~ints;
|
||||
USB_RXIE &= ~rx_ints;
|
||||
USB_TXIE &= ~tx_ints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @cond private
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user