mirror of
https://github.com/sakumisu/CherryUSB.git
synced 2025-05-08 16:18:44 +08:00
add timer to control interrupt transfer
This commit is contained in:
parent
869b5809f3
commit
2660af5d87
@ -304,11 +304,21 @@ static void hub_int_complete_callback(void *arg, int nbytes)
|
||||
if (nbytes > 0) {
|
||||
usbh_hub_thread_wakeup(hub);
|
||||
} else if (nbytes == -USB_ERR_NAK) {
|
||||
usbh_submit_urb(&hub->intin_urb);
|
||||
/* Restart timer to submit urb again */
|
||||
USB_LOG_DBG("Restart timer\r\n");
|
||||
usb_osal_timer_start(hub->int_timer);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
static void hub_int_timeout(void *arg)
|
||||
{
|
||||
struct usbh_hub *hub = (struct usbh_hub *)arg;
|
||||
|
||||
usbh_int_urb_fill(&hub->intin_urb, hub->parent, hub->intin, hub->int_buffer, 1, 0, hub_int_complete_callback, hub);
|
||||
usbh_submit_urb(&hub->intin_urb);
|
||||
}
|
||||
|
||||
static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
@ -384,8 +394,9 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
|
||||
usbh_int_urb_fill(&hub->intin_urb, hub->parent, hub->intin, hub->int_buffer, 1, 0, hub_int_complete_callback, hub);
|
||||
usbh_submit_urb(&hub->intin_urb);
|
||||
|
||||
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed), hub_int_timeout, hub, 0);
|
||||
usb_osal_timer_start(hub->int_timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -401,6 +412,8 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_kill_urb(&hub->intin_urb);
|
||||
}
|
||||
|
||||
usb_osal_timer_delete(hub->int_timer);
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
child = &hub->child[port];
|
||||
usbh_hubport_release(child);
|
||||
@ -616,7 +629,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
|
||||
/* Start next hub int transfer */
|
||||
if (!hub->is_roothub && hub->connected) {
|
||||
usbh_submit_urb(&hub->intin_urb);
|
||||
usb_osal_timer_start(hub->int_timer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ struct usbh_urb {
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
uint8_t data_toggle;
|
||||
uint8_t interval;
|
||||
struct usb_setup_packet *setup;
|
||||
uint8_t *transfer_buffer;
|
||||
uint32_t transfer_buffer_length;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define USB_OSAL_WAITING_FOREVER (0xFFFFFFFFU)
|
||||
|
||||
@ -16,6 +17,12 @@ typedef void *usb_osal_sem_t;
|
||||
typedef void *usb_osal_mutex_t;
|
||||
typedef void *usb_osal_mq_t;
|
||||
typedef void (*usb_thread_entry_t)(void *argument);
|
||||
typedef void (*usb_timer_handler_t)(void *argument);
|
||||
struct usb_osal_timer {
|
||||
usb_timer_handler_t handler;
|
||||
void *argument;
|
||||
void *timer;
|
||||
};
|
||||
|
||||
/*
|
||||
* Task with smaller priority value indicates higher task priority
|
||||
@ -39,6 +46,11 @@ void usb_osal_mq_delete(usb_osal_mq_t mq);
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr);
|
||||
int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout);
|
||||
|
||||
struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ms, usb_timer_handler_t handler, void *argument, bool is_period);
|
||||
void usb_osal_timer_delete(struct usb_osal_timer *timer);
|
||||
void usb_osal_timer_start(struct usb_osal_timer *timer);
|
||||
void usb_osal_timer_stop(struct usb_osal_timer *timer);
|
||||
|
||||
size_t usb_osal_enter_critical_section(void);
|
||||
void usb_osal_leave_critical_section(size_t flag);
|
||||
|
||||
|
@ -43,6 +43,8 @@ extern "C" {
|
||||
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
|
||||
#endif
|
||||
|
||||
#define USBH_GET_URB_INTERVAL(interval, speed) (speed < USB_SPEED_HIGH ? interval: (1 << (interval - 1)))
|
||||
|
||||
#define USBH_EP_INIT(ep, ep_desc) \
|
||||
do { \
|
||||
ep = ep_desc; \
|
||||
@ -128,6 +130,7 @@ struct usbh_hub {
|
||||
struct usb_endpoint_descriptor *intin;
|
||||
struct usbh_urb intin_urb;
|
||||
uint8_t *int_buffer;
|
||||
struct usb_osal_timer *int_timer;
|
||||
};
|
||||
|
||||
struct usbh_devaddr_map {
|
||||
@ -214,6 +217,7 @@ static inline void usbh_int_urb_fill(struct usbh_urb *urb,
|
||||
urb->timeout = timeout;
|
||||
urb->complete = complete;
|
||||
urb->arg = arg;
|
||||
urb->interval = USBH_GET_URB_INTERVAL(ep->bInterval, hport->speed);
|
||||
}
|
||||
|
||||
extern struct usbh_bus g_usbhost_bus[];
|
||||
|
@ -116,6 +116,51 @@ int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
|
||||
}
|
||||
}
|
||||
|
||||
static void __usb_timeout(TimerHandle_t *handle)
|
||||
{
|
||||
struct usb_osal_timer *timer = (struct usb_osal_timer *)pvTimerGetTimerID((TimerHandle_t)handle);
|
||||
|
||||
timer->handler(timer->argument);
|
||||
}
|
||||
|
||||
struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ms, usb_timer_handler_t handler, void *argument, bool is_period)
|
||||
{
|
||||
struct usb_osal_timer *timer;
|
||||
|
||||
timer = pvPortMalloc(sizeof(struct usb_osal_timer));
|
||||
|
||||
if (timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(timer, 0, sizeof(struct usb_osal_timer));
|
||||
|
||||
timer->handler = handler;
|
||||
timer->argument = argument;
|
||||
|
||||
timer->timer = (void *)xTimerCreate("usb_tim", pdMS_TO_TICKS(timeout_ms), is_period, timer, (TimerCallbackFunction_t)__usb_timeout);
|
||||
if (timer->timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
|
||||
void usb_osal_timer_delete(struct usb_osal_timer *timer)
|
||||
{
|
||||
xTimerStop(timer->timer, 0);
|
||||
xTimerDelete(timer->timer, 0);
|
||||
vPortFree(timer);
|
||||
}
|
||||
|
||||
void usb_osal_timer_start(struct usb_osal_timer *timer)
|
||||
{
|
||||
xTimerStart(timer->timer, 0);
|
||||
}
|
||||
|
||||
void usb_osal_timer_stop(struct usb_osal_timer *timer)
|
||||
{
|
||||
xTimerStop(timer->timer, 0);
|
||||
}
|
||||
|
||||
size_t usb_osal_enter_critical_section(void)
|
||||
{
|
||||
taskDISABLE_INTERRUPTS();
|
||||
|
@ -122,6 +122,37 @@ int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ms, usb_timer_handler_t handler, void *argument, bool is_period)
|
||||
{
|
||||
struct usb_osal_timer *timer;
|
||||
|
||||
timer = rt_malloc(sizeof(struct usb_osal_timer));
|
||||
memset(timer, 0, sizeof(struct usb_osal_timer));
|
||||
|
||||
timer->timer = (void *)rt_timer_create("usb_tim", handler, argument, timeout_ms, is_period ? (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER) : (RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER));
|
||||
if (timer->timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
|
||||
void usb_osal_timer_delete(struct usb_osal_timer *timer)
|
||||
{
|
||||
rt_timer_stop(timer->timer);
|
||||
rt_timer_delete(timer->timer);
|
||||
rt_free(timer);
|
||||
}
|
||||
|
||||
void usb_osal_timer_start(struct usb_osal_timer *timer)
|
||||
{
|
||||
rt_timer_start(timer->timer);
|
||||
}
|
||||
|
||||
void usb_osal_timer_stop(struct usb_osal_timer *timer)
|
||||
{
|
||||
rt_timer_stop(timer->timer);
|
||||
}
|
||||
|
||||
size_t usb_osal_enter_critical_section(void)
|
||||
{
|
||||
return rt_hw_interrupt_disable();
|
||||
|
Loading…
x
Reference in New Issue
Block a user