mirror of https://github.com/ARMmbed/mbed-os.git
Reviewing functions. Added critical sections to some functions that access state information.
parent
f00053820b
commit
c006888557
|
@ -16,8 +16,31 @@
|
||||||
|
|
||||||
#include "USBPhyHw.h"
|
#include "USBPhyHw.h"
|
||||||
|
|
||||||
|
#include "platform/mbed_critical.h"
|
||||||
|
|
||||||
#include "nrf_clock.h"
|
#include "nrf_clock.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO list for nRF52840 USBD driver
|
||||||
|
*
|
||||||
|
* 1.) Properly enable/disable start-of-frame interrupt.
|
||||||
|
*
|
||||||
|
* Description: Currently, start-of-frame interrupts are masked by a flag at this layer
|
||||||
|
* but still cause the processor to be interrupted for no purpose.
|
||||||
|
*
|
||||||
|
* The Nordic driver requires you to call nrf_drv_start(bool)
|
||||||
|
* with a boolean flag indicating whether it should enable start-of-frame
|
||||||
|
* interrupts or not. From the datasheet it seems to be possible to
|
||||||
|
* enable/disable SoF interrupts on the fly, but the fact that they
|
||||||
|
* force you to make the SoF decision during "start" makes me suspicious
|
||||||
|
* the underlying driver may manage/use the SoF flag in other ways.
|
||||||
|
*
|
||||||
|
* Next steps: Investigate how the SoF flag is used during "nrf_drv_start" and
|
||||||
|
* determine if enabling/disabling this interrupt would cause internal problems
|
||||||
|
* with the Nordic USBD driver
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
#define MAX_PACKET_SIZE_SETUP NRF_DRV_USBD_EPSIZE
|
#define MAX_PACKET_SIZE_SETUP NRF_DRV_USBD_EPSIZE
|
||||||
#define MAX_PACKET_NON_ISO NRF_DRV_USBD_EPSIZE
|
#define MAX_PACKET_NON_ISO NRF_DRV_USBD_EPSIZE
|
||||||
#define MAX_PACKET_ISO NRF_DRV_USBD_ISOSIZE
|
#define MAX_PACKET_ISO NRF_DRV_USBD_ISOSIZE
|
||||||
|
@ -79,11 +102,6 @@ void USBPhyHw::init(USBPhyEvents *events) {
|
||||||
ret = nrf_drv_power_init(NULL);
|
ret = nrf_drv_power_init(NULL);
|
||||||
APP_ERROR_CHECK(ret);
|
APP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
/* Configure selected size of the packed on EP0 */
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
// Register callback for USB Power events
|
// Register callback for USB Power events
|
||||||
static const nrf_drv_power_usbevt_config_t config = { .handler =
|
static const nrf_drv_power_usbevt_config_t config = { .handler =
|
||||||
power_usb_event_handler };
|
power_usb_event_handler };
|
||||||
|
@ -94,13 +112,17 @@ void USBPhyHw::init(USBPhyEvents *events) {
|
||||||
ret = nrf_drv_usbd_init(usbd_event_handler);
|
ret = nrf_drv_usbd_init(usbd_event_handler);
|
||||||
APP_ERROR_CHECK(ret);
|
APP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
/* Configure selected size of the packed on EP0 */
|
||||||
|
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);
|
||||||
|
|
||||||
// Store a reference to this instance
|
// Store a reference to this instance
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
// Enable IRQ
|
// Enable IRQ
|
||||||
NVIC_SetVector(USBD_IRQn, (uint32_t)USBD_IRQHandler);
|
NVIC_SetVector(USBD_IRQn, (uint32_t)USBD_IRQHandler);
|
||||||
NVIC_SetPriority(USBD_IRQn, 7);
|
//NVIC_SetPriority(USBD_IRQn, 7);
|
||||||
NVIC_EnableIRQ(USBD_IRQn);
|
//NVIC_EnableIRQ(USBD_IRQn); // This is handled by the Nordic driver
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::deinit() {
|
void USBPhyHw::deinit() {
|
||||||
|
@ -109,10 +131,13 @@ void USBPhyHw::deinit() {
|
||||||
// Disable the USB Device driver
|
// Disable the USB Device driver
|
||||||
ret_code_t ret = nrf_drv_usbd_uninit();
|
ret_code_t ret = nrf_drv_usbd_uninit();
|
||||||
APP_ERROR_CHECK(ret);
|
APP_ERROR_CHECK(ret);
|
||||||
NVIC_DisableIRQ(USBD_IRQn);
|
//NVIC_DisableIRQ(USBD_IRQn); // This is handled by the Nordic driver
|
||||||
|
|
||||||
// Clear the instance pointer?
|
// Disable the power peripheral driver
|
||||||
//instance = 0;
|
nrf_drv_power_uninit();
|
||||||
|
|
||||||
|
// Clear the instance pointer
|
||||||
|
instance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBPhyHw::powered() {
|
bool USBPhyHw::powered() {
|
||||||
|
@ -142,7 +167,7 @@ void USBPhyHw::connect() {
|
||||||
|
|
||||||
if(nrf_drv_power_usbstatus_get() == NRF_DRV_POWER_USB_STATE_READY
|
if(nrf_drv_power_usbstatus_get() == NRF_DRV_POWER_USB_STATE_READY
|
||||||
&& !nrf_drv_usbd_is_started())
|
&& !nrf_drv_usbd_is_started())
|
||||||
nrf_drv_usbd_start(false);//nrf_drv_usbd_start(true);
|
nrf_drv_usbd_start(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,8 +177,8 @@ void USBPhyHw::disconnect() {
|
||||||
|
|
||||||
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())
|
if(nrf_drv_usbd_is_enabled())
|
||||||
// nrf_drv_usbd_disable();
|
nrf_drv_usbd_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::configure() {
|
void USBPhyHw::configure() {
|
||||||
|
@ -214,20 +239,30 @@ const usb_ep_table_t *USBPhyHw::endpoint_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();
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::ep0_read(uint8_t *data, uint32_t size) {
|
void USBPhyHw::ep0_read(uint8_t *data, uint32_t size) {
|
||||||
|
@ -454,10 +489,10 @@ void USBPhyHw::process() {
|
||||||
events->power(false);
|
events->power(false);
|
||||||
break;
|
break;
|
||||||
case NRF_DRV_POWER_USB_EVT_READY:
|
case NRF_DRV_POWER_USB_EVT_READY:
|
||||||
if(this->connect_enabled) {
|
//if(this->connect_enabled) { // Not really necessary (only happens after enabled)
|
||||||
if(!nrf_drv_usbd_is_started())
|
if(!nrf_drv_usbd_is_started())
|
||||||
nrf_drv_usbd_start(false);//nrf_drv_usbd_start(true);
|
nrf_drv_usbd_start(true);
|
||||||
}
|
//}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
|
@ -468,7 +503,7 @@ void USBPhyHw::process() {
|
||||||
usb_event_type = USB_HW_EVENT_NONE;
|
usb_event_type = USB_HW_EVENT_NONE;
|
||||||
|
|
||||||
// Re-enable interrupt
|
// Re-enable interrupt
|
||||||
NVIC_ClearPendingIRQ(USBD_IRQn);
|
//NVIC_ClearPendingIRQ(USBD_IRQn);
|
||||||
enable_usb_interrupts();
|
enable_usb_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +576,6 @@ static void power_usb_event_handler(nrf_drv_power_usb_evt_t 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) {
|
if(instance) {
|
||||||
NVIC_DisableIRQ(USBD_IRQn);
|
|
||||||
// Pass the event on to the USBPhyHW instance
|
// Pass the event on to the USBPhyHW instance
|
||||||
instance->_usb_event_handler(p_event);
|
instance->_usb_event_handler(p_event);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue