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 */
|
/** Controller type */
|
||||||
#define USB_PP_TYPE_MASK (0x0F << 0)
|
#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 */
|
#endif /* LIBOPENCM3_LM4F_USB_H */
|
@ -40,6 +40,47 @@
|
|||||||
* usbd_dev = usbd_init(&lm4f_usb_driver, ...);
|
* usbd_dev = usbd_init(&lm4f_usb_driver, ...);
|
||||||
* @endcode
|
* @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;
|
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
|
* @cond private
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user