drivers: udc_nrf: implement method to distiguish hal and shim events

Implement method to distiguish hal driver and UDC shim driver events.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
Johann Fischer 2022-12-01 15:04:44 +01:00 committed by Carles Cufí
parent 1fa31bbc30
commit 292951da4b

View file

@ -28,7 +28,21 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(udc_nrf, CONFIG_UDC_DRIVER_LOG_LEVEL);
K_MSGQ_DEFINE(drv_msgq, sizeof(nrfx_usbd_evt_t),
enum udc_nrf_event_type {
/* An event generated by the HAL driver */
UDC_NRF_EVT_HAL,
/* Shim driver event to trigger next transfer */
UDC_NRF_EVT_XFER,
};
struct udc_nrf_evt {
enum udc_nrf_event_type type;
union {
nrfx_usbd_evt_t hal_evt;
};
};
K_MSGQ_DEFINE(drv_msgq, sizeof(struct udc_nrf_evt),
CONFIG_UDC_NRF_MAX_QMESSAGES, sizeof(uint32_t));
static K_KERNEL_STACK_DEFINE(drv_stack, CONFIG_UDC_NRF_THREAD_STACK_SIZE);
@ -295,19 +309,19 @@ static int udc_event_xfer_setup(const struct device *dev)
static void udc_nrf_thread(const struct device *dev)
{
nrfx_usbd_evt_t event;
struct udc_nrf_evt evt;
uint8_t ep;
while (true) {
k_msgq_get(&drv_msgq, &event, K_FOREVER);
ep = event.data.eptransfer.ep;
k_msgq_get(&drv_msgq, &evt, K_FOREVER);
ep = evt.hal_evt.data.eptransfer.ep;
switch (event.type) {
switch (evt.hal_evt.type) {
case NRFX_USBD_EVT_EPTRANSFER:
if (USB_EP_DIR_IS_IN(ep)) {
udc_event_xfer_in(dev, &event);
udc_event_xfer_in(dev, &evt.hal_evt);
} else {
udc_event_xfer_out(dev, &event);
udc_event_xfer_out(dev, &evt.hal_evt);
}
break;
case NRFX_USBD_EVT_SETUP:
@ -322,12 +336,15 @@ static void udc_nrf_thread(const struct device *dev)
static void udc_sof_check_iso_out(const struct device *dev)
{
const uint8_t iso_out_addr = 0x08;
nrfx_usbd_evt_t event = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = iso_out_addr,
.status = NRFX_USBD_EP_WAITING,
struct udc_nrf_evt evt = {
.type = UDC_NRF_EVT_HAL,
.hal_evt = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = iso_out_addr,
.status = NRFX_USBD_EP_WAITING,
},
},
},
};
@ -339,13 +356,13 @@ static void udc_sof_check_iso_out(const struct device *dev)
}
if (ep_cfg->stat.enabled && !k_fifo_is_empty(&ep_cfg->fifo)) {
k_msgq_put(&drv_msgq, &event, K_NO_WAIT);
k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
}
}
static void usbd_event_handler(nrfx_usbd_evt_t const *const event)
static void usbd_event_handler(nrfx_usbd_evt_t const *const hal_evt)
{
switch (event->type) {
switch (hal_evt->type) {
case NRFX_USBD_EVT_SUSPEND:
LOG_INF("SUSPEND state detected");
nrfx_usbd_suspend();
@ -370,10 +387,15 @@ static void usbd_event_handler(nrfx_usbd_evt_t const *const event)
break;
case NRFX_USBD_EVT_EPTRANSFER:
case NRFX_USBD_EVT_SETUP:
struct udc_nrf_evt evt = {
.type = UDC_NRF_EVT_HAL,
.hal_evt = *hal_evt,
};
/* Forward these two to the thread since mutually exclusive
* access to the controller is necessary.
*/
k_msgq_put(&drv_msgq, event, K_NO_WAIT);
k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
break;
default:
break;
@ -402,37 +424,43 @@ static void udc_nrf_power_handler(nrfx_power_usb_evt_t pwr_evt)
static void udc_nrf_fake_in_ack(const struct device *dev)
{
nrfx_usbd_evt_t event = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = USB_CONTROL_EP_IN,
.status = NRFX_USBD_EP_OK,
struct udc_nrf_evt evt = {
.type = UDC_NRF_EVT_HAL,
.hal_evt = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = USB_CONTROL_EP_IN,
.status = NRFX_USBD_EP_OK,
},
},
},
};
if (nrfx_usbd_last_setup_dir_get() == USB_CONTROL_EP_OUT) {
/* Host -> Device or no Data stage */
k_msgq_put(&drv_msgq, &event, K_NO_WAIT);
k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
}
}
static void udc_nrf_check_pending(const struct device *dev,
struct udc_ep_config *ep_cfg)
{
nrfx_usbd_evt_t event = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = ep_cfg->addr,
.status = NRFX_USBD_EP_WAITING,
struct udc_nrf_evt evt = {
.type = UDC_NRF_EVT_HAL,
.hal_evt = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = ep_cfg->addr,
.status = NRFX_USBD_EP_WAITING,
},
},
},
};
if (ep_cfg->stat.pending) {
k_msgq_put(&drv_msgq, &event, K_NO_WAIT);
k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
}
}
@ -462,8 +490,11 @@ static int udc_nrf_ep_enqueue(const struct device *dev,
LOG_ERR("ep 0x%02x nrfx error: %x", cfg->addr, err);
return -EIO;
}
return 0;
}
if (USB_EP_DIR_IS_OUT(cfg->addr)) {
udc_nrf_check_pending(dev, cfg);
}
@ -474,12 +505,15 @@ static int udc_nrf_ep_enqueue(const struct device *dev,
static int udc_nrf_ep_dequeue(const struct device *dev,
struct udc_ep_config *cfg)
{
nrfx_usbd_evt_t event = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = cfg->addr,
.status = NRFX_USBD_EP_ABORTED,
struct udc_nrf_evt evt = {
.type = UDC_NRF_EVT_HAL,
.hal_evt = {
.type = NRFX_USBD_EVT_EPTRANSFER,
.data = {
.eptransfer = {
.ep = cfg->addr,
.status = NRFX_USBD_EP_ABORTED,
},
},
},
};
@ -488,7 +522,7 @@ static int udc_nrf_ep_dequeue(const struct device *dev,
/* FIXME: check the queue state before */
nrfx_usbd_ep_abort(cfg->addr);
if (USB_EP_DIR_IS_OUT(cfg->addr)) {
ret = k_msgq_put(&drv_msgq, &event, K_NO_WAIT);
ret = k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
}
return ret;