Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ Notable contributors
- Add new DCD and HCD port for Mentor musb with MSP432E4
- Add new class driver for USB Video Class (UVC 1.5)

`Matej Fitos <https://github.com/Matt-prog>`__
-----------------------------------------------

- Improved HFCLK management for nRF5x

`Nathan Conrad <https://github.com/pigrew>`__
---------------------------------------------

Expand Down
185 changes: 100 additions & 85 deletions src/portable/nordic/nrf5x/dcd_nrf5x.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
* Copyright (c) 2023 Matej Fitos
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -34,6 +35,7 @@
#include "nrf_power.h"
#include "nrfx_usbd_errata.h"
#include "device/dcd.h"
#include "dcd_nrf5x_cb.h"

// TODO remove later
#include "device/usbd.h"
Expand Down Expand Up @@ -92,6 +94,91 @@ static struct
atomic_bool dma_running;
}_dcd;

//--------------------------------------------------------------------+
// HFCLK helper
//--------------------------------------------------------------------+
#ifdef SOFTDEVICE_PRESENT

// For enable/disable hfclk with SoftDevice
#include "nrf_mbr.h"
#include "nrf_sdm.h"
#include "nrf_soc.h"

#ifndef SD_MAGIC_NUMBER
#define SD_MAGIC_NUMBER 0x51B1E5DB
#endif

static inline bool is_sd_existed(void)
{
return *((uint32_t*)(SOFTDEVICE_INFO_STRUCT_ADDRESS+4)) == SD_MAGIC_NUMBER;
}

// check if SD is existed and enabled
static inline bool is_sd_enabled(void)
{
if ( !is_sd_existed() ) return false;

uint8_t sd_en = false;
(void) sd_softdevice_is_enabled(&sd_en);
return sd_en;
}
#endif

static bool hfclk_running(void)
{
#ifdef SOFTDEVICE_PRESENT
if ( is_sd_enabled() )
{
uint32_t is_running = 0;
(void) sd_clock_hfclk_is_running(&is_running);
return (is_running ? true : false);
}
#endif

return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY);
}

static void hfclk_enable(void)
{
#if CFG_TUSB_OS == OPT_OS_MYNEWT
usb_clock_request();
return;
#else

// already running, nothing to do
if ( hfclk_running() ) return;

#ifdef SOFTDEVICE_PRESENT
if ( is_sd_enabled() )
{
(void)sd_clock_hfclk_request();
return;
}
#endif

dcd_enable_hfclk();
#endif
}

static void hfclk_disable(void)
{
#if CFG_TUSB_OS == OPT_OS_MYNEWT
usb_clock_release();
return;
#else

#ifdef SOFTDEVICE_PRESENT
if ( is_sd_enabled() )
{
(void)sd_clock_hfclk_release();
return;
}
#endif

dcd_disable_hfclk();
#endif
}

/*------------------------------------------------------------------*/
/* Control / Bulk / Interrupt (CBI) Transfer
*------------------------------------------------------------------*/
Expand Down Expand Up @@ -233,6 +320,18 @@ static void xact_in_dma(uint8_t epnum)
void dcd_init (uint8_t rhport)
{
TU_LOG1("dcd init\r\n");

#ifdef SOFTDEVICE_PRESENT
if(!is_sd_enabled()){
#endif
if(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk){
//Bootloader already initialized USB
dcd_enable_hfclk(); //Just reserving HFCLK
}
#ifdef SOFTDEVICE_PRESENT
}
#endif

(void) rhport;
}

Expand Down Expand Up @@ -859,92 +958,8 @@ void dcd_int_handler(uint8_t rhport)
}

//--------------------------------------------------------------------+
// HFCLK helper
//--------------------------------------------------------------------+
#ifdef SOFTDEVICE_PRESENT

// For enable/disable hfclk with SoftDevice
#include "nrf_mbr.h"
#include "nrf_sdm.h"
#include "nrf_soc.h"

#ifndef SD_MAGIC_NUMBER
#define SD_MAGIC_NUMBER 0x51B1E5DB
#endif

static inline bool is_sd_existed(void)
{
return *((uint32_t*)(SOFTDEVICE_INFO_STRUCT_ADDRESS+4)) == SD_MAGIC_NUMBER;
}

// check if SD is existed and enabled
static inline bool is_sd_enabled(void)
{
if ( !is_sd_existed() ) return false;

uint8_t sd_en = false;
(void) sd_softdevice_is_enabled(&sd_en);
return sd_en;
}
#endif

static bool hfclk_running(void)
{
#ifdef SOFTDEVICE_PRESENT
if ( is_sd_enabled() )
{
uint32_t is_running = 0;
(void) sd_clock_hfclk_is_running(&is_running);
return (is_running ? true : false);
}
#endif

return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY);
}

static void hfclk_enable(void)
{
#if CFG_TUSB_OS == OPT_OS_MYNEWT
usb_clock_request();
return;
#else

// already running, nothing to do
if ( hfclk_running() ) return;

#ifdef SOFTDEVICE_PRESENT
if ( is_sd_enabled() )
{
(void)sd_clock_hfclk_request();
return;
}
#endif

nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART);
#endif
}

static void hfclk_disable(void)
{
#if CFG_TUSB_OS == OPT_OS_MYNEWT
usb_clock_release();
return;
#else

#ifdef SOFTDEVICE_PRESENT
if ( is_sd_enabled() )
{
(void)sd_clock_hfclk_release();
return;
}
#endif

nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
#endif
}

// Power & Clock Peripheral on nRF5x to manage USB
//--------------------------------------------------------------------+
//
// USB Bus power is managed by Power module, there are 3 VBUS power events:
// Detected, Ready, Removed. Upon these power events, This function will
Expand Down
43 changes: 43 additions & 0 deletions src/portable/nordic/nrf5x/dcd_nrf5x_cb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2023 Matej Fitoš
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

#include "dcd_nrf5x_cb.h"
#include "nrf.h"
#include "nrf_clock.h"

//Do not forget to include dcd_nrf5x_cb.h file in the code file, where funtion will be overridden

//Override this function, to manage HFCLK activation by your own code
//This function is called only when SoftDevice is not present
__WEAK void dcd_enable_hfclk(void){
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART);
}

//Override this function, to manage HFCLK deactivation by your own code
//This function is called only when SoftDevice is not present
__WEAK void dcd_disable_hfclk(void){
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
}
40 changes: 40 additions & 0 deletions src/portable/nordic/nrf5x/dcd_nrf5x_cb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2023, Matej Fitoš
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef DCD_NRF5X_H_
#define DCD_NRF5X_H_

#ifdef __cplusplus
extern "C" {
#endif

void dcd_enable_hfclk(void);

void dcd_disable_hfclk(void);

#ifdef __cplusplus
}
#endif

#endif /* DCD_NRF5X_H_ */