mirror of https://github.com/ARMmbed/mbed-os.git
Autoformatted with astyle
parent
b2ae05f991
commit
974e8899e0
|
@ -21,8 +21,8 @@
|
||||||
#include "USBPhy.h"
|
#include "USBPhy.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "nrf_drv_usbd.h"
|
#include "nrf_drv_usbd.h"
|
||||||
#include "nrfx_power.h"
|
#include "nrfx_power.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
class USBPhyHw : public USBPhy {
|
class USBPhyHw : public USBPhy {
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
virtual void sof_disable();
|
virtual void sof_disable();
|
||||||
virtual void set_address(uint8_t address);
|
virtual void set_address(uint8_t address);
|
||||||
virtual void remote_wakeup();
|
virtual void remote_wakeup();
|
||||||
virtual const usb_ep_table_t* endpoint_table();
|
virtual const usb_ep_table_t *endpoint_table();
|
||||||
|
|
||||||
virtual uint32_t ep0_set_max_packet(uint32_t max_packet);
|
virtual uint32_t ep0_set_max_packet(uint32_t max_packet);
|
||||||
virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size);
|
virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size);
|
||||||
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
virtual void process();
|
virtual void process();
|
||||||
|
|
||||||
static void _usb_event_handler(nrf_drv_usbd_evt_t const * const p_event);
|
static void _usb_event_handler(nrf_drv_usbd_evt_t const *const p_event);
|
||||||
static void _usb_power_event_handler(nrfx_power_usb_evt_t event);
|
static void _usb_power_event_handler(nrfx_power_usb_evt_t event);
|
||||||
static void _usb_virtual_status_event_handler(void);
|
static void _usb_virtual_status_event_handler(void);
|
||||||
|
|
||||||
|
@ -73,10 +73,10 @@ private:
|
||||||
bool connect_enabled;
|
bool connect_enabled;
|
||||||
|
|
||||||
typedef enum usb_hw_event_type_t {
|
typedef enum usb_hw_event_type_t {
|
||||||
USB_HW_EVENT_NONE = 0,
|
USB_HW_EVENT_NONE = 0,
|
||||||
USB_HW_EVENT_USBD = 1,
|
USB_HW_EVENT_USBD = 1,
|
||||||
USB_HW_EVENT_POWER = 2,
|
USB_HW_EVENT_POWER = 2,
|
||||||
USB_HW_EVENT_VIRTUAL_STATUS = 3
|
USB_HW_EVENT_VIRTUAL_STATUS = 3
|
||||||
} usb_hw_event_type_t;
|
} usb_hw_event_type_t;
|
||||||
|
|
||||||
// Event type to process
|
// Event type to process
|
||||||
|
@ -95,7 +95,7 @@ private:
|
||||||
nrf_drv_usbd_transfer_t transfer_buf[18];
|
nrf_drv_usbd_transfer_t transfer_buf[18];
|
||||||
|
|
||||||
// Returns the appropriate transfer structure buffer for the given endpoint
|
// Returns the appropriate transfer structure buffer for the given endpoint
|
||||||
nrf_drv_usbd_transfer_t* get_transfer_buffer(usb_ep_t endpoint);
|
nrf_drv_usbd_transfer_t *get_transfer_buffer(usb_ep_t endpoint);
|
||||||
|
|
||||||
// Returns the corresponding enumeration given an mbed endpoint number
|
// Returns the corresponding enumeration given an mbed endpoint number
|
||||||
static nrf_drv_usbd_ep_t get_nordic_endpoint(usb_ep_t endpoint);
|
static nrf_drv_usbd_ep_t get_nordic_endpoint(usb_ep_t endpoint);
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#define MAX_PACKET_ISO NRF_DRV_USBD_ISOSIZE
|
#define MAX_PACKET_ISO NRF_DRV_USBD_ISOSIZE
|
||||||
#define ENDPOINT_NON_ISO (USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_ALLOW_INT)
|
#define ENDPOINT_NON_ISO (USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_ALLOW_INT)
|
||||||
|
|
||||||
#define IS_IN_EP(ep) (ep & 0x80) // Checks if the given endpoint is an IN endpoint (MSB set)
|
#define IS_IN_EP(ep) (ep & 0x80) // Checks if the given endpoint is an IN endpoint (MSB set)
|
||||||
#define IS_OUT_EP(ep) (ep & ~0x80) // Checks if the given endpoint is an OUT endpoint (MSB clear)
|
#define IS_OUT_EP(ep) (ep & ~0x80) // Checks if the given endpoint is an OUT endpoint (MSB clear)
|
||||||
|
|
||||||
// If this bit is set in setup.bmRequestType, the setup transfer
|
// If this bit is set in setup.bmRequestType, the setup transfer
|
||||||
// is DEVICE->HOST (IN transfer)
|
// is DEVICE->HOST (IN transfer)
|
||||||
|
@ -45,549 +45,591 @@ static USBPhyHw *instance = 0;
|
||||||
|
|
||||||
static volatile bool virtual_status_xfer_event;
|
static volatile bool virtual_status_xfer_event;
|
||||||
|
|
||||||
static void usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event);
|
static void usbd_event_handler(nrf_drv_usbd_evt_t const *const p_event);
|
||||||
static void power_usb_event_handler(nrfx_power_usb_evt_t event);
|
static void power_usb_event_handler(nrfx_power_usb_evt_t event);
|
||||||
|
|
||||||
USBPhy *get_usb_phy() {
|
USBPhy *get_usb_phy()
|
||||||
static USBPhyHw usbphy;
|
{
|
||||||
return &usbphy;
|
static USBPhyHw usbphy;
|
||||||
|
return &usbphy;
|
||||||
}
|
}
|
||||||
|
|
||||||
USBPhyHw::USBPhyHw() :
|
USBPhyHw::USBPhyHw() :
|
||||||
events(NULL), sof_enabled(false), connect_enabled(false),
|
events(NULL), sof_enabled(false), connect_enabled(false),
|
||||||
usb_event_type(USB_HW_EVENT_NONE),
|
usb_event_type(USB_HW_EVENT_NONE),
|
||||||
usb_power_event(NRFX_POWER_USB_EVT_REMOVED) {
|
usb_power_event(NRFX_POWER_USB_EVT_REMOVED)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
USBPhyHw::~USBPhyHw() {
|
USBPhyHw::~USBPhyHw()
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::init(USBPhyEvents *events) {
|
void USBPhyHw::init(USBPhyEvents *events)
|
||||||
|
{
|
||||||
|
|
||||||
this->events = events;
|
this->events = events;
|
||||||
|
|
||||||
ret_code_t ret;
|
ret_code_t ret;
|
||||||
|
|
||||||
// Initialize power module to track USB Power events
|
// Initialize power module to track USB Power events
|
||||||
ret = nrfx_power_init(NULL);
|
ret = nrfx_power_init(NULL);
|
||||||
MBED_ASSERT(ret == NRF_SUCCESS);
|
MBED_ASSERT(ret == NRF_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
// Register callback for USB Power events
|
// Register callback for USB Power events
|
||||||
static const nrfx_power_usbevt_config_t config = { .handler =
|
static const nrfx_power_usbevt_config_t config = {
|
||||||
power_usb_event_handler };
|
.handler = power_usb_event_handler
|
||||||
nrfx_power_usbevt_init(&config);
|
};
|
||||||
|
|
||||||
// Initialize USB Device driver
|
nrfx_power_usbevt_init(&config);
|
||||||
ret = nrf_drv_usbd_init(usbd_event_handler);
|
|
||||||
MBED_ASSERT(ret == NRF_SUCCESS);
|
|
||||||
|
|
||||||
/* Configure selected size of the packed on EP0 */
|
// Initialize USB Device driver
|
||||||
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, MAX_PACKET_SIZE_SETUP);
|
ret = nrf_drv_usbd_init(usbd_event_handler);
|
||||||
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, MAX_PACKET_SIZE_SETUP);
|
MBED_ASSERT(ret == NRF_SUCCESS);
|
||||||
|
|
||||||
// Store a reference to this instance
|
/* Configure selected size of the packed on EP0 */
|
||||||
instance = this;
|
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, MAX_PACKET_SIZE_SETUP);
|
||||||
|
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, MAX_PACKET_SIZE_SETUP);
|
||||||
|
|
||||||
virtual_status_xfer_event = false;
|
// Store a reference to this instance
|
||||||
|
instance = this;
|
||||||
|
|
||||||
/*
|
virtual_status_xfer_event = false;
|
||||||
* Configure ISOIN endpoint to respond with ZLP when
|
|
||||||
* no data is ready to be sent
|
|
||||||
*/
|
|
||||||
NRF_USBD->ISOINCONFIG |= 0x01; // set RESPONSE to 1 (respond with ZLP)
|
|
||||||
|
|
||||||
// Set up the IRQ handler
|
/*
|
||||||
NVIC_SetVector(USBD_IRQn, (uint32_t)USBD_HAL_IRQHandler);
|
* Configure ISOIN endpoint to respond with ZLP when
|
||||||
|
* no data is ready to be sent
|
||||||
|
*/
|
||||||
|
NRF_USBD->ISOINCONFIG |= 0x01; // set RESPONSE to 1 (respond with ZLP)
|
||||||
|
|
||||||
// Enable the power events
|
// Set up the IRQ handler
|
||||||
nrfx_power_usbevt_enable();
|
NVIC_SetVector(USBD_IRQn, (uint32_t)USBD_HAL_IRQHandler);
|
||||||
|
|
||||||
|
// Enable the power events
|
||||||
|
nrfx_power_usbevt_enable();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::deinit() {
|
void USBPhyHw::deinit()
|
||||||
// Disconnect and disable interrupt
|
{
|
||||||
disconnect();
|
// Disconnect and disable interrupt
|
||||||
// Disable the USB Device driver
|
disconnect();
|
||||||
ret_code_t ret = nrf_drv_usbd_uninit();
|
|
||||||
MBED_ASSERT(ret == NRF_SUCCESS);
|
|
||||||
//NVIC_DisableIRQ(USBD_IRQn); // This is handled by the Nordic driver
|
|
||||||
|
|
||||||
// Disable the power peripheral driver
|
// Disable the USB Device driver
|
||||||
nrfx_power_uninit();
|
ret_code_t ret = nrf_drv_usbd_uninit();
|
||||||
|
MBED_ASSERT(ret == NRF_SUCCESS);
|
||||||
|
|
||||||
// Clear the instance pointer
|
// Disable the power peripheral driver
|
||||||
instance = 0;
|
nrfx_power_uninit();
|
||||||
|
|
||||||
|
// Clear the instance pointer
|
||||||
|
instance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBPhyHw::powered() {
|
bool USBPhyHw::powered()
|
||||||
if (nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_CONNECTED
|
{
|
||||||
|| nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_READY)
|
if (nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_CONNECTED
|
||||||
return true;
|
|| nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_READY) {
|
||||||
else
|
return true;
|
||||||
return false;
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::connect() {
|
void USBPhyHw::connect()
|
||||||
|
{
|
||||||
|
|
||||||
// To save power, we only enable the USBD peripheral
|
// To save power, we only enable the USBD peripheral
|
||||||
// when there's actually VBUS detected
|
// when there's actually VBUS detected
|
||||||
|
|
||||||
// So flag that the USB stack is ready to connect
|
// So flag that the USB stack is ready to connect
|
||||||
this->connect_enabled = true;
|
this->connect_enabled = true;
|
||||||
|
|
||||||
// If VBUS is already available, enable immediately
|
// If VBUS is already available, enable immediately
|
||||||
if(nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_CONNECTED)
|
if (nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_CONNECTED) {
|
||||||
{
|
// Enabling USB will cause NRF_DRV_POWER_USB_EVT_READY
|
||||||
// Enabling USB will cause NRF_DRV_POWER_USB_EVT_READY
|
// to occur, which will start the USBD peripheral
|
||||||
// to occur, which will start the USBD peripheral
|
// when the internal regulator has settled
|
||||||
// when the internal regulator has settled
|
if (!nrf_drv_usbd_is_enabled()) {
|
||||||
if(!nrf_drv_usbd_is_enabled())
|
nrf_drv_usbd_enable();
|
||||||
nrf_drv_usbd_enable();
|
}
|
||||||
|
|
||||||
if(nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_READY
|
if (nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_READY
|
||||||
&& !nrf_drv_usbd_is_started())
|
&& !nrf_drv_usbd_is_started()) {
|
||||||
nrf_drv_usbd_start(true);
|
nrf_drv_usbd_start(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::disconnect() {
|
void USBPhyHw::disconnect()
|
||||||
|
{
|
||||||
|
|
||||||
this->connect_enabled = false;
|
this->connect_enabled = false;
|
||||||
|
|
||||||
if(nrf_drv_usbd_is_started())
|
if (nrf_drv_usbd_is_started()) {
|
||||||
nrf_drv_usbd_stop();
|
nrf_drv_usbd_stop();
|
||||||
if(nrf_drv_usbd_is_enabled())
|
}
|
||||||
nrf_drv_usbd_disable();
|
if (nrf_drv_usbd_is_enabled()) {
|
||||||
|
nrf_drv_usbd_disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::configure() {
|
void USBPhyHw::configure()
|
||||||
// Not needed
|
{
|
||||||
|
// Not needed
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::unconfigure() {
|
void USBPhyHw::unconfigure()
|
||||||
// Remove all endpoints (except control, obviously)
|
{
|
||||||
nrf_drv_usbd_ep_default_config();
|
// Remove all endpoints (except control, obviously)
|
||||||
|
nrf_drv_usbd_ep_default_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::sof_enable() {
|
void USBPhyHw::sof_enable()
|
||||||
// TODO - Enable SOF interrupt
|
{
|
||||||
// Can this safely be done if
|
// TODO - Enable SOF interrupt
|
||||||
// nrf_drv_usbd_start is called with SoF enabled?
|
// Can this safely be done if
|
||||||
// For now just mask the interrupt with a boolean flag
|
// nrf_drv_usbd_start is called with SoF enabled?
|
||||||
sof_enabled = true;
|
// For now just mask the interrupt with a boolean flag
|
||||||
|
sof_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::sof_disable() {
|
void USBPhyHw::sof_disable()
|
||||||
// TODO - Disable SOF interrupt
|
{
|
||||||
// Can this safely be done if
|
// TODO - Disable SOF interrupt
|
||||||
// nrf_drv_usbd_start is called with SoF enabled?
|
// Can this safely be done if
|
||||||
sof_enabled = false;
|
// nrf_drv_usbd_start is called with SoF enabled?
|
||||||
|
sof_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::set_address(uint8_t address) {
|
void USBPhyHw::set_address(uint8_t address)
|
||||||
// nothing to do, handled by hardware; but don't STALL
|
{
|
||||||
|
// nothing to do, handled by hardware; but don't STALL
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::remote_wakeup() {
|
void USBPhyHw::remote_wakeup()
|
||||||
// Not supported(?)
|
{
|
||||||
|
// Not supported(?)
|
||||||
}
|
}
|
||||||
|
|
||||||
const usb_ep_table_t *USBPhyHw::endpoint_table() {
|
const usb_ep_table_t *USBPhyHw::endpoint_table()
|
||||||
|
{
|
||||||
|
|
||||||
static const usb_ep_table_t template_table =
|
static const usb_ep_table_t template_table = {
|
||||||
{
|
1536, // 64 bytes per bulk/int endpoint pair (8), 1023 bytes for iso endpoint pair (1)
|
||||||
1536, // 64 bytes per bulk/int endpoint pair (8), 1023 bytes for iso endpoint pair (1)
|
{
|
||||||
{
|
{ USB_EP_ATTR_ALLOW_CTRL | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ USB_EP_ATTR_ALLOW_CTRL | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ ENDPOINT_NON_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ USB_EP_ATTR_ALLOW_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ USB_EP_ATTR_ALLOW_ISO | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
||||||
{ 0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0 },
|
}
|
||||||
}
|
};
|
||||||
};
|
return &template_table;
|
||||||
return &template_table;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t USBPhyHw::ep0_set_max_packet(uint32_t max_packet) {
|
uint32_t USBPhyHw::ep0_set_max_packet(uint32_t max_packet)
|
||||||
disable_usb_interrupts();
|
{
|
||||||
|
disable_usb_interrupts();
|
||||||
|
|
||||||
if (max_packet > MAX_PACKET_SIZE_SETUP)
|
if (max_packet > MAX_PACKET_SIZE_SETUP) {
|
||||||
max_packet = MAX_PACKET_SIZE_SETUP;
|
max_packet = MAX_PACKET_SIZE_SETUP;
|
||||||
|
}
|
||||||
|
|
||||||
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, max_packet);
|
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, max_packet);
|
||||||
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, max_packet);
|
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, max_packet);
|
||||||
|
|
||||||
enable_usb_interrupts();
|
enable_usb_interrupts();
|
||||||
|
|
||||||
return max_packet;
|
return max_packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read setup packet
|
// read setup packet
|
||||||
void USBPhyHw::ep0_setup_read_result(uint8_t *buffer, uint32_t size) {
|
void USBPhyHw::ep0_setup_read_result(uint8_t *buffer, uint32_t size)
|
||||||
|
{
|
||||||
|
|
||||||
disable_usb_interrupts();
|
disable_usb_interrupts();
|
||||||
|
|
||||||
if (size > sizeof(this->setup_buf)) {
|
if (size > sizeof(this->setup_buf)) {
|
||||||
size = sizeof(this->setup_buf);
|
size = sizeof(this->setup_buf);
|
||||||
}
|
}
|
||||||
memcpy(buffer, &this->setup_buf, size);
|
memcpy(buffer, &this->setup_buf, size);
|
||||||
|
|
||||||
enable_usb_interrupts();
|
enable_usb_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::ep0_read(uint8_t *data, uint32_t size) {
|
void USBPhyHw::ep0_read(uint8_t *data, uint32_t size)
|
||||||
|
{
|
||||||
|
|
||||||
// Check for status stage
|
// Check for status stage
|
||||||
if(data == NULL && size == 0)
|
if (data == NULL && size == 0) {
|
||||||
{
|
// If the data stage transfer direction was OUT
|
||||||
// If the data stage transfer direction was OUT
|
if (setup_buf.bmRequestType & SETUP_TRANSFER_DIR_MASK) {
|
||||||
if(setup_buf.bmRequestType & SETUP_TRANSFER_DIR_MASK)
|
// This is the status stage -- trigger the status task and notify the Mbed stack
|
||||||
{
|
// Don't trigger status stage unless endpoint is not busy!
|
||||||
// This is the status stage -- trigger the status task and notify the Mbed stack
|
// (Causes an undocumented hardware-initiated stall on the control endpoint)
|
||||||
// Don't trigger status stage unless endpoint is not busy!
|
if (nrf_drv_usbd_ep_is_busy(NRF_DRV_USBD_EPIN0)) {
|
||||||
// (Causes an undocumented hardware-initiated stall on the control endpoint)
|
nrf_usbd_shorts_enable(NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK);
|
||||||
if(nrf_drv_usbd_ep_is_busy(NRF_DRV_USBD_EPIN0))
|
} else {
|
||||||
nrf_usbd_shorts_enable(NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK);
|
nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS);
|
||||||
else
|
}
|
||||||
nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS);
|
|
||||||
|
|
||||||
virtual_status_xfer_event = true;
|
virtual_status_xfer_event = true;
|
||||||
|
|
||||||
// Trigger an interrupt to process the virtual status event
|
// Trigger an interrupt to process the virtual status event
|
||||||
NRFX_IRQ_PENDING_SET(USBD_IRQn);
|
NRFX_IRQ_PENDING_SET(USBD_IRQn);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nrf_drv_usbd_transfer_t* transfer = get_transfer_buffer((usb_ep_t)(NRF_DRV_USBD_EPOUT0));
|
nrf_drv_usbd_transfer_t *transfer = get_transfer_buffer((usb_ep_t)(NRF_DRV_USBD_EPOUT0));
|
||||||
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
||||||
transfer->p_data.rx = data;
|
transfer->p_data.rx = data;
|
||||||
transfer->size = size;
|
transfer->size = size;
|
||||||
|
|
||||||
nrf_drv_usbd_setup_data_clear(); // tell the hardware to receive another OUT packet
|
nrf_drv_usbd_setup_data_clear(); // tell the hardware to receive another OUT packet
|
||||||
|
|
||||||
ret_code_t ret = nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, transfer);
|
ret_code_t ret = nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, transfer);
|
||||||
MBED_ASSERT(ret == NRF_SUCCESS);
|
MBED_ASSERT(ret == NRF_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t USBPhyHw::ep0_read_result() {
|
uint32_t USBPhyHw::ep0_read_result()
|
||||||
return nrf_drv_usbd_epout_size_get(NRF_DRV_USBD_EPOUT0);
|
{
|
||||||
|
return nrf_drv_usbd_epout_size_get(NRF_DRV_USBD_EPOUT0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::ep0_write(uint8_t *buffer, uint32_t size) {
|
void USBPhyHw::ep0_write(uint8_t *buffer, uint32_t size)
|
||||||
|
{
|
||||||
|
|
||||||
// Check for status stage
|
// Check for status stage
|
||||||
if(buffer == NULL && size == 0)
|
if (buffer == NULL && size == 0) {
|
||||||
{
|
// If the requested size was 0 OR the data stage transfer direction was OUT
|
||||||
// If the requested size was 0 OR the data stage transfer direction was OUT
|
if (setup_buf.wLength == 0
|
||||||
if(setup_buf.wLength == 0
|
|| ((setup_buf.bmRequestType & SETUP_TRANSFER_DIR_MASK) == 0)) {
|
||||||
|| ((setup_buf.bmRequestType & SETUP_TRANSFER_DIR_MASK) == 0))
|
|
||||||
{
|
|
||||||
|
|
||||||
// This is the status stage -- trigger the status task and notify the Mbed stack
|
// This is the status stage -- trigger the status task and notify the Mbed stack
|
||||||
|
|
||||||
// Don't trigger status stage unless endpoint is not busy!
|
// Don't trigger status stage unless endpoint is not busy!
|
||||||
// (Causes an undocumented hardware-initiated stall on the control endpoint)
|
// (Causes an undocumented hardware-initiated stall on the control endpoint)
|
||||||
if(nrf_drv_usbd_ep_is_busy(NRF_DRV_USBD_EPOUT0))
|
if (nrf_drv_usbd_ep_is_busy(NRF_DRV_USBD_EPOUT0)) {
|
||||||
nrf_usbd_shorts_enable(NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK);
|
nrf_usbd_shorts_enable(NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK);
|
||||||
else
|
} else {
|
||||||
nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS);
|
nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
virtual_status_xfer_event = true;
|
virtual_status_xfer_event = true;
|
||||||
|
|
||||||
// Trigger an interrupt to process the virtual status event
|
// Trigger an interrupt to process the virtual status event
|
||||||
NRFX_IRQ_PENDING_SET(USBD_IRQn);
|
NRFX_IRQ_PENDING_SET(USBD_IRQn);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nrf_drv_usbd_transfer_t* transfer = get_transfer_buffer(NRF_DRV_USBD_EPIN0);
|
nrf_drv_usbd_transfer_t *transfer = get_transfer_buffer(NRF_DRV_USBD_EPIN0);
|
||||||
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
||||||
transfer->p_data.tx = buffer;
|
transfer->p_data.tx = buffer;
|
||||||
transfer->size = size;
|
transfer->size = size;
|
||||||
|
|
||||||
if(size == 0)
|
if (size == 0) {
|
||||||
transfer->flags |= NRF_DRV_USBD_TRANSFER_ZLP_FLAG;
|
transfer->flags |= NRF_DRV_USBD_TRANSFER_ZLP_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
ret_code_t ret = nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPIN0, transfer);
|
ret_code_t ret = nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPIN0, transfer);
|
||||||
MBED_ASSERT(ret == NRF_SUCCESS);
|
MBED_ASSERT(ret == NRF_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::ep0_stall() {
|
void USBPhyHw::ep0_stall()
|
||||||
// Note: This stall must be automatically cleared by the next setup packet
|
{
|
||||||
nrf_drv_usbd_setup_stall();
|
// Note: This stall must be automatically cleared by the next setup packet
|
||||||
|
nrf_drv_usbd_setup_stall();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBPhyHw::endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type) {
|
bool USBPhyHw::endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type)
|
||||||
nrf_drv_usbd_ep_t nrf_ep = get_nordic_endpoint(endpoint);
|
{
|
||||||
nrf_drv_usbd_ep_enable(nrf_ep);
|
nrf_drv_usbd_ep_t nrf_ep = get_nordic_endpoint(endpoint);
|
||||||
nrf_drv_usbd_ep_max_packet_size_set(nrf_ep, max_packet);
|
nrf_drv_usbd_ep_enable(nrf_ep);
|
||||||
return nrf_drv_usbd_ep_enable_check(nrf_ep);
|
nrf_drv_usbd_ep_max_packet_size_set(nrf_ep, max_packet);
|
||||||
|
return nrf_drv_usbd_ep_enable_check(nrf_ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::endpoint_remove(usb_ep_t endpoint) {
|
void USBPhyHw::endpoint_remove(usb_ep_t endpoint)
|
||||||
nrf_drv_usbd_ep_t nrf_ep = get_nordic_endpoint(endpoint);
|
{
|
||||||
// Reset data toggle for bulk/interrupt endpoints
|
nrf_drv_usbd_ep_t nrf_ep = get_nordic_endpoint(endpoint);
|
||||||
if(nrf_ep != NRF_DRV_USBD_EPOUT8 && nrf_ep != NRF_DRV_USBD_EPIN8)
|
// Reset data toggle for bulk/interrupt endpoints
|
||||||
nrf_drv_usbd_ep_dtoggle_clear(nrf_ep);
|
if (nrf_ep != NRF_DRV_USBD_EPOUT8 && nrf_ep != NRF_DRV_USBD_EPIN8) {
|
||||||
|
nrf_drv_usbd_ep_dtoggle_clear(nrf_ep);
|
||||||
|
}
|
||||||
|
|
||||||
nrf_drv_usbd_ep_disable(nrf_ep);
|
nrf_drv_usbd_ep_disable(nrf_ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::endpoint_stall(usb_ep_t endpoint) {
|
void USBPhyHw::endpoint_stall(usb_ep_t endpoint)
|
||||||
nrf_drv_usbd_ep_stall(get_nordic_endpoint(endpoint));
|
{
|
||||||
|
nrf_drv_usbd_ep_stall(get_nordic_endpoint(endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::endpoint_unstall(usb_ep_t endpoint) {
|
void USBPhyHw::endpoint_unstall(usb_ep_t endpoint)
|
||||||
nrf_drv_usbd_ep_t ep = get_nordic_endpoint(endpoint);
|
{
|
||||||
nrf_drv_usbd_ep_stall_clear(ep);
|
nrf_drv_usbd_ep_t ep = get_nordic_endpoint(endpoint);
|
||||||
|
nrf_drv_usbd_ep_stall_clear(ep);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a somewhat hacky fix to fully "unload"
|
* This is a somewhat hacky fix to fully "unload"
|
||||||
* an IN endpoint after a buffer has been
|
* an IN endpoint after a buffer has been
|
||||||
* transferred via EasyDMA...
|
* transferred via EasyDMA...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nrf_drv_usbd_ep_disable(ep);
|
nrf_drv_usbd_ep_disable(ep);
|
||||||
nrf_drv_usbd_ep_enable(ep);
|
nrf_drv_usbd_ep_enable(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBPhyHw::endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size) {
|
bool USBPhyHw::endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size)
|
||||||
nrf_drv_usbd_transfer_t* transfer = get_transfer_buffer(endpoint);
|
{
|
||||||
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
nrf_drv_usbd_transfer_t *transfer = get_transfer_buffer(endpoint);
|
||||||
transfer->p_data.rx = data;
|
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
||||||
transfer->size = size;
|
transfer->p_data.rx = data;
|
||||||
|
transfer->size = size;
|
||||||
|
|
||||||
ret_code_t ret = nrf_drv_usbd_ep_transfer(get_nordic_endpoint(endpoint), transfer);
|
ret_code_t ret = nrf_drv_usbd_ep_transfer(get_nordic_endpoint(endpoint), transfer);
|
||||||
return (ret == NRF_SUCCESS);
|
return (ret == NRF_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t USBPhyHw::endpoint_read_result(usb_ep_t endpoint) {
|
uint32_t USBPhyHw::endpoint_read_result(usb_ep_t endpoint)
|
||||||
return nrf_drv_usbd_epout_size_get(get_nordic_endpoint(endpoint));
|
{
|
||||||
|
return nrf_drv_usbd_epout_size_get(get_nordic_endpoint(endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBPhyHw::endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size) {
|
bool USBPhyHw::endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size)
|
||||||
nrf_drv_usbd_transfer_t* transfer = get_transfer_buffer(endpoint);
|
{
|
||||||
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
nrf_drv_usbd_transfer_t *transfer = get_transfer_buffer(endpoint);
|
||||||
transfer->p_data.tx = data;
|
memset(transfer, 0, sizeof(nrf_drv_usbd_transfer_t));
|
||||||
transfer->size = size;
|
transfer->p_data.tx = data;
|
||||||
|
transfer->size = size;
|
||||||
|
|
||||||
// If this is a zero-length-packet (ZLP)
|
// If this is a zero-length-packet (ZLP)
|
||||||
// Set the ZLP flag
|
// Set the ZLP flag
|
||||||
if(size == 0)
|
if (size == 0) {
|
||||||
transfer->flags |= NRF_DRV_USBD_TRANSFER_ZLP_FLAG;
|
transfer->flags |= NRF_DRV_USBD_TRANSFER_ZLP_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
ret_code_t ret = nrf_drv_usbd_ep_transfer(get_nordic_endpoint(endpoint), transfer);
|
ret_code_t ret = nrf_drv_usbd_ep_transfer(get_nordic_endpoint(endpoint), transfer);
|
||||||
return (ret == NRF_SUCCESS);
|
return (ret == NRF_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::endpoint_abort(usb_ep_t endpoint) {
|
void USBPhyHw::endpoint_abort(usb_ep_t endpoint)
|
||||||
nrf_drv_usbd_ep_abort(get_nordic_endpoint(endpoint));
|
{
|
||||||
|
nrf_drv_usbd_ep_abort(get_nordic_endpoint(endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::process() {
|
void USBPhyHw::process()
|
||||||
|
{
|
||||||
|
|
||||||
if (usb_event_type == USB_HW_EVENT_USBD) {
|
if (usb_event_type == USB_HW_EVENT_USBD) {
|
||||||
|
|
||||||
// Process regular USBD events
|
// Process regular USBD events
|
||||||
switch (usb_event.type) {
|
switch (usb_event.type) {
|
||||||
case NRF_DRV_USBD_EVT_SUSPEND:
|
case NRF_DRV_USBD_EVT_SUSPEND:
|
||||||
events->suspend(true);
|
events->suspend(true);
|
||||||
break;
|
break;
|
||||||
case NRF_DRV_USBD_EVT_RESUME:
|
case NRF_DRV_USBD_EVT_RESUME:
|
||||||
events->suspend(false);
|
events->suspend(false);
|
||||||
break;
|
break;
|
||||||
case NRF_DRV_USBD_EVT_WUREQ:
|
case NRF_DRV_USBD_EVT_WUREQ:
|
||||||
break;
|
break;
|
||||||
case NRF_DRV_USBD_EVT_RESET:
|
case NRF_DRV_USBD_EVT_RESET:
|
||||||
this->_reset();
|
this->_reset();
|
||||||
events->reset();
|
events->reset();
|
||||||
break;
|
break;
|
||||||
case NRF_DRV_USBD_EVT_SOF:
|
case NRF_DRV_USBD_EVT_SOF:
|
||||||
if(sof_enabled)
|
if (sof_enabled) {
|
||||||
events->sof(usb_event.data.sof.framecnt);
|
events->sof(usb_event.data.sof.framecnt);
|
||||||
break;
|
}
|
||||||
case NRF_DRV_USBD_EVT_EPTRANSFER:
|
break;
|
||||||
if(usb_event.data.eptransfer.status == NRF_USBD_EP_OK)
|
case NRF_DRV_USBD_EVT_EPTRANSFER:
|
||||||
{
|
if (usb_event.data.eptransfer.status == NRF_USBD_EP_OK) {
|
||||||
if(!nrf_drv_usbd_ep_stall_check(usb_event.data.eptransfer.ep))
|
if (!nrf_drv_usbd_ep_stall_check(usb_event.data.eptransfer.ep)) {
|
||||||
{
|
if (IS_IN_EP(usb_event.data.eptransfer.ep)) {
|
||||||
if(IS_IN_EP(usb_event.data.eptransfer.ep))
|
if ((usb_event.data.eptransfer.ep & 0x7F) == 0) {
|
||||||
{
|
events->ep0_in();
|
||||||
if((usb_event.data.eptransfer.ep & 0x7F) == 0)
|
} else {
|
||||||
events->ep0_in();
|
events->in((usb_ep_t) usb_event.data.eptransfer.ep);
|
||||||
else
|
}
|
||||||
events->in((usb_ep_t) usb_event.data.eptransfer.ep);
|
} else {
|
||||||
}
|
if ((usb_event.data.eptransfer.ep & 0x7F) == 0) {
|
||||||
else
|
events->ep0_out();
|
||||||
{
|
} else {
|
||||||
if((usb_event.data.eptransfer.ep & 0x7F) == 0)
|
events->out((usb_ep_t) usb_event.data.eptransfer.ep);
|
||||||
events->ep0_out();
|
}
|
||||||
else
|
}
|
||||||
events->out((usb_ep_t) usb_event.data.eptransfer.ep);
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
case NRF_DRV_USBD_EVT_SETUP: {
|
||||||
break;
|
nrf_drv_usbd_ep_stall_clear(NRF_DRV_USBD_EPIN0);
|
||||||
case NRF_DRV_USBD_EVT_SETUP: {
|
nrf_drv_usbd_ep_stall_clear(NRF_DRV_USBD_EPOUT0);
|
||||||
nrf_drv_usbd_ep_stall_clear(NRF_DRV_USBD_EPIN0);
|
|
||||||
nrf_drv_usbd_ep_stall_clear(NRF_DRV_USBD_EPOUT0);
|
|
||||||
|
|
||||||
// Copy the setup packet into the internal buffer
|
// Copy the setup packet into the internal buffer
|
||||||
nrf_drv_usbd_setup_get(&setup_buf);
|
nrf_drv_usbd_setup_get(&setup_buf);
|
||||||
|
|
||||||
// Notify the Mbed stack
|
// Notify the Mbed stack
|
||||||
events->ep0_setup();
|
events->ep0_setup();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} else if (usb_event_type == USB_HW_EVENT_POWER) {
|
||||||
else if (usb_event_type == USB_HW_EVENT_POWER)
|
// Process USB power-related events
|
||||||
{
|
switch (usb_power_event) {
|
||||||
// Process USB power-related events
|
case NRFX_POWER_USB_EVT_DETECTED:
|
||||||
switch (usb_power_event) {
|
if (this->connect_enabled) {
|
||||||
case NRFX_POWER_USB_EVT_DETECTED:
|
if (!nrf_drv_usbd_is_enabled()) {
|
||||||
if(this->connect_enabled) {
|
nrf_drv_usbd_enable();
|
||||||
if(!nrf_drv_usbd_is_enabled())
|
}
|
||||||
nrf_drv_usbd_enable();
|
events->power(true);
|
||||||
events->power(true);
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case NRFX_POWER_USB_EVT_REMOVED:
|
||||||
case NRFX_POWER_USB_EVT_REMOVED:
|
events->power(false);
|
||||||
events->power(false);
|
break;
|
||||||
break;
|
case NRFX_POWER_USB_EVT_READY:
|
||||||
case NRFX_POWER_USB_EVT_READY:
|
if (!nrf_drv_usbd_is_started()) {
|
||||||
if(!nrf_drv_usbd_is_started())
|
nrf_drv_usbd_start(true);
|
||||||
nrf_drv_usbd_start(true);
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
}
|
} else if (usb_event_type == USB_HW_EVENT_VIRTUAL_STATUS) {
|
||||||
else if (usb_event_type == USB_HW_EVENT_VIRTUAL_STATUS)
|
// Notify Mbed stack of status stage transfer completion
|
||||||
{
|
if (setup_buf.bmRequestType & SETUP_TRANSFER_DIR_MASK) { // DATA IN transfer, Status OUT transfer
|
||||||
// Notify Mbed stack of status stage transfer completion
|
events->ep0_out();
|
||||||
if(setup_buf.bmRequestType & SETUP_TRANSFER_DIR_MASK) // DATA IN transfer, Status OUT transfer
|
} else { // DATA OUT transfer, Status IN transfer
|
||||||
events->ep0_out();
|
events->ep0_in();
|
||||||
else // DATA OUT transfer, Status IN transfer
|
}
|
||||||
events->ep0_in();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Unflag the event type
|
// Unflag the event type
|
||||||
usb_event_type = USB_HW_EVENT_NONE;
|
usb_event_type = USB_HW_EVENT_NONE;
|
||||||
|
|
||||||
// Re-enable interrupt
|
// Re-enable interrupt
|
||||||
enable_usb_interrupts();
|
enable_usb_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::_usb_event_handler(
|
void USBPhyHw::_usb_event_handler(
|
||||||
nrf_drv_usbd_evt_t const * const p_event) {
|
nrf_drv_usbd_evt_t const *const p_event)
|
||||||
disable_usb_interrupts();
|
{
|
||||||
// Copy the event data into internal memory
|
disable_usb_interrupts();
|
||||||
memcpy(&instance->usb_event, p_event, sizeof(instance->usb_event));
|
// Copy the event data into internal memory
|
||||||
// Tell the upper layers of the stack to process the event
|
memcpy(&instance->usb_event, p_event, sizeof(instance->usb_event));
|
||||||
instance->usb_event_type = USB_HW_EVENT_USBD;
|
// Tell the upper layers of the stack to process the event
|
||||||
instance->events->start_process();
|
instance->usb_event_type = USB_HW_EVENT_USBD;
|
||||||
|
instance->events->start_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::_usb_power_event_handler(nrfx_power_usb_evt_t event) {
|
void USBPhyHw::_usb_power_event_handler(nrfx_power_usb_evt_t event)
|
||||||
disable_usb_interrupts();
|
{
|
||||||
// Copy the event data into internal memory
|
disable_usb_interrupts();
|
||||||
instance->usb_power_event = event;
|
// Copy the event data into internal memory
|
||||||
// Tell the upper layers of the stack to process the event
|
instance->usb_power_event = event;
|
||||||
instance->usb_event_type = USB_HW_EVENT_POWER;
|
// Tell the upper layers of the stack to process the event
|
||||||
instance->events->start_process();
|
instance->usb_event_type = USB_HW_EVENT_POWER;
|
||||||
|
instance->events->start_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::_usb_virtual_status_event_handler(void) {
|
void USBPhyHw::_usb_virtual_status_event_handler(void)
|
||||||
disable_usb_interrupts();
|
{
|
||||||
|
disable_usb_interrupts();
|
||||||
|
|
||||||
// Tell the upper layers of the stack to process the event
|
// Tell the upper layers of the stack to process the event
|
||||||
instance->usb_event_type = USB_HW_EVENT_VIRTUAL_STATUS;
|
instance->usb_event_type = USB_HW_EVENT_VIRTUAL_STATUS;
|
||||||
instance->events->start_process();
|
instance->events->start_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
nrf_drv_usbd_transfer_t* USBPhyHw::get_transfer_buffer(usb_ep_t endpoint) {
|
nrf_drv_usbd_transfer_t *USBPhyHw::get_transfer_buffer(usb_ep_t endpoint)
|
||||||
// Index is base endpoint number * 2 (output), add 1 for input endpoints
|
{
|
||||||
return &transfer_buf[(((endpoint & 0x7F) << 1) + ((endpoint & 0x80) >> 7))];
|
// Index is base endpoint number * 2 (output), add 1 for input endpoints
|
||||||
|
return &transfer_buf[(((endpoint & 0x7F) << 1) + ((endpoint & 0x80) >> 7))];
|
||||||
}
|
}
|
||||||
|
|
||||||
nrf_drv_usbd_ep_t USBPhyHw::get_nordic_endpoint(usb_ep_t endpoint) {
|
nrf_drv_usbd_ep_t USBPhyHw::get_nordic_endpoint(usb_ep_t endpoint)
|
||||||
// Clear the most-significant-bit (input endpoint flag)
|
{
|
||||||
return (nrf_drv_usbd_ep_t) endpoint;
|
// Clear the most-significant-bit (input endpoint flag)
|
||||||
|
return (nrf_drv_usbd_ep_t) endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::_reset(void)
|
void USBPhyHw::_reset(void)
|
||||||
{
|
{
|
||||||
// Disable all endpoints except for control endpoints
|
// Disable all endpoints except for control endpoints
|
||||||
nrf_drv_usbd_ep_default_config();
|
nrf_drv_usbd_ep_default_config();
|
||||||
|
|
||||||
nrf_drv_usbd_setup_clear();
|
nrf_drv_usbd_setup_clear();
|
||||||
|
|
||||||
usb_event_type = USB_HW_EVENT_NONE;
|
usb_event_type = USB_HW_EVENT_NONE;
|
||||||
|
|
||||||
// Clear all endpoint interrupts
|
// Clear all endpoint interrupts
|
||||||
NRFX_IRQ_PENDING_CLEAR(USBD_IRQn);
|
NRFX_IRQ_PENDING_CLEAR(USBD_IRQn);
|
||||||
nrf_usbd_event_clear((nrf_usbd_event_t)0x01FFFFFF);
|
nrf_usbd_event_clear((nrf_usbd_event_t)0x01FFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::enable_usb_interrupts(void) {
|
void USBPhyHw::enable_usb_interrupts(void)
|
||||||
// Enable USB and USB-related power interrupts
|
{
|
||||||
NRFX_IRQ_ENABLE(USBD_IRQn);
|
// Enable USB and USB-related power interrupts
|
||||||
nrfx_power_usbevt_enable();
|
NRFX_IRQ_ENABLE(USBD_IRQn);
|
||||||
|
nrfx_power_usbevt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::disable_usb_interrupts(void) {
|
void USBPhyHw::disable_usb_interrupts(void)
|
||||||
// Disable USB and USB-related power interrupts
|
{
|
||||||
NRFX_IRQ_DISABLE(USBD_IRQn);
|
// Disable USB and USB-related power interrupts
|
||||||
nrfx_power_usbevt_disable();
|
NRFX_IRQ_DISABLE(USBD_IRQn);
|
||||||
|
nrfx_power_usbevt_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void power_usb_event_handler(nrfx_power_usb_evt_t event) {
|
static void power_usb_event_handler(nrfx_power_usb_evt_t event)
|
||||||
if(instance) {
|
{
|
||||||
// Pass the event on to the USBPhyHW instance
|
if (instance) {
|
||||||
instance->_usb_power_event_handler(event);
|
// Pass the event on to the USBPhyHW instance
|
||||||
}
|
instance->_usb_power_event_handler(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event) {
|
static void usbd_event_handler(nrf_drv_usbd_evt_t const *const p_event)
|
||||||
if(instance) {
|
{
|
||||||
// Pass the event on to the USBPhyHW instance
|
if (instance) {
|
||||||
instance->_usb_event_handler(p_event);
|
// Pass the event on to the USBPhyHW instance
|
||||||
}
|
instance->_usb_event_handler(p_event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBD_HAL_IRQHandler(void)
|
void USBD_HAL_IRQHandler(void)
|
||||||
{
|
{
|
||||||
// Process the virtual status stage transfer event
|
// Process the virtual status stage transfer event
|
||||||
if(virtual_status_xfer_event)
|
if (virtual_status_xfer_event) {
|
||||||
{
|
if (instance) {
|
||||||
if(instance) {
|
instance->_usb_virtual_status_event_handler();
|
||||||
instance->_usb_virtual_status_event_handler();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual_status_xfer_event = false;
|
virtual_status_xfer_event = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
// Call Nordic driver IRQ handler
|
// Call Nordic driver IRQ handler
|
||||||
USBD_IRQHandler();
|
USBD_IRQHandler();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue