mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-14 04:18:56 +00:00
update code, remove nrf_drv_clock dependency
This commit is contained in:
parent
2f0fcf80e0
commit
9f5fcb64ed
@ -36,7 +36,9 @@
|
||||
|
||||
#include "board_pca10056.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
#include "nrf_drv_systick.h"
|
||||
#include "nrf_drv_power.h"
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* MACRO TYPEDEF CONSTANT ENUM
|
||||
@ -55,6 +57,12 @@
|
||||
*------------------------------------------------------------------*/
|
||||
void board_init(void)
|
||||
{
|
||||
// Config clock source: XTAL or RC in sdk_config.h
|
||||
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_CONFIG_LF_SRC << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
|
||||
|
||||
nrf_drv_power_init(NULL);
|
||||
|
||||
nrf_gpio_cfg_output(LED_1);
|
||||
|
||||
SysTick_Config(SystemCoreClock/1000);
|
||||
|
141
hw/mcu/nordic/nrf52/sdk/drivers_nrf/usbd/nrf_drv_usbd_errata.h
Normal file
141
hw/mcu/nordic/nrf52/sdk/drivers_nrf/usbd/nrf_drv_usbd_errata.h
Normal file
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NRF_DRV_USBD_ERRATA_H__
|
||||
#define NRF_DRV_USBD_ERRATA_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
/**
|
||||
* @defgroup nrf_drv_usbd_errata Functions to check if selected PAN is present in current chip
|
||||
* @{
|
||||
* @ingroup nrf_drv_usbd
|
||||
*
|
||||
* Functions here are checking the presence of an error in current chip.
|
||||
* The checking is done at runtime based on the microcontroller version.
|
||||
* This file is subject to removal when nRF51840 prototype support is removed.
|
||||
*/
|
||||
|
||||
#ifndef NRF_DRV_USBD_ERRATA_ENABLE
|
||||
/**
|
||||
* @brief The constant that informs if errata should be enabled at all
|
||||
*
|
||||
* If this constant is set to 0, all the Errata bug fixes will be automatically disabled.
|
||||
*/
|
||||
#define NRF_DRV_USBD_ERRATA_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Internal auxiliary function to check if the program is running on NRF52840 chip
|
||||
* @retval true It is NRF52480 chip
|
||||
* @retval false It is other chip
|
||||
*/
|
||||
static inline bool nrf_drv_usbd_errata_type_52840(void)
|
||||
{
|
||||
return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) &&
|
||||
(((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal auxiliary function to check if the program is running on first sample of
|
||||
* NRF52840 chip
|
||||
* @retval true It is NRF52480 chip and it is first sample version
|
||||
* @retval false It is other chip
|
||||
*/
|
||||
static inline bool nrf_drv_usbd_errata_type_52840_proto1(void)
|
||||
{
|
||||
return ( nrf_drv_usbd_errata_type_52840() &&
|
||||
( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
|
||||
( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to check if chip requires errata 104
|
||||
*
|
||||
* Errata: USBD: EPDATA event is not always generated.
|
||||
*
|
||||
* @retval true Errata should be implemented
|
||||
* @retval false Errata should not be implemented
|
||||
*/
|
||||
static inline bool nrf_drv_usbd_errata_104(void)
|
||||
{
|
||||
return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to check if chip requires errata 154
|
||||
*
|
||||
* Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task.
|
||||
*
|
||||
* @retval true Errata should be implemented
|
||||
* @retval false Errata should not be implemented
|
||||
*/
|
||||
static inline bool nrf_drv_usbd_errata_154(void)
|
||||
{
|
||||
return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to check if chip requires errata 166
|
||||
*
|
||||
* Errata: ISO double buffering not functional
|
||||
*
|
||||
* @retval true Errata should be implemented
|
||||
* @retval false Errata should not be implemented
|
||||
*/
|
||||
static inline bool nrf_drv_usbd_errata_166(void)
|
||||
{
|
||||
return NRF_DRV_USBD_ERRATA_ENABLE && true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to check if chip requires errata ???
|
||||
*
|
||||
* Errata: SIZE.EPOUT not writable
|
||||
*
|
||||
* @retval true Errata should be implemented
|
||||
* @retval false Errata should not be implemented
|
||||
*/
|
||||
static inline bool nrf_drv_usbd_errata_sizeepout_rw(void)
|
||||
{
|
||||
return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
|
||||
}
|
||||
|
||||
/** @} */
|
||||
#endif /* NRF_DRV_USBD_ERRATA_H__ */
|
@ -52,126 +52,8 @@
|
||||
// <e> APP_USBD_ENABLED - app_usbd - USB Device library
|
||||
//==========================================================
|
||||
#ifndef APP_USBD_ENABLED
|
||||
#define APP_USBD_ENABLED 1
|
||||
#define APP_USBD_ENABLED 0
|
||||
#endif
|
||||
// <s> APP_USBD_VID - Vendor ID
|
||||
|
||||
// <i> Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
|
||||
#ifndef APP_USBD_VID
|
||||
#define APP_USBD_VID 0x1915
|
||||
#endif
|
||||
|
||||
// <s> APP_USBD_PID - Product ID
|
||||
|
||||
// <i> Selected Product ID
|
||||
#ifndef APP_USBD_PID
|
||||
#define APP_USBD_PID 0x520F
|
||||
#endif
|
||||
|
||||
// <o> APP_USBD_DEVICE_VER_MAJOR - Device version, major part <0-99>
|
||||
|
||||
|
||||
// <i> Device version, will be converted automatically to BCD notation. Use just decimal values.
|
||||
|
||||
#ifndef APP_USBD_DEVICE_VER_MAJOR
|
||||
#define APP_USBD_DEVICE_VER_MAJOR 1
|
||||
#endif
|
||||
|
||||
// <o> APP_USBD_DEVICE_VER_MINOR - Device version, minor part <0-99>
|
||||
|
||||
|
||||
// <i> Device version, will be converted automatically to BCD notation. Use just decimal values.
|
||||
|
||||
#ifndef APP_USBD_DEVICE_VER_MINOR
|
||||
#define APP_USBD_DEVICE_VER_MINOR 0
|
||||
#endif
|
||||
|
||||
// <e> APP_USBD_EVENT_QUEUE_ENABLE - Enable event queue
|
||||
|
||||
// <i> This is the default configuration when all the events are placed into internal queue.
|
||||
// <i> Disable it when external queue is used like app_scheduler or if you wish to process all events inside interrupts.
|
||||
// <i> Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context.
|
||||
// <i> Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable and disable.
|
||||
//==========================================================
|
||||
#ifndef APP_USBD_EVENT_QUEUE_ENABLE
|
||||
#define APP_USBD_EVENT_QUEUE_ENABLE 1
|
||||
#endif
|
||||
// <o> APP_USBD_EVENT_QUEUE_SIZE - The size of event queue <16-64>
|
||||
|
||||
|
||||
// <i> The size of the queue for the events that would be processed in the main loop.
|
||||
|
||||
#ifndef APP_USBD_EVENT_QUEUE_SIZE
|
||||
#define APP_USBD_EVENT_QUEUE_SIZE 32
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// <q> APP_USBD_CONFIG_PROVIDE_SOF_TIMESTAMP - Provide a function that generates timestamps for logs based on the current SOF
|
||||
|
||||
|
||||
// <i> The function app_usbd_sof_timestamp_get will be implemented if the logger is enabled.
|
||||
// <i> Use it when initializing the logger.
|
||||
// <i> SOF processing will be always enabled when this configuration parameter is active.
|
||||
// <i> Notice that this option is configured outside of APP_USBD_CONFIG_LOG_ENABLED.
|
||||
// <i> This means that it will work even if the logging in this very module is disabled.
|
||||
|
||||
#ifndef APP_USBD_CONFIG_PROVIDE_SOF_TIMESTAMP
|
||||
#define APP_USBD_CONFIG_PROVIDE_SOF_TIMESTAMP 0
|
||||
#endif
|
||||
|
||||
// <e> APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module
|
||||
//==========================================================
|
||||
#ifndef APP_USBD_CONFIG_LOG_ENABLED
|
||||
#define APP_USBD_CONFIG_LOG_ENABLED 0
|
||||
#endif
|
||||
// <o> APP_USBD_CONFIG_LOG_LEVEL - Default Severity level
|
||||
|
||||
// <0=> Off
|
||||
// <1=> Error
|
||||
// <2=> Warning
|
||||
// <3=> Info
|
||||
// <4=> Debug
|
||||
|
||||
#ifndef APP_USBD_CONFIG_LOG_LEVEL
|
||||
#define APP_USBD_CONFIG_LOG_LEVEL 3
|
||||
#endif
|
||||
|
||||
// <o> APP_USBD_CONFIG_INFO_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef APP_USBD_CONFIG_INFO_COLOR
|
||||
#define APP_USBD_CONFIG_INFO_COLOR 0
|
||||
#endif
|
||||
|
||||
// <o> APP_USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef APP_USBD_CONFIG_DEBUG_COLOR
|
||||
#define APP_USBD_CONFIG_DEBUG_COLOR 0
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// </e>
|
||||
|
||||
// <e> CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver
|
||||
//==========================================================
|
||||
@ -410,7 +292,7 @@
|
||||
// <e> USBD_ENABLED - nrf_drv_usbd - USB driver
|
||||
//==========================================================
|
||||
#ifndef USBD_ENABLED
|
||||
#define USBD_ENABLED 1
|
||||
#define USBD_ENABLED 0
|
||||
#endif
|
||||
// <o> USBD_CONFIG_IRQ_PRIORITY - Interrupt priority
|
||||
|
||||
@ -573,7 +455,7 @@
|
||||
|
||||
|
||||
#ifndef APP_USBD_CLASS_CDC_ACM_ENABLED
|
||||
#define APP_USBD_CLASS_CDC_ACM_ENABLED 1
|
||||
#define APP_USBD_CLASS_CDC_ACM_ENABLED 0
|
||||
#endif
|
||||
|
||||
// <q> BUTTON_ENABLED - app_button - buttons handling module
|
||||
@ -608,7 +490,7 @@
|
||||
// <e> NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module
|
||||
//==========================================================
|
||||
#ifndef NRF_BALLOC_ENABLED
|
||||
#define NRF_BALLOC_ENABLED 1
|
||||
#define NRF_BALLOC_ENABLED 0
|
||||
#endif
|
||||
// <e> NRF_BALLOC_CONFIG_DEBUG_ENABLED - Enables debug mode in the module.
|
||||
//==========================================================
|
||||
@ -665,7 +547,7 @@
|
||||
|
||||
|
||||
#ifndef NRF_MEMOBJ_ENABLED
|
||||
#define NRF_MEMOBJ_ENABLED 1
|
||||
#define NRF_MEMOBJ_ENABLED 0
|
||||
#endif
|
||||
|
||||
// <q> NRF_STRERROR_ENABLED - nrf_strerror - Library for converting error code to string.
|
||||
|
@ -38,9 +38,9 @@
|
||||
#include "nrf.h"
|
||||
#include "nrf_power.h"
|
||||
#include "nrf_usbd.h"
|
||||
#include "nrf_clock.h"
|
||||
|
||||
#include "nrf_drv_power.h"
|
||||
#include "nrf_drv_clock.h"
|
||||
#include "nrf_drv_usbd_errata.h"
|
||||
|
||||
#include "tusb_dcd.h"
|
||||
@ -87,9 +87,48 @@ typedef struct
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Controller API
|
||||
*------------------------------------------------------------------*/
|
||||
static void hfclk_ready(nrf_drv_clock_evt_type_t event)
|
||||
static bool hfclk_running(void)
|
||||
{
|
||||
// do nothing
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
uint32_t is_running;
|
||||
(void) sd_clock_hfclk_is_running(&is_running);
|
||||
return (is_running ? true : false);
|
||||
}
|
||||
#endif
|
||||
|
||||
return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY);
|
||||
}
|
||||
|
||||
static void hfclk_enable(void)
|
||||
{
|
||||
// already running, nothing to do
|
||||
if ( hfclk_running() ) return;
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
(void)sd_clock_hfclk_request();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART);
|
||||
}
|
||||
|
||||
static void hfclk_disable(void)
|
||||
{
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
(void)sd_clock_hfclk_release();
|
||||
return;
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP);
|
||||
}
|
||||
|
||||
static void power_usb_event_handler(nrf_drv_power_usb_evt_t event)
|
||||
@ -107,11 +146,7 @@ static void power_usb_event_handler(nrf_drv_power_usb_evt_t event)
|
||||
nrf_usbd_enable();
|
||||
|
||||
// Enable HFCLK
|
||||
static nrf_drv_clock_handler_item_t clock_handler_item =
|
||||
{
|
||||
.event_handler = hfclk_ready
|
||||
};
|
||||
nrf_drv_clock_hfclk_request(&clock_handler_item);
|
||||
hfclk_enable();
|
||||
|
||||
/* Waiting for peripheral to enable, this should take a few us */
|
||||
while ( !(NRF_USBD_EVENTCAUSE_READY_MASK & NRF_USBD->EVENTCAUSE) ) { }
|
||||
@ -122,7 +157,7 @@ static void power_usb_event_handler(nrf_drv_power_usb_evt_t event)
|
||||
|
||||
case NRF_DRV_POWER_USB_EVT_READY:
|
||||
// Wait for HFCLK
|
||||
while ( !nrf_drv_clock_hfclk_is_running() ) {}
|
||||
while ( !hfclk_running() ) {}
|
||||
|
||||
if ( nrf_drv_usbd_errata_166() )
|
||||
{
|
||||
@ -144,7 +179,8 @@ static void power_usb_event_handler(nrf_drv_power_usb_evt_t event)
|
||||
// ints_to_enable |= NRF_USBD_INT_SOF_MASK;
|
||||
// }
|
||||
|
||||
// Enable interrupt
|
||||
// Enable interrupt, Priorities 0,1,4,5 (nRF52) are reserved for SoftDevice
|
||||
NVIC_SetPriority(USBD_IRQn, 7);
|
||||
NVIC_ClearPendingIRQ(USBD_IRQn);
|
||||
NVIC_EnableIRQ(USBD_IRQn);
|
||||
|
||||
@ -167,6 +203,7 @@ static void power_usb_event_handler(nrf_drv_power_usb_evt_t event)
|
||||
NRF_USBD->INTENCLR = NRF_USBD->INTEN;
|
||||
|
||||
nrf_usbd_disable();
|
||||
hfclk_disable();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -335,15 +372,18 @@ static void normal_xact_start(uint8_t epnum, uint8_t dir)
|
||||
{
|
||||
// HW issue on nrf5284 sample, SIZE.EPOUT won't trigger ACK as spec
|
||||
// use the back door interface as sdk for walk around
|
||||
#if 0
|
||||
// Overwrite size will allow hw to accept data
|
||||
NRF_USBD->SIZE.EPOUT[epnum] = 0;
|
||||
__ISB(); __DSB();
|
||||
#else
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + 2*epnum;
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
|
||||
(void) (((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
|
||||
#endif
|
||||
if ( nrf_drv_usbd_errata_sizeepout_rw() )
|
||||
{
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + 2*epnum;
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
|
||||
(void) (((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Overwrite size will allow hw to accept data
|
||||
NRF_USBD->SIZE.EPOUT[epnum] = 0;
|
||||
__ISB(); __DSB();
|
||||
}
|
||||
}else
|
||||
{
|
||||
NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer;
|
||||
@ -582,15 +622,18 @@ void USBD_IRQHandler(void)
|
||||
|
||||
// HW issue on nrf5284 sample, SIZE.EPOUT won't trigger ACK as spec
|
||||
// use the back door interface as sdk for walk around
|
||||
#if 0
|
||||
// Overwrite size will allow hw to accept data
|
||||
NRF_USBD->SIZE.EPOUT[epnum] = 0;
|
||||
__ISB(); __DSB();
|
||||
#else
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + 2*epnum;
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
|
||||
(void) (((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
|
||||
#endif
|
||||
if ( nrf_drv_usbd_errata_sizeepout_rw() )
|
||||
{
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + 2*epnum;
|
||||
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
|
||||
(void) (((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Overwrite size will allow hw to accept data
|
||||
NRF_USBD->SIZE.EPOUT[epnum] = 0;
|
||||
__ISB(); __DSB();
|
||||
}
|
||||
}else
|
||||
{
|
||||
xfer->total_len = xfer->actual_len;
|
||||
|
@ -65,10 +65,6 @@ void SysTick_Handler (void)
|
||||
|
||||
bool tusb_hal_init(void)
|
||||
{
|
||||
VERIFY( NRF_SUCCESS == nrf_drv_clock_init() );
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user