Merge pull request #226 from fishman/nuc123sd4an0
Nuvoton NUC123SD4AN0 MCU port
This commit is contained in:
commit
efdb0ce711
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,75 @@
|
||||||
|
/**************************************************************************//**
|
||||||
|
* @file system_NUC123SD4AN0.h
|
||||||
|
* @brief CMSIS Cortex-M0 Device Peripheral Access Layer Header File for
|
||||||
|
* Device NUC123SD4AN0
|
||||||
|
* @version V5.00
|
||||||
|
* @date 13. May 2019
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 /u/KeepItUnder. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SYSTEM_NUC123SD4AN0_H /* ToDo: replace '<Device>' with your device name */
|
||||||
|
#define SYSTEM_NUC123SD4AN0_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frequency Defines
|
||||||
|
*
|
||||||
|
* See NUC123 Technical Reference Manual 5.4.2, page 103
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __HXT (12000000ul) // PCB-mounted High Frequency Crystal (12MHz)
|
||||||
|
#define __HIRC (22118400ul) // Internal MCU-block HF Oscillator Frequency (22.1184MHz)
|
||||||
|
#define __LXT (32768ul) // PCB-mounted Low Frequency Crystal (32kHz)
|
||||||
|
#define __LIRC (10000ul) // Internal MCU-block LF Oscillator Frequency (10kHz)
|
||||||
|
#define __HSI (50000000ul) // PLL clock (50MHz)
|
||||||
|
|
||||||
|
|
||||||
|
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||||
|
extern uint32_t CyclesPerUs; /*!< Cycles per micro second */
|
||||||
|
extern uint32_t PllClock; /*!< PLL Output Clock Frequency */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Setup the microcontroller system.
|
||||||
|
|
||||||
|
Initialize the System and update the SystemCoreClock variable.
|
||||||
|
*/
|
||||||
|
extern void SystemInit (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Update SystemCoreClock variable.
|
||||||
|
|
||||||
|
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
|
||||||
|
*/
|
||||||
|
extern void SystemCoreClockUpdate (void);
|
||||||
|
|
||||||
|
extern void SystemUnlockReg (void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SYSTEM_NUC123SD4AN0_H */
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NUC123SD4AN0 memory setup.
|
||||||
|
*/
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
flash0 : org = 0x00000000, len = 64k
|
||||||
|
flash1 : org = 0x00000000, len = 0
|
||||||
|
flash2 : org = 0x00000000, len = 0
|
||||||
|
flash3 : org = 0x00000000, len = 0
|
||||||
|
flash4 : org = 0x00000000, len = 0
|
||||||
|
flash5 : org = 0x00000000, len = 0
|
||||||
|
flash6 : org = 0x00000000, len = 0
|
||||||
|
flash7 : org = 0x00000000, len = 0
|
||||||
|
ram0 : org = 0x20000000, len = 20k
|
||||||
|
ram1 : org = 0x00000000, len = 0
|
||||||
|
ram2 : org = 0x00000000, len = 0
|
||||||
|
ram3 : org = 0x00000000, len = 0
|
||||||
|
ram4 : org = 0x00000000, len = 0
|
||||||
|
ram5 : org = 0x00000000, len = 0
|
||||||
|
ram6 : org = 0x00000000, len = 0
|
||||||
|
ram7 : org = 0x00000000, len = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For each data/text section two region are defined, a virtual region
|
||||||
|
and a load region (_LMA suffix).*/
|
||||||
|
|
||||||
|
/* Flash region to be used for exception vectors.*/
|
||||||
|
REGION_ALIAS("VECTORS_FLASH", flash0);
|
||||||
|
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
|
||||||
|
|
||||||
|
/* Flash region to be used for constructors and destructors.*/
|
||||||
|
REGION_ALIAS("XTORS_FLASH", flash0);
|
||||||
|
REGION_ALIAS("XTORS_FLASH_LMA", flash0);
|
||||||
|
|
||||||
|
/* Flash region to be used for code text.*/
|
||||||
|
REGION_ALIAS("TEXT_FLASH", flash0);
|
||||||
|
REGION_ALIAS("TEXT_FLASH_LMA", flash0);
|
||||||
|
|
||||||
|
/* Flash region to be used for read only data.*/
|
||||||
|
REGION_ALIAS("RODATA_FLASH", flash0);
|
||||||
|
REGION_ALIAS("RODATA_FLASH_LMA", flash0);
|
||||||
|
|
||||||
|
/* Flash region to be used for various.*/
|
||||||
|
REGION_ALIAS("VARIOUS_FLASH", flash0);
|
||||||
|
REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
|
||||||
|
|
||||||
|
/* Flash region to be used for RAM(n) initialization data.*/
|
||||||
|
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
|
||||||
|
|
||||||
|
/* RAM region to be used for Main stack. This stack accommodates the processing
|
||||||
|
of all exceptions and interrupts.*/
|
||||||
|
REGION_ALIAS("MAIN_STACK_RAM", ram0);
|
||||||
|
|
||||||
|
/* RAM region to be used for the process stack. This is the stack used by
|
||||||
|
the main() function.*/
|
||||||
|
REGION_ALIAS("PROCESS_STACK_RAM", ram0);
|
||||||
|
|
||||||
|
/* RAM region to be used for data segment.*/
|
||||||
|
REGION_ALIAS("DATA_RAM", ram0);
|
||||||
|
REGION_ALIAS("DATA_RAM_LMA", flash0);
|
||||||
|
|
||||||
|
/* RAM region to be used for BSS segment.*/
|
||||||
|
REGION_ALIAS("BSS_RAM", ram0);
|
||||||
|
|
||||||
|
/* RAM region to be used for the default heap.*/
|
||||||
|
REGION_ALIAS("HEAP_RAM", ram0);
|
||||||
|
|
||||||
|
/* Generic rules inclusion.*/
|
||||||
|
INCLUDE rules.ld
|
|
@ -0,0 +1,19 @@
|
||||||
|
# List of the ChibiOS generic NUC123SD4AN0 startup and CMSIS files.
|
||||||
|
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c
|
||||||
|
|
||||||
|
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.S \
|
||||||
|
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.S
|
||||||
|
|
||||||
|
STARTUPINC = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/devices/NUC123SD4AN0 \
|
||||||
|
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld \
|
||||||
|
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||||
|
$(CHIBIOS)/os/common/ext/ARM/CMSIS/Core/Include \
|
||||||
|
$(CHIBIOS_CONTRIB)/os/common/ext/CMSIS/Nuvoton/NUMICRO
|
||||||
|
|
||||||
|
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||||
|
STARTUPLD_CONTRIB = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||||
|
|
||||||
|
# Shared variables
|
||||||
|
ALLXASMSRC += $(STARTUPASM)
|
||||||
|
ALLCSRC += $(STARTUPSRC)
|
||||||
|
ALLINC += $(STARTUPINC)
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file NUC123SD4AN0/cmparams.h
|
||||||
|
* @brief ARM Cortex-M0 parameters for the NUC123SD4AN0.
|
||||||
|
*
|
||||||
|
* @defgroup ARMCMx_NUC123 NUC123SD4AN0 Specific Parameters
|
||||||
|
* @ingroup ARMCMx_SPECIFIC
|
||||||
|
* @details This file contains the Cortex-M0 specific parameters for the
|
||||||
|
* NUC123SD4AN0 platform.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CMPARAMS_H
|
||||||
|
#define CMPARAMS_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cortex core model.
|
||||||
|
*/
|
||||||
|
#define CORTEX_MODEL 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Floating Point unit presence.
|
||||||
|
*/
|
||||||
|
#define CORTEX_HAS_FPU 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of bits in priority masks.
|
||||||
|
*/
|
||||||
|
#define CORTEX_PRIORITY_BITS 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of interrupt vectors.
|
||||||
|
* @note This number does not include the 16 system vectors and must be
|
||||||
|
* rounded to a multiple of 8.
|
||||||
|
*/
|
||||||
|
#define CORTEX_NUM_VECTORS 32
|
||||||
|
|
||||||
|
/* The following code is not processed when the file is included from an
|
||||||
|
asm module.*/
|
||||||
|
#if !defined(_FROM_ASM_)
|
||||||
|
|
||||||
|
/* If the device type is not externally defined, for example from the Makefile,
|
||||||
|
then a file named board.h is included. This file must contain a device
|
||||||
|
definition compatible with the vendor include file.*/
|
||||||
|
#if !defined (NUC123SD4AN0)
|
||||||
|
#include "board.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Including the device CMSIS header. Note, we are not using the definitions
|
||||||
|
from this header because we need this file to be usable also from
|
||||||
|
assembler source files. We verify that the info matches instead.*/
|
||||||
|
// #include "NUC123.h"
|
||||||
|
#include "NUC123SD4AN0.h"
|
||||||
|
|
||||||
|
/*lint -save -e9029 [10.4] Signedness comes from external files, it is
|
||||||
|
unpredictable but gives no problems.*/
|
||||||
|
#if CORTEX_MODEL != __CORTEX_M
|
||||||
|
#error "CMSIS __CORTEX_M mismatch"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CORTEX_PRIORITY_BITS != __NVIC_PRIO_BITS
|
||||||
|
#error "CMSIS __NVIC_PRIO_BITS mismatch"
|
||||||
|
#endif
|
||||||
|
/*lint -restore*/
|
||||||
|
|
||||||
|
#endif /* !defined(_FROM_ASM_) */
|
||||||
|
|
||||||
|
#endif /* CMPARAMS_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,2 @@
|
||||||
|
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/CLKv1/hal_clks_lld.c
|
||||||
|
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/CLKv1
|
|
@ -0,0 +1,511 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file CLKv1/hal_clks_lld.c
|
||||||
|
* @brief CLK subsystem low level driver code.
|
||||||
|
*
|
||||||
|
* @addtogroup CLKS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WDT_ModuleNum
|
||||||
|
* ADC_ModuleNum
|
||||||
|
* SPI0_ModuleNum
|
||||||
|
* SPI1_ModuleNum
|
||||||
|
* SPI2_ModuleNum
|
||||||
|
* TMR0_ModuleNum
|
||||||
|
* TMR1_ModuleNum
|
||||||
|
* TMR2_ModuleNum
|
||||||
|
* TMR3_ModuleNum
|
||||||
|
* UART0_ModuleNum
|
||||||
|
* UART1_ModuleNum
|
||||||
|
* PWM01_ModuleNum
|
||||||
|
* PWM23_ModuleNum
|
||||||
|
* I2S_ModuleNum
|
||||||
|
* FDIV_ModuleNum
|
||||||
|
* WWDT_ModuleNum
|
||||||
|
* USBD_ModuleNum
|
||||||
|
* I2C0_ModuleNum
|
||||||
|
* I2C1_ModuleNum
|
||||||
|
* PS2_ModuleNum
|
||||||
|
* PDMA_ModuleNum
|
||||||
|
* ISP_ModuleNum
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool clks_module_hxt_source[22] = { 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
bool clks_module_hirc_source[22] = { 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
bool clks_module_lirc_source[22] = { 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
|
||||||
|
bool clks_module_hclk_source[22] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
|
||||||
|
bool clks_module_pll_source[22] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
bool clks_module_ext_source[22] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
bool clks_module_divider[22] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 };
|
||||||
|
uint32_t clks_module_enable[22] = { CLK_APBCLK_WDT_EN_Msk,
|
||||||
|
CLK_APBCLK_ADC_EN_Msk,
|
||||||
|
CLK_APBCLK_SPI0_EN_Msk,
|
||||||
|
CLK_APBCLK_SPI1_EN_Msk,
|
||||||
|
CLK_APBCLK_SPI2_EN_Msk,
|
||||||
|
CLK_APBCLK_TMR0_EN_Msk,
|
||||||
|
CLK_APBCLK_TMR1_EN_Msk,
|
||||||
|
CLK_APBCLK_TMR2_EN_Msk,
|
||||||
|
CLK_APBCLK_TMR3_EN_Msk,
|
||||||
|
CLK_APBCLK_UART0_EN_Msk,
|
||||||
|
CLK_APBCLK_UART1_EN_Msk,
|
||||||
|
CLK_APBCLK_PWM01_EN_Msk,
|
||||||
|
CLK_APBCLK_PWM23_EN_Msk,
|
||||||
|
CLK_APBCLK_I2S_EN_Msk,
|
||||||
|
CLK_APBCLK_FDIV_EN_Msk,
|
||||||
|
0,
|
||||||
|
CLK_APBCLK_USBD_EN_Msk,
|
||||||
|
CLK_APBCLK_I2C0_EN_Msk,
|
||||||
|
CLK_APBCLK_I2C1_EN_Msk,
|
||||||
|
CLK_APBCLK_PS2_EN_Msk,
|
||||||
|
CLK_AHBCLK_PDMA_EN_Msk,
|
||||||
|
CLK_AHBCLK_ISP_EN_Msk };
|
||||||
|
uint32_t clks_module_sel1_mask[22] = { CLK_CLKSEL1_WDT_S_Msk,
|
||||||
|
CLK_CLKSEL1_ADC_S_Msk,
|
||||||
|
CLK_CLKSEL1_SPI0_S_Msk,
|
||||||
|
CLK_CLKSEL1_SPI1_S_Msk,
|
||||||
|
CLK_CLKSEL1_SPI2_S_Msk,
|
||||||
|
CLK_CLKSEL1_TMR0_S_Msk,
|
||||||
|
CLK_CLKSEL1_TMR1_S_Msk,
|
||||||
|
CLK_CLKSEL1_TMR2_S_Msk,
|
||||||
|
CLK_CLKSEL1_TMR3_S_Msk,
|
||||||
|
CLK_CLKSEL1_UART_S_Msk,
|
||||||
|
CLK_CLKSEL1_UART_S_Msk,
|
||||||
|
CLK_CLKSEL1_PWM01_S_Msk,
|
||||||
|
CLK_CLKSEL1_PWM23_S_Msk,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level CLK driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @brief Set Core Clock
|
||||||
|
*
|
||||||
|
* @description Set the core system clock some reference speed (Hz).
|
||||||
|
* This should be between 25MHz and 72MHz for the NUC123SD4AN0.
|
||||||
|
*
|
||||||
|
* Use either the HXT (exact) or HIRC (nearest using 22.1184MHz)
|
||||||
|
* as the clock source.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t clks_lld_set_core_clock(uint32_t clkCore)
|
||||||
|
{
|
||||||
|
uint32_t stableHIRC;
|
||||||
|
|
||||||
|
/* Read HIRC clock source stable flag */
|
||||||
|
stableHIRC = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;
|
||||||
|
|
||||||
|
/* Setup __HIRC */
|
||||||
|
CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;
|
||||||
|
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_OSC22M_STB_Msk);
|
||||||
|
|
||||||
|
/* Use __HIRC as HCLK temporarily */
|
||||||
|
CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_Msk;
|
||||||
|
CLK->CLKDIV &= (~CLK_CLKDIV_HCLK_N_Msk);
|
||||||
|
|
||||||
|
/* Is HXT stable ? */
|
||||||
|
if(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk) {
|
||||||
|
/* Use __HXT as PLL source */
|
||||||
|
clkCore = clks_lld_enable_pll(CLK_PLLCON_PLL_SRC_HXT, (clkCore << 1));
|
||||||
|
} else {
|
||||||
|
/* Use __HIRC as PLL source */
|
||||||
|
clkCore = clks_lld_enable_pll(CLK_PLLCON_PLL_SRC_HIRC, (clkCore << 1));
|
||||||
|
|
||||||
|
/* Read HIRC clock source stable flag again (since we're using it now) */
|
||||||
|
stableHIRC = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set HCLK clock source to PLL */
|
||||||
|
clks_lld_set_HCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(2));
|
||||||
|
|
||||||
|
/* Disable HIRC if HIRC was disabled before we started */
|
||||||
|
if (stableHIRC == 0) {
|
||||||
|
CLK->PWRCON &= ~CLK_PWRCON_OSC22M_EN_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return actual HCLK frequency is PLL frequency divide 2 */
|
||||||
|
return (clkCore >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief Set system HCLK
|
||||||
|
*
|
||||||
|
* @description Setup HCLK source and divider
|
||||||
|
*
|
||||||
|
* Always switch to a known stable clock source before changing a
|
||||||
|
* system clock, to avoid issues related to the original clock's
|
||||||
|
* speed/settings.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void clks_lld_set_HCLK(uint32_t clkSource, uint32_t clkDivider)
|
||||||
|
{
|
||||||
|
uint32_t stableHIRC;
|
||||||
|
|
||||||
|
/* Read HIRC clock source stable flag */
|
||||||
|
stableHIRC = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;
|
||||||
|
|
||||||
|
/* Setup __HIRC */
|
||||||
|
CLK->PWRCON |= CLK_CLKSTATUS_OSC22M_STB_Msk;
|
||||||
|
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_OSC22M_STB_Msk);
|
||||||
|
|
||||||
|
/* Use __HIRC as HCLK, temporarily */
|
||||||
|
CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_HIRC;
|
||||||
|
|
||||||
|
/* Set new clock divider */
|
||||||
|
CLK->CLKDIV = (CLK->CLKDIV & (~CLK_CLKDIV_HCLK_N_Msk)) | clkDivider;
|
||||||
|
|
||||||
|
/* Switch HCLK to new HCLK source */
|
||||||
|
CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | clkSource;
|
||||||
|
|
||||||
|
/* Update System Core Clock */
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
|
||||||
|
/* Disable HIRC if HIRC was disabled before we started */
|
||||||
|
if (stableHIRC == 0) {
|
||||||
|
CLK->PWRCON &= ~CLK_CLKSTATUS_OSC22M_STB_Msk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void clks_lld_set_module_clock(uint32_t module, uint32_t clkSource, uint32_t clkDivider)
|
||||||
|
{
|
||||||
|
/* Set clock source */
|
||||||
|
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~(clks_module_sel1_mask[module]))) | clkSource;
|
||||||
|
|
||||||
|
/* Set secondary clock source bit for PWM01/PWM23 */
|
||||||
|
if (module == PWM01_ModuleNum) {
|
||||||
|
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_PWM01_S_Msk)) | (clkSource & CLK_CLKSEL2_PWM01_S_Msk);
|
||||||
|
} else if (module == PWM23_ModuleNum) {
|
||||||
|
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_PWM23_S_Msk)) | (clkSource & CLK_CLKSEL2_PWM23_S_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set clock divider */
|
||||||
|
if (clks_module_divider[module]) {
|
||||||
|
switch (module) {
|
||||||
|
case ADC_ModuleNum:
|
||||||
|
CLK->CLKDIV = (CLK->CLKDIV & ~CLK_CLKDIV_ADC_N_Msk) | clkDivider;
|
||||||
|
break;
|
||||||
|
case UART0_ModuleNum:
|
||||||
|
case UART1_ModuleNum:
|
||||||
|
CLK->CLKDIV = (CLK->CLKDIV & ~CLK_CLKDIV_UART_N_Msk) | clkDivider;
|
||||||
|
break;
|
||||||
|
case USBD_ModuleNum:
|
||||||
|
CLK->CLKDIV = (CLK->CLKDIV & ~CLK_CLKDIV_USB_N_Msk) | clkDivider;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void clks_lld_enable_ck0(uint32_t clkSource, uint32_t clkDivider)
|
||||||
|
{
|
||||||
|
CLK->FRQDIV = (CLK_FRQDIV_DIVIDER_EN_Msk | clkDivider) ;
|
||||||
|
|
||||||
|
clks_lld_enable_module_clock(FDIV_ModuleNum);
|
||||||
|
|
||||||
|
clks_lld_set_module_clock(FDIV_ModuleNum, clkSource, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable module clock
|
||||||
|
*
|
||||||
|
* @description Module clock enables are all in either AHBCLK or APBCLK
|
||||||
|
* Register masks are stored in a table to save knowing bit width
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void clks_lld_enable_module_clock(uint32_t clkModule) {
|
||||||
|
switch (clkModule) {
|
||||||
|
case PDMA_ModuleNum:
|
||||||
|
case ISP_ModuleNum:
|
||||||
|
/* AHB Clocks */
|
||||||
|
CLK->AHBCLK |= clks_module_enable[clkModule];
|
||||||
|
break;
|
||||||
|
case WWDT_ModuleNum:
|
||||||
|
/* No Module Clock */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* APB Clocks */
|
||||||
|
CLK->APBCLK |= clks_module_enable[clkModule];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable module clock
|
||||||
|
*
|
||||||
|
* @description Module clock enables are all in either AHBCLK or APBCLK
|
||||||
|
* Register masks are stored in a table to save knowing bit width
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void clks_lld_disable_module_clock(uint32_t clkModule) {
|
||||||
|
switch (clkModule) {
|
||||||
|
case PDMA_ModuleNum:
|
||||||
|
case ISP_ModuleNum:
|
||||||
|
/* AHB Clocks */
|
||||||
|
CLK->AHBCLK &= ~clks_module_enable[clkModule];
|
||||||
|
break;
|
||||||
|
case WWDT_ModuleNum:
|
||||||
|
/* No Module Clock */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* APB Clocks */
|
||||||
|
CLK->APBCLK &= ~clks_module_enable[clkModule];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t clks_lld_enable_pll(uint32_t pllSrc, uint32_t pllFreq)
|
||||||
|
{
|
||||||
|
/* Disable PLL first to avoid unstable when setting PLL. */
|
||||||
|
CLK->PLLCON = CLK_PLLCON_PD_Msk;
|
||||||
|
|
||||||
|
/* Check and setup correct clock source */
|
||||||
|
switch (pllSrc) {
|
||||||
|
case CLK_PLLCON_PLL_SRC_HXT:
|
||||||
|
/* Use HXT clock */
|
||||||
|
CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;
|
||||||
|
|
||||||
|
/* Wait for stable HXT */
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_XTL12M_STB_Msk);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CLK_PLLCON_PLL_SRC_HIRC:
|
||||||
|
/* Use HIRC clock */
|
||||||
|
CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;
|
||||||
|
|
||||||
|
/* Wait for stable HIRC */
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_OSC22M_STB_Msk);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate best PLL variables from requested frequency
|
||||||
|
*
|
||||||
|
* See NUC123 Technical Reference Manual 5.4.8 PLL Control Register Description, page 124
|
||||||
|
*
|
||||||
|
* NF 1
|
||||||
|
* FOUT = FIN x -- x --
|
||||||
|
* NR NO
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t NO = 0;
|
||||||
|
uint32_t NR = 0;
|
||||||
|
uint32_t clkCalc = 0;
|
||||||
|
|
||||||
|
/* Set "NO" for requested frequency */
|
||||||
|
/* We're using "NO" first to set the PLLCON - so make it "NO" - 1; */
|
||||||
|
if (pllFreq >= FREQ_25MHZ && pllFreq <= FREQ_50MHZ) {
|
||||||
|
/* Low frequency - use full variable headroom */
|
||||||
|
pllFreq <<= 2;
|
||||||
|
NO = 3;
|
||||||
|
} else if (pllFreq > FREQ_50MHZ && pllFreq <= FREQ_100MHZ) {
|
||||||
|
/* Medium frequency - use full variable headroom */
|
||||||
|
pllFreq <<= 1;
|
||||||
|
NO = 1;
|
||||||
|
} else if (pllFreq > FREQ_100MHZ && pllFreq <= FREQ_200MHZ) {
|
||||||
|
/* High frequency - full variable headroom already used */
|
||||||
|
NO = 0;
|
||||||
|
} else {
|
||||||
|
/* Frequency out of range - use default PLL settings
|
||||||
|
*
|
||||||
|
* See NUC123 Technical Reference Manual PLL COntrol Register Description, page 124
|
||||||
|
* The default value: 0xC22E
|
||||||
|
* FIN = 12 MHz
|
||||||
|
* NR = (1+2) = 3
|
||||||
|
* NF = (46+2) = 48
|
||||||
|
* NO = 4
|
||||||
|
* FOUT = 12/4 x 48 x 1/3 = 48 MHz
|
||||||
|
*/
|
||||||
|
if (pllSrc == CLK_PLLCON_PLL_SRC_HXT) {
|
||||||
|
CLK->PLLCON = 0xC22E;
|
||||||
|
} else {
|
||||||
|
CLK->PLLCON = 0xD66F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for stable PLL clock */
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_PLL_STB_Msk);
|
||||||
|
|
||||||
|
return clks_lld_get_pll_clock_freq();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup "NR" and clkCalc */
|
||||||
|
switch (pllSrc) {
|
||||||
|
case CLK_PLLCON_PLL_SRC_HXT:
|
||||||
|
NR = 2;
|
||||||
|
clkCalc = __HXT;
|
||||||
|
break;
|
||||||
|
case CLK_PLLCON_PLL_SRC_HIRC:
|
||||||
|
NR = 4;
|
||||||
|
clkCalc = __HIRC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop to calculate best/lowest NR (between 0 or 2 and 31) and best/lowest NF (between 0 and 511)
|
||||||
|
*
|
||||||
|
* Best results are off-by-2 until final equation calculation (to allow use in PLLCON)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t bestNR = 0;
|
||||||
|
uint32_t bestNF = 0;
|
||||||
|
uint32_t minLimit = -1;
|
||||||
|
|
||||||
|
while (NR <= 33) {
|
||||||
|
uint32_t tmpCalc1 = clkCalc / NR;
|
||||||
|
|
||||||
|
if (tmpCalc1 > 1600000 && tmpCalc1 < 16000000) {
|
||||||
|
uint32_t NF = 2;
|
||||||
|
|
||||||
|
while (NF <= 513) {
|
||||||
|
uint32_t tmpCalc2 = tmpCalc1 * NF;
|
||||||
|
|
||||||
|
if (tmpCalc2 >= 100000000 && tmpCalc2 <= 200000000) {
|
||||||
|
uint32_t tmpCalc3;
|
||||||
|
|
||||||
|
if (tmpCalc2 > pllFreq) {
|
||||||
|
tmpCalc3 = tmpCalc2 - pllFreq;
|
||||||
|
} else {
|
||||||
|
tmpCalc3 = pllFreq - tmpCalc2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpCalc3 < minLimit) {
|
||||||
|
minLimit = tmpCalc3;
|
||||||
|
bestNF = NF;
|
||||||
|
bestNR = NR;
|
||||||
|
|
||||||
|
/* Stop NF calc loop when minLimit tends back to 0 */
|
||||||
|
if(minLimit == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NF++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NR++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable and apply new PLL setting. */
|
||||||
|
CLK->PLLCON = pllSrc | (NO << 14) | ((bestNR - 2) << 9) | (bestNF - 2);
|
||||||
|
|
||||||
|
/* Wait for stable PLL clock */
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_PLL_STB_Msk);
|
||||||
|
|
||||||
|
/* Return equation result */
|
||||||
|
return (clkCalc / ((NO + 1) * bestNR) * bestNF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wait for stable clock
|
||||||
|
*
|
||||||
|
* @description Always wait around 300ms for clock to be stable
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t clks_lld_wait_for_clock_ready(uint32_t clkMask)
|
||||||
|
{
|
||||||
|
int32_t timeout = 2180000;
|
||||||
|
|
||||||
|
while (timeout-- > 0) {
|
||||||
|
if ((CLK->CLKSTATUS & clkMask) == clkMask) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void clks_lld_enable_SysTick(uint32_t clkSrc, uint32_t count) {
|
||||||
|
|
||||||
|
// Disable the counter
|
||||||
|
clks_lld_disable_SysTick();
|
||||||
|
|
||||||
|
// Clear current values/flags
|
||||||
|
SysTick->VAL = 0;
|
||||||
|
|
||||||
|
// Set SysTick Clock Source
|
||||||
|
switch (clkSrc) {
|
||||||
|
case CLK_CLKSEL0_STCLK_S_HCLK:
|
||||||
|
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLK_S_Msk) | clkSrc;
|
||||||
|
// CLK->CLKSEL0 |= SysTick_CTRL_CLKSOURCE_Msk;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set reload value
|
||||||
|
SysTick->LOAD = count;
|
||||||
|
|
||||||
|
// Enable Interrupt and Counter
|
||||||
|
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void clks_lld_disable_SysTick(void) {
|
||||||
|
/* Disable System Tick counter */
|
||||||
|
SysTick->CTRL = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,222 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file hal_clks_lld.h
|
||||||
|
* @brief Clock/Timer subsystem low level header.
|
||||||
|
*
|
||||||
|
* @addtogroup CLKS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_CLKS_LLD_H
|
||||||
|
#define HAL_CLKS_LLD_H
|
||||||
|
|
||||||
|
// #if HAL_USE_CLKS || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define FREQ_25MHZ 25000000
|
||||||
|
#define FREQ_50MHZ 50000000
|
||||||
|
#define FREQ_72MHZ 72000000
|
||||||
|
#define FREQ_100MHZ 100000000
|
||||||
|
#define FREQ_200MHZ 200000000
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* CLKSEL0 */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
#define CLK_CLKSEL0_HCLK_S_HXT (0x0ul<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Set HCLK clock source as HXT */
|
||||||
|
#define CLK_CLKSEL0_HCLK_S_PLL_DIV2 (0x1ul<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Set HCLK clock source as PLL/2 */
|
||||||
|
#define CLK_CLKSEL0_HCLK_S_PLL (0x2ul<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Set HCLK clock source as PLL */
|
||||||
|
#define CLK_CLKSEL0_HCLK_S_LIRC (0x3ul<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Set HCLK clock source as LIRC */
|
||||||
|
#define CLK_CLKSEL0_HCLK_S_HIRC (0x7ul<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Set HCLK clock source as HIRC */
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* CLKSEL1 */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
#define CLK_CLKSEL1_TMR0_S_HXT (0x0ul<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Set TMR0 clock source as HXT */
|
||||||
|
#define CLK_CLKSEL1_TMR0_S_HCLK (0x2ul<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Set TMR0 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL1_TMR0_S_EXT_TRG (0x3ul<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Set TMR0 clock source as external trigger */
|
||||||
|
#define CLK_CLKSEL1_TMR0_S_LIRC (0x5ul<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Set TMR0 clock source as LIRC */
|
||||||
|
#define CLK_CLKSEL1_TMR0_S_HIRC (0x7ul<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Set TMR0 clock source as HIRC */
|
||||||
|
#define CLK_CLKSEL1_TMR1_S_HXT (0x0ul<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Set TMR1 clock source as HXT */
|
||||||
|
#define CLK_CLKSEL1_TMR1_S_HCLK (0x2ul<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Set TMR1 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL1_TMR1_S_EXT_TRG (0x3ul<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Set TMR1 clock source as external trigger */
|
||||||
|
#define CLK_CLKSEL1_TMR1_S_LIRC (0x5ul<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Set TMR1 clock source as LIRC */
|
||||||
|
#define CLK_CLKSEL1_TMR1_S_HIRC (0x7ul<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Set TMR1 clock source as HIRC*/
|
||||||
|
#define CLK_CLKSEL1_TMR2_S_HXT (0x0ul<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Set TMR2 clock source as external X'tal */
|
||||||
|
#define CLK_CLKSEL1_TMR2_S_HCLK (0x2ul<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Set TMR2 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL1_TMR2_S_EXT_TRG (0x3ul<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Set TMR2 clock source as external trigger */
|
||||||
|
#define CLK_CLKSEL1_TMR2_S_LIRC (0x5ul<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Set TMR2 clock source as LIRC */
|
||||||
|
#define CLK_CLKSEL1_TMR2_S_HIRC (0x7ul<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Set TMR2 clock source as HIRC */
|
||||||
|
#define CLK_CLKSEL1_TMR3_S_HXT (0x0ul<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Set TMR3 clock source as HXT */
|
||||||
|
#define CLK_CLKSEL1_TMR3_S_HCLK (0x2ul<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Set TMR3 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL1_TMR3_S_EXT_TRG (0x3ul<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Set TMR3 clock source as external trigger */
|
||||||
|
#define CLK_CLKSEL1_TMR3_S_LIRC (0x5ul<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Set TMR3 clock source as LIRC */
|
||||||
|
#define CLK_CLKSEL1_TMR3_S_HIRC (0x7ul<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Set TMR3 clock source as HIRC */
|
||||||
|
#define CLK_CLKSEL1_PWM01_S_HXT (0x0ul<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Set PWM01 clock source as HXT */
|
||||||
|
#define CLK_CLKSEL1_PWM01_S_HCLK (0x2ul<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Set PWM01 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL1_PWM01_S_HIRC (0x3ul<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Set PWM01 clock source as HIRC */
|
||||||
|
#define CLK_CLKSEL1_PWM01_S_LIRC (0x3ul<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Set PWM01 clock source as LIRC */
|
||||||
|
#define CLK_CLKSEL1_PWM23_S_HXT (0x0ul<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Set PWM23 clock source as HXT */
|
||||||
|
#define CLK_CLKSEL1_PWM23_S_HCLK (0x2ul<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Set PWM23 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL1_PWM23_S_HIRC (0x3ul<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Set PWM23 clock source as HIRC */
|
||||||
|
#define CLK_CLKSEL1_PWM23_S_LIRC (0x3ul<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Set PWM23 clock source as LIRC */
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* CLKSEL2 */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define CLK_CLKSEL2_PWM01_EXT_HXT (0x0ul<<CLK_CLKSEL2_PWM01_S_Pos) /*!< Set PWM01 clock source as HXT */
|
||||||
|
#define CLK_CLKSEL2_PWM01_EXT_HCLK (0x0ul<<CLK_CLKSEL2_PWM01_S_Pos) /*!< Set PWM01 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL2_PWM01_EXT_HIRC (0x0ul<<CLK_CLKSEL2_PWM01_S_Pos) /*!< Set PWM01 clock source as HIRC */
|
||||||
|
#define CLK_CLKSEL2_PWM01_EXT_LIRC (0x1ul<<CLK_CLKSEL2_PWM01_S_Pos) /*!< Set PWM01 clock source as LIRC */
|
||||||
|
#define CLK_CLKSEL2_PWM23_EXT_HXT (0x0ul<<CLK_CLKSEL2_PWM23_S_Pos) /*!< Set PWM23 clock source as HXT */
|
||||||
|
#define CLK_CLKSEL2_PWM23_EXT_HCLK (0x0ul<<CLK_CLKSEL2_PWM23_S_Pos) /*!< Set PWM23 clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL2_PWM23_EXT_HIRC (0x0ul<<CLK_CLKSEL2_PWM23_S_Pos) /*!< Set PWM23 clock source as HIRC */
|
||||||
|
#define CLK_CLKSEL2_PWM23_EXT_LIRC (0x1ul<<CLK_CLKSEL2_PWM23_S_Pos) /*!< Set PWM23 clock source as LIRC */
|
||||||
|
|
||||||
|
#define CLK_CLKSEL2_FRQDIV_S_HXT (0x0ul<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Set FRQDIV clock source as HXT */
|
||||||
|
#define CLK_CLKSEL2_FRQDIV_S_HCLK (0x2ul<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Set FRQDIV clock source as HCLK */
|
||||||
|
#define CLK_CLKSEL2_FRQDIV_S_HIRC (0x3ul<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Set FRQDIV clock source as HIRC */
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* CLKDIV */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define CLK_CLKDIV_HCLK(x) ((x)-1) /*!< HCLK clock divider (1~16) */
|
||||||
|
#define CLK_CLKDIV_USB(x) (((x)-1) << CLK_CLKDIV_USB_N_Pos) /*!< USB clock divider (1~16) */
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* PLLCON */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define CLK_PLLCON_PLL_SRC_HXT 0x00000000ul /*!< Set PLL clock source as HXT */
|
||||||
|
#define CLK_PLLCON_PLL_SRC_HIRC 0x00080000ul /*!< Set PLL clock source as HIRC */
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
// extern DACDriver DACD1;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
// void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv);
|
||||||
|
// void CLK_EnableModuleClock(uint32_t u32ModuleIdx);
|
||||||
|
// void CLK_DisableModuleClock(uint32_t u32ModuleIdx);
|
||||||
|
// uint32_t CLK_WaitClockReady(uint32_t u32ClkMask);
|
||||||
|
// void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count);
|
||||||
|
// void CLK_DisableSysTick(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get PLL clock frequency
|
||||||
|
* @param None
|
||||||
|
* @return PLL frequency
|
||||||
|
* @details This function get PLL frequency. The frequency unit is Hz.
|
||||||
|
*/
|
||||||
|
static inline uint32_t clks_lld_get_pll_clock_freq(void) {
|
||||||
|
uint32_t PllReg;
|
||||||
|
uint32_t pllFIN, pllNF, pllNR, pllNO;
|
||||||
|
|
||||||
|
PllReg = CLK->PLLCON;
|
||||||
|
|
||||||
|
if(PllReg & (CLK_PLLCON_PD_Msk | CLK_PLLCON_OE_Msk)) {
|
||||||
|
PllClock = 0; /* PLL is in power down mode or fix low */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (PllReg & CLK_PLLCON_PLL_SRC_HIRC) {
|
||||||
|
pllFIN = __HIRC; /* Use HXT for PLL clock */
|
||||||
|
} else {
|
||||||
|
pllFIN = __HXT; /* Use HXT for PLL clock */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PllReg & CLK_PLLCON_BP_Msk) {
|
||||||
|
PllClock = pllFIN;
|
||||||
|
} else {
|
||||||
|
switch (((PllReg & CLK_PLLCON_OUT_DV_Msk) >> CLK_PLLCON_OUT_DV_Pos)) {
|
||||||
|
case 0b00: // OUT_DIV == 00 : NO = 1
|
||||||
|
pllNO = 1;
|
||||||
|
break;
|
||||||
|
case 0b11: // OUT_DIV == 11 : NO = 4
|
||||||
|
pllNO = 4;
|
||||||
|
break;
|
||||||
|
default: // OUT_DIV == 01 or 10 : NO = 2
|
||||||
|
pllNO = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pllNF = ((PllReg & CLK_PLLCON_FB_DV_Msk) >> CLK_PLLCON_FB_DV_Pos) + 2;
|
||||||
|
pllNR = ((PllReg & CLK_PLLCON_IN_DV_Msk) >> CLK_PLLCON_IN_DV_Pos) + 2;
|
||||||
|
|
||||||
|
/* shift to avoid overflow condition */
|
||||||
|
PllClock = (((pllFIN >> 2) * pllNF) / (pllNR * pllNO) << 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PllClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t clks_lld_set_core_clock(uint32_t clkCore);
|
||||||
|
void clks_lld_set_HCLK(uint32_t clkSource, uint32_t clkDivider);
|
||||||
|
void clks_lld_set_module_clock(uint32_t module, uint32_t clkSource, uint32_t clkDivider);
|
||||||
|
void clks_lld_enable_ck0(uint32_t clkSource, uint32_t clkDivider);
|
||||||
|
void clks_lld_enable_module_clock(uint32_t moduleIdx);
|
||||||
|
void clks_lld_disable_module_clock(uint32_t moduleIdx);
|
||||||
|
uint32_t clks_lld_enable_pll(uint32_t pllSrc, uint32_t pllFreq);
|
||||||
|
uint32_t clks_lld_wait_for_clock_ready(uint32_t clkMask);
|
||||||
|
void clks_lld_enable_SysTick(uint32_t clkSource, uint32_t count);
|
||||||
|
void clks_lld_disable_SysTick(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_CLK_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,10 @@
|
||||||
|
# PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/gpio.c
|
||||||
|
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1
|
||||||
|
|
||||||
|
ifeq ($(USE_SMART_BUILD),yes)
|
||||||
|
ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
|
||||||
|
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
|
||||||
|
endif
|
|
@ -0,0 +1,196 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file hal_pal_lld.c
|
||||||
|
* @brief PLATFORM PAL subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup PAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/* DEBUG
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_GPIOAB_HANDLER){
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB4);
|
||||||
|
GPIO_TOGGLE(PB5);
|
||||||
|
GPIO_TOGGLE(PB6);
|
||||||
|
GPIO_TOGGLE(PB7);
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_GPIOCDF_HANDLER){
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB4);
|
||||||
|
GPIO_TOGGLE(PB5);
|
||||||
|
GPIO_TOGGLE(PB6);
|
||||||
|
GPIO_TOGGLE(PB7);
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief NUC123 I/O ports configuration.
|
||||||
|
* @details Ports A-D(E, F, G, H) clocks enabled.
|
||||||
|
*
|
||||||
|
* @param[in] config the NUC123 ports configuration
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void _pal_lld_init(const PALConfig *config) {
|
||||||
|
|
||||||
|
//(void)config;
|
||||||
|
/* Turn on GPIO subsystem
|
||||||
|
* Set all GPIO to Input/HZ
|
||||||
|
* Clear all GPIO Interrupts
|
||||||
|
* Set all GPIO Interrupt Modes to Level
|
||||||
|
* Turn off DeBounce
|
||||||
|
* Zero all GPIO Outputs (just in case)
|
||||||
|
*/
|
||||||
|
|
||||||
|
GPIOA->PMD = config->PAData.PMD;
|
||||||
|
GPIOA->OFFD = config->PAData.OFFD;
|
||||||
|
GPIOA->DMASK = config->PAData.DMASK;
|
||||||
|
GPIOA->DBEN = config->PAData.DBEN;
|
||||||
|
GPIOA->IMD = config->PAData.IMD;
|
||||||
|
GPIOA->IEN = config->PAData.IEN;
|
||||||
|
GPIOA->ISRC = config->PAData.ISRC;
|
||||||
|
GPIOA->DOUT = config->PAData.DOUT;
|
||||||
|
|
||||||
|
GPIOB->PMD = config->PBData.PMD;
|
||||||
|
GPIOB->OFFD = config->PBData.OFFD;
|
||||||
|
GPIOB->DMASK = config->PBData.DMASK;
|
||||||
|
GPIOB->DBEN = config->PBData.DBEN;
|
||||||
|
GPIOB->IMD = config->PBData.IMD;
|
||||||
|
GPIOB->IEN = config->PBData.IEN;
|
||||||
|
GPIOB->ISRC = config->PBData.ISRC;
|
||||||
|
GPIOB->DOUT = config->PBData.DOUT;
|
||||||
|
|
||||||
|
GPIOC->PMD = config->PCData.PMD;
|
||||||
|
GPIOC->OFFD = config->PCData.OFFD;
|
||||||
|
GPIOC->DMASK = config->PCData.DMASK;
|
||||||
|
GPIOC->DBEN = config->PCData.DBEN;
|
||||||
|
GPIOC->IMD = config->PCData.IMD;
|
||||||
|
GPIOC->IEN = config->PCData.IEN;
|
||||||
|
GPIOC->ISRC = config->PCData.ISRC;
|
||||||
|
GPIOC->DOUT = config->PCData.DOUT;
|
||||||
|
|
||||||
|
GPIOD->PMD = config->PDData.PMD;
|
||||||
|
GPIOD->OFFD = config->PDData.OFFD;
|
||||||
|
GPIOD->DMASK = config->PDData.DMASK;
|
||||||
|
GPIOD->DBEN = config->PDData.DBEN;
|
||||||
|
GPIOD->IMD = config->PDData.IMD;
|
||||||
|
GPIOD->IEN = config->PDData.IEN;
|
||||||
|
GPIOD->ISRC = config->PDData.ISRC;
|
||||||
|
GPIOD->DOUT = config->PDData.DOUT;
|
||||||
|
|
||||||
|
GPIOF->PMD = config->PFData.PMD;
|
||||||
|
GPIOF->OFFD = config->PFData.OFFD;
|
||||||
|
GPIOF->DMASK = config->PFData.DMASK;
|
||||||
|
GPIOF->DBEN = config->PFData.DBEN;
|
||||||
|
GPIOF->IMD = config->PFData.IMD;
|
||||||
|
GPIOF->IEN = config->PFData.IEN;
|
||||||
|
GPIOF->ISRC = config->PFData.ISRC;
|
||||||
|
GPIOF->DOUT = config->PFData.DOUT;
|
||||||
|
|
||||||
|
/* Set DeBounce conditions */
|
||||||
|
GPIO_DBNCE->DBNCECON = 0x04u;
|
||||||
|
|
||||||
|
/* Enable External Crystal Oscillator pins */
|
||||||
|
SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;
|
||||||
|
|
||||||
|
// SYS->GPD_MFP |= SYS_GPD_MFP_PD10_CLKO;
|
||||||
|
|
||||||
|
/* Enable UART1 data pins */
|
||||||
|
SYS->GPB_MFP |= SYS_GPB_MFP_PB1_UART0_TXD | SYS_GPB_MFP_PB0_UART0_RXD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pads mode setup.
|
||||||
|
* @details This function programs a pads group belonging to the same port
|
||||||
|
* with the specified mode.
|
||||||
|
*
|
||||||
|
* @param[in] port the port identifier
|
||||||
|
* @param[in] mask the group mask
|
||||||
|
* @param[in] mode the mode
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _pal_lld_setgroupmode(ioportid_t port,
|
||||||
|
ioportmask_t mask,
|
||||||
|
iomode_t mode) {
|
||||||
|
|
||||||
|
uint32_t nucMode = 0;
|
||||||
|
|
||||||
|
if (mode == PAL_MODE_INPUT || mode == PAL_MODE_INPUT_PULLUP)
|
||||||
|
nucMode = GPIO_PMD_INPUT;
|
||||||
|
else if (mode == PAL_MODE_OUTPUT_OPENDRAIN)
|
||||||
|
nucMode = GPIO_PMD_OPEN_DRAIN;
|
||||||
|
else if (mode == PAL_MODE_OUTPUT_PUSHPULL)
|
||||||
|
nucMode = GPIO_PMD_OUTPUT;
|
||||||
|
else
|
||||||
|
nucMode = GPIO_PMD_QUASI;
|
||||||
|
|
||||||
|
// GPIO_SetMode(port, mask, nucMode);
|
||||||
|
for (uint32_t i = 0; i < PAL_IOPORTS_WIDTH; i++) {
|
||||||
|
// for(uint32_t i = 0; i < GPIO_PINSPERPORT_MAX; i++) {
|
||||||
|
if(mask & (1 << i)) {
|
||||||
|
port->PMD = (port->PMD & ~(0x03ul << (i << 1))) | (nucMode << (i << 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_USE_PAL == TRUE */
|
||||||
|
|
||||||
|
/** @} */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
||||||
|
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/hal_st_lld.c
|
||||||
|
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/hal_pwm_lld.c
|
||||||
|
#PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/timer.c
|
||||||
|
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1
|
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file TIMv1/hal_pwm_lld.c
|
||||||
|
* @brief PWM subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup PWM
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
// #if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level PWM driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
// void pwm_lld_init(void) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
void pwm_lld_start(PWM_T *pwm, uint32_t mask) {
|
||||||
|
uint32_t pwmStart = 0;
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < PWM_CHANNELS; i++) {
|
||||||
|
if (mask & (1 << i)) {
|
||||||
|
pwmStart |= (PWM_PCR_CH0EN_Msk << (i * 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(pwm)->PCR |= pwmStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pwm_lld_enable_period_int(PWM_T *pwm, uint32_t pwmChannel, uint32_t periodType) {
|
||||||
|
(pwm)->PIER = ((pwm)->PIER & ~(0x01ul << (pwmChannel >> 1))) | (0x01ul << pwmChannel) | (periodType << (pwmChannel >> 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pwm_lld_disable_period_int(PWM_T *pwm, uint32_t pwmChannel) {
|
||||||
|
(pwm)->PIER &= ~(PWM_PIER_PWMIE0_Msk << pwmChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t pwm_lld_get_period_int(PWM_T *pwm, uint32_t pwmChannel) {
|
||||||
|
if ((pwm)->PIIR & (0x01ul << (pwmChannel))) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pwm_lld_clear_period_int(PWM_T *pwm, uint32_t pwmChannel) {
|
||||||
|
(pwm)->PIIR = (0x01ul << pwmChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t pwm_lld_config_output_channel(PWM_T *pwm, uint32_t channel, uint32_t freq, uint32_t duty)
|
||||||
|
{
|
||||||
|
uint32_t regSource;
|
||||||
|
uint32_t clkSource;
|
||||||
|
uint32_t pwmClk;
|
||||||
|
uint8_t divider = 1;
|
||||||
|
uint8_t prescale = 0xFF;
|
||||||
|
uint16_t CNR = 0xFFFF;
|
||||||
|
|
||||||
|
if (channel < 2) {
|
||||||
|
regSource = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM01_S_Msk)) >> (CLK_CLKSEL2_PWM01_S_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM01_S_Msk)) >> (CLK_CLKSEL1_PWM01_S_Pos);
|
||||||
|
} else {
|
||||||
|
regSource = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM23_S_Msk)) >> (CLK_CLKSEL2_PWM23_S_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM23_S_Msk)) >> (CLK_CLKSEL1_PWM23_S_Pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regSource == 2) {
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
clkSource = SystemCoreClock;
|
||||||
|
} else {
|
||||||
|
switch (regSource) {
|
||||||
|
case 0:
|
||||||
|
clkSource = __HXT;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
clkSource = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
clkSource = SystemCoreClock;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
clkSource = __HIRC;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
clkSource = __LIRC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate best divider */
|
||||||
|
while (divider < 17) {
|
||||||
|
pwmClk = (clkSource / (freq)) / divider;
|
||||||
|
// If pwmClk is larger than (CNR * prescale) then divider can still be bigger
|
||||||
|
if (pwmClk > (0x10000 * 0x100)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set prescaler to CNR value lower than 0xFFFF
|
||||||
|
prescale = (pwmClk + 0xFFFF) / 0x10000;
|
||||||
|
|
||||||
|
// Keep prescale bigger than 2 this loop
|
||||||
|
if (prescale < 3) {
|
||||||
|
prescale = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwmClk /= prescale;
|
||||||
|
|
||||||
|
if (pwmClk <= 0x10000) {
|
||||||
|
if (pwmClk == 1) {
|
||||||
|
CNR = 1; // Too fast, and PWM cannot generate expected frequency...
|
||||||
|
} else {
|
||||||
|
CNR = pwmClk;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
divider = divider << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwmClk = clkSource / (prescale * divider * CNR);
|
||||||
|
|
||||||
|
/* Calculate PWM Registers */
|
||||||
|
prescale -= 1;
|
||||||
|
CNR -= 1;
|
||||||
|
|
||||||
|
/* Set final divider for output calculation */
|
||||||
|
switch (divider) {
|
||||||
|
case 1:
|
||||||
|
divider = 4;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
divider = 1;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
divider = 2;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
divider = 3;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
default:
|
||||||
|
divider = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prescaler is shared every two channels (01/23/etc.)
|
||||||
|
(pwm)->PPR = ((pwm)->PPR & ~(PWM_PPR_CP01_Msk << ((channel >> 1) * 8))) | (prescale << ((channel >> 1) * 8));
|
||||||
|
(pwm)->CSR = ((pwm)->CSR & ~(PWM_CSR_CSR0_Msk << (4 * channel))) | (divider << (4 * channel));
|
||||||
|
|
||||||
|
// Set edge-aligned PWM
|
||||||
|
(pwm)->PCR &= ~(PWM_PCR_PWM01TYPE_Msk << (channel >> 1));
|
||||||
|
(pwm)->PCR |= PWM_PCR_CH0MOD_Msk << (8 * channel);
|
||||||
|
|
||||||
|
// Set PWM register values
|
||||||
|
if (duty) {
|
||||||
|
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CMR0)) + channel * 12))) = duty * (CNR + 1) / 100 - 1;
|
||||||
|
} else {
|
||||||
|
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CMR0)) + channel * 12))) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CNR0)) + channel * 12))) = CNR;
|
||||||
|
|
||||||
|
return(pwmClk);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endif /* HAL_USE_PWM */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file TIMv1/hal_pwm_lld.h
|
||||||
|
* @brief PWM subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup PWM
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_PWM_LLD_H
|
||||||
|
#define HAL_PWM_LLD_H
|
||||||
|
|
||||||
|
// #if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
// #include "stm32_tim.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of PWM channels per PWM driver.
|
||||||
|
*/
|
||||||
|
#define PWM_CHANNELS (4)
|
||||||
|
|
||||||
|
#define PWM_CH0 0x0ul
|
||||||
|
#define PWM_CH1 0x1ul
|
||||||
|
#define PWM_CH2 0x2ul
|
||||||
|
#define PWM_CH3 0x3ul
|
||||||
|
|
||||||
|
#define PWM_EDGE_ALIGNED (0x0ul) /*!< Edge aligned */
|
||||||
|
#define PWM_CENTER_ALIGNED (0x01ul) /*!< Center aligned */
|
||||||
|
|
||||||
|
#define PWM_CLK_DIV_1 (0x04ul) /*!< Divide by 1 */
|
||||||
|
#define PWM_CLK_DIV_2 (0x0ul) /*!< Divide by 2 */
|
||||||
|
#define PWM_CLK_DIV_4 (0x01ul) /*!< Divide by 4 */
|
||||||
|
#define PWM_CLK_DIV_8 (0x02ul) /*!< Divide by 8 */
|
||||||
|
#define PWM_CLK_DIV_16 (0x03ul) /*!< Divide by 16 */
|
||||||
|
|
||||||
|
#define PWM_PERIOD_INT_UNDERFLOW (0) /*!< Period interrupt - counter underflow */
|
||||||
|
#define PWM_PERIOD_INT_MATCH_CNR (PWM_PIER_INT01TYPE_Msk) /*!< Period interrupt - counter matches CNR */
|
||||||
|
#define PWM_CAPTURE_INT_RISING_LATCH (PWM_CCR0_CRL_IE0_Msk) /*!< Capture interrupt - rising latch */
|
||||||
|
#define PWM_CAPTURE_INT_FALLING_LATCH (PWM_CCR0_CFL_IE0_Msk) /*!< Capture interrupt - falling latch */
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Configuration checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
// void pwm_lld_init(void);
|
||||||
|
// void pwm_lld_start(PWMDriver *pwmp);
|
||||||
|
// void pwm_lld_stop(PWMDriver *pwmp);
|
||||||
|
// void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||||
|
// pwmchannel_t channel,
|
||||||
|
// pwmcnt_t width);
|
||||||
|
// void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
|
||||||
|
// void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
|
||||||
|
// void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
|
||||||
|
// void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
|
||||||
|
// pwmchannel_t channel);
|
||||||
|
// void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
|
||||||
|
// pwmchannel_t channel);
|
||||||
|
// void pwm_lld_serve_interrupt(PWMDriver *pwmp);
|
||||||
|
|
||||||
|
void pwm_lld_enable_period_int(PWM_T *pwm, uint32_t pwmChannel, uint32_t periodType);
|
||||||
|
void pwm_lld_disable_period_int(PWM_T *pwm, uint32_t pwmChannel);
|
||||||
|
void pwm_lld_start(PWM_T *pwm, uint32_t mask);
|
||||||
|
void pwm_lld_clear_period_int(PWM_T *pwm, uint32_t pwmChannel);
|
||||||
|
uint32_t pwm_lld_get_period_int(PWM_T *pwm, uint32_t pwmChannel);
|
||||||
|
uint32_t pwm_lld_config_output_channel(PWM_T *pwm, uint32_t channel, uint32_t freq, uint32_t duty);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// #endif /* HAL_USE_PWM */
|
||||||
|
|
||||||
|
#endif /* HAL_PWM_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,376 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file TIMv1/hal_st_lld.c
|
||||||
|
* @brief ST Driver subsystem low level driver code.
|
||||||
|
*
|
||||||
|
* @addtogroup ST
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
|
||||||
|
|
||||||
|
#if (OSAL_ST_RESOLUTION == 32)
|
||||||
|
#define ST_ARR_INIT 0xFFFFFFFF
|
||||||
|
#else
|
||||||
|
#define ST_ARR_INIT 0x0000FFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NUC123_ST_USE_TIMER == 2
|
||||||
|
#if (OSAL_ST_RESOLUTION == 32) && !NUC123_TIM2_IS_32BITS
|
||||||
|
#error "TIM2 is not a 32bits timer"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(NUC123_TIM2_IS_USED)
|
||||||
|
#error "ST requires TIM2 but the timer is already used"
|
||||||
|
#else
|
||||||
|
#define NUC123_TIM2_IS_USED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ST_HANDLER NUC123_TIM2_HANDLER
|
||||||
|
#define ST_NUMBER NUC123_TIM2_NUMBER
|
||||||
|
#define ST_USE_TIMER TIMER2
|
||||||
|
|
||||||
|
#elif NUC123_ST_USE_TIMER == 3
|
||||||
|
#if (OSAL_ST_RESOLUTION == 32) && !NUC123_TIM3_IS_32BITS
|
||||||
|
#error "TIM3 is not a 32bits timer"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(NUC123_TIM3_IS_USED)
|
||||||
|
#error "ST requires TIM3 but the timer is already used"
|
||||||
|
#else
|
||||||
|
#define NUC123_TIM3_IS_USED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ST_HANDLER NUC123_TIM3_HANDLER
|
||||||
|
#define ST_NUMBER NUC123_TIM3_NUMBER
|
||||||
|
#define ST_USE_TIMER TIMER3
|
||||||
|
|
||||||
|
#elif NUC123_ST_USE_TIMER == 4
|
||||||
|
#if (OSAL_ST_RESOLUTION == 32) && !NUC123_TIM4_IS_32BITS
|
||||||
|
#error "TIM4 is not a 32bits timer"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(NUC123_TIM4_IS_USED)
|
||||||
|
#error "ST requires TIM4 but the timer is already used"
|
||||||
|
#else
|
||||||
|
#define NUC123_TIM4_IS_USED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ST_HANDLER NUC123_TIM4_HANDLER
|
||||||
|
#define ST_NUMBER NUC123_TIM4_NUMBER
|
||||||
|
#define ST_USE_TIMER TIMER4
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "NUC123_ST_USE_TIMER specifies an unsupported timer"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief System Timer vector.
|
||||||
|
* @details This interrupt is used for system tick in periodic mode.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(SysTick_Handler) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
osalSysLockFromISR();
|
||||||
|
osalOsTimerHandlerI();
|
||||||
|
osalSysUnlockFromISR();
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
|
||||||
|
|
||||||
|
#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief TIM2 interrupt handler.
|
||||||
|
* @details This interrupt is used for system tick in free running mode.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(ST_HANDLER) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
/* Note, under rare circumstances an interrupt can remain latched even if
|
||||||
|
the timer SR register has been cleared, in those cases the interrupt
|
||||||
|
is simply ignored.*/
|
||||||
|
if (NUC123_ST_TIM->TISR & TIMER_TISR_TIF_Msk) {
|
||||||
|
|
||||||
|
// TIMER_ClearIntFlag(NUC123_ST_TIM);
|
||||||
|
NUC123_ST_TIM->TISR = TIMER_TISR_TIF_Msk;
|
||||||
|
|
||||||
|
osalSysLockFromISR();
|
||||||
|
osalOsTimerHandlerI();
|
||||||
|
osalSysUnlockFromISR();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
|
||||||
|
|
||||||
|
/* DEBUG - Catch unused Interrupt Vectors and output to test pins
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(Vector7C){
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
GPIO_TOGGLE(PB11);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_TIM3_HANDLER){
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB4);
|
||||||
|
GPIO_TOGGLE(PB5);
|
||||||
|
GPIO_TOGGLE(PB6);
|
||||||
|
GPIO_TOGGLE(PB7);
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_TIM4_HANDLER){
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB4);
|
||||||
|
GPIO_TOGGLE(PB5);
|
||||||
|
GPIO_TOGGLE(PB6);
|
||||||
|
GPIO_TOGGLE(PB7);
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_ADC_HANDLER){
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB4);
|
||||||
|
GPIO_TOGGLE(PB5);
|
||||||
|
GPIO_TOGGLE(PB6);
|
||||||
|
GPIO_TOGGLE(PB7);
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_USB1_HANDLER){
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB4);
|
||||||
|
GPIO_TOGGLE(PB5);
|
||||||
|
GPIO_TOGGLE(PB6);
|
||||||
|
GPIO_TOGGLE(PB7);
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_PDMA_HANDLER){
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
GPIO_TOGGLE(PB4);
|
||||||
|
GPIO_TOGGLE(PB5);
|
||||||
|
GPIO_TOGGLE(PB6);
|
||||||
|
GPIO_TOGGLE(PB7);
|
||||||
|
GPIO_TOGGLE(PB8);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
//OSAL_IRQ_HANDLER(HardFault_Handler){
|
||||||
|
// OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
// NVIC_SystemReset();
|
||||||
|
|
||||||
|
// OSAL_IRQ_EPILOGUE();
|
||||||
|
//}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level ST driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void st_lld_init(void) {
|
||||||
|
|
||||||
|
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
|
||||||
|
/* Free running counter mode.*/
|
||||||
|
|
||||||
|
/* Enabling timer clock.*/
|
||||||
|
|
||||||
|
st_lld_timer_open(ST_USE_TIMER, TIMER_MODE_CONTINUOUS, OSAL_ST_FREQUENCY);
|
||||||
|
|
||||||
|
/* Initializing the counter in free running mode.*/
|
||||||
|
/* NUC123_ST_TIM->PSC = (ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1;
|
||||||
|
NUC123_ST_TIM->ARR = ST_ARR_INIT;
|
||||||
|
NUC123_ST_TIM->CCMR1 = 0;
|
||||||
|
NUC123_ST_TIM->CCR[0] = 0;
|
||||||
|
NUC123_ST_TIM->DIER = 0;
|
||||||
|
NUC123_ST_TIM->CR2 = 0;
|
||||||
|
NUC123_ST_TIM->EGR = TIM_EGR_UG;
|
||||||
|
NUC123_ST_TIM->CR1 = TIM_CR1_CEN;
|
||||||
|
*/
|
||||||
|
/* IRQ enabled.*/
|
||||||
|
nvicEnableVector(ST_NUMBER, NUC123_ST_IRQ_PRIORITY);
|
||||||
|
|
||||||
|
// TIMER_EnableInt(ST_USE_TIMER);
|
||||||
|
ST_USE_TIMER->TCSR |= TIMER_TCSR_IE_Msk;
|
||||||
|
|
||||||
|
/* Start the Timer! */
|
||||||
|
// TIMER_Start(ST_USE_TIMER);
|
||||||
|
ST_USE_TIMER->TCSR |= TIMER_TCSR_CEN_Msk;
|
||||||
|
|
||||||
|
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
|
||||||
|
|
||||||
|
#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
|
||||||
|
/* Periodic systick mode, the Cortex-Mx internal systick timer is used
|
||||||
|
in this mode.*/
|
||||||
|
|
||||||
|
// CLK_EnableSysTick(CLK_CLKSEL0_STCLK_S_HCLK, (NUC123_HCLK / OSAL_ST_FREQUENCY) - 1);
|
||||||
|
SysTick->LOAD = (NUC123_HCLK / OSAL_ST_FREQUENCY) - 1;
|
||||||
|
SysTick->VAL = 0;
|
||||||
|
SysTick->CTRL = (~SysTick_CTRL_CLKSOURCE_Msk) &
|
||||||
|
(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
|
||||||
|
|
||||||
|
/* IRQ enabled.*/
|
||||||
|
nvicSetSystemHandlerPriority(HANDLER_SYSTICK, NUC123_ST_IRQ_PRIORITY);
|
||||||
|
|
||||||
|
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* OSAL_ST_MODE == OSAL_ST_MODE_NONE!!! */
|
||||||
|
#error "We can't proceed without an OSAL_ST clock!"
|
||||||
|
|
||||||
|
#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t st_lld_timer_getmoduleclock(TIMER_T *timer) {
|
||||||
|
uint32_t clkSource;
|
||||||
|
|
||||||
|
if (timer == TIMER0) {
|
||||||
|
clkSource = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0_S_Msk) >> CLK_CLKSEL1_TMR0_S_Pos;
|
||||||
|
} else if (timer == TIMER1) {
|
||||||
|
clkSource = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1_S_Msk) >> CLK_CLKSEL1_TMR1_S_Pos;
|
||||||
|
} else if (timer == TIMER2) {
|
||||||
|
clkSource = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2_S_Msk) >> CLK_CLKSEL1_TMR2_S_Pos;
|
||||||
|
} else {
|
||||||
|
clkSource = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3_S_Msk) >> CLK_CLKSEL1_TMR3_S_Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clkSource == 2) {
|
||||||
|
return(SystemCoreClock);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (clkSource) {
|
||||||
|
case 0: // Clock source is HXT
|
||||||
|
return __HXT;
|
||||||
|
break;
|
||||||
|
case 5: // Clock source is LIRC
|
||||||
|
return __LIRC;
|
||||||
|
break;
|
||||||
|
case 7: // Clock source is HIRC
|
||||||
|
return __HIRC;
|
||||||
|
break;
|
||||||
|
default: // All other clock sources return 0
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t st_lld_timer_open(TIMER_T *timer, uint32_t tmrMode, uint32_t tmrFreq) {
|
||||||
|
uint32_t tmrClk = st_lld_timer_getmoduleclock(timer);
|
||||||
|
uint32_t cmpr = 0;
|
||||||
|
uint32_t prescale = 0;
|
||||||
|
|
||||||
|
// Fastest possible timer working freq is (tmrClk / 2). While cmpr = 2, pre-scale = 0.
|
||||||
|
if (tmrFreq > (tmrClk / 2)) {
|
||||||
|
cmpr = 2;
|
||||||
|
} else {
|
||||||
|
if (tmrClk >= 0x4000000) {
|
||||||
|
prescale = 7; // prescaler value - 1
|
||||||
|
tmrClk >>= 3;
|
||||||
|
} else if (tmrClk >= 0x2000000) {
|
||||||
|
prescale = 3; // prescaler value - 1
|
||||||
|
tmrClk >>= 2; // Divide Clock by 4 in preparation
|
||||||
|
} else if (tmrClk >= 0x1000000) {
|
||||||
|
prescale = 1; // prescaler value - 1
|
||||||
|
tmrClk >>= 1; // Divide Clock by 2 in preparation
|
||||||
|
}
|
||||||
|
|
||||||
|
cmpr = tmrClk / tmrFreq;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->TCSR = tmrMode | prescale;
|
||||||
|
timer->TCMPR = cmpr;
|
||||||
|
|
||||||
|
return (tmrClk / (cmpr * (prescale + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void st_lld_timer_close(TIMER_T *timer) {
|
||||||
|
timer->TCSR = 0;
|
||||||
|
timer->TEXCON = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file hal_st_lld.h
|
||||||
|
* @brief ST Driver subsystem low level driver header.
|
||||||
|
* @details This header is designed to be include-able without having to
|
||||||
|
* include other files from the HAL.
|
||||||
|
*
|
||||||
|
* @addtogroup ST
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_ST_LLD_H
|
||||||
|
#define HAL_ST_LLD_H
|
||||||
|
|
||||||
|
#include "mcuconf.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Registry definitions.
|
||||||
|
*/
|
||||||
|
#include "nuc123_registry.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define CLK_CLKSEL0_STCLK_S_HXT (0x0ul<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Set HXT as STCLK clock source */
|
||||||
|
#define CLK_CLKSEL0_STCLK_S_HXT_DIV2 (0x2ul<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Set HXT/2 as STCLK clock source */
|
||||||
|
#define CLK_CLKSEL0_STCLK_S_HCLK_DIV2 (0x3ul<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Set HCLK/2 as STCLK clock source */
|
||||||
|
#define CLK_CLKSEL0_STCLK_S_HIRC_DIV2 (0x7ul<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Set HIRC/2 as STCLK clock source */
|
||||||
|
#define CLK_CLKSEL0_STCLK_S_HCLK (0x1ul<<SysTick_CTRL_CLKSOURCE_Pos) /*!< Set HCLK as STCLK clock source */
|
||||||
|
|
||||||
|
#define TIMER_MODE_PERIODIC (0x01ul << TIMER_TCSR_MODE_Pos)
|
||||||
|
#define TIMER_MODE_CONTINUOUS (0x03ul << TIMER_TCSR_MODE_Pos)
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief SysTick timer IRQ priority.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_ST_IRQ_PRIORITY 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TIMx unit (by number) to be used for free running operations.
|
||||||
|
* @note You must select a 32 bits timer if a 32 bits @p systick_t type
|
||||||
|
* is required.
|
||||||
|
* @note Timers 2, 3 and 4 are supported.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_ST_USE_TIMER) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_ST_USE_TIMER 2
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if NUC123_ST_USE_TIMER == 2
|
||||||
|
#if !NUC123_HAS_TIM2
|
||||||
|
#error "TIM2 not present"
|
||||||
|
#endif
|
||||||
|
#define NUC123_ST_TIM TIMER1
|
||||||
|
|
||||||
|
#elif NUC123_ST_USE_TIMER == 3
|
||||||
|
#if !NUC123_HAS_TIM3
|
||||||
|
#error "TIM3 not present"
|
||||||
|
#endif
|
||||||
|
#define NUC123_ST_TIM TIMER2
|
||||||
|
|
||||||
|
#elif NUC123_ST_USE_TIMER == 4
|
||||||
|
#if !NUC123_HAS_TIM4
|
||||||
|
#error "TIM4 not present"
|
||||||
|
#endif
|
||||||
|
#define NUC123_ST_TIM TIMER3
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "NUC123_ST_USE_TIMER specifies an unsupported timer"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void st_lld_init(void);
|
||||||
|
uint32_t st_lld_timer_getmoduleclock(TIMER_T *timer);
|
||||||
|
uint32_t st_lld_timer_open(TIMER_T *timer, uint32_t tmrMode, uint32_t tmrFreq);
|
||||||
|
void st_lld_timer_close(TIMER_T *timer);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the time counter value.
|
||||||
|
*
|
||||||
|
* @return The counter value.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline systime_t st_lld_get_counter(void) {
|
||||||
|
|
||||||
|
return (systime_t)NUC123_ST_TIM->TDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the alarm time.
|
||||||
|
*
|
||||||
|
* @param[in] time the time to be set for the next alarm
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline void st_lld_set_alarm(systime_t time) {
|
||||||
|
|
||||||
|
// TIMER_SET_CMP_VALUE(NUC123_ST_TIM, (uint32_t)time);
|
||||||
|
|
||||||
|
NUC123_ST_TIM->TCMPR = (uint32_t)time;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the current alarm time.
|
||||||
|
*
|
||||||
|
* @return The currently set alarm time.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline systime_t st_lld_get_alarm(void) {
|
||||||
|
|
||||||
|
return (systime_t)NUC123_ST_TIM->TCMPR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the alarm.
|
||||||
|
* @note Makes sure that no spurious alarms are triggered after
|
||||||
|
* this call.
|
||||||
|
*
|
||||||
|
* @param[in] time the time to be set for the first alarm
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline void st_lld_start_alarm(systime_t time) {
|
||||||
|
|
||||||
|
// NUC123_ST_TIM->TCMP = (uint32_t)time;
|
||||||
|
// NUC123_ST_TIM->SR = 0;
|
||||||
|
// NUC123_ST_TIM->DIER = NUC123_TIM_DIER_CC1IE;
|
||||||
|
|
||||||
|
st_lld_timer_open(NUC123_ST_TIM, TIMER_MODE_CONTINUOUS | TIMER_TCSR_TDR_EN_Msk, st_lld_timer_getmoduleclock(NUC123_ST_TIM));
|
||||||
|
|
||||||
|
//TIMER_SET_CMP_VALUE(NUC123_ST_TIM, (uint32_t)time);
|
||||||
|
|
||||||
|
// NUC123_ST_TIM->TCMPR = (uint32_t)time;
|
||||||
|
st_lld_set_alarm(time);
|
||||||
|
|
||||||
|
// TIMER_SET_PRESCALE_VALUE(NUC123_ST_TIM, 0);
|
||||||
|
NUC123_ST_TIM->TCSR = (NUC123_ST_TIM->TCSR & ~TIMER_TCSR_PRESCALE_Msk) | 0;
|
||||||
|
|
||||||
|
// TIMER_Start(NUC123_ST_TIM);
|
||||||
|
NUC123_ST_TIM->TCSR |= TIMER_TCSR_CEN_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stops the alarm interrupt.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline void st_lld_stop_alarm(void) {
|
||||||
|
|
||||||
|
// TIMER_DisableInt(NUC123_ST_TIM);
|
||||||
|
NUC123_ST_TIM->TCSR &= ~TIMER_TCSR_IE_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Determines if the alarm is active.
|
||||||
|
*
|
||||||
|
* @return The alarm status.
|
||||||
|
* @retval false if the alarm is not active.
|
||||||
|
* @retval true is the alarm is active
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline bool st_lld_is_alarm_active(void) {
|
||||||
|
|
||||||
|
return (bool)(((NUC123_ST_TIM->TISR & TIMER_TISR_TIF_Msk) & (NUC123_ST_TIM->TCSR & TIMER_TCSR_CACT_Msk)) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_ST_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,9 @@
|
||||||
|
ifeq ($(USE_SMART_BUILD),yes)
|
||||||
|
ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),)
|
||||||
|
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1/hal_usb_lld.c
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1/hal_usb_lld.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1
|
|
@ -0,0 +1,570 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2017 Frank Zschockelt
|
||||||
|
ChibiOS - Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file hal_usb_lld.c
|
||||||
|
* @brief NUC123 USB subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup USB
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB1 driver identifier.
|
||||||
|
*/
|
||||||
|
#if (NUC123_USB_USE_USB1 == TRUE) || defined(__DOXYGEN__)
|
||||||
|
USBDriver USBD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
uint8_t * const usbd_sram = (uint8_t*)(USBD_BASE + 0x100);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EP0 state.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief IN EP0 state.
|
||||||
|
*/
|
||||||
|
USBInEndpointState ep0_in;
|
||||||
|
/**
|
||||||
|
* @brief OUT EP0 state.
|
||||||
|
*/
|
||||||
|
USBOutEndpointState ep0_out;
|
||||||
|
|
||||||
|
static uint8_t ep0setup_buffer[8];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EP0 initialization structure.
|
||||||
|
*/
|
||||||
|
static const USBEndpointConfig ep0config = {
|
||||||
|
USB_EP_MODE_TYPE_CTRL,
|
||||||
|
_usb_ep0setup,
|
||||||
|
_usb_ep0in,
|
||||||
|
_usb_ep0out,
|
||||||
|
0x40,
|
||||||
|
0x40,
|
||||||
|
&ep0_in,
|
||||||
|
&ep0_out,
|
||||||
|
1,
|
||||||
|
ep0setup_buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
void _toggle_dsq(int ep, uint8_t *dsq)
|
||||||
|
{
|
||||||
|
if (*dsq) {
|
||||||
|
USBD->EP[ep].CFG &= ~USBD_CFG_DSQ_SYNC_Msk;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
USBD->EP[ep].CFG |= USBD_CFG_DSQ_SYNC_Msk;
|
||||||
|
}
|
||||||
|
*dsq = !*dsq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers and threads. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
static void serve_endpoint_irq(USBDriver *usbp,
|
||||||
|
uint32_t endpoint_mask,
|
||||||
|
uint32_t epstatus)
|
||||||
|
{
|
||||||
|
for (int hwEp = 0; hwEp < USB_MAX_ENDPOINTS; hwEp++) {
|
||||||
|
if (endpoint_mask & (1 << hwEp)) {
|
||||||
|
uint32_t bus_status = ((epstatus >> (hwEp*(USBD_EPSTS_EPSTS1_Pos - USBD_EPSTS_EPSTS0_Pos))) & USBD_EPSTS_EPSTS0_Msk) >> USBD_EPSTS_EPSTS0_Pos;
|
||||||
|
usbep_t ep = (USBD->EP[hwEp].CFG & USBD_CFG_EP_NUM_Msk) >> USBD_CFG_EP_NUM_Pos;
|
||||||
|
|
||||||
|
switch (bus_status) {
|
||||||
|
case 0: /* In ACK */
|
||||||
|
{
|
||||||
|
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
|
||||||
|
iesp->txcnt += USBD->EP[hwEp].MXPLD;
|
||||||
|
if (iesp->txcnt >= iesp->txsize) {
|
||||||
|
_usb_isr_invoke_in_cb(usbp, ep);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint32_t txcnt;
|
||||||
|
if ((iesp->txcnt + usbp->epc[ep]->in_maxsize) > iesp->txsize) {
|
||||||
|
txcnt = iesp->txsize - iesp->txcnt;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
txcnt = usbp->epc[ep]->in_maxsize;
|
||||||
|
}
|
||||||
|
for (uint32_t n = 0; n < txcnt; n++) {
|
||||||
|
usbd_sram[(USBD->EP[hwEp].BUFSEG) + n] = iesp->txbuf[iesp->txcnt + n];
|
||||||
|
}
|
||||||
|
_toggle_dsq(hwEp, &(iesp->dsq));
|
||||||
|
USBD->EP[hwEp].MXPLD = txcnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1: /* In NAK */
|
||||||
|
break;
|
||||||
|
case 0x2: /* Out Packet Data 0 ACK */
|
||||||
|
case 0x6: /* Out Packet Data 1 ACK */
|
||||||
|
{
|
||||||
|
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
||||||
|
for (uint32_t n = 0; n < USBD->EP[hwEp].MXPLD; n++) {
|
||||||
|
oesp->rxbuf[oesp->rxcnt] = usbd_sram[USBD->EP[hwEp].BUFSEG + n];
|
||||||
|
oesp->rxcnt++;
|
||||||
|
}
|
||||||
|
if (oesp->rxcnt == oesp->rxsize) {
|
||||||
|
_usb_isr_invoke_out_cb(usbp, ep);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_toggle_dsq(hwEp, &(oesp->dsq));
|
||||||
|
if ((oesp->rxcnt + usbp->epc[ep]->out_maxsize) > oesp->rxsize) {
|
||||||
|
USBD->EP[hwEp].MXPLD = oesp->rxsize - oesp->rxcnt;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
USBD->EP[hwEp].MXPLD = usbp->epc[ep]->out_maxsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x3: /* Setup ACK */
|
||||||
|
break;
|
||||||
|
case 0x7: /* Isochronous transfer end */
|
||||||
|
default:
|
||||||
|
osalDbgAssert(FALSE, "not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serve_usb_irq(USBDriver *usbp) {
|
||||||
|
uint32_t intsts = USBD->INTSTS;
|
||||||
|
uint32_t epsts = USBD->EPSTS;
|
||||||
|
|
||||||
|
if (intsts & USBD_INTSTS_FLDET_STS_Msk) {
|
||||||
|
USBD->INTSTS |= USBD_INTSTS_FLDET_STS_Msk;
|
||||||
|
if (USBD->FLDET) {
|
||||||
|
usbConnectBus(usbp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
usbDisconnectBus(usbp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intsts & USBD_INTSTS_BUS_STS_Msk) {
|
||||||
|
uint32_t bus_attr = USBD->ATTR;
|
||||||
|
USBD->INTSTS |= USBD_INTSTS_BUS_STS_Msk;
|
||||||
|
if (bus_attr & USBD_ATTR_USBRST_Msk) {
|
||||||
|
_usb_reset(usbp);
|
||||||
|
}
|
||||||
|
if (bus_attr & USBD_ATTR_SUSPEND_Msk) {
|
||||||
|
if (usbp->state == USB_ACTIVE) {
|
||||||
|
_usb_suspend(usbp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bus_attr & USBD_ATTR_RESUME_Msk) {
|
||||||
|
usbConnectBus(usbp);
|
||||||
|
(usbp)->receiving = 0;
|
||||||
|
(usbp)->transmitting = 0;
|
||||||
|
_usb_wakeup(usbp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intsts & USBD_INTSTS_USB_STS_Msk) {
|
||||||
|
/* check endpoints first */
|
||||||
|
serve_endpoint_irq(usbp, (intsts & USBD_INTSTS_EPEVT_Msk) >> USBD_INTSTS_EPEVT_Pos, epsts);
|
||||||
|
USBD->INTSTS = intsts & USBD_INTSTS_EPEVT_Msk;
|
||||||
|
/* then handle setup packets */
|
||||||
|
if (intsts & USBD_INTSTS_SETUP_Msk) {
|
||||||
|
USBD->INTSTS |= USBD_INTSTS_SETUP_Msk;
|
||||||
|
USBInEndpointState *iesp = usbp->epc[0]->in_state;
|
||||||
|
iesp->dsq = 0;
|
||||||
|
_usb_isr_invoke_setup_cb(usbp, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (intsts & USBD_INTSTS_WAKEUP_STS_Msk) {
|
||||||
|
USBD->INTSTS |= USBD_INTSTS_WAKEUP_STS_Msk;
|
||||||
|
USBD->ATTR |= USBD_ATTR_PHY_EN_Msk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_USB1_HANDLER) {
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
serve_usb_irq(&USBD1);
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level USB driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_init(void) {
|
||||||
|
|
||||||
|
#if NUC123_USB_USE_USB1 == TRUE
|
||||||
|
/* Driver initialization.*/
|
||||||
|
usbObjectInit(&USBD1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures and activates the USB peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_start(USBDriver *usbp) {
|
||||||
|
if (usbp->state == USB_STOP) {
|
||||||
|
/* Enables the peripheral.*/
|
||||||
|
#if NUC123_USB_USE_USB1 == TRUE
|
||||||
|
if (&USBD1 == usbp) {
|
||||||
|
uint16_t delay;
|
||||||
|
/* Enable USB Clock */
|
||||||
|
UNLOCKREG();
|
||||||
|
CLK->APBCLK |= CLK_APBCLK_USBD_EN_Msk;
|
||||||
|
|
||||||
|
/* Reset USB */
|
||||||
|
SYS->IPRSTC2 |= SYS_IPRSTC2_USBD_RST_Msk;
|
||||||
|
for (delay=0x100; delay > 0; delay--);
|
||||||
|
SYS->IPRSTC2 &= ~SYS_IPRSTC2_USBD_RST_Msk;
|
||||||
|
LOCKREG();
|
||||||
|
|
||||||
|
usbConnectBus(usbp);
|
||||||
|
USBD->ATTR = (USBD_ATTR_BYTEM_Msk | USBD_ATTR_PWRDN_Msk |
|
||||||
|
USBD_ATTR_DPPU_EN_Msk |USBD_ATTR_USB_EN_Msk |
|
||||||
|
USBD_ATTR_PHY_EN_Msk);
|
||||||
|
|
||||||
|
|
||||||
|
USBD->DRVSE0 = 1u;
|
||||||
|
for (delay=0x100; delay > 0; delay--);
|
||||||
|
USBD->DRVSE0 = 0u;
|
||||||
|
|
||||||
|
USBD->INTSTS = USBD->INTSTS;
|
||||||
|
|
||||||
|
nvicEnableVector(NUC123_USB1_NUMBER, NUC123_USB_USB1_IRQ_PRIORITY);
|
||||||
|
|
||||||
|
USBD->INTEN = (USBD_INTEN_WAKEUP_EN_Msk |
|
||||||
|
USBD_INTEN_WAKEUP_IE_Msk |
|
||||||
|
USBD_INTEN_FLDET_IE_Msk |
|
||||||
|
USBD_INTEN_USB_IE_Msk |
|
||||||
|
USBD_INTEN_BUS_IE_Msk);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deactivates the USB peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_stop(USBDriver *usbp) {
|
||||||
|
if (usbp->state == USB_READY) {
|
||||||
|
/* Resets the peripheral.*/
|
||||||
|
/* Disables the peripheral.*/
|
||||||
|
#if NUC123_USB_USE_USB1 == TRUE
|
||||||
|
if (&USBD1 == usbp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB low level reset routine.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_reset(USBDriver *usbp) {
|
||||||
|
/* Post reset initialization.*/
|
||||||
|
/* EP0 initialization.*/
|
||||||
|
usbp->epc[0] = &ep0config;
|
||||||
|
/* NUC123 has 512b SRAM for EP-buffers; the first 8b are reserved for setup packets */
|
||||||
|
usbp->bufnext = 8;
|
||||||
|
usbp->epnext = 0;
|
||||||
|
|
||||||
|
usb_lld_init_endpoint(usbp, 0);
|
||||||
|
usbConnectBus(usbp);
|
||||||
|
USBD->FADDR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the USB address.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_set_address(USBDriver *usbp) {
|
||||||
|
USBD->FADDR = usbp->address;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t usb_alloc_buf(USBDriver *usbp, size_t size) {
|
||||||
|
uint32_t buf;
|
||||||
|
buf = usbp->bufnext;
|
||||||
|
usbp->bufnext += size;
|
||||||
|
osalDbgAssert(usbp->bufnext <= 512, "usb buffer space full");
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables an endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
||||||
|
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||||
|
uint8_t hwep;
|
||||||
|
|
||||||
|
|
||||||
|
if (epcp->in_state != NULL) {
|
||||||
|
hwep = usbp->epnext;
|
||||||
|
usbp->epnext += 1;
|
||||||
|
osalDbgAssert(usbp->epnext <= USB_MAX_ENDPOINTS, "No endpoints left");
|
||||||
|
|
||||||
|
USBD->EP[hwep].BUFSEG = usb_alloc_buf(usbp, epcp->in_maxsize);
|
||||||
|
if (epcp->ep_mode == USB_EP_MODE_TYPE_CTRL)
|
||||||
|
/* 2 == in */
|
||||||
|
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (2 << USBD_CFG_STATE_Pos) | USBD_CFG_CSTALL_Msk;
|
||||||
|
else
|
||||||
|
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (2 << USBD_CFG_STATE_Pos);
|
||||||
|
epcp->in_state->hwEp = hwep;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (epcp->out_state != NULL) {
|
||||||
|
hwep = usbp->epnext;
|
||||||
|
usbp->epnext += 1;
|
||||||
|
osalDbgAssert(usbp->epnext <= USB_MAX_ENDPOINTS, "No endpoints left");
|
||||||
|
|
||||||
|
USBD->EP[hwep].BUFSEG = usb_alloc_buf(usbp, epcp->out_maxsize);
|
||||||
|
if (epcp->ep_mode == USB_EP_MODE_TYPE_CTRL)
|
||||||
|
/* 1 == Out */
|
||||||
|
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (1 << USBD_CFG_STATE_Pos) | USBD_CFG_CSTALL_Msk;
|
||||||
|
else
|
||||||
|
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (1 << USBD_CFG_STATE_Pos);
|
||||||
|
epcp->out_state->hwEp = hwep;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables all the active endpoints except the endpoint zero.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_disable_endpoints(USBDriver *usbp) {
|
||||||
|
(void)usbp;
|
||||||
|
|
||||||
|
for (int i = 0; i < USB_MAX_ENDPOINTS; i++) {
|
||||||
|
USBD->EP[i].CFGP |= USBD_CFGP_CLRRDY_Msk;
|
||||||
|
USBD->EP[i].CFG &= ~USBD_CFG_STATE_Msk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the status of an OUT endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @return The endpoint status.
|
||||||
|
* @retval EP_STATUS_DISABLED The endpoint is not active.
|
||||||
|
* @retval EP_STATUS_STALLED The endpoint is stalled.
|
||||||
|
* @retval EP_STATUS_ACTIVE The endpoint is active.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
(void)usbp;
|
||||||
|
(void)ep;
|
||||||
|
|
||||||
|
return EP_STATUS_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the status of an IN endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @return The endpoint status.
|
||||||
|
* @retval EP_STATUS_DISABLED The endpoint is not active.
|
||||||
|
* @retval EP_STATUS_STALLED The endpoint is stalled.
|
||||||
|
* @retval EP_STATUS_ACTIVE The endpoint is active.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
return EP_STATUS_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a setup packet from the dedicated packet buffer.
|
||||||
|
* @details This function must be invoked in the context of the @p setup_cb
|
||||||
|
* callback in order to read the received setup packet.
|
||||||
|
* @pre In order to use this function the endpoint must have been
|
||||||
|
* initialized as a control endpoint.
|
||||||
|
* @post The endpoint is ready to accept another packet.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @param[out] buf buffer where to copy the packet data
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
||||||
|
(void)usbp;
|
||||||
|
(void)ep;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
*buf = usbd_sram[i];
|
||||||
|
//*buf = ep0setup_buffer[i];
|
||||||
|
ep0setup_buffer[i] = usbd_sram[i];
|
||||||
|
buf += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a receive operation on an OUT endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
uint32_t rxcnt;
|
||||||
|
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
||||||
|
if (oesp->rxsize > usbp->epc[ep]->out_maxsize) {
|
||||||
|
rxcnt = usbp->epc[ep]->out_maxsize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rxcnt = oesp->rxsize;
|
||||||
|
}
|
||||||
|
_toggle_dsq(oesp->hwEp, &(oesp->dsq));
|
||||||
|
USBD->EP[oesp->hwEp].MXPLD = rxcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a transmit operation on an IN endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
uint32_t i, txcnt;
|
||||||
|
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
|
||||||
|
if (iesp->txsize > usbp->epc[ep]->in_maxsize) {
|
||||||
|
txcnt = usbp->epc[ep]->in_maxsize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
txcnt = iesp->txsize;
|
||||||
|
}
|
||||||
|
for (i = 0; i < txcnt; i++) {
|
||||||
|
usbd_sram[(USBD->EP[iesp->hwEp].BUFSEG) + i] = iesp->txbuf[i];
|
||||||
|
}
|
||||||
|
_toggle_dsq(iesp->hwEp, &(iesp->dsq));
|
||||||
|
USBD->EP[iesp->hwEp].MXPLD = txcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an OUT endpoint in the stalled state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
||||||
|
USBD->EP[oesp->hwEp].CFGP |= (USBD_CFGP_SSTALL_Msk | USBD_CFGP_CLRRDY_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an IN endpoint in the stalled state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
|
||||||
|
USBD->EP[iesp->hwEp].CFGP |= (USBD_CFGP_SSTALL_Msk | USBD_CFGP_CLRRDY_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an OUT endpoint in the active state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
||||||
|
USBD->EP[oesp->hwEp].CFGP &= ~USBD_CFGP_SSTALL_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an IN endpoint in the active state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
|
||||||
|
USBD->EP[iesp->hwEp].CFGP &= ~USBD_CFGP_SSTALL_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_USE_USB == TRUE */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,425 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2017 Frank Zschockelt
|
||||||
|
ChibiOS - Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file hal_usb_lld.h
|
||||||
|
* @brief NUC123 USB subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup USB
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_USB_LLD_H
|
||||||
|
#define HAL_USB_LLD_H
|
||||||
|
|
||||||
|
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum endpoint address.
|
||||||
|
*/
|
||||||
|
#define USB_MAX_ENDPOINTS 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Status stage handling method.
|
||||||
|
*/
|
||||||
|
#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The address can be changed immediately upon packet reception.
|
||||||
|
*/
|
||||||
|
#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Method for set address acknowledge.
|
||||||
|
*/
|
||||||
|
#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name NUC123 configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief USB driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for USB1 is included.
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_USB_USE_USB1) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_USB_USE_USB1 FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB interrupt priority level setting.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_USB_USB1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_USB_USB1_IRQ_PRIORITY 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Host wake-up procedure duration.
|
||||||
|
*/
|
||||||
|
#if !defined(USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
|
||||||
|
#define USB_HOST_WAKEUP_DURATION 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (USB_HOST_WAKEUP_DURATION < 2) || (USB_HOST_WAKEUP_DURATION > 15)
|
||||||
|
#error "invalid USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an IN endpoint state structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Requested transmit transfer size.
|
||||||
|
*/
|
||||||
|
size_t txsize;
|
||||||
|
/**
|
||||||
|
* @brief Transmitted bytes so far.
|
||||||
|
*/
|
||||||
|
size_t txcnt;
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the transmission linear buffer.
|
||||||
|
*/
|
||||||
|
const uint8_t *txbuf;
|
||||||
|
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Waiting thread.
|
||||||
|
*/
|
||||||
|
thread_reference_t thread;
|
||||||
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
uint8_t hwEp;
|
||||||
|
uint8_t dsq;
|
||||||
|
} USBInEndpointState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an OUT endpoint state structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Requested receive transfer size.
|
||||||
|
*/
|
||||||
|
size_t rxsize;
|
||||||
|
/**
|
||||||
|
* @brief Received bytes so far.
|
||||||
|
*/
|
||||||
|
size_t rxcnt;
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the receive linear buffer.
|
||||||
|
*/
|
||||||
|
uint8_t *rxbuf;
|
||||||
|
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Waiting thread.
|
||||||
|
*/
|
||||||
|
thread_reference_t thread;
|
||||||
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
uint8_t hwEp;
|
||||||
|
uint8_t dsq;
|
||||||
|
} USBOutEndpointState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an USB endpoint configuration structure.
|
||||||
|
* @note Platform specific restrictions may apply to endpoints.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Type and mode of the endpoint.
|
||||||
|
*/
|
||||||
|
uint32_t ep_mode;
|
||||||
|
/**
|
||||||
|
* @brief Setup packet notification callback.
|
||||||
|
* @details This callback is invoked when a setup packet has been
|
||||||
|
* received.
|
||||||
|
* @post The application must immediately call @p usbReadPacket() in
|
||||||
|
* order to access the received packet.
|
||||||
|
* @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
|
||||||
|
* endpoints, it should be set to @p NULL for other endpoint
|
||||||
|
* types.
|
||||||
|
*/
|
||||||
|
usbepcallback_t setup_cb;
|
||||||
|
/**
|
||||||
|
* @brief IN endpoint notification callback.
|
||||||
|
* @details This field must be set to @p NULL if the IN endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
usbepcallback_t in_cb;
|
||||||
|
/**
|
||||||
|
* @brief OUT endpoint notification callback.
|
||||||
|
* @details This field must be set to @p NULL if the OUT endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
usbepcallback_t out_cb;
|
||||||
|
/**
|
||||||
|
* @brief IN endpoint maximum packet size.
|
||||||
|
* @details This field must be set to zero if the IN endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
uint16_t in_maxsize;
|
||||||
|
/**
|
||||||
|
* @brief OUT endpoint maximum packet size.
|
||||||
|
* @details This field must be set to zero if the OUT endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
uint16_t out_maxsize;
|
||||||
|
/**
|
||||||
|
* @brief @p USBEndpointState associated to the IN endpoint.
|
||||||
|
* @details This structure maintains the state of the IN endpoint.
|
||||||
|
*/
|
||||||
|
USBInEndpointState *in_state;
|
||||||
|
/**
|
||||||
|
* @brief @p USBEndpointState associated to the OUT endpoint.
|
||||||
|
* @details This structure maintains the state of the OUT endpoint.
|
||||||
|
*/
|
||||||
|
USBOutEndpointState *out_state;
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
/**
|
||||||
|
* @brief Reserved field, not currently used.
|
||||||
|
* @note Initialize this field to 1 in order to be forward compatible.
|
||||||
|
*/
|
||||||
|
uint16_t ep_buffers;
|
||||||
|
/**
|
||||||
|
* @brief Pointer to a buffer for setup packets.
|
||||||
|
* @details Setup packets require a dedicated 8-bytes buffer, set this
|
||||||
|
* field to @p NULL for non-control endpoints.
|
||||||
|
*/
|
||||||
|
uint8_t *setup_buf;
|
||||||
|
} USBEndpointConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an USB driver configuration structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief USB events callback.
|
||||||
|
* @details This callback is invoked when an USB driver event is registered.
|
||||||
|
*/
|
||||||
|
usbeventcb_t event_cb;
|
||||||
|
/**
|
||||||
|
* @brief Device GET_DESCRIPTOR request callback.
|
||||||
|
* @note This callback is mandatory and cannot be set to @p NULL.
|
||||||
|
*/
|
||||||
|
usbgetdescriptor_t get_descriptor_cb;
|
||||||
|
/**
|
||||||
|
* @brief Requests hook callback.
|
||||||
|
* @details This hook allows to be notified of standard requests or to
|
||||||
|
* handle non standard requests.
|
||||||
|
*/
|
||||||
|
usbreqhandler_t requests_hook_cb;
|
||||||
|
/**
|
||||||
|
* @brief Start Of Frame callback.
|
||||||
|
*/
|
||||||
|
usbcallback_t sof_cb;
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
} USBConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure representing an USB driver.
|
||||||
|
*/
|
||||||
|
struct USBDriver {
|
||||||
|
/**
|
||||||
|
* @brief Driver state.
|
||||||
|
*/
|
||||||
|
usbstate_t state;
|
||||||
|
/**
|
||||||
|
* @brief Current configuration data.
|
||||||
|
*/
|
||||||
|
const USBConfig *config;
|
||||||
|
/**
|
||||||
|
* @brief Bit map of the transmitting IN endpoints.
|
||||||
|
*/
|
||||||
|
uint16_t transmitting;
|
||||||
|
/**
|
||||||
|
* @brief Bit map of the receiving OUT endpoints.
|
||||||
|
*/
|
||||||
|
uint16_t receiving;
|
||||||
|
/**
|
||||||
|
* @brief Active endpoints configurations.
|
||||||
|
*/
|
||||||
|
const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
|
||||||
|
/**
|
||||||
|
* @brief Fields available to user, it can be used to associate an
|
||||||
|
* application-defined handler to an IN endpoint.
|
||||||
|
* @note The base index is one, the endpoint zero does not have a
|
||||||
|
* reserved element in this array.
|
||||||
|
*/
|
||||||
|
void *in_params[USB_MAX_ENDPOINTS];
|
||||||
|
/**
|
||||||
|
* @brief Fields available to user, it can be used to associate an
|
||||||
|
* application-defined handler to an OUT endpoint.
|
||||||
|
* @note The base index is one, the endpoint zero does not have a
|
||||||
|
* reserved element in this array.
|
||||||
|
*/
|
||||||
|
void *out_params[USB_MAX_ENDPOINTS];
|
||||||
|
/**
|
||||||
|
* @brief Endpoint 0 state.
|
||||||
|
*/
|
||||||
|
usbep0state_t ep0state;
|
||||||
|
/**
|
||||||
|
* @brief Next position in the buffer to be transferred through endpoint 0.
|
||||||
|
*/
|
||||||
|
uint8_t *ep0next;
|
||||||
|
/**
|
||||||
|
* @brief Number of bytes yet to be transferred through endpoint 0.
|
||||||
|
*/
|
||||||
|
size_t ep0n;
|
||||||
|
/**
|
||||||
|
* @brief Endpoint 0 end transaction callback.
|
||||||
|
*/
|
||||||
|
usbcallback_t ep0endcb;
|
||||||
|
/**
|
||||||
|
* @brief Setup packet buffer.
|
||||||
|
*/
|
||||||
|
uint8_t setup[8];
|
||||||
|
/**
|
||||||
|
* @brief Current USB device status.
|
||||||
|
*/
|
||||||
|
uint16_t status;
|
||||||
|
/**
|
||||||
|
* @brief Assigned USB address.
|
||||||
|
*/
|
||||||
|
uint8_t address;
|
||||||
|
/**
|
||||||
|
* @brief Current USB device configuration.
|
||||||
|
*/
|
||||||
|
uint8_t configuration;
|
||||||
|
/**
|
||||||
|
* @brief State of the driver when a suspend happened.
|
||||||
|
*/
|
||||||
|
usbstate_t saved_state;
|
||||||
|
#if defined(USB_DRIVER_EXT_FIELDS)
|
||||||
|
USB_DRIVER_EXT_FIELDS
|
||||||
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
uint32_t bufnext;
|
||||||
|
uint8_t epnext;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the current frame number.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @return The current frame number.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define usb_lld_get_frame_number(usbp) 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the exact size of a receive transaction.
|
||||||
|
* @details The received size can be different from the size specified in
|
||||||
|
* @p usbStartReceiveI() because the last packet could have a size
|
||||||
|
* different from the expected one.
|
||||||
|
* @pre The OUT endpoint must have been configured in transaction mode
|
||||||
|
* in order to use this function.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @return Received data size.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define usb_lld_get_transaction_size(usbp, ep) \
|
||||||
|
((usbp)->epc[ep]->out_state->rxcnt)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Connects the USB device.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
#define usb_lld_connect_bus(usbp) (USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect the USB device.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
#define usb_lld_disconnect_bus(usbp) (USBD->ATTR &= ~USBD_ATTR_USB_EN_Msk)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start of host wake-up procedure.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define usb_lld_wakeup_host(usbp) \
|
||||||
|
do{ \
|
||||||
|
USBD->ATTR |= USBD_ATTR_RWAKEUP_Msk; \
|
||||||
|
osalThreadSleepMilliseconds(USB_HOST_WAKEUP_DURATION); \
|
||||||
|
USBD->ATTR &= ~USBD_ATTR_RWAKEUP_Msk; \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (NUC123_USB_USE_USB1 == TRUE) && !defined(__DOXYGEN__)
|
||||||
|
extern USBDriver USBD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void usb_lld_init(void);
|
||||||
|
void usb_lld_start(USBDriver *usbp);
|
||||||
|
void usb_lld_stop(USBDriver *usbp);
|
||||||
|
void usb_lld_reset(USBDriver *usbp);
|
||||||
|
void usb_lld_set_address(USBDriver *usbp);
|
||||||
|
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_disable_endpoints(USBDriver *usbp);
|
||||||
|
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
|
||||||
|
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_USB == TRUE */
|
||||||
|
|
||||||
|
#endif /* HAL_USB_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file NUC123SD4AN0/hal_lld.c
|
||||||
|
* @brief NUC123SD4AN0 HAL subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup HAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define NUC123_PLLXTPRE_OFFSET 17 /**< PLLXTPRE offset */
|
||||||
|
#define NUC123_PLLXTPRE_MASK 0x01 /**< PLLXTPRE mask */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CMSIS system core clock variable.
|
||||||
|
* @note It is declared in system_NUC123SD4AN0.h.
|
||||||
|
*/
|
||||||
|
//uint32_t SystemCoreClock = NUC123_HCLK;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if defined(NUC123_DMA_REQUIRED) || defined(__DOXYGEN__)
|
||||||
|
#if defined(NUC123_DMA1_CH23_HANDLER) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief DMA1 streams 2 and 3 shared ISR.
|
||||||
|
* @note It is declared here because this device has a non-standard
|
||||||
|
* DMA shared IRQ handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_DMA1_CH23_HANDLER) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
/* Check on channel 2.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM2);
|
||||||
|
|
||||||
|
/* Check on channel 3.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM3);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* defined(NUC123_DMA1_CH23_HANDLER) */
|
||||||
|
|
||||||
|
#if defined(NUC123_DMA1_CH4567_HANDLER) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief DMA1 streams 4, 5, 6 and 7 shared ISR.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_DMA1_CH4567_HANDLER) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
/* Check on channel 4.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM4);
|
||||||
|
|
||||||
|
/* Check on channel 5.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM5);
|
||||||
|
|
||||||
|
#if NUC123_DMA1_NUM_CHANNELS > 5
|
||||||
|
/* Check on channel 6.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM6);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NUC123_DMA1_NUM_CHANNELS > 6
|
||||||
|
/* Check on channel 7.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM7);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* defined(NUC123_DMA1_CH4567_HANDLER) */
|
||||||
|
|
||||||
|
#if defined(NUC123_DMA12_CH23_CH12_HANDLER) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief DMA1 streams 2 and 3, DMA2 streams 1 and 1 shared ISR.
|
||||||
|
* @note It is declared here because this device has a non-standard
|
||||||
|
* DMA shared IRQ handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_DMA12_CH23_CH12_HANDLER) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
/* Check on channel 2 of DMA1.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM2);
|
||||||
|
|
||||||
|
/* Check on channel 3 of DMA1.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM3);
|
||||||
|
|
||||||
|
/* Check on channel 1 of DMA2.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA2_STREAM1);
|
||||||
|
|
||||||
|
/* Check on channel 2 of DMA2.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA2_STREAM2);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* defined(NUC123_DMA12_CH23_CH12_HANDLER) */
|
||||||
|
|
||||||
|
#if defined(NUC123_DMA12_CH4567_CH345_HANDLER) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief DMA1 streams 4, 5, 6 and 7, DMA2 streams 3, 4 and 5 shared ISR.
|
||||||
|
* @note It is declared here because this device has a non-standard
|
||||||
|
* DMA shared IRQ handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(NUC123_DMA12_CH4567_CH345_HANDLER) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
/* Check on channel 4 of DMA1.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM4);
|
||||||
|
|
||||||
|
/* Check on channel 5 of DMA1.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM5);
|
||||||
|
|
||||||
|
/* Check on channel 6 of DMA1.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM6);
|
||||||
|
|
||||||
|
/* Check on channel 7 of DMA1.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA1_STREAM7);
|
||||||
|
|
||||||
|
/* Check on channel 3 of DMA2.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA2_STREAM3);
|
||||||
|
|
||||||
|
/* Check on channel 4 of DMA2.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA2_STREAM4);
|
||||||
|
|
||||||
|
/* Check on channel 5 of DMA2.*/
|
||||||
|
dmaServeInterrupt(NUC123_DMA2_STREAM5);
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* defined(NUC123_DMA12_CH4567_CH345_HANDLER) */
|
||||||
|
#endif /* defined(NUC123_DMA_REQUIRED) */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level HAL driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void hal_lld_init(void) {
|
||||||
|
|
||||||
|
/* Reset of all peripherals.*/
|
||||||
|
// **NUC123TODO
|
||||||
|
#if defined(NUC123_DMA_REQUIRED)
|
||||||
|
//dmaInit();
|
||||||
|
//usbInit();
|
||||||
|
//uartInit();
|
||||||
|
//spiInit();
|
||||||
|
#endif
|
||||||
|
//usbInit();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief NUC123 clocks and PLL initialization.
|
||||||
|
* @note All the involved constants come from the file @p board.h.
|
||||||
|
* @note This function should be invoked just after the system reset.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
void NUC123_clock_init(void) {
|
||||||
|
SystemUnlockReg();
|
||||||
|
|
||||||
|
/* Enable XT1_OUT (PF.0) and XT1_IN (PF.1) */
|
||||||
|
SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* Init System Clock */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Enable Internal RC 22.1184 MHz clock */
|
||||||
|
CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;
|
||||||
|
|
||||||
|
/* Waiting for Internal RC clock ready */
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_OSC22M_STB_Msk);
|
||||||
|
|
||||||
|
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
|
||||||
|
clks_lld_set_HCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
|
||||||
|
|
||||||
|
/* Enable external XTAL 12 MHz clock */
|
||||||
|
CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;
|
||||||
|
|
||||||
|
/* Waiting for external XTAL clock ready */
|
||||||
|
clks_lld_wait_for_clock_ready(CLK_CLKSTATUS_XTL12M_STB_Msk);
|
||||||
|
|
||||||
|
/* Set core clock */
|
||||||
|
clks_lld_set_core_clock(FREQ_72MHZ);
|
||||||
|
|
||||||
|
SystemCoreClock = NUC123_HCLK;
|
||||||
|
|
||||||
|
clks_lld_enable_SysTick(CLK_CLKSEL0_STCLK_S_HCLK_DIV2, (NUC123_HCLK / OSAL_ST_FREQUENCY) - 1);
|
||||||
|
|
||||||
|
/* Enable module clock */
|
||||||
|
clks_lld_enable_module_clock(USBD_ModuleNum);
|
||||||
|
|
||||||
|
/* Select module clock source */
|
||||||
|
clks_lld_set_module_clock(USBD_ModuleNum, 0, CLK_CLKDIV_USB(3));
|
||||||
|
|
||||||
|
/* TEMPORARY!!! */
|
||||||
|
/* Set GPB multi-function pins for UART0 RXD and TXD */
|
||||||
|
SYS->GPB_MFP = (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD);
|
||||||
|
/* Set PC.13 as CLKO function pin */
|
||||||
|
//SYS->GPC_MFP = SYS_GPC_MFP_PC13_CLKO;
|
||||||
|
//SYS->ALT_MFP = SYS_ALT_MFP_PC13_CLKO;
|
||||||
|
|
||||||
|
/* Enable CLKO (PC.13) for monitor HCLK. CLKO = HCLK/8 Hz*/
|
||||||
|
// clks_lld_enable_ck0(CLK_CLKSEL2_FRQDIV_S_HCLK, 2, 0);
|
||||||
|
|
||||||
|
LOCKREG();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,759 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file NUC123SD4AN0/hal_lld.h
|
||||||
|
* @brief NUC123SD4AN0 HAL subsystem low level driver header.
|
||||||
|
* @pre This module requires the following macros to be defined in the
|
||||||
|
* @p board.h file:
|
||||||
|
* - NUC123_LSECLK.
|
||||||
|
* - NUC123_LSEDRV.
|
||||||
|
* - NUC123_LSE_BYPASS (optionally).
|
||||||
|
* - NUC123_HSECLK.
|
||||||
|
* - NUC123_HSE_BYPASS (optionally).
|
||||||
|
* .
|
||||||
|
* .
|
||||||
|
*
|
||||||
|
* @addtogroup HAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_LLD_H
|
||||||
|
#define HAL_LLD_H
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Platform identification macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if defined(NUC123SD4AN0) || defined(__DOXYGEN__)
|
||||||
|
#define PLATFORM_NAME "NUC123SD4AN0 NUC123 Cortex M0 USB Micro"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "NUC123 device unsupported or not specified"
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Absolute Maximum Ratings
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Maximum system clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_SYSCLK_MAX FREQ_72MHZ
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum HSE clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_HSECLK_MAX 24000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Minimum HSE clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_HSECLK_MIN 4000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum LSE clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_LSECLK_MAX 10000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Minimum LSE clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_LSECLK_MIN 10000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum PLLs input clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_PLLIN_MAX 24000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Minimum PLLs input clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_PLLIN_MIN 4000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum PLL output clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_PLLOUT_MAX FREQ_72MHZ
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Minimum PLL output clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_PLLOUT_MIN 4000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum APB clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_PCLK_MAX FREQ_72MHZ
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Internal clock sources
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define NUC123_HSICLK __HIRC /**< High speed internal clock. */
|
||||||
|
#define NUC123_HSI_69CLK 691200 /**< ~0.69MHz High speed internal clock. */
|
||||||
|
#define NUC123_HSI1_38CLK 1382400 /**< ~1.375MHz High speed internal clock. */
|
||||||
|
#define NUC123_HSI2_76CLK 2764800 /**< ~2.75MHz High speed internal clock. */
|
||||||
|
#define NUC123_HSI5_5CLK 5529600 /**< ~5.5MHz speed internal clock.*/
|
||||||
|
#define NUC123_HSI11CLK 11059200 /**< ~11MHz speed internal clock.*/
|
||||||
|
#define NUC123_LSICLK __LIRC /**< Low speed internal clock. */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CLKSEL0 register bits definitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NUC123_HCLKSRC_HSE (0 << 0) /**< HCLK source is HSE */
|
||||||
|
#define NUC123_HCLKSRC_PLL_2 (1 << 0) /**< HCLK source is PLL/2 */
|
||||||
|
#define NUC123_HCLKSRC_PLL (2 << 0) /**< HCLK source is PLL */
|
||||||
|
#define NUC123_HCLKSRC_LSI (3 << 0) /**< HCLK source is LSI */
|
||||||
|
#define NUC123_HCLKSRC_HSI (7 << 0) /**< HCLK source is HSI */
|
||||||
|
|
||||||
|
#define NUC123_SW_HSE (0 << 3) /**< SYSCLK source is HSE. */
|
||||||
|
#define NUC123_SW_HSE_2 (1 << 3) /**< SYSCLK source is HSE/2. */
|
||||||
|
#define NUC123_SW_HCLK_2 (3 << 3) /**< SYSCLK source is HCLK/2. */
|
||||||
|
#define NUC123_SW_HSI_2 (7 << 3) /**< SYSCLK source is HSI. */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CLKSEL1 register bits definitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define NUC123_WDTSRC_MASK (3 << 0) /**< WDT source mask */
|
||||||
|
#define NUC123_WDTSRC_HCLK_2048 (2 << 0) /**< WDT source is HCLK/2048 */
|
||||||
|
#define NUC123_WDTSRC_LSI (3 << 0) /**< WDT source is LSI */
|
||||||
|
|
||||||
|
#define NUC123_ADCSRC_MASK (3 << 2) /**< ADC source mask */
|
||||||
|
#define NUC123_ADCSRC_HSE (0 << 2) /**< ADC source is HSE */
|
||||||
|
#define NUC123_ADCSRC_PLL (1 << 2) /**< ADC source is PLL */
|
||||||
|
#define NUC123_ADCSRC_HCLK (2 << 2) /**< ADC source is HCLK */
|
||||||
|
#define NUC123_ADCSRC_HSI (3 << 2) /**< ADC source is HSI */
|
||||||
|
|
||||||
|
#define NUC123_SPI0SRC_MASK (1 << 4) /**< SPI0 source mask */
|
||||||
|
#define NUC123_SPI0SRC_PLL (0 << 4) /**< SPI0 source is PLL */
|
||||||
|
#define NUC123_SPI0SRC_HCLK (1 << 4) /**< SPI0 source is HCLK */
|
||||||
|
#define NUC123_SPI1SRC_MASK (1 << 5) /**< SPI1 source MASK */
|
||||||
|
#define NUC123_SPI1SRC_PLL (0 << 5) /**< SPI1 source is PLL */
|
||||||
|
#define NUC123_SPI1SRC_HCLK (1 << 5) /**< SPI1 source is HCLK */
|
||||||
|
#define NUC123_SPI2SRC_MASK (1 << 6) /**< SPI2 source mask */
|
||||||
|
#define NUC123_SPI2SRC_PLL (0 << 6) /**< SPI2 source is PLL */
|
||||||
|
#define NUC123_SPI2SRC_HCLK (1 << 6) /**< SPI2 source is HCLK */
|
||||||
|
|
||||||
|
#define NUC123_TMR0SRC_MASK (7 << 8) /**< TMR0 source mask */
|
||||||
|
#define NUC123_TMR0SRC_HSE (0 << 8) /**< TMR0 source is HSE */
|
||||||
|
#define NUC123_TMR0SRC_HCLK (2 << 8) /**< TMR0 source is HCLK */
|
||||||
|
#define NUC123_TMR0SRC_TM0 (3 << 8) /**< TMR0 source is TM0 pin */
|
||||||
|
#define NUC123_TMR0SRC_LSI (5 << 8) /**< TMR0 source is LSI */
|
||||||
|
#define NUC123_TMR0SRC_HSI (7 << 8) /**< TMR0 source is HSI */
|
||||||
|
|
||||||
|
#define NUC123_TMR1SRC_MASK (7 << 12) /**< TMR1 source mask */
|
||||||
|
#define NUC123_TMR1SRC_HSE (0 << 12) /**< TMR1 source is HSE */
|
||||||
|
#define NUC123_TMR1SRC_HCLK (2 << 12) /**< TMR1 source is HCLK */
|
||||||
|
#define NUC123_TMR1SRC_TM1 (3 << 12) /**< TMR1 source is TM1 pin */
|
||||||
|
#define NUC123_TMR1SRC_LSI (5 << 12) /**< TMR1 source is LSI */
|
||||||
|
#define NUC123_TMR1SRC_HSI (7 << 12) /**< TMR1 source is HSI */
|
||||||
|
|
||||||
|
#define NUC123_TMR2SRC_MASK (7 << 16) /**< TMR2 source mask */
|
||||||
|
#define NUC123_TMR2SRC_HSE (0 << 16) /**< TMR2 source is HSE */
|
||||||
|
#define NUC123_TMR2SRC_HCLK (2 << 16) /**< TMR2 source is HCLK */
|
||||||
|
#define NUC123_TMR2SRC_TM2 (3 << 16) /**< TMR2 source is TM2 pin */
|
||||||
|
#define NUC123_TMR2SRC_LSI (5 << 16) /**< TMR2 source is LSI */
|
||||||
|
#define NUC123_TMR2SRC_HSI (7 << 16) /**< TMR2 source is HSI */
|
||||||
|
|
||||||
|
#define NUC123_TMR3SRC_MASK (7 << 20) /**< TMR3 source mask */
|
||||||
|
#define NUC123_TMR3SRC_HSE (0 << 20) /**< TMR3 source is HSE */
|
||||||
|
#define NUC123_TMR3SRC_HCLK (2 << 20) /**< TMR3 source is HCLK */
|
||||||
|
#define NUC123_TMR3SRC_LSI (5 << 20) /**< TMR3 source is LSI */
|
||||||
|
#define NUC123_TMR3SRC_HSI (7 << 20) /**< TMR3 source is HSI */
|
||||||
|
|
||||||
|
#define NUC123_USARTSRC_MASK (3 << 24) /**< UART source mask. */
|
||||||
|
#define NUC123_USARTSRC_HS3 (0 << 24) /**< UART source is HSE. */
|
||||||
|
#define NUC123_USARTSRC_PLL (1 << 24) /**< UART source is PLL. */
|
||||||
|
#define NUC123_USARTSRC_HSI (3 << 24) /**< UART source is HSI. */
|
||||||
|
|
||||||
|
#define NUC123_PWM01SRCA_MASK (3 << 28) /**< PWM0/1 source [1:0] mask */
|
||||||
|
#define NUC123_PWM01SRCA_HSE (0 << 28) /**< PWM0/1 source [1:0] is HSE */
|
||||||
|
#define NUC123_PWM01SRCA_HCLK (2 << 28) /**< PWM0/1 source [1:0] is HCLK*/
|
||||||
|
#define NUC123_PWM01SRCA_HSI (3 << 28) /**< PWM0/1 source [1:0] is HSI */
|
||||||
|
#define NUC123_PWM01SRCA_LSI (3 << 28) /**< PWM0/1 source [1:0] is LSI */
|
||||||
|
|
||||||
|
#define NUC123_PWM23SRCA_MASK (3 << 30) /**< PWM2/3 source [1:0] mask */
|
||||||
|
#define NUC123_PWM23SRCA_HSE (0 << 30) /**< PWM2/3 source [1:0] is HSE */
|
||||||
|
#define NUC123_PWM23SRCA_HCLK (2 << 30) /**< PWM2/3 source [1:0] is HCLK*/
|
||||||
|
#define NUC123_PWM23SRCA_HSI (3 << 30) /**< PWM2/3 source [1:0] is HSI */
|
||||||
|
#define NUC123_PWM23SRCA_LSI (3 << 30) /**< PWM2/3 source [1:0] is LSI */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CLKSEL2 register bits definitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define NUC123_I2SSRC_MASK (3 << 0) /**< I2S clock source mask. */
|
||||||
|
#define NUC123_I2SSRC_HSE (0 << 0) /**< I2S clock source is HSE. */
|
||||||
|
#define NUC123_I2SSRC_PLL (1 << 0) /**< I2S clock source is PLL. */
|
||||||
|
#define NUC123_I2SSRC_HCLK (2 << 0) /**< I2S clock source is HCLK. */
|
||||||
|
#define NUC123_I2SSRC_HSI (3 << 0) /**< I2S clock source is HSI. */
|
||||||
|
|
||||||
|
#define NUC123_FREQDIVSRC_MASK (3 << 2) /**< FRQDIV clock source mask */
|
||||||
|
#define NUC123_FREQDIVSRC_HSE (0 << 2) /**< FRQDIV clock source is HSE */
|
||||||
|
#define NUC123_FREQDIVSRC_HCLK (2 << 2) /**< FRQDIV clock source is HCLK*/
|
||||||
|
#define NUC123_FREQDIVSRC_HSI (3 << 2) /**< FRQDIV clock source is LSI */
|
||||||
|
|
||||||
|
#define NUC123_PWM01SRCB_MASK (1 << 8) /**< PWM0/1 source [2] mask */
|
||||||
|
#define NUC123_PWM01SRCB_HSI (0 << 8) /**< PWM0/1 source [2] is HSI */
|
||||||
|
#define NUC123_PWM01SRCB_LSI (1 << 8) /**< PWM0/1 source [2] is LSI */
|
||||||
|
|
||||||
|
#define NUC123_PWM23SRCB_MASK (1 << 9) /**< PWM2/3 source [2] mask */
|
||||||
|
#define NUC123_PWM23SRCB_HSI (0 << 9) /**< PWM2/3 source [2] is HSI */
|
||||||
|
#define NUC123_PWM23SRCB_LSI (1 << 9) /**< PWM2/3 source [2] is LSI */
|
||||||
|
|
||||||
|
#define NUC123_WWDTSRC_MASK (3 << 16) /**< WWDT source mask */
|
||||||
|
#define NUC123_WWDTSRC_HCLK_2048 (2 << 16) /**< WWDT source is HCLK/2048 */
|
||||||
|
#define NUC123_WWDTSRC_LSI (3 << 16) /**< WWDT source is LSI */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Disables the PWR/RCC initialization in the HAL.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_NO_INIT) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_NO_INIT FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the HSI clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_HSI_ENABLED) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_HSI_ENABLED TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the LSI clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_LSI_ENABLED) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_LSI_ENABLED TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the HSE clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_HSE_ENABLED) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_HSE_ENABLED TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the LSE clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_LSE_ENABLED) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_LSE_ENABLED FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main clock source selection.
|
||||||
|
* @note If the selected clock source is not the PLL then the PLL is not
|
||||||
|
* initialized and started.
|
||||||
|
* @note The default value is calculated for a 72MHz system clock from
|
||||||
|
* a 12MHz crystal using the PLL.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_SW) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_SW NUC123_SW_HCLK_2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clock source for the PLL.
|
||||||
|
* @note This setting has only effect if the PLL is selected as the
|
||||||
|
* system clock source.
|
||||||
|
* @note The default value is calculated for a 72MHz system clock from
|
||||||
|
* a 12MHz crystal using the PLL.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_PLLSRC) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PLLSRC NUC123_PLLSRC_HSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Crystal PLL pre-divider.
|
||||||
|
* @note This setting has only effect if the PLL is selected as the
|
||||||
|
* system clock source.
|
||||||
|
* @note The default value is calculated for a 72MHz system clock from
|
||||||
|
* a 21MHz crystal using the PLL.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_PREDIV_VALUE) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PREDIV_VALUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PLL multiplier value.
|
||||||
|
* @note The allowed range is 2...16.
|
||||||
|
* @note The default value is calculated for a 72MHz system clock from
|
||||||
|
* a 12MHz crystal using the PLL.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_PLLMUL_VALUE) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PLLMUL_VALUE 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AHB prescaler value.
|
||||||
|
* @note The default value is calculated for a 72MHz system clock from
|
||||||
|
* a 12MHz crystal using the PLL.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_HPRE) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_HPRE NUC123_HPRE_DIV1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief APB1 prescaler value.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_PPRE) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PPRE NUC123_PPRE_DIV1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MCO pin setting.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_MCOSEL) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_MCOSEL NUC123_MCOSEL_NOCLOCK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MCO divider setting.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_MCOPRE) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_MCOPRE NUC123_MCOPRE_DIV1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MCO PLL divider setting.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_PLLNODIV) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PLLNODIV NUC123_PLLNODIV_DIV2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB Clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_USBSW) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_USBSW NUC123_USBSW_HSI48
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CEC clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_CECSW) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_CECSW NUC123_CECSW_HSI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C1 clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_I2C1SW) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_I2C1SW NUC123_I2C1SW_HSI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USART1 clock source.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123_USART1SW) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_USART1SW NUC123_USART1SW_PCLK
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configuration-related checks.
|
||||||
|
*/
|
||||||
|
#if !defined(NUC123SD4AN0_MCUCONF)
|
||||||
|
#error "Using a wrong mcuconf.h file, NUC123SD4AN0_MCUCONF not defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HSI related checks.
|
||||||
|
*/
|
||||||
|
#if NUC123_HSI_ENABLED
|
||||||
|
|
||||||
|
/*#if NUC123_SW == NUC123_SW_HSE
|
||||||
|
#error "HSI not enabled, required by NUC123_SW"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NUC123_CECSW == NUC123_CECSW_HSI
|
||||||
|
#error "HSI not enabled, required by NUC123_CECSW"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NUC123_I2C1SW == NUC123_I2C1SW_HSI
|
||||||
|
#error "HSI not enabled, required by NUC123_I2C1SW"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NUC123_USART1SW == NUC123_USART1SW_HSI
|
||||||
|
#error "HSI not enabled, required by NUC123_USART1SW"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NUC123_SW == NUC123_SW_PLL) && \
|
||||||
|
(NUC123_PLLSRC == NUC123_PLLSRC_HSI_DIV2) || \
|
||||||
|
(NUC123_PLLSRC == NUC123_PLLSRC_HSI)
|
||||||
|
#error "HSI not enabled, required by NUC123_SW and NUC123_PLLSRC"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NUC123_MCOSEL == NUC123_MCOSEL_HSI) || \
|
||||||
|
((NUC123_MCOSEL == NUC123_MCOSEL_PLLDIV2) && \
|
||||||
|
((NUC123_PLLSRC == NUC123_PLLSRC_HSI_DIV2) || \
|
||||||
|
(NUC123_PLLSRC == NUC123_PLLSRC_HSI)))
|
||||||
|
#error "HSI not enabled, required by NUC123_MCOSEL"
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
#endif /* !NUC123_HSI_ENABLED */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HSE related checks.
|
||||||
|
*/
|
||||||
|
#if NUC123_HSE_ENABLED
|
||||||
|
|
||||||
|
#if NUC123_HSECLK == 0
|
||||||
|
#error "HSE frequency not defined"
|
||||||
|
#elif (NUC123_HSECLK < NUC123_HSECLK_MIN) || (NUC123_HSECLK > NUC123_HSECLK_MAX)
|
||||||
|
#error "NUC123_HSECLK outside acceptable range (NUC123_HSECLK_MIN...NUC123_HSECLK_MAX)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* !NUC123_HSE_ENABLED */
|
||||||
|
|
||||||
|
#if (NUC123_SW == NUC123_SW_HSE) || (NUC123_SW == NUC123_SW_HSE_2)
|
||||||
|
#error "HSE not enabled, required by NUC123_SW"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NUC123_SW == NUC123_SW_HCL) && (NUC123_PLLSRC == NUC123_PLLSRC_HSE)
|
||||||
|
#error "HSE not enabled, required by NUC123_SW and NUC123_PLLSRC"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NUC123_MCOSEL == NUC123_MCOSEL_HSE) || \
|
||||||
|
((NUC123_MCOSEL == NUC123_MCOSEL_PLLDIV2) && \
|
||||||
|
(NUC123_PLLSRC == NUC123_PLLSRC_HSE))
|
||||||
|
#error "HSE not enabled, required by NUC123_MCOSEL"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !NUC123_HSE_ENABLED */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LSI related checks.
|
||||||
|
*/
|
||||||
|
#if NUC123_LSI_ENABLED
|
||||||
|
#else /* !NUC123_LSI_ENABLED */
|
||||||
|
|
||||||
|
#if NUC123_RTCSEL == NUC123_RTCSEL_LSI
|
||||||
|
#error "LSI not enabled, required by NUC123_RTCSEL"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !NUC123_LSI_ENABLED */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LSE related checks.
|
||||||
|
*/
|
||||||
|
#if NUC123_LSE_ENABLED
|
||||||
|
|
||||||
|
#if (NUC123_LSECLK == 0)
|
||||||
|
#error "LSE frequency not defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NUC123_LSECLK < NUC123_LSECLK_MIN) || (NUC123_LSECLK > NUC123_LSECLK_MAX)
|
||||||
|
#error "NUC123_LSECLK outside acceptable range (NUC123_LSECLK_MIN...NUC123_LSECLK_MAX)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(NUC123_LSEDRV)
|
||||||
|
#error "NUC123_LSEDRV not defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NUC123_LSEDRV >> 3) > 3
|
||||||
|
#error "NUC123_LSEDRV outside acceptable range ((0<<3)...(3<<3))"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* !NUC123_LSE_ENABLED */
|
||||||
|
|
||||||
|
#endif /* !NUC123_LSE_ENABLED */
|
||||||
|
|
||||||
|
/* PLL activation conditions.*/
|
||||||
|
#if (NUC123_SW == NUC123_SW_PLL) || \
|
||||||
|
(NUC123_USBSW == NUC123_USBSW_PCLK) || \
|
||||||
|
(NUC123_MCOSEL == NUC123_MCOSEL_PLLDIV2) || \
|
||||||
|
defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief PLL activation flag.
|
||||||
|
*/
|
||||||
|
#define NUC123_ACTIVATE_PLL TRUE
|
||||||
|
#else
|
||||||
|
#define NUC123_ACTIVATE_PLL FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* HSE, HSI prescaler setting check.*/
|
||||||
|
#if ((NUC123_PREDIV_VALUE >= 1) || (NUC123_PREDIV_VALUE <= 16))
|
||||||
|
#define NUC123_PREDIV ((NUC123_PREDIV_VALUE - 1) << 0)
|
||||||
|
#else
|
||||||
|
#error "invalid NUC123_PREDIV value specified"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PLLMUL field.
|
||||||
|
*/
|
||||||
|
#if ((NUC123_PLLMUL_VALUE >= 2) && (NUC123_PLLMUL_VALUE <= 16)) || \
|
||||||
|
defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PLLMUL ((NUC123_PLLMUL_VALUE - 2) << 18)
|
||||||
|
#else
|
||||||
|
#error "invalid NUC123_PLLMUL_VALUE value specified"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PLL input clock frequency.
|
||||||
|
*/
|
||||||
|
#if (NUC123_PLLSRC == NUC123_PLLSRC_HSE) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PLLCLKIN (NUC123_HSECLK / NUC123_PREDIV_VALUE)
|
||||||
|
#elif NUC123_PLLSRC == NUC123_PLLSRC_HSI_DIV2
|
||||||
|
#define NUC123_PLLCLKIN (NUC123_HSICLK / 2)
|
||||||
|
#elif NUC123_PLLSRC == NUC123_PLLSRC_HSI
|
||||||
|
#define NUC123_PLLCLKIN (NUC123_HSICLK / NUC123_PREDIV_VALUE)
|
||||||
|
#else
|
||||||
|
#error "invalid NUC123_PLLSRC value specified"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* PLL input frequency range check.*/
|
||||||
|
#if (NUC123_PLLCLKIN < NUC123_PLLIN_MIN) || (NUC123_PLLCLKIN > NUC123_PLLIN_MAX)
|
||||||
|
#error "NUC123_PLLCLKIN outside acceptable range (NUC123_PLLIN_MIN...NUC123_PLLIN_MAX)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PLL output clock frequency.
|
||||||
|
*/
|
||||||
|
#define NUC123_PLLCLKOUT (NUC123_PLLCLKIN * NUC123_PLLMUL_VALUE)
|
||||||
|
|
||||||
|
/* PLL output frequency range check.
|
||||||
|
#if (NUC123_PLLCLKOUT < NUC123_PLLOUT_MIN) || (NUC123_PLLCLKOUT > NUC123_PLLOUT_MAX)
|
||||||
|
#error "NUC123_PLLCLKOUT outside acceptable range (NUC123_PLLOUT_MIN...NUC123_PLLOUT_MAX)"
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief System clock source.
|
||||||
|
*/
|
||||||
|
#if (NUC123_SW == NUC123_SW_HSE) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_SYSCLK NUC123_HSECLK
|
||||||
|
#elif (NUC123_SW == NUC123_SW_HSE_2)
|
||||||
|
#define NUC123_SYSCLK NUC123_HSECLK >> 1
|
||||||
|
#elif (NUC123_SW == NUC123_SW_HCLK_2)
|
||||||
|
#define NUC123_SYSCLK FREQ_72MHZ >> 1
|
||||||
|
#elif (NUC123_SW == NUC123_SW_HSI_2)
|
||||||
|
#define NUC123_SYSCLK NUC123_HSI11CLK
|
||||||
|
#else
|
||||||
|
#error "invalid NUC123_SW value specified"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check on the system clock.*/
|
||||||
|
#if NUC123_SYSCLK > NUC123_SYSCLK_MAX
|
||||||
|
#error "NUC123_SYSCLK above maximum rated frequency (NUC123_SYSCLK_MAX)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AHB frequency.
|
||||||
|
*
|
||||||
|
#if (NUC123_HPRE == NUC123_HPRE_DIV1) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 1)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV2
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 2)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV4
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 4)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV8
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 8)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV16
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 16)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV64
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 64)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV128
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 128)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV256
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 256)
|
||||||
|
#elif NUC123_HPRE == NUC123_HPRE_DIV512
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 512)
|
||||||
|
#else
|
||||||
|
#error "invalid NUC123_HPRE value specified"
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
#define NUC123_HCLK (NUC123_SYSCLK / 1)
|
||||||
|
|
||||||
|
/* AHB frequency check.*/
|
||||||
|
#if NUC123_HCLK > NUC123_SYSCLK_MAX
|
||||||
|
#error "NUC123_HCLK exceeding maximum frequency (NUC123_SYSCLK_MAX)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief APB frequency.
|
||||||
|
*/
|
||||||
|
#if (NUC123_PPRE == NUC123_PPRE_DIV1) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_PCLK (NUC123_HCLK / 1)
|
||||||
|
#elif NUC123_PPRE == NUC123_PPRE_DIV2
|
||||||
|
#define NUC123_PCLK (NUC123_HCLK / 2)
|
||||||
|
#elif NUC123_PPRE == NUC123_PPRE_DIV4
|
||||||
|
#define NUC123_PCLK (NUC123_HCLK / 4)
|
||||||
|
#elif NUC123_PPRE == NUC123_PPRE_DIV8
|
||||||
|
#define NUC123_PCLK (NUC123_HCLK / 8)
|
||||||
|
#elif NUC123_PPRE == NUC123_PPRE_DIV16
|
||||||
|
#define NUC123_PCLK (NUC123_HCLK / 16)
|
||||||
|
#else
|
||||||
|
#error "invalid NUC123_PPRE value specified"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* APB frequency check.*/
|
||||||
|
#if NUC123_PCLK > NUC123_PCLK_MAX
|
||||||
|
#error "NUC123_PCLK exceeding maximum frequency (NUC123_PCLK_MAX)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* NUC123_PLLNODIV check.*/
|
||||||
|
#if (NUC123_PLLNODIV != NUC123_PLLNODIV_DIV2) && \
|
||||||
|
(NUC123_PLLNODIV != NUC123_PLLNODIV_DIV1)
|
||||||
|
#error "invalid NUC123_PLLNODIV value specified"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CEC frequency.
|
||||||
|
*/
|
||||||
|
#if (NUC123_CECSW == NUC123_CECSW_HSI) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_CECCLK NUC123_HSICLK
|
||||||
|
#elif NUC123_CECSW == NUC123_CECSW_LSE
|
||||||
|
#define NUC123_CECCLK NUC123_LSECLK
|
||||||
|
#elif NUC123_CECSW == NUC123_CECSW_OFF
|
||||||
|
#define NUC123_CECCLK 0
|
||||||
|
#else
|
||||||
|
#error "invalid source selected for CEC clock"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C1 frequency.
|
||||||
|
*/
|
||||||
|
#if (NUC123_I2C1SW == NUC123_I2C1SW_HSI) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_I2C1CLK NUC123_HSICLK
|
||||||
|
#elif NUC123_I2C1SW == NUC123_I2C1SW_SYSCLK
|
||||||
|
#define NUC123_I2C1CLK NUC123_SYSCLK
|
||||||
|
#else
|
||||||
|
#error "invalid source selected for I2C1 clock"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USART1 frequency.
|
||||||
|
*/
|
||||||
|
#if (NUC123_USART1SW == NUC123_USART1SW_PCLK) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_USART1CLK NUC123_PCLK
|
||||||
|
#elif NUC123_USART1SW == NUC123_USART1SW_SYSCLK
|
||||||
|
#define NUC123_USART1CLK NUC123_SYSCLK
|
||||||
|
#elif NUC123_USART1SW == NUC123_USART1SW_LSE
|
||||||
|
#define NUC123_USART1CLK NUC123_LSECLK
|
||||||
|
#elif NUC123_USART1SW == NUC123_USART1SW_HSI
|
||||||
|
#define NUC123_USART1CLK NUC123_HSICLK
|
||||||
|
#else
|
||||||
|
#error "invalid source selected for USART1 clock"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @brief USART2 frequency.
|
||||||
|
// */
|
||||||
|
// #define NUC123_USART2CLK NUC123_PCLK
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @brief USART3 frequency.
|
||||||
|
// */
|
||||||
|
// #define NUC123_USART3CLK NUC123_PCLK
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @brief USART4 frequency.
|
||||||
|
// */
|
||||||
|
// #define NUC123_UART4CLK NUC123_PCLK
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @brief USART5 frequency.
|
||||||
|
// */
|
||||||
|
// #define NUC123_UART5CLK NUC123_PCLK
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @brief USART6 frequency.
|
||||||
|
// */
|
||||||
|
// #define NUC123_USART6CLK NUC123_PCLK
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Timers clock.
|
||||||
|
*/
|
||||||
|
#if (NUC123_PPRE == NUC123_PPRE_DIV1) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_TIMCLK1 (NUC123_PCLK * 1)
|
||||||
|
#define NUC123_TIMCLK2 (NUC123_PCLK * 1)
|
||||||
|
#else
|
||||||
|
#define NUC123_TIMCLK1 (NUC123_PCLK * 2)
|
||||||
|
#define NUC123_TIMCLK2 (NUC123_PCLK * 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flash settings.
|
||||||
|
*/
|
||||||
|
#if (NUC123_HCLK <= 24000000) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123_FLASHBITS 0x00000010
|
||||||
|
#else
|
||||||
|
#define NUC123_FLASHBITS 0x00000011
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For compatibility with driver assuming a specific PPRE clock.
|
||||||
|
*/
|
||||||
|
#define NUC123_PCLK1 NUC123_PCLK
|
||||||
|
#define NUC123_PCLK2 NUC123_PCLK
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/* Various helpers.*/
|
||||||
|
#include "nvic.h"
|
||||||
|
#include "nuc123_isr.h"
|
||||||
|
//#include "nuc123_dma.h"
|
||||||
|
#include "hal_clks_lld.h"
|
||||||
|
#include "hal_pwm_lld.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void hal_lld_init(void);
|
||||||
|
void NUC123_clock_init(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file NUMICRO/nuc123_isr.h
|
||||||
|
* @brief ISR remapper driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup NUC123SD4AN0_ISR
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUC123_ISR_H
|
||||||
|
#define NUC123_ISR_H
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ISR names and numbers remapping
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO units.
|
||||||
|
*/
|
||||||
|
#if defined(NUC123SD4AN0)
|
||||||
|
#define NUC123_GPIOAB_HANDLER Vector50
|
||||||
|
#define NUC123_GPIOCDF_HANDLER Vector54
|
||||||
|
|
||||||
|
#define NUC123_GPIOAB_NUMBER GPAB_IRQn
|
||||||
|
#define NUC123_GPIOCDF_NUMBER GPCDF_IRQn
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special ST unit
|
||||||
|
*/
|
||||||
|
#define NUC123_ST_HANDLER Vector3C
|
||||||
|
#define NUC123_ST_NUMBER SysTick_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA units.
|
||||||
|
*/
|
||||||
|
#define NUC123_PDMA_HANDLER VectorA8
|
||||||
|
#define NUC123_PDMA_NUMBER PDMA_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADC units.
|
||||||
|
*/
|
||||||
|
#define NUC123_ADC_HANDLER VectorB0
|
||||||
|
#define NUC123_ADC_NUMBER ADC_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PWM units.
|
||||||
|
*/
|
||||||
|
#define NUC123_PWMA_HANDLER Vector58
|
||||||
|
#define NUC123_PWMA_NUMBER PWMA_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI units.
|
||||||
|
*/
|
||||||
|
#define NUC123_SPI0_HANDLER Vector78
|
||||||
|
#define NUC123_SPI1_HANDLER Vector7C
|
||||||
|
#define NUC123_SPI2_HANDLER Vector80
|
||||||
|
|
||||||
|
#define NUC123_SPI0_NUMBER SPI0_IRQn
|
||||||
|
#define NUC123_SPI1_NUMBER SPI1_IRQn
|
||||||
|
#define NUC123_SPI2_NUMBER SPI2_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I2S units.
|
||||||
|
*/
|
||||||
|
#define NUC123_I2C1_HANDLER VectorB8
|
||||||
|
#define NUC123_I2C1_NUMBER I2S_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I2C units.
|
||||||
|
*/
|
||||||
|
#define NUC123_I2C1_GLOBAL_HANDLER Vector88
|
||||||
|
#define NUC123_I2C1_GLOBAL_NUMBER I2C0_IRQn
|
||||||
|
|
||||||
|
#define NUC123_I2C2_GLOBAL_HANDLER Vector8C
|
||||||
|
#define NUC123_I2C2_GLOBAL_NUMBER I2C1_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TIM units.
|
||||||
|
*/
|
||||||
|
#define NUC123_TIM1_HANDLER Vector60
|
||||||
|
#define NUC123_TIM2_HANDLER Vector64
|
||||||
|
#define NUC123_TIM3_HANDLER Vector68
|
||||||
|
#define NUC123_TIM4_HANDLER Vector6C
|
||||||
|
|
||||||
|
#define NUC123_TIM1_NUMBER TMR0_IRQn
|
||||||
|
#define NUC123_TIM2_NUMBER TMR1_IRQn
|
||||||
|
#define NUC123_TIM3_NUMBER TMR2_IRQn
|
||||||
|
#define NUC123_TIM4_NUMBER TMR3_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USART units.
|
||||||
|
*/
|
||||||
|
#define NUC123_USART1_HANDLER Vector70
|
||||||
|
#define NUC123_USART2_HANDLER Vector74
|
||||||
|
|
||||||
|
#define NUC123_USART1_NUMBER UART0_IRQn
|
||||||
|
#define NUC123_USART2_NUMBER UART1_IRQn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB units.
|
||||||
|
*/
|
||||||
|
#define NUC123_USB1_HANDLER Vector9C
|
||||||
|
#define NUC123_USB1_NUMBER USBD_IRQn
|
||||||
|
|
||||||
|
#define USBD_INTSTS_EPEVT_Pos USBD_INTSTS_EPEVT0_Pos
|
||||||
|
#define USBD_INTSTS_EPEVT_Msk (0xFFul << USBD_INTSTS_EPEVT_Pos)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#endif /* NUC123_ISR_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,263 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2019 /u/KeepItUnder
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file NUC123SD4AN0/nuc123_registry.h
|
||||||
|
* @brief NUC123SD4AN0 capabilities registry.
|
||||||
|
*
|
||||||
|
* @addtogroup HAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUC123_REGISTRY_H
|
||||||
|
#define NUC123_REGISTRY_H
|
||||||
|
|
||||||
|
#if !defined(NUC123SD4AN0) || defined(__DOXYGEN__)
|
||||||
|
#define NUC123SD4AN0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Platform capabilities. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name NUC123SD4AN0 capabilities
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* RCC attributes. */
|
||||||
|
#define NUC123_HAS_HSI48 FALSE
|
||||||
|
#define NUC123_HAS_HSI_PREDIV FALSE
|
||||||
|
#define NUC123_HAS_MCO_PREDIV TRUE
|
||||||
|
|
||||||
|
/* ADC attributes.*/
|
||||||
|
#define NUC123_HAS_ADC1 TRUE
|
||||||
|
#define NUC123_ADC_SUPPORTS_PRESCALER FALSE
|
||||||
|
#define NUC123_ADC_SUPPORTS_OVERSAMPLING FALSE
|
||||||
|
#define NUC123_ADC1_IRQ_SHARED_WITH_EXTI FALSE
|
||||||
|
#define NUC123_ADC1_HANDLER Vector70
|
||||||
|
#define NUC123_ADC1_NUMBER Vector70_IRQn
|
||||||
|
#define NUC123_ADC1_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 1) |\
|
||||||
|
NUC123_DMA_STREAM_ID_MSK(1, 2))
|
||||||
|
#define NUC123_ADC1_DMA_CHN 0x00000011
|
||||||
|
|
||||||
|
#define NUC123_HAS_ADC2 FALSE
|
||||||
|
#define NUC123_HAS_ADC3 FALSE
|
||||||
|
#define NUC123_HAS_ADC4 FALSE
|
||||||
|
|
||||||
|
/* CAN attributes.*/
|
||||||
|
#define NUC123_HAS_CAN1 FALSE
|
||||||
|
#define NUC123_HAS_CAN2 FALSE
|
||||||
|
#define NUC123_HAS_CAN3 FALSE
|
||||||
|
|
||||||
|
/* DAC attributes.*/
|
||||||
|
#define NUC123_HAS_DAC1_CH1 FALSE
|
||||||
|
#define NUC123_HAS_DAC1_CH2 FALSE
|
||||||
|
#define NUC123_HAS_DAC2_CH1 FALSE
|
||||||
|
#define NUC123_HAS_DAC2_CH2 FALSE
|
||||||
|
|
||||||
|
/* DMA attributes.*/
|
||||||
|
#define NUC123_ADVANCED_DMA FALSE
|
||||||
|
#define NUC123_DMA_SUPPORTS_CSELR FALSE
|
||||||
|
#define NUC123_DMA1_NUM_CHANNELS 6
|
||||||
|
#define NUC123_DMA2_NUM_CHANNELS 0
|
||||||
|
#define NUC123_DMA1_CH1_HANDLER Vector64
|
||||||
|
#define NUC123_DMA1_CH23_HANDLER Vector68
|
||||||
|
#define NUC123_DMA1_CH4567_HANDLER Vector6C
|
||||||
|
#define NUC123_DMA1_CH1_NUMBER Vector64_IRQn
|
||||||
|
#define NUC123_DMA1_CH23_NUMBER Vector68_IRQn
|
||||||
|
#define NUC123_DMA1_CH4567_NUMBER Vector6C_IRQn
|
||||||
|
|
||||||
|
#define NUC123_DMA1_CH2_NUMBER NUC123_DMA1_CH23_NUMBER
|
||||||
|
#define NUC123_DMA1_CH3_NUMBER NUC123_DMA1_CH23_NUMBER
|
||||||
|
#define DMA1_CH2_CMASK 0x00000006U
|
||||||
|
#define DMA1_CH3_CMASK 0x00000006U
|
||||||
|
|
||||||
|
#define NUC123_DMA1_CH4_NUMBER NUC123_DMA1_CH4567_NUMBER
|
||||||
|
#define NUC123_DMA1_CH5_NUMBER NUC123_DMA1_CH4567_NUMBER
|
||||||
|
#define NUC123_DMA1_CH6_NUMBER NUC123_DMA1_CH4567_NUMBER
|
||||||
|
#define NUC123_DMA1_CH7_NUMBER NUC123_DMA1_CH4567_NUMBER
|
||||||
|
#define DMA1_CH4_CMASK 0x00000078U
|
||||||
|
#define DMA1_CH5_CMASK 0x00000078U
|
||||||
|
#define DMA1_CH6_CMASK 0x00000078U
|
||||||
|
#define DMA1_CH7_CMASK 0x00000078U
|
||||||
|
|
||||||
|
/* ETH attributes.*/
|
||||||
|
#define NUC123_HAS_ETH FALSE
|
||||||
|
|
||||||
|
/* EXTI attributes.*/
|
||||||
|
//#define NUC123_EXTI_NUM_LINES 20
|
||||||
|
//#define NUC123_EXTI_IMR_MASK 0xFFF50000U
|
||||||
|
|
||||||
|
/* GPIO attributes.*/
|
||||||
|
#define NUC123_HAS_GPIOA TRUE
|
||||||
|
#define NUC123_HAS_GPIOB TRUE
|
||||||
|
#define NUC123_HAS_GPIOC TRUE
|
||||||
|
#define NUC123_HAS_GPIOD TRUE
|
||||||
|
#define NUC123_HAS_GPIOE FALSE
|
||||||
|
#define NUC123_HAS_GPIOF TRUE
|
||||||
|
#define NUC123_HAS_GPIOG FALSE
|
||||||
|
#define NUC123_HAS_GPIOH FALSE
|
||||||
|
#define NUC123_HAS_GPIOI FALSE
|
||||||
|
#define NUC123_HAS_GPIOJ FALSE
|
||||||
|
#define NUC123_HAS_GPIOK FALSE
|
||||||
|
|
||||||
|
/* I2C attributes.*/
|
||||||
|
#define NUC123_HAS_I2C1 TRUE
|
||||||
|
#define NUC123_I2C1_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 3)
|
||||||
|
#define NUC123_I2C1_RX_DMA_CHN 0x00000200
|
||||||
|
#define NUC123_I2C1_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 2)
|
||||||
|
#define NUC123_I2C1_TX_DMA_CHN 0x00000020
|
||||||
|
|
||||||
|
#define NUC123_HAS_I2C2 TRUE
|
||||||
|
#define NUC123_I2C2_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 5)
|
||||||
|
#define NUC123_I2C2_RX_DMA_CHN 0x00020000
|
||||||
|
#define NUC123_I2C2_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 4)
|
||||||
|
#define NUC123_I2C2_TX_DMA_CHN 0x00002000
|
||||||
|
|
||||||
|
#define NUC123_HAS_I2C3 FALSE
|
||||||
|
#define NUC123_HAS_I2C4 FALSE
|
||||||
|
|
||||||
|
/* QUADSPI attributes.*/
|
||||||
|
#define NUC123_HAS_QUADSPI1 FALSE
|
||||||
|
|
||||||
|
/* RTC attributes.*/
|
||||||
|
#define NUC123_HAS_RTC FALSE
|
||||||
|
#define NUC123_RTC_HAS_SUBSECONDS FALSE
|
||||||
|
#define NUC123_RTC_HAS_PERIODIC_WAKEUPS FALSE
|
||||||
|
#define NUC123_RTC_NUM_ALARMS 0
|
||||||
|
#define NUC123_RTC_HAS_INTERRUPTS FALSE
|
||||||
|
|
||||||
|
/* SDIO attributes.*/
|
||||||
|
#define NUC123_HAS_SDIO FALSE
|
||||||
|
|
||||||
|
/* SPI attributes.*/
|
||||||
|
#define NUC123_HAS_SPI1 TRUE
|
||||||
|
#define NUC123_SPI1_SUPPORTS_I2S FALSE
|
||||||
|
#define NUC123_SPI1_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 2)
|
||||||
|
#define NUC123_SPI1_RX_DMA_CHN 0x00000030
|
||||||
|
#define NUC123_SPI1_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 3)
|
||||||
|
#define NUC123_SPI1_TX_DMA_CHN 0x00000300
|
||||||
|
|
||||||
|
#define NUC123_HAS_SPI2 TRUE
|
||||||
|
#define NUC123_SPI2_SUPPORTS_I2S FALSE
|
||||||
|
#define NUC123_SPI2_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 4)
|
||||||
|
#define NUC123_SPI2_RX_DMA_CHN 0x00003000
|
||||||
|
#define NUC123_SPI2_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 5)
|
||||||
|
#define NUC123_SPI2_TX_DMA_CHN 0x00030000
|
||||||
|
|
||||||
|
#define NUC123_HAS_SPI3 FALSE
|
||||||
|
#define NUC123_HAS_SPI4 FALSE
|
||||||
|
#define NUC123_HAS_SPI5 FALSE
|
||||||
|
#define NUC123_HAS_SPI6 FALSE
|
||||||
|
|
||||||
|
/* TIM attributes.*/
|
||||||
|
#define NUC123_TIM_MAX_CHANNELS 4
|
||||||
|
|
||||||
|
#define NUC123_HAS_TIM1 TRUE
|
||||||
|
#define NUC123_TIM1_IS_32BITS TRUE
|
||||||
|
#define NUC123_TIM1_CHANNELS 1
|
||||||
|
|
||||||
|
#define NUC123_HAS_TIM2 TRUE
|
||||||
|
#define NUC123_TIM2_IS_32BITS TRUE
|
||||||
|
#define NUC123_TIM2_CHANNELS 1
|
||||||
|
|
||||||
|
#define NUC123_HAS_TIM3 TRUE
|
||||||
|
#define NUC123_TIM3_IS_32BITS TRUE
|
||||||
|
#define NUC123_TIM3_CHANNELS 1
|
||||||
|
|
||||||
|
#define NUC123_HAS_TIM4 TRUE
|
||||||
|
#define NUC123_TIM14_IS_32BITS TRUE
|
||||||
|
#define NUC123_TIM14_CHANNELS 1
|
||||||
|
|
||||||
|
#define NUC123_HAS_TIM5 FALSE
|
||||||
|
#define NUC123_HAS_TIM6 FALSE
|
||||||
|
#define NUC123_HAS_TIM7 FALSE
|
||||||
|
#define NUC123_HAS_TIM8 FALSE
|
||||||
|
#define NUC123_HAS_TIM9 FALSE
|
||||||
|
#define NUC123_HAS_TIM10 FALSE
|
||||||
|
#define NUC123_HAS_TIM11 FALSE
|
||||||
|
#define NUC123_HAS_TIM12 FALSE
|
||||||
|
#define NUC123_HAS_TIM13 FALSE
|
||||||
|
#define NUC123_HAS_TIM14 FALSE
|
||||||
|
#define NUC123_HAS_TIM15 FALSE
|
||||||
|
#define NUC123_HAS_TIM16 FALSE
|
||||||
|
#define NUC123_HAS_TIM17 FALSE
|
||||||
|
#define NUC123_HAS_TIM18 FALSE
|
||||||
|
#define NUC123_HAS_TIM19 FALSE
|
||||||
|
#define NUC123_HAS_TIM20 FALSE
|
||||||
|
#define NUC123_HAS_TIM21 FALSE
|
||||||
|
#define NUC123_HAS_TIM22 FALSE
|
||||||
|
|
||||||
|
/* USART attributes.*/
|
||||||
|
/*#define NUC123_HAS_USART1 TRUE
|
||||||
|
#define NUC123_USART1_RX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 1) |\
|
||||||
|
NUC123_DMA_STREAM_ID_MSK(1, 3) |\
|
||||||
|
NUC123_DMA_STREAM_ID_MSK(1, 5))
|
||||||
|
#define NUC123_USART1_RX_DMA_CHN 0x00080808
|
||||||
|
#define NUC123_USART1_TX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 2) |\
|
||||||
|
NUC123_DMA_STREAM_ID_MSK(1, 4))
|
||||||
|
#define NUC123_USART1_TX_DMA_CHN 0x00008080
|
||||||
|
|
||||||
|
#define NUC123_HAS_USART2 TRUE
|
||||||
|
#define NUC123_USART2_RX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 1) |\
|
||||||
|
NUC123_DMA_STREAM_ID_MSK(1, 3) |\
|
||||||
|
NUC123_DMA_STREAM_ID_MSK(1, 5))
|
||||||
|
#define NUC123_USART2_RX_DMA_CHN 0x00090909
|
||||||
|
#define NUC123_USART2_TX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 2) |\
|
||||||
|
NUC123_DMA_STREAM_ID_MSK(1, 4))
|
||||||
|
#define NUC123_USART2_TX_DMA_CHN 0x00009090
|
||||||
|
*/
|
||||||
|
#define NUC123_HAS_USART1 FALSE
|
||||||
|
#define NUC123_HAS_USART2 FALSE
|
||||||
|
#define NUC123_HAS_USART3 FALSE
|
||||||
|
#define NUC123_HAS_UART4 FALSE
|
||||||
|
#define NUC123_HAS_UART5 FALSE
|
||||||
|
#define NUC123_HAS_USART6 FALSE
|
||||||
|
#define NUC123_HAS_UART7 FALSE
|
||||||
|
#define NUC123_HAS_UART8 FALSE
|
||||||
|
#define NUC123_HAS_LPUART1 FALSE
|
||||||
|
|
||||||
|
/* USB attributes.*/
|
||||||
|
#define NUC123_HAS_USB TRUE
|
||||||
|
#define NUC123_HAS_OTG1 FALSE
|
||||||
|
#define NUC123_HAS_OTG2 FALSE
|
||||||
|
|
||||||
|
/* IWDG attributes.*/
|
||||||
|
#define NUC123_HAS_IWDG TRUE
|
||||||
|
#define NUC123_IWDG_IS_WINDOWED TRUE
|
||||||
|
|
||||||
|
/* LTDC attributes.*/
|
||||||
|
#define NUC123_HAS_LTDC FALSE
|
||||||
|
|
||||||
|
/* DMA2D attributes.*/
|
||||||
|
#define NUC123_HAS_DMA2D FALSE
|
||||||
|
|
||||||
|
/* FSMC attributes.*/
|
||||||
|
#define NUC123_HAS_FSMC FALSE
|
||||||
|
|
||||||
|
/* CRC attributes.*/
|
||||||
|
#define NUC123_HAS_CRC TRUE
|
||||||
|
#define NUC123_CRC_PROGRAMMABLE FALSE
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "NUC123SD4AN0 device not specified"
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* NUC123_REGISTRY_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Required platform files.
|
||||||
|
PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
|
||||||
|
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/NUC123SD4AN0/hal_lld.c \
|
||||||
|
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/NUC123SD4AN0/system_NUC123SD4AN0.c
|
||||||
|
|
||||||
|
# Required include directories.
|
||||||
|
PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
|
||||||
|
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/NUC123SD4AN0 \
|
||||||
|
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD
|
||||||
|
|
||||||
|
# Optional platform files.
|
||||||
|
ifeq ($(USE_SMART_BUILD),yes)
|
||||||
|
HALCONF := $(strip $(shell cat halconf.h | egrep -e "\#define"))
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Drivers compatible with the platform.
|
||||||
|
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/CLKv1/driver.mk
|
||||||
|
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/driver.mk
|
||||||
|
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/driver.mk
|
||||||
|
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1/driver.mk
|
|
@ -0,0 +1,153 @@
|
||||||
|
/**************************************************************************//**
|
||||||
|
* @file system_NUC123SD4AN0.c
|
||||||
|
* @brief CMSIS Cortex-M0 Device Peripheral Access Layer Source File for
|
||||||
|
* Device NUC123SD4AN0
|
||||||
|
* @version V5.00
|
||||||
|
* @date 13. May 2019
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 /u/KeepItUnder. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "NUC123SD4AN0.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Define clocks
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
/* ToDo: add here your necessary defines for device initialization
|
||||||
|
following is an example for different system frequencies */
|
||||||
|
// #define XTAL (12000000U) /* Oscillator frequency */
|
||||||
|
|
||||||
|
// #define SYSTEM_CLOCK (5 * XTAL)
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
System Core Clock Variable
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
/* ToDo: initialize SystemCoreClock with the system core clock frequency value
|
||||||
|
achieved after system intitialization.
|
||||||
|
This means system core clock frequency after call to SystemInit() */
|
||||||
|
// uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Clock Frequency (Core Clock)*/
|
||||||
|
// uint32_t CyclesPerUs = (SYSTEM_CLOCK / 1000000); /* Cycles per micro second */
|
||||||
|
// uint32_t PllClock = SYSTEM_CLOCK; /*!< PLL Clock Frequency */
|
||||||
|
uint32_t SystemCoreClock = __HSI; /* System Clock Frequency (Core Clock)*/
|
||||||
|
uint32_t CyclesPerUs = (__HSI / 1000000); /* Cycles per micro second */
|
||||||
|
uint32_t PllClock = __HSI; /*!< PLL Clock Frequency */
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Clock functions
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
|
||||||
|
{
|
||||||
|
/* ToDo: add code to calculate the system frequency based upon the current
|
||||||
|
register settings.
|
||||||
|
This function can be used to retrieve the system core clock frequeny
|
||||||
|
after user changed register sittings. */
|
||||||
|
// SystemCoreClock = SYSTEM_CLOCK;
|
||||||
|
|
||||||
|
uint32_t clkFreq;
|
||||||
|
uint32_t PllReg;
|
||||||
|
|
||||||
|
uint32_t pllFIN, pllNF, pllNR, pllNO;
|
||||||
|
|
||||||
|
/* Update PLL Clock */
|
||||||
|
// PllClock = clks_lld_get_pll_clock_freq();
|
||||||
|
PllReg = CLK->PLLCON;
|
||||||
|
|
||||||
|
if(PllReg & (CLK_PLLCON_PD_Msk | CLK_PLLCON_OE_Msk)) {
|
||||||
|
PllClock = 0; /* PLL is off. */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (PllReg & 0x00080000ul) {
|
||||||
|
pllFIN = __HIRC; /* Use HXT for PLL clock */
|
||||||
|
} else {
|
||||||
|
pllFIN = __HXT; /* Use HXT for PLL clock */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PllReg & CLK_PLLCON_BP_Msk) {
|
||||||
|
PllClock = pllFIN;
|
||||||
|
} else {
|
||||||
|
switch (((PllReg & CLK_PLLCON_OUT_DV_Msk) >> CLK_PLLCON_OUT_DV_Pos)) {
|
||||||
|
case 0b00: /* OUT_DIV == 00 : NO = 1 */
|
||||||
|
pllNO = 1;
|
||||||
|
break;
|
||||||
|
case 0b11: /* OUT_DIV == 11 : NO = 4 */
|
||||||
|
pllNO = 4;
|
||||||
|
break;
|
||||||
|
default: /* OUT_DIV == 01 or 10 : NO = 2 */
|
||||||
|
pllNO = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pllNF = ((PllReg & CLK_PLLCON_FB_DV_Msk) >> CLK_PLLCON_FB_DV_Pos) + 2;
|
||||||
|
pllNR = ((PllReg & CLK_PLLCON_IN_DV_Msk) >> CLK_PLLCON_IN_DV_Pos) + 2;
|
||||||
|
|
||||||
|
/* Shift right to avoid overflow condition */
|
||||||
|
PllClock = (((pllFIN >> 2) * pllNF) / (pllNR * pllNO) << 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pick Clock Source */
|
||||||
|
switch (CLK->CLKSEL0 & CLK_CLKSEL0_HCLK_S_Msk) {
|
||||||
|
case 0: // External HF Xtal
|
||||||
|
clkFreq = __HXT;
|
||||||
|
break;
|
||||||
|
case 1: // PLL clock / 2
|
||||||
|
clkFreq = PllClock >> 1;
|
||||||
|
break;
|
||||||
|
case 3: // Internal 10kHz
|
||||||
|
clkFreq = __LIRC;
|
||||||
|
break;
|
||||||
|
case 2: // PLL clock
|
||||||
|
clkFreq = PllClock;
|
||||||
|
break;
|
||||||
|
case 7: // Internal 22.184MHz
|
||||||
|
clkFreq = __HIRC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
clkFreq = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemCoreClock = clkFreq / ((CLK->CLKDIV & CLK_CLKDIV_HCLK_N_Msk) + 1);
|
||||||
|
// CyclesPerUs = (SystemCoreClock + 500000) / 1000000;
|
||||||
|
CyclesPerUs = SystemCoreClock / 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SystemInit (void)
|
||||||
|
{
|
||||||
|
/* ToDo: add code to initialize the system
|
||||||
|
do not use global variables because this function is called before
|
||||||
|
reaching pre-main. RW section maybe overwritten afterwards. */
|
||||||
|
// SystemCoreClock = SYSTEM_CLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SystemUnlockReg(void)
|
||||||
|
{
|
||||||
|
while(SYS->REGWRPROT != SYS_REGWRPROT_REGPROTDIS_Msk)
|
||||||
|
{
|
||||||
|
SYS->REGWRPROT = 0x59ul;
|
||||||
|
SYS->REGWRPROT = 0x16ul;
|
||||||
|
SYS->REGWRPROT = 0x88ul;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue