[HAL/HT32]: Initial HT32 Support with a USB-DFU Demo
This commit is contained in:
parent
a9c5088165
commit
7230eb96cc
|
@ -50,6 +50,10 @@ jobs:
|
|||
run: |
|
||||
$CHC_PATH/tools/chbuild.sh $CHC_PATH/testhal/LPC
|
||||
$CHC_PATH/tools/chbuild.sh $CHC_PATH/demos/LPC
|
||||
- name: build HT32
|
||||
run: |
|
||||
$CHC_PATH/tools/chbuild.sh $CHC_PATH/testhal/HT32
|
||||
$CHC_PATH/tools/chbuild.sh $CHC_PATH/demos/HT32
|
||||
- name: build NUMICRO
|
||||
run: |
|
||||
$CHC_PATH/tools/chbuild.sh $CHC_PATH/testhal/NUMICRO
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.dep/
|
||||
build/
|
||||
.vscode/
|
||||
.idea/
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
##############################################################################
|
||||
# Build global options
|
||||
# NOTE: Can be overridden externally.
|
||||
#
|
||||
|
||||
# Compiler options here.
|
||||
ifeq ($(USE_OPT),)
|
||||
USE_OPT = -Os -fomit-frame-pointer -falign-functions=16
|
||||
endif
|
||||
|
||||
# C specific options here (added to USE_OPT).
|
||||
ifeq ($(USE_COPT),)
|
||||
USE_COPT =
|
||||
endif
|
||||
|
||||
# C++ specific options here (added to USE_OPT).
|
||||
ifeq ($(USE_CPPOPT),)
|
||||
USE_CPPOPT = -fno-rtti
|
||||
endif
|
||||
|
||||
# Enable this if you want the linker to remove unused code and data.
|
||||
ifeq ($(USE_LINK_GC),)
|
||||
USE_LINK_GC = yes
|
||||
endif
|
||||
|
||||
# Linker extra options here.
|
||||
ifeq ($(USE_LDOPT),)
|
||||
USE_LDOPT =
|
||||
endif
|
||||
|
||||
# Enable this if you want link time optimizations (LTO).
|
||||
ifeq ($(USE_LTO),)
|
||||
USE_LTO = yes
|
||||
endif
|
||||
|
||||
# Enable this if you want to see the full log while compiling.
|
||||
ifeq ($(USE_VERBOSE_COMPILE),)
|
||||
USE_VERBOSE_COMPILE = no
|
||||
endif
|
||||
|
||||
# If enabled, this option makes the build process faster by not compiling
|
||||
# modules not used in the current configuration.
|
||||
ifeq ($(USE_SMART_BUILD),)
|
||||
USE_SMART_BUILD = no
|
||||
endif
|
||||
|
||||
#
|
||||
# Build global options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Architecture or project specific options
|
||||
#
|
||||
|
||||
# Stack size to be allocated to the Cortex-M process stack. This stack is
|
||||
# the stack used by the main() thread.
|
||||
ifeq ($(USE_PROCESS_STACKSIZE),)
|
||||
USE_PROCESS_STACKSIZE = 0x400
|
||||
endif
|
||||
|
||||
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
|
||||
# stack is used for processing interrupts and exceptions.
|
||||
ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
|
||||
USE_EXCEPTIONS_STACKSIZE = 0x400
|
||||
endif
|
||||
|
||||
# Enables the use of FPU (no, softfp, hard).
|
||||
ifeq ($(USE_FPU),)
|
||||
USE_FPU = no
|
||||
endif
|
||||
|
||||
# FPU-related options.
|
||||
ifeq ($(USE_FPU_OPT),)
|
||||
USE_FPU_OPT =
|
||||
endif
|
||||
|
||||
#
|
||||
# Architecture or project specific options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Project, target, sources and paths
|
||||
#
|
||||
|
||||
# Define project name here
|
||||
PROJECT = usbdfu
|
||||
|
||||
# Target settings.
|
||||
MCU = cortex-m3
|
||||
|
||||
# Imported source files and paths.
|
||||
CHIBIOS = ../../../../ChibiOS
|
||||
CHIBIOS_CONTRIB = $(CHIBIOS)/../ChibiOS-Contrib
|
||||
CONFDIR := ./cfg
|
||||
BUILDDIR := ./build
|
||||
DEPDIR := ./.dep
|
||||
BOARDDIR := ./board
|
||||
|
||||
# Licensing files.
|
||||
include $(CHIBIOS)/os/license/license.mk
|
||||
# Startup files.
|
||||
include $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_ht32f165x.mk
|
||||
# HAL-OSAL files (optional).
|
||||
include $(CHIBIOS)/os/hal/hal.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/HT32F165x/platform.mk
|
||||
include $(BOARDDIR)/board.mk
|
||||
include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk
|
||||
# RTOS files (optional).
|
||||
include $(CHIBIOS)/os/rt/rt.mk
|
||||
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
|
||||
# Auto-build files in ./source recursively.
|
||||
include $(CHIBIOS)/tools/mk/autobuild.mk
|
||||
# Other files (optional).
|
||||
#include $(CHIBIOS)/test/lib/test.mk
|
||||
#include $(CHIBIOS)/test/rt/rt_test.mk
|
||||
#include $(CHIBIOS)/test/oslib/oslib_test.mk
|
||||
|
||||
# Define linker script file here
|
||||
# We used the 1653 config, because this is the smaller device of the two
|
||||
LDSCRIPT= $(STARTUPLD_CONTRIB)/HT32F1653.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CSRC = $(ALLCSRC) \
|
||||
$(TESTSRC) \
|
||||
main.c
|
||||
|
||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CPPSRC = $(ALLCPPSRC)
|
||||
|
||||
# List ASM source files here.
|
||||
ASMSRC = $(ALLASMSRC)
|
||||
|
||||
# List ASM with preprocessor source files here.
|
||||
ASMXSRC = $(ALLXASMSRC)
|
||||
|
||||
# Inclusion directories.
|
||||
INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC)
|
||||
|
||||
# Define C warning options here.
|
||||
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes -Wno-unused-function
|
||||
|
||||
# Define C++ warning options here.
|
||||
CPPWARN = -Wall -Wextra -Wundef -Werror -Wno-unused-function
|
||||
|
||||
#
|
||||
# Project, target, sources and paths
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of user section
|
||||
#
|
||||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS = -DPORT_IGNORE_GCC_VERSION_CHECK
|
||||
|
||||
# Define ASM defines here
|
||||
UADEFS = -DPORT_IGNORE_GCC_VERSION_CHECK
|
||||
|
||||
# List all user directories here
|
||||
UINCDIR =
|
||||
|
||||
# List the user directory to look for the libraries here
|
||||
ULIBDIR =
|
||||
|
||||
# List all user libraries here
|
||||
ULIBS =
|
||||
|
||||
#
|
||||
# End of user section
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Common rules
|
||||
#
|
||||
|
||||
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk
|
||||
include $(RULESPATH)/arm-none-eabi.mk
|
||||
include $(RULESPATH)/rules.mk
|
||||
|
||||
#
|
||||
# Common rules
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Custom rules
|
||||
#
|
||||
|
||||
#
|
||||
# Custom rules
|
||||
##############################################################################
|
|
@ -0,0 +1,88 @@
|
|||
#include "board.h"
|
||||
#include "hal.h"
|
||||
|
||||
#define PBIT(PORT, LINE) ((PAL_PORT(LINE) == PORT) ? (1 << PAL_PAD(LINE)) : 0)
|
||||
#define PAFIO_L(PORT, LINE, AF) (((PAL_PORT(LINE) == PORT) && (PAL_PAD(LINE) < 8)) ? (AF << (PAL_PAD(LINE) << 2)) : 0)
|
||||
#define PAFIO_H(PORT, LINE, AF) (((PAL_PORT(LINE) == PORT) && (PAL_PAD(LINE) >= 8)) ? (AF << ((PAL_PAD(LINE) - 8) << 2)) : 0)
|
||||
#define PAFIO(PORT, N, LINE, AF) ((N) ? PAFIO_H(PORT, LINE, AF) : PAFIO_L(PORT, LINE, AF))
|
||||
|
||||
#define OPEN_DRAIN(PORT) (\
|
||||
0)
|
||||
|
||||
#define OUT_BITS(PORT) (\
|
||||
0)
|
||||
|
||||
#define IN_BITS(PORT) (\
|
||||
0)
|
||||
|
||||
// Alternate Functions
|
||||
#define AF_BITS(PORT, N) (\
|
||||
0)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief PAL setup.
|
||||
* @details Digital I/O ports static configuration as defined in @p board.h.
|
||||
* This variable is used by the HAL when initializing the PAL driver.
|
||||
*/
|
||||
const PALConfig pal_default_config = {
|
||||
// GPIO A
|
||||
.setup[0] = {
|
||||
.DIR = OUT_BITS(IOPORTA),
|
||||
.INE = IN_BITS(IOPORTA),
|
||||
.PU = IN_BITS(IOPORTA),
|
||||
.PD = 0x0000,
|
||||
.OD = OPEN_DRAIN(IOPORTA),
|
||||
.DRV = 0x0000,
|
||||
.LOCK = 0x0000,
|
||||
.OUT = 0x0000,
|
||||
.CFG[0] = AF_BITS(IOPORTA, 0),
|
||||
.CFG[1] = AF_BITS(IOPORTA, 1),
|
||||
},
|
||||
// GPIO B
|
||||
.setup[1] = {
|
||||
.DIR = OUT_BITS(IOPORTB),
|
||||
.INE = IN_BITS(IOPORTB),
|
||||
.PU = IN_BITS(IOPORTB),
|
||||
.PD = 0x0000,
|
||||
.OD = OPEN_DRAIN(IOPORTB),
|
||||
.DRV = 0x0000,
|
||||
.LOCK = 0x0000,
|
||||
.OUT = 0x0000,
|
||||
.CFG[0] = AF_BITS(IOPORTB, 0),
|
||||
.CFG[1] = AF_BITS(IOPORTB, 1),
|
||||
},
|
||||
// GPIO C
|
||||
.setup[2] = {
|
||||
.DIR = OUT_BITS(IOPORTC),
|
||||
.INE = IN_BITS(IOPORTC),
|
||||
.PU = IN_BITS(IOPORTC),
|
||||
.PD = 0x0000,
|
||||
.OD = OPEN_DRAIN(IOPORTC),
|
||||
.DRV = 0x0000,
|
||||
.LOCK = 0x0000,
|
||||
.OUT = 0x0000,
|
||||
.CFG[0] = AF_BITS(IOPORTC, 0),
|
||||
.CFG[1] = AF_BITS(IOPORTC, 1),
|
||||
},
|
||||
// GPIO D
|
||||
.setup[3] = {
|
||||
.DIR = OUT_BITS(IOPORTD),
|
||||
.INE = IN_BITS(IOPORTD),
|
||||
.PU = IN_BITS(IOPORTD),
|
||||
.PD = 0x0000,
|
||||
.OD = OPEN_DRAIN(IOPORTD),
|
||||
.DRV = 0x0000,
|
||||
.LOCK = 0x0000,
|
||||
.OUT = 0x0000,
|
||||
.CFG[0] = AF_BITS(IOPORTD, 0),
|
||||
.CFG[1] = AF_BITS(IOPORTD, 1),
|
||||
},
|
||||
.ESSR[0] = 0x00000000,
|
||||
.ESSR[1] = 0x00000000,
|
||||
};
|
||||
|
||||
|
||||
void boardInit(void) {
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
/*
|
||||
ChibiOS - Copyright (C) 2006..2020 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file has been automatically generated using ChibiStudio board
|
||||
* generator plugin. Do not edit manually.
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Setup board.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Board identifier.
|
||||
*/
|
||||
|
||||
#ifndef HT32F165x
|
||||
#define HT32F1653
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(_FROM_ASM_)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void boardInit(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FROM_ASM_ */
|
||||
|
||||
#endif /* BOARD_H */
|
|
@ -0,0 +1,9 @@
|
|||
# List of all the board related files.
|
||||
BOARDSRC = $(BOARDDIR)/board.c
|
||||
|
||||
# Required include directories
|
||||
BOARDINC = $(BOARDDIR)
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(BOARDSRC)
|
||||
ALLINC += $(BOARDINC)
|
|
@ -0,0 +1,757 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file rt/templates/chconf.h
|
||||
* @brief Configuration file template.
|
||||
* @details A copy of this file must be placed in each project directory, it
|
||||
* contains the application specific kernel settings.
|
||||
*
|
||||
* @addtogroup config
|
||||
* @details Kernel related settings and hooks.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef CHCONF_H
|
||||
#define CHCONF_H
|
||||
|
||||
#define _CHIBIOS_RT_CONF_
|
||||
#define _CHIBIOS_RT_CONF_VER_6_1_
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name System timers settings
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief System time counter resolution.
|
||||
* @note Allowed values are 16 or 32 bits.
|
||||
*/
|
||||
#if !defined(CH_CFG_ST_RESOLUTION)
|
||||
#define CH_CFG_ST_RESOLUTION 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System tick frequency.
|
||||
* @details Frequency of the system timer that drives the system ticks. This
|
||||
* setting also defines the system tick time unit.
|
||||
*/
|
||||
#if !defined(CH_CFG_ST_FREQUENCY)
|
||||
#define CH_CFG_ST_FREQUENCY 10000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time intervals data size.
|
||||
* @note Allowed values are 16, 32 or 64 bits.
|
||||
*/
|
||||
#if !defined(CH_CFG_INTERVALS_SIZE)
|
||||
#define CH_CFG_INTERVALS_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time types data size.
|
||||
* @note Allowed values are 16 or 32 bits.
|
||||
*/
|
||||
#if !defined(CH_CFG_TIME_TYPES_SIZE)
|
||||
#define CH_CFG_TIME_TYPES_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time delta constant for the tick-less mode.
|
||||
* @note If this value is zero then the system uses the classic
|
||||
* periodic tick. This value represents the minimum number
|
||||
* of ticks that is safe to specify in a timeout directive.
|
||||
* The value one is not valid, timeouts are rounded up to
|
||||
* this value.
|
||||
*/
|
||||
#if !defined(CH_CFG_ST_TIMEDELTA)
|
||||
#define CH_CFG_ST_TIMEDELTA 0
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Kernel parameters and options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Round robin interval.
|
||||
* @details This constant is the number of system ticks allowed for the
|
||||
* threads before preemption occurs. Setting this value to zero
|
||||
* disables the preemption for threads with equal priority and the
|
||||
* round robin becomes cooperative. Note that higher priority
|
||||
* threads can still preempt, the kernel is always preemptive.
|
||||
* @note Disabling the round robin preemption makes the kernel more compact
|
||||
* and generally faster.
|
||||
* @note The round robin preemption is not supported in tickless mode and
|
||||
* must be set to zero in that case.
|
||||
*/
|
||||
#if !defined(CH_CFG_TIME_QUANTUM)
|
||||
#define CH_CFG_TIME_QUANTUM 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Idle thread automatic spawn suppression.
|
||||
* @details When this option is activated the function @p chSysInit()
|
||||
* does not spawn the idle thread. The application @p main()
|
||||
* function becomes the idle thread and must implement an
|
||||
* infinite loop.
|
||||
*/
|
||||
#if !defined(CH_CFG_NO_IDLE_THREAD)
|
||||
#define CH_CFG_NO_IDLE_THREAD FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Performance options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief OS optimization.
|
||||
* @details If enabled then time efficient rather than space efficient code
|
||||
* is used when two possible implementations exist.
|
||||
*
|
||||
* @note This is not related to the compiler optimization options.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_OPTIMIZE_SPEED)
|
||||
#define CH_CFG_OPTIMIZE_SPEED TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Subsystem options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Time Measurement APIs.
|
||||
* @details If enabled then the time measurement APIs are included in
|
||||
* the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_TM)
|
||||
#define CH_CFG_USE_TM FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Threads registry APIs.
|
||||
* @details If enabled then the registry APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_REGISTRY)
|
||||
#define CH_CFG_USE_REGISTRY TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Threads synchronization APIs.
|
||||
* @details If enabled then the @p chThdWait() function is included in
|
||||
* the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_WAITEXIT)
|
||||
#define CH_CFG_USE_WAITEXIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Semaphores APIs.
|
||||
* @details If enabled then the Semaphores APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_SEMAPHORES)
|
||||
#define CH_CFG_USE_SEMAPHORES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Semaphores queuing mode.
|
||||
* @details If enabled then the threads are enqueued on semaphores by
|
||||
* priority rather than in FIFO order.
|
||||
*
|
||||
* @note The default is @p FALSE. Enable this if you have special
|
||||
* requirements.
|
||||
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
|
||||
#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Mutexes APIs.
|
||||
* @details If enabled then the mutexes APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MUTEXES)
|
||||
#define CH_CFG_USE_MUTEXES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables recursive behavior on mutexes.
|
||||
* @note Recursive mutexes are heavier and have an increased
|
||||
* memory footprint.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
|
||||
#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Conditional Variables APIs.
|
||||
* @details If enabled then the conditional variables APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_CONDVARS)
|
||||
#define CH_CFG_USE_CONDVARS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Conditional Variables APIs with timeout.
|
||||
* @details If enabled then the conditional variables APIs with timeout
|
||||
* specification are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_CONDVARS.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
|
||||
#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Events Flags APIs.
|
||||
* @details If enabled then the event flags APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_EVENTS)
|
||||
#define CH_CFG_USE_EVENTS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Events Flags APIs with timeout.
|
||||
* @details If enabled then the events APIs with timeout specification
|
||||
* are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_EVENTS.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
|
||||
#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Synchronous Messages APIs.
|
||||
* @details If enabled then the synchronous messages APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MESSAGES)
|
||||
#define CH_CFG_USE_MESSAGES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Synchronous Messages queuing mode.
|
||||
* @details If enabled then messages are served by priority rather than in
|
||||
* FIFO order.
|
||||
*
|
||||
* @note The default is @p FALSE. Enable this if you have special
|
||||
* requirements.
|
||||
* @note Requires @p CH_CFG_USE_MESSAGES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
|
||||
#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Dynamic Threads APIs.
|
||||
* @details If enabled then the dynamic threads creation APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_WAITEXIT.
|
||||
* @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_DYNAMIC)
|
||||
#define CH_CFG_USE_DYNAMIC TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name OSLIB options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Mailboxes APIs.
|
||||
* @details If enabled then the asynchronous messages (mailboxes) APIs are
|
||||
* included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MAILBOXES)
|
||||
#define CH_CFG_USE_MAILBOXES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Core Memory Manager APIs.
|
||||
* @details If enabled then the core memory manager APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MEMCORE)
|
||||
#define CH_CFG_USE_MEMCORE TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Managed RAM size.
|
||||
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||
* then the whole available RAM is used. The core memory is made
|
||||
* available to the heap allocator and/or can be used directly through
|
||||
* the simplified core memory allocator.
|
||||
*
|
||||
* @note In order to let the OS manage the whole RAM the linker script must
|
||||
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||
* @note Requires @p CH_CFG_USE_MEMCORE.
|
||||
*/
|
||||
#if !defined(CH_CFG_MEMCORE_SIZE)
|
||||
#define CH_CFG_MEMCORE_SIZE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Heap Allocator APIs.
|
||||
* @details If enabled then the memory heap allocator APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
|
||||
* @p CH_CFG_USE_SEMAPHORES.
|
||||
* @note Mutexes are recommended.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_HEAP)
|
||||
#define CH_CFG_USE_HEAP TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory Pools Allocator APIs.
|
||||
* @details If enabled then the memory pools allocator APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MEMPOOLS)
|
||||
#define CH_CFG_USE_MEMPOOLS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Objects FIFOs APIs.
|
||||
* @details If enabled then the objects FIFOs APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_OBJ_FIFOS)
|
||||
#define CH_CFG_USE_OBJ_FIFOS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Pipes APIs.
|
||||
* @details If enabled then the pipes APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_PIPES)
|
||||
#define CH_CFG_USE_PIPES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Objects Caches APIs.
|
||||
* @details If enabled then the objects caches APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_OBJ_CACHES)
|
||||
#define CH_CFG_USE_OBJ_CACHES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Delegate threads APIs.
|
||||
* @details If enabled then the delegate threads APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_DELEGATES)
|
||||
#define CH_CFG_USE_DELEGATES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Jobs Queues APIs.
|
||||
* @details If enabled then the jobs queues APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_JOBS)
|
||||
#define CH_CFG_USE_JOBS TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Objects factory options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Objects Factory APIs.
|
||||
* @details If enabled then the objects factory APIs are included in the
|
||||
* kernel.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_FACTORY)
|
||||
#define CH_CFG_USE_FACTORY TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum length for object names.
|
||||
* @details If the specified length is zero then the name is stored by
|
||||
* pointer but this could have unintended side effects.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
|
||||
#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the registry of generic objects.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
|
||||
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for generic buffers.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
|
||||
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for semaphores.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_SEMAPHORES)
|
||||
#define CH_CFG_FACTORY_SEMAPHORES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for mailboxes.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_MAILBOXES)
|
||||
#define CH_CFG_FACTORY_MAILBOXES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for objects FIFOs.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
|
||||
#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for Pipes.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
|
||||
#define CH_CFG_FACTORY_PIPES TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Debug options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Debug option, kernel statistics.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_STATISTICS)
|
||||
#define CH_DBG_STATISTICS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, system state check.
|
||||
* @details If enabled the correct call protocol for system APIs is checked
|
||||
* at runtime.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, parameters checks.
|
||||
* @details If enabled then the checks on the API functions input
|
||||
* parameters are activated.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_CHECKS)
|
||||
#define CH_DBG_ENABLE_CHECKS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, consistency checks.
|
||||
* @details If enabled then all the assertions in the kernel code are
|
||||
* activated. This includes consistency checks inside the kernel,
|
||||
* runtime anomalies and port-defined checks.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_ASSERTS)
|
||||
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, trace buffer.
|
||||
* @details If enabled then the trace buffer is activated.
|
||||
*
|
||||
* @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
|
||||
*/
|
||||
#if !defined(CH_DBG_TRACE_MASK)
|
||||
#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Trace buffer entries.
|
||||
* @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
|
||||
* different from @p CH_DBG_TRACE_MASK_DISABLED.
|
||||
*/
|
||||
#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
|
||||
#define CH_DBG_TRACE_BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, stack checks.
|
||||
* @details If enabled then a runtime stack check is performed.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
* @note The stack check is performed in a architecture/port dependent way.
|
||||
* It may not be implemented or some ports.
|
||||
* @note The default failure mode is to halt the system with the global
|
||||
* @p panic_msg variable set to @p NULL.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK)
|
||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, stacks initialization.
|
||||
* @details If enabled then the threads working area is filled with a byte
|
||||
* value when a thread is created. This can be useful for the
|
||||
* runtime measurement of the used stack.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_FILL_THREADS)
|
||||
#define CH_DBG_FILL_THREADS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, threads profiling.
|
||||
* @details If enabled then a field is added to the @p thread_t structure that
|
||||
* counts the system ticks occurred while executing the thread.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
* @note This debug option is not currently compatible with the
|
||||
* tickless mode.
|
||||
*/
|
||||
#if !defined(CH_DBG_THREADS_PROFILING)
|
||||
#define CH_DBG_THREADS_PROFILING FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Kernel hooks
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief System structure extension.
|
||||
* @details User fields added to the end of the @p ch_system_t structure.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_EXTRA_FIELDS \
|
||||
/* Add threads custom fields here.*/
|
||||
|
||||
/**
|
||||
* @brief System initialization hook.
|
||||
* @details User initialization code added to the @p chSysInit() function
|
||||
* just before interrupts are enabled globally.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_INIT_HOOK() { \
|
||||
/* Add threads initialization code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Threads descriptor structure extension.
|
||||
* @details User fields added to the end of the @p thread_t structure.
|
||||
*/
|
||||
#define CH_CFG_THREAD_EXTRA_FIELDS \
|
||||
/* Add threads custom fields here.*/
|
||||
|
||||
/**
|
||||
* @brief Threads initialization hook.
|
||||
* @details User initialization code added to the @p _thread_init() function.
|
||||
*
|
||||
* @note It is invoked from within @p _thread_init() and implicitly from all
|
||||
* the threads creation APIs.
|
||||
*/
|
||||
#define CH_CFG_THREAD_INIT_HOOK(tp) { \
|
||||
/* Add threads initialization code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Threads finalization hook.
|
||||
* @details User finalization code added to the @p chThdExit() API.
|
||||
*/
|
||||
#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
|
||||
/* Add threads finalization code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Context switch hook.
|
||||
* @details This hook is invoked just before switching between threads.
|
||||
*/
|
||||
#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
|
||||
/* Context switch code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ISR enter hook.
|
||||
*/
|
||||
#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
|
||||
/* IRQ prologue code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ISR exit hook.
|
||||
*/
|
||||
#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
|
||||
/* IRQ epilogue code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Idle thread enter hook.
|
||||
* @note This hook is invoked within a critical zone, no OS functions
|
||||
* should be invoked from here.
|
||||
* @note This macro can be used to activate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_ENTER_HOOK() { \
|
||||
/* Idle-enter code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Idle thread leave hook.
|
||||
* @note This hook is invoked within a critical zone, no OS functions
|
||||
* should be invoked from here.
|
||||
* @note This macro can be used to deactivate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_LEAVE_HOOK() { \
|
||||
/* Idle-leave code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Idle Loop hook.
|
||||
* @details This hook is continuously invoked by the idle thread loop.
|
||||
*/
|
||||
#define CH_CFG_IDLE_LOOP_HOOK() { \
|
||||
/* Idle loop code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System tick event hook.
|
||||
* @details This hook is invoked in the system tick handler immediately
|
||||
* after processing the virtual timers queue.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_TICK_HOOK() { \
|
||||
/* System tick event code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System halt hook.
|
||||
* @details This hook is invoked in case to a system halting error before
|
||||
* the system is halted.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
|
||||
/* System halt code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trace hook.
|
||||
* @details This hook is invoked each time a new record is written in the
|
||||
* trace buffer.
|
||||
*/
|
||||
#define CH_CFG_TRACE_HOOK(tep) { \
|
||||
/* Trace code here.*/ \
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port-specific settings (override port settings defaulted in chcore.h). */
|
||||
/*===========================================================================*/
|
||||
|
||||
#endif /* CHCONF_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,532 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file templates/halconf.h
|
||||
* @brief HAL configuration header.
|
||||
* @details HAL configuration file, this file allows to enable or disable the
|
||||
* various device drivers from your application. You may also use
|
||||
* this file in order to override the device drivers default settings.
|
||||
*
|
||||
* @addtogroup HAL_CONF
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HALCONF_H
|
||||
#define HALCONF_H
|
||||
|
||||
#define _CHIBIOS_HAL_CONF_
|
||||
#define _CHIBIOS_HAL_CONF_VER_7_1_
|
||||
|
||||
#include "mcuconf.h"
|
||||
|
||||
/**
|
||||
* @brief Enables the PAL subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_PAL TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the ADC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ADC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the CAN subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_CAN FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the cryptographic subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_CRY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the DAC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_DAC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the EFlash subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_EFL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_EFL FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the GPT subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_GPT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the I2C subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_I2C FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the I2S subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_I2S FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the ICU subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ICU FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the MAC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_MAC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the MMC_SPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_MMC_SPI FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the PWM subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_PWM FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the RTC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_RTC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SDC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SDC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SERIAL subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SIO subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SIO FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SPI FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the TRNG subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_TRNG FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the UART subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_UART FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_USB TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the WDG subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_WDG FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the WSPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_WSPI FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* PAL driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#define PAL_USE_CALLBACKS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define PAL_USE_WAIT FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* ADC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_WAIT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CAN driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Sleep mode related APIs inclusion switch.
|
||||
*/
|
||||
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
|
||||
#define CAN_USE_SLEEP_MODE FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enforces the driver to use direct callbacks rather than OSAL events.
|
||||
*/
|
||||
#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#define CAN_ENFORCE_USE_CALLBACKS FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CRY driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the SW fall-back of the cryptographic driver.
|
||||
* @details When enabled, this option, activates a fall-back software
|
||||
* implementation for algorithms not supported by the underlying
|
||||
* hardware.
|
||||
* @note Fall-back implementations may not be present for all algorithms.
|
||||
*/
|
||||
#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
|
||||
#define HAL_CRY_USE_FALLBACK FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Makes the driver forcibly use the fall-back implementations.
|
||||
*/
|
||||
#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
|
||||
#define HAL_CRY_ENFORCE_FALLBACK FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* DAC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define DAC_USE_WAIT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define DAC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I2C driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the mutual exclusion APIs on the I2C bus.
|
||||
*/
|
||||
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MAC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the zero-copy API.
|
||||
*/
|
||||
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_ZERO_COPY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables an event sources for incoming packets.
|
||||
*/
|
||||
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_EVENTS FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MMC_SPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Delays insertions.
|
||||
* @details If enabled this options inserts delays into the MMC waiting
|
||||
* routines releasing some extra CPU time for the threads with
|
||||
* lower priority, this may slow down the driver a bit however.
|
||||
* This option is recommended also if the SPI driver does not
|
||||
* use a DMA channel and heavily loads the CPU.
|
||||
*/
|
||||
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define MMC_NICE_WAITING FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SDC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of initialization attempts before rejecting the card.
|
||||
* @note Attempts are performed at 10mS intervals.
|
||||
*/
|
||||
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_RETRY 100
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Include support for MMC cards.
|
||||
* @note MMC support is not yet implemented so this option must be kept
|
||||
* at @p FALSE.
|
||||
*/
|
||||
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
|
||||
#define SDC_MMC_SUPPORT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Delays insertions.
|
||||
* @details If enabled this options inserts delays into the MMC waiting
|
||||
* routines releasing some extra CPU time for the threads with
|
||||
* lower priority, this may slow down the driver a bit however.
|
||||
*/
|
||||
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define SDC_NICE_WAITING TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OCR initialization constant for V20 cards.
|
||||
*/
|
||||
#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_OCR_V20 0x50FF8000U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OCR initialization constant for non-V20 cards.
|
||||
*/
|
||||
#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_OCR 0x80100000U
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SERIAL driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Default bit rate.
|
||||
* @details Configuration parameter, this is the baud rate selected for the
|
||||
* default configuration.
|
||||
*/
|
||||
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_DEFAULT_BITRATE 38400
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Serial buffers size.
|
||||
* @details Configuration parameter, you can change the depth of the queue
|
||||
* buffers depending on the requirements of your application.
|
||||
* @note The default is 16 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_BUFFERS_SIZE 16
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SERIAL_USB driver related setting. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Serial over USB buffers size.
|
||||
* @details Configuration parameter, the buffer size must be a multiple of
|
||||
* the USB data endpoint maximum packet size.
|
||||
* @note The default is 256 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_USB_BUFFERS_SIZE 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Serial over USB number of buffers.
|
||||
* @note The default is 2 buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
|
||||
#define SERIAL_USB_BUFFERS_NUMBER 2
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables circular transfers APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_CIRCULAR FALSE
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Handling method for SPI CS line.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
|
||||
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* UART driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define UART_USE_WAIT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define UART_USE_MUTUAL_EXCLUSION FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* USB driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define USB_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* WSPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define WSPI_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define WSPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
#endif /* HALCONF_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef MCUCONF_H
|
||||
#define MCUCONF_H
|
||||
|
||||
#define HT32F1654_MCUCONF
|
||||
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Clock configuration.
|
||||
*/
|
||||
|
||||
#define HT32_CK_HSE_FREQUENCY 8000000UL // 8 MHz
|
||||
#define HT32_CKCU_SW CKCU_GCCR_SW_PLL
|
||||
#define HT32_PLL_USE_HSE TRUE
|
||||
#define HT32_PLL_FBDIV 18 // 8 MHz -> 144 MHz
|
||||
#define HT32_PLL_OTDIV 0
|
||||
#define HT32_AHB_PRESCALER 2 // 144 MHz -> 72 MHz
|
||||
#define HT32_USART_PRESCALER 1 // 72 MHz
|
||||
#define HT32_USB_PRESCALER 3 // 144 MHz -> 48 MHz
|
||||
// SysTick uses processor clock at 72MHz
|
||||
#define HT32_ST_USE_HCLK TRUE
|
||||
|
||||
#define HT32_GPT_USE_BFTM0 FALSE
|
||||
#define HT32_GPT_BFTM0_IRQ_PRIORITY 4
|
||||
/*
|
||||
* USB driver settings
|
||||
*/
|
||||
#define HT32_USB_USE_USB0 TRUE
|
||||
#define HT32_USB_USB0_IRQ_PRIORITY 5
|
||||
|
||||
#define HT32_PWM_USE_GPTM1 FALSE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 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.
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "usbdfu.h"
|
||||
#include <string.h>
|
||||
|
||||
#define CM_RESET_VECTOR_OFFSET 4
|
||||
|
||||
static void jump_to_application(void) __attribute__ ((noreturn));
|
||||
|
||||
static void jump_to_application(void) {
|
||||
|
||||
/* Use the application's vector table */
|
||||
// Copy Vector Table to RAM_START(0x10000000)
|
||||
memcpy((void*) 0x10000000, (void*)APP_BASE, 512);
|
||||
|
||||
/* Initialize the application's stack pointer */
|
||||
__set_MSP(*((volatile uint32_t*)(APP_BASE)));
|
||||
uint32_t target_start = *((volatile uint32_t*)(APP_BASE + CM_RESET_VECTOR_OFFSET));
|
||||
uint32_t initial_sp = *((volatile uint32_t*)(APP_BASE));
|
||||
/* Jump to the application entry point */
|
||||
__ASM volatile ("mov sp, %0\n" "bx %1" : : "r" (initial_sp), "r" (target_start) : );
|
||||
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
/*
|
||||
* Application entry point.
|
||||
*/
|
||||
int main(void) {
|
||||
halInit();
|
||||
/*
|
||||
* System initializations.
|
||||
* - Kernel initialization, the main() function becomes a thread and the
|
||||
* RTOS is active.
|
||||
*/
|
||||
chSysInit();
|
||||
|
||||
/*
|
||||
* Normal main() thread activity, in this demo it does nothing except
|
||||
* increasing the minutes counter.
|
||||
*/
|
||||
usbDisconnectBus(&USBD1);
|
||||
chThdSleepMilliseconds(1500);
|
||||
usbStart(&USBD1, &usbcfg);
|
||||
usbConnectBus(&USBD1);
|
||||
|
||||
while(1){
|
||||
chThdSleepSeconds(600);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
adapter driver jlink
|
||||
|
||||
transport select swd
|
||||
|
||||
set WORKAREASIZE 0x400
|
||||
set HT32_SRAM_SIZE 8192
|
||||
set HT32_FLASH_SIZE 65536
|
||||
|
||||
source [find target/ht32f165x.cfg]
|
||||
|
||||
adapter speed 5000
|
||||
|
||||
proc program {file} {
|
||||
init
|
||||
reset halt
|
||||
flash write_image erase $file 0x00000000
|
||||
reset run
|
||||
|
||||
echo "\n PROGRAM COMPLETE!!!"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# USB DFU Demo
|
||||
|
||||
This is an example software bootloader implementing the USB-DFU 1.1 standard.
|
||||
|
||||
You can customize the USB Vendor ID / Product ID in the `source/usbdfu.c` file.
|
||||
The VID:PID is default to `04d9:F00D`
|
||||
|
||||
It expect that your actual code to be loaded at `0x2000` (APP_BASE)
|
|
@ -0,0 +1,34 @@
|
|||
#include "usbdfu.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include <string.h>
|
||||
|
||||
size_t target_get_max_fw_size(void) {
|
||||
return (MAX_FLASH_ADDR - APP_BASE);
|
||||
}
|
||||
|
||||
uint16_t target_get_timeout(void) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
void target_flash_unlock(void) {
|
||||
chSysLock();
|
||||
}
|
||||
|
||||
bool target_flash_write(uint8_t* dst, uint8_t* src, size_t len) {
|
||||
// TODO: Write flash
|
||||
return true;
|
||||
}
|
||||
|
||||
bool target_prepare_flash(void) {
|
||||
// TODO: Erase All Flash Pages
|
||||
return true;
|
||||
}
|
||||
|
||||
void target_flash_lock(void) {
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
void target_complete_programming(void) {
|
||||
// Do nothing
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MAX_FLASH_ADDR 0x10000
|
||||
#define FLASH_BASE 0x0
|
||||
#define BL_SIZE 0x2000
|
||||
#define APP_BASE (FLASH_BASE + BL_SIZE)
|
||||
#define FLASH_PAGE_SIZE 1024
|
||||
|
||||
size_t target_get_max_fw_size(void);
|
||||
uint16_t target_get_timeout(void);
|
||||
void target_flash_unlock(void);
|
||||
bool target_flash_write(uint8_t* dst, uint8_t* src, size_t len);
|
||||
bool target_prepare_flash(void);
|
||||
void target_flash_lock(void);
|
||||
void target_complete_programming(void);
|
|
@ -0,0 +1,302 @@
|
|||
#include "hal.h"
|
||||
#include "usbdfu.h"
|
||||
#include "dfu_target.h"
|
||||
|
||||
uint8_t fw_buffer[FW_BUFFER_SIZE];
|
||||
/*
|
||||
* USB Device Descriptor.
|
||||
*/
|
||||
static const uint8_t dfu_device_descriptor_data[18] = {
|
||||
USB_DESC_DEVICE (0x0200, /* bcdUSB (1.1). */
|
||||
0x00, /* bDeviceClass */
|
||||
0x00, /* bDeviceSubClass. */
|
||||
0x00, /* bDeviceProtocol. */
|
||||
64, /* bMaxPacketSize. */
|
||||
0x04d9, /* idVendor (ST). */
|
||||
0xf00d, /* idProduct. */
|
||||
0x0200, /* bcdDevice. */
|
||||
1, /* iManufacturer. */
|
||||
2, /* iProduct. */
|
||||
3, /* iSerialNumber. */
|
||||
1) /* bNumConfigurations. */
|
||||
};
|
||||
|
||||
static const USBDescriptor dfu_device_descriptor = {
|
||||
sizeof dfu_device_descriptor_data,
|
||||
dfu_device_descriptor_data
|
||||
};
|
||||
|
||||
|
||||
/* Configuration Descriptor tree for a DFU.*/
|
||||
static const uint8_t dfu_configuration_descriptor_data[27] = {
|
||||
/* Configuration Descriptor.*/
|
||||
USB_DESC_CONFIGURATION(27, /* wTotalLength. */
|
||||
0x01, /* bNumInterfaces. */
|
||||
0x01, /* bConfigurationValue. */
|
||||
0, /* iConfiguration. */
|
||||
0xC0, /* bmAttributes (self powered). */
|
||||
50), /* bMaxPower (100mA). */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x00, /* bNumEndpoints. */
|
||||
0xFE, /* bInterfaceClass (DFU Class
|
||||
*/
|
||||
0x01, /* bInterfaceSubClass */
|
||||
0x02, /* bInterfaceProtocol */
|
||||
2), /* iInterface. */
|
||||
/* DFU Class Descriptor.*/
|
||||
USB_DESC_BYTE (9), /* bLength. */
|
||||
USB_DESC_BYTE (0x21), /* bDescriptorType (DFU_FCUNTION). */
|
||||
USB_DESC_BYTE (0b1011), /* bmAttributes (DETACH | DOWNLOAD) */
|
||||
USB_DESC_WORD ( 1000), /* DetachTimeout. */
|
||||
USB_DESC_WORD ( 64),
|
||||
USB_DESC_BCD (0x0110)
|
||||
};
|
||||
|
||||
static const USBDescriptor dfu_configuration_descriptor = {
|
||||
sizeof dfu_configuration_descriptor_data,
|
||||
dfu_configuration_descriptor_data
|
||||
};
|
||||
|
||||
static const uint8_t dfu_string0[] = {
|
||||
USB_DESC_BYTE(4), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
|
||||
};
|
||||
|
||||
static const uint8_t dfu_string1[] = {
|
||||
USB_DESC_BYTE(14), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'H', 0, 'o', 0, 'l', 0, 't', 0, 'e', 0, 'k', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Description string.
|
||||
*/
|
||||
static const uint8_t dfu_string2[] = {
|
||||
USB_DESC_BYTE(16), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'U', 0, 'S', 0, 'B', 0, ' ', 0 , 'D', 0, 'F', 0, 'U', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial Number string.
|
||||
*/
|
||||
static const uint8_t dfu_string3[] = {
|
||||
USB_DESC_BYTE(8), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'1', 0, '.', 0, '1', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings wrappers array.
|
||||
*/
|
||||
static const USBDescriptor dfu_strings[] = {
|
||||
{sizeof dfu_string0, dfu_string0},
|
||||
{sizeof dfu_string1, dfu_string1},
|
||||
{sizeof dfu_string2, dfu_string2},
|
||||
{sizeof dfu_string3, dfu_string3}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Handles the GET_DESCRIPTOR callback. All required descriptors must be
|
||||
* handled here.
|
||||
*/
|
||||
static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
||||
uint8_t dtype,
|
||||
uint8_t dindex,
|
||||
uint16_t lang) {
|
||||
(void)usbp;
|
||||
(void)lang;
|
||||
switch (dtype) {
|
||||
case USB_DESCRIPTOR_DEVICE:
|
||||
return &dfu_device_descriptor;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
return &dfu_configuration_descriptor;
|
||||
case USB_DESCRIPTOR_STRING:
|
||||
if (dindex < 4)
|
||||
return &dfu_strings[dindex];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
volatile enum dfu_state currentState = STATE_DFU_IDLE;
|
||||
volatile enum dfu_status currentStatus = DFU_STATUS_OK;
|
||||
size_t current_dfu_offset = 0;
|
||||
size_t dfu_download_size = 0;
|
||||
|
||||
static void dfu_on_download_request(USBDriver *usbp) {
|
||||
(void)usbp;
|
||||
uint8_t *dest = (uint8_t*)(APP_BASE + current_dfu_offset);
|
||||
|
||||
bool ok = true;
|
||||
target_flash_unlock();
|
||||
if (current_dfu_offset == 0) {
|
||||
ok = target_prepare_flash();
|
||||
}
|
||||
if (ok) {
|
||||
ok = target_flash_write(dest, fw_buffer, dfu_download_size);
|
||||
}
|
||||
target_flash_lock();
|
||||
|
||||
if (ok) {
|
||||
current_dfu_offset += dfu_download_size;
|
||||
currentState = STATE_DFU_DNLOAD_IDLE;
|
||||
} else {
|
||||
currentState = STATE_DFU_ERROR;
|
||||
currentStatus = DFU_STATUS_ERR_VERIFY;
|
||||
}
|
||||
}
|
||||
|
||||
static void dfu_on_download_complete(USBDriver *usbp) {
|
||||
(void)usbp;
|
||||
currentState = STATE_DFU_MANIFEST_SYNC;
|
||||
}
|
||||
|
||||
static void dfu_on_manifest_request(USBDriver *usbp) {
|
||||
(void)usbp;
|
||||
target_complete_programming();
|
||||
currentState = STATE_DFU_MANIFEST_WAIT_RESET;
|
||||
}
|
||||
|
||||
static void dfu_on_detach_complete(USBDriver *usbp) {
|
||||
(void)usbp;
|
||||
__asm__ __volatile__("dsb");
|
||||
SCB->AIRCR = 0x05FA0004; // System Reset
|
||||
__asm__ __volatile__("dsb");
|
||||
while(1){};
|
||||
}
|
||||
|
||||
static inline void dfu_status_req(USBDriver *usbp) {
|
||||
static uint8_t status_response_buffer[6] = {};
|
||||
uint32_t pollTime = 10;
|
||||
usbcallback_t cb = NULL;
|
||||
|
||||
switch(currentState) {
|
||||
case STATE_DFU_DNLOAD_SYNC: {
|
||||
currentState = STATE_DFU_DNBUSY;
|
||||
pollTime = target_get_timeout();
|
||||
cb = &dfu_on_download_request;
|
||||
break;
|
||||
}
|
||||
case STATE_DFU_MANIFEST_SYNC: {
|
||||
currentState = STATE_DFU_MANIFEST;
|
||||
cb = &dfu_on_manifest_request;
|
||||
break;
|
||||
}
|
||||
case STATE_DFU_MANIFEST_WAIT_RESET: {
|
||||
cb = &dfu_on_detach_complete;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Response Construction
|
||||
status_response_buffer[0] = (uint8_t) currentStatus;
|
||||
status_response_buffer[1] = (uint8_t) (pollTime & 0xFFU);
|
||||
status_response_buffer[2] = (uint8_t) ((pollTime >> 8U) & 0xFFU);
|
||||
status_response_buffer[3] = (uint8_t) ((pollTime >> 16U) & 0xFFU);
|
||||
status_response_buffer[4] = (uint8_t) currentState;
|
||||
status_response_buffer[5] = 0; // No Index
|
||||
|
||||
usbSetupTransfer(usbp, status_response_buffer, 6, cb);
|
||||
}
|
||||
|
||||
static bool request_handler(USBDriver *usbp) {
|
||||
struct usb_setup* setup = (struct usb_setup*) usbp->setup;
|
||||
if((setup->bmRequestType & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
|
||||
switch (setup->bRequest) {
|
||||
case DFU_GETSTATUS: {
|
||||
dfu_status_req(usbp);
|
||||
return true;
|
||||
}
|
||||
case DFU_GETSTATE: {
|
||||
usbSetupTransfer(usbp, (uint8_t *)¤tState, 1, NULL);
|
||||
return true;
|
||||
}
|
||||
case DFU_UPLOAD: {
|
||||
switch (currentState) {
|
||||
case STATE_DFU_IDLE: {
|
||||
current_dfu_offset = 0;
|
||||
__attribute__((fallthrough));
|
||||
}
|
||||
case STATE_DFU_UPLOAD_IDLE: {
|
||||
uint16_t copy_len = setup->wLength;
|
||||
size_t fw_size = target_get_max_fw_size();
|
||||
if (current_dfu_offset + setup->wLength > fw_size) {
|
||||
copy_len = fw_size - current_dfu_offset;
|
||||
currentState = STATE_DFU_IDLE;
|
||||
} else {
|
||||
currentState = STATE_DFU_UPLOAD_IDLE;
|
||||
}
|
||||
usbSetupTransfer(usbp, (uint8_t *)(APP_BASE + current_dfu_offset), copy_len, NULL );
|
||||
current_dfu_offset += copy_len;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
usbSetupTransfer(usbp, NULL, 0, NULL);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case DFU_CLRSTATUS: {
|
||||
currentStatus = DFU_STATUS_OK;
|
||||
if (currentState != STATE_DFU_ERROR) {
|
||||
usbSetupTransfer(usbp, NULL, 0, NULL);
|
||||
break;
|
||||
}
|
||||
__attribute__((fallthrough));
|
||||
}
|
||||
case DFU_ABORT: {
|
||||
currentState = STATE_DFU_IDLE;
|
||||
usbSetupTransfer(usbp, NULL, 0, NULL);
|
||||
return true;
|
||||
}
|
||||
case DFU_DETACH: {
|
||||
usbSetupTransfer(usbp, NULL, 0, &dfu_on_detach_complete);
|
||||
return true;
|
||||
}
|
||||
case DFU_DNLOAD: {
|
||||
switch (currentState) {
|
||||
case STATE_DFU_IDLE: {
|
||||
current_dfu_offset = 0;
|
||||
dfu_download_size = setup->wLength;
|
||||
currentState = STATE_DFU_DNLOAD_SYNC;
|
||||
usbSetupTransfer(usbp, &fw_buffer[0], dfu_download_size, NULL);
|
||||
break;
|
||||
}
|
||||
case STATE_DFU_DNLOAD_IDLE: {
|
||||
if (setup->wLength > 0) {
|
||||
dfu_download_size = setup->wLength;
|
||||
usbSetupTransfer(usbp, &fw_buffer[0], dfu_download_size, NULL);
|
||||
currentState = STATE_DFU_DNLOAD_SYNC;
|
||||
} else {
|
||||
usbSetupTransfer(usbp, NULL, 0, &dfu_on_download_complete);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
usbSetupTransfer(usbp, NULL, 0, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* USB driver configuration.
|
||||
*/
|
||||
const USBConfig usbcfg = {
|
||||
NULL,
|
||||
get_descriptor,
|
||||
request_handler,
|
||||
NULL
|
||||
};
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "stdint.h"
|
||||
#include "hal.h"
|
||||
#include "dfu_target.h"
|
||||
|
||||
extern const USBConfig usbcfg;
|
||||
|
||||
#define FW_BUFFER_SIZE 256
|
||||
|
||||
enum dfu_req {
|
||||
DFU_DETACH,
|
||||
DFU_DNLOAD,
|
||||
DFU_UPLOAD,
|
||||
DFU_GETSTATUS,
|
||||
DFU_CLRSTATUS,
|
||||
DFU_GETSTATE,
|
||||
DFU_ABORT,
|
||||
};
|
||||
|
||||
enum dfu_state {
|
||||
STATE_APP_IDLE,
|
||||
STATE_APP_DETACH,
|
||||
STATE_DFU_IDLE,
|
||||
STATE_DFU_DNLOAD_SYNC,
|
||||
STATE_DFU_DNBUSY,
|
||||
STATE_DFU_DNLOAD_IDLE,
|
||||
STATE_DFU_MANIFEST_SYNC,
|
||||
STATE_DFU_MANIFEST,
|
||||
STATE_DFU_MANIFEST_WAIT_RESET,
|
||||
STATE_DFU_UPLOAD_IDLE,
|
||||
STATE_DFU_ERROR,
|
||||
};
|
||||
|
||||
|
||||
enum dfu_status {
|
||||
DFU_STATUS_OK,
|
||||
DFU_STATUS_ERR_TARGET,
|
||||
DFU_STATUS_ERR_FILE,
|
||||
DFU_STATUS_ERR_WRITE,
|
||||
DFU_STATUS_ERR_ERASE,
|
||||
DFU_STATUS_ERR_CHECK_ERASED,
|
||||
DFU_STATUS_ERR_PROG,
|
||||
DFU_STATUS_ERR_VERIFY,
|
||||
DFU_STATUS_ERR_ADDRESS,
|
||||
DFU_STATUS_ERR_NOTDONE,
|
||||
DFU_STATUS_ERR_FIRMWARE,
|
||||
DFU_STATUS_ERR_VENDOR,
|
||||
DFU_STATUS_ERR_USBR,
|
||||
DFU_STATUS_ERR_POR,
|
||||
DFU_STATUS_ERR_UNKNOWN,
|
||||
DFU_STATUS_ERR_STALLEDPKT,
|
||||
};
|
||||
|
||||
struct usb_setup {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} __attribute__((packed));
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2016 Fabio Utzig, http://fabioutzig.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _HT32F165x_H_
|
||||
#define _HT32F165x_H_
|
||||
|
||||
#if defined(HT32F1653) || defined(HT32F1654)
|
||||
#define HT32F1653_4
|
||||
#elif defined(HT32F1655) || defined(HT32F1656)
|
||||
#define HT32F1655_6
|
||||
#else
|
||||
#error "Unknown HT32 device"
|
||||
#endif
|
||||
|
||||
#if defined(HT32F1653_4) || defined(HT32F1655_6)
|
||||
#define HT32
|
||||
#define HT32F165x
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
* ---------- Interrupt Number Definition -----------------------
|
||||
* ==============================================================
|
||||
*/
|
||||
typedef enum IRQn
|
||||
{
|
||||
/****** Cortex-M3 Processor Exceptions Numbers ****************/
|
||||
InitialSP_IRQn = -16,
|
||||
InitialPC_IRQn = -15,
|
||||
NonMaskableInt_IRQn = -14,
|
||||
HardFault_IRQn = -13,
|
||||
MemoryManagement_IRQn = -12,
|
||||
BusFault_IRQn = -11,
|
||||
UsageFault_IRQn = -10,
|
||||
|
||||
SVCall_IRQn = -5,
|
||||
DebugMonitor_IRQn = -4,
|
||||
|
||||
PendSV_IRQn = -2,
|
||||
SysTick_IRQn = -1,
|
||||
|
||||
/****** HT32F165x Specific Interrupt Numbers ***********************/
|
||||
CKRDY_IRQn = 0,
|
||||
LVD_IRQn = 1,
|
||||
BOD_IRQn = 2,
|
||||
WDT_IRQn = 3,
|
||||
RTC_IRQn = 4,
|
||||
FMC_IRQn = 5,
|
||||
EVWUP_IRQn = 6,
|
||||
LPWUP_IRQn = 7,
|
||||
EXTI0_IRQn = 8,
|
||||
EXTI1_IRQn = 9,
|
||||
EXTI2_IRQn = 10,
|
||||
EXTI3_IRQn = 11,
|
||||
EXTI4_IRQn = 12,
|
||||
EXTI5_IRQn = 13,
|
||||
EXTI6_IRQn = 14,
|
||||
EXTI7_IRQn = 15,
|
||||
EXTI8_IRQn = 16,
|
||||
EXTI9_IRQn = 17,
|
||||
EXTI10_IRQn = 18,
|
||||
EXTI11_IRQn = 19,
|
||||
EXTI12_IRQn = 20,
|
||||
EXTI13_IRQn = 21,
|
||||
EXTI14_IRQn = 22,
|
||||
EXTI15_IRQn = 23,
|
||||
COMP_IRQn = 24,
|
||||
ADC_IRQn = 25,
|
||||
|
||||
MCTM0_BRK_IRQn = 27,
|
||||
MCTM0_UP_IRQn = 28,
|
||||
MCTM0_TR_UP2_IRQn = 29,
|
||||
MCTM0_CC_IRQn = 30,
|
||||
MCTM1_BRK_IRQn = 31,
|
||||
MCTM1_UP_IRQn = 32,
|
||||
MCTM1_TR_UP2_IRQn = 33,
|
||||
MCTM1_CC_IRQn = 34,
|
||||
GPTM0_IRQn = 35,
|
||||
GPTM1_IRQn = 36,
|
||||
|
||||
BFTM0_IRQn = 41,
|
||||
BFTM1_IRQn = 42,
|
||||
I2C0_IRQn = 43,
|
||||
I2C1_IRQn = 44,
|
||||
SPI0_IRQn = 45,
|
||||
SPI1_IRQn = 46,
|
||||
USART0_IRQn = 47,
|
||||
USART1_IRQn = 48,
|
||||
UART0_IRQn = 49,
|
||||
UART1_IRQn = 50,
|
||||
SCI_IRQn = 51,
|
||||
I2C_IRQn = 52,
|
||||
USB_IRQn = 53,
|
||||
|
||||
PDMA_CH0_IRQn = 55,
|
||||
PDMA_CH1_IRQn = 56,
|
||||
PDMA_CH2_IRQn = 57,
|
||||
PDMA_CH3_IRQn = 58,
|
||||
PDMA_CH4_IRQn = 59,
|
||||
PDMA_CH5_IRQn = 60,
|
||||
PDMA_CH6_IRQn = 61,
|
||||
PDMA_CH7_IRQn = 62,
|
||||
|
||||
EBI_IRQn = 68,
|
||||
} IRQn_Type;
|
||||
|
||||
/*
|
||||
* ==========================================================================
|
||||
* ----------- Processor and Core Peripheral Section ------------------------
|
||||
* ==========================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief HT32F165x Interrupt Number Definition, according to the selected device
|
||||
* in @ref Library_configuration_section
|
||||
*/
|
||||
#define __FPU_PRESENT 0
|
||||
#define __MPU_PRESENT 0
|
||||
#define __NVIC_PRIO_BITS 4
|
||||
#define __Vendor_SysTickConfig 0
|
||||
#define __CM3_REV 0x0201
|
||||
|
||||
#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
|
||||
|
||||
/****************************************************************/
|
||||
/* Peripheral memory map */
|
||||
/****************************************************************/
|
||||
#define USART0_BASE ((uint32_t)0x40000000)
|
||||
#define UART0_BASE ((uint32_t)0x40001000)
|
||||
#define SPI0_BASE ((uint32_t)0x40004000)
|
||||
#define ADC_BASE ((uint32_t)0x40010000)
|
||||
#if defined(HT32F1655_6)
|
||||
#define OPACMP0_BASE ((uint32_t)0x40018000)
|
||||
#define OPACMP1_BASE ((uint32_t)0x40018100)
|
||||
#endif
|
||||
#define AFIO_BASE ((uint32_t)0x40022000)
|
||||
#define EXTI_BASE ((uint32_t)0x40024000)
|
||||
#define I2S_BASE ((uint32_t)0x40026000)
|
||||
#define MCTM0_BASE ((uint32_t)0x4002C000)
|
||||
#define MCTM1_BASE ((uint32_t)0x4002D000)
|
||||
|
||||
#define USART1_BASE ((uint32_t)0x40040000)
|
||||
#define UART1_BASE ((uint32_t)0x40041000)
|
||||
#define SCI_BASE ((uint32_t)0x40043000)
|
||||
#define SPI1_BASE ((uint32_t)0x40044000)
|
||||
#define I2C0_BASE ((uint32_t)0x40048000)
|
||||
#define I2C1_BASE ((uint32_t)0x40049000)
|
||||
#if defined(HT32F1653_4)
|
||||
#define CMP0_BASE ((uint32_t)0x40058000)
|
||||
#define CMP1_BASE ((uint32_t)0x40058100)
|
||||
#endif
|
||||
#define WDT_BASE ((uint32_t)0x40068000)
|
||||
#define RTC_BASE ((uint32_t)0x4006A000)
|
||||
#define PWRCU_BASE ((uint32_t)0x4006A000)
|
||||
#define GPTM0_BASE ((uint32_t)0x4006E000)
|
||||
#define GPTM1_BASE ((uint32_t)0x4006F000)
|
||||
#define BFTM0_BASE ((uint32_t)0x40076000)
|
||||
#define BFTM1_BASE ((uint32_t)0x40077000)
|
||||
|
||||
#define FMC_BASE ((uint32_t)0x40080000)
|
||||
#define CKCU_BASE ((uint32_t)0x40088000)
|
||||
#define RSTCU_BASE ((uint32_t)0x40088000)
|
||||
#define CRC_BASE ((uint32_t)0x4008A000)
|
||||
#define PDMA_BASE ((uint32_t)0x40090000)
|
||||
#define EBI_BASE ((uint32_t)0x40098000)
|
||||
#define USB_BASE ((uint32_t)0x400A8000)
|
||||
#define USB_SRAM_BASE ((uint32_t)0x400AA000)
|
||||
#define GPIO_A_BASE ((uint32_t)0x400B0000)
|
||||
#define GPIO_B_BASE ((uint32_t)0x400B2000)
|
||||
#define GPIO_C_BASE ((uint32_t)0x400B4000)
|
||||
#define GPIO_D_BASE ((uint32_t)0x400B6000)
|
||||
#if defined(HT32F1655_6)
|
||||
#define GPIO_E_BASE ((uint32_t)0x400B8000)
|
||||
#endif
|
||||
|
||||
// Registers Headers
|
||||
#include "ht32f165x_reg.h"
|
||||
|
||||
/****************************************************************/
|
||||
/* Peripheral declaration */
|
||||
/****************************************************************/
|
||||
#define USART0 ((USART_TypeDef *) USART0_BASE)
|
||||
#define UART0 ((USART_TypeDef *) UART0_BASE)
|
||||
#define SPI0 ((SPI_TypeDef *) SPI0_BASE)
|
||||
#define ADC ((ADC_TypeDef *) ADC_BASE)
|
||||
#if defined(HT32F1655_6)
|
||||
#define OPACMP0 ((OPACMP_TypeDef *) OPACMP0_BASE)
|
||||
#define OPACMP1 ((OPACMP_TypeDef *) OPACMP1_BASE)
|
||||
#endif
|
||||
#define AFIO ((AFIO_TypeDef *) AFIO_BASE)
|
||||
#define EXTI ((EXTI_TypeDef *) EXTI_BASE)
|
||||
#define I2S ((I2S_TypeDef *) I2S_BASE)
|
||||
#define MCTM0 ((TM_TypeDef *) MCTM0_BASE)
|
||||
#define MCTM1 ((TM_TypeDef *) MCTM1_BASE)
|
||||
|
||||
#define USART1 ((USART_TypeDef *) USART1_BASE)
|
||||
#define UART1 ((USART_TypeDef *) UART1_BASE)
|
||||
#define SCI ((SCI_TypeDef *) SCI_BASE)
|
||||
#define SPI1 ((SPI_TypeDef *) SPI1_BASE)
|
||||
#define I2C0 ((I2C_TypeDef *) I2C0_BASE)
|
||||
#define I2C1 ((I2C_TypeDef *) I2C1_BASE)
|
||||
#if defined(HT32F1653_4)
|
||||
#define CMP0 ((CMP_TypeDef *) CMP0_BASE)
|
||||
#define CMP1 ((CMP_TypeDef *) CMP1_BASE)
|
||||
#endif
|
||||
#define WDT ((WDT_TypeDef *) WDT_BASE)
|
||||
#define RTC ((RTC_TypeDef *) RTC_BASE)
|
||||
#define PWRCU ((PWRCU_TypeDef *) PWRCU_BASE)
|
||||
#define GPTM0 ((TM_TypeDef *) GPTM0_BASE)
|
||||
#define GPTM1 ((TM_TypeDef *) GPTM1_BASE)
|
||||
#define BFTM0 ((BFTM_TypeDef *) BFTM0_BASE)
|
||||
#define BFTM1 ((BFTM_TypeDef *) BFTM1_BASE)
|
||||
|
||||
#define FMC ((FMC_TypeDef *) FMC_BASE)
|
||||
#define CKCU ((CKCU_TypeDef *) CKCU_BASE)
|
||||
#define RSTCU ((RSTCU_TypeDef *) RSTCU_BASE)
|
||||
#define CRC ((CRC_TypeDef *) CRC_BASE)
|
||||
#define PDMA ((PDMA_TypeDef *) PDMA_BASE)
|
||||
#define EBI ((EBI_TypeDef *) EBI_BASE)
|
||||
#define USB ((USB_TypeDef *) USB_BASE)
|
||||
|
||||
#define GPIOA ((GPIO_TypeDef *) GPIO_A_BASE)
|
||||
#define GPIO_A GPIOA
|
||||
#define GPIOB ((GPIO_TypeDef *) GPIO_B_BASE)
|
||||
#define GPIO_B GPIOB
|
||||
#define GPIOC ((GPIO_TypeDef *) GPIO_C_BASE)
|
||||
#define GPIO_C GPIOC
|
||||
#define GPIOD ((GPIO_TypeDef *) GPIO_D_BASE)
|
||||
#define GPIO_D GPIOD
|
||||
#if defined(HT32F1655_6)
|
||||
#define GPIOE ((GPIO_TypeDef *) GPIO_E_BASE)
|
||||
#define GPIO_E GPIOE
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,679 @@
|
|||
#ifndef HT32F165x_REG_H
|
||||
#define HT32F165x_REG_H
|
||||
|
||||
#ifndef __IO
|
||||
#define __IO volatile
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
#define AFIO_DEFAULT 0
|
||||
#define AFIO_GPIO 1
|
||||
#define AFIO_ADC 2
|
||||
#define AFIO_CMP 3
|
||||
#define AFIO_TM 4
|
||||
#define AFIO_SPI 5
|
||||
#define AFIO_USART 6
|
||||
#define AFIO_I2C 7
|
||||
#define AFIO_SMC 8
|
||||
#define AFIO_EBI 9
|
||||
#define AFIO_I2S 10
|
||||
#define AFIO_OTHER 15
|
||||
|
||||
// Flash Memory Controller
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t TADR; //!< 0x000 Flash Target Address Register
|
||||
__IO uint32_t WRDR; //!< 0x004 Flash Write Data Register
|
||||
uint32_t RESERVED0[1]; //!< 0x008 Reserved
|
||||
__IO uint32_t OCMR; //!< 0x00C Flash Operation Command Register
|
||||
__IO uint32_t OPCR; //!< 0x010 Flash Operation Control Register
|
||||
__IO uint32_t OIER; //!< 0x014 Flash Operation Interrupt Enable Register
|
||||
__IO uint32_t OISR; //!< 0x018 Flash Operation Interrupt and Status Register
|
||||
uint32_t RESERVED1[1]; //!< 0x01C Reserved
|
||||
__IO uint32_t PPSR[4]; //!< 0x020 ~ 0x02C Flash Page Erase/Program Protection Status Register
|
||||
__IO uint32_t CPSR; //!< 0x030 Flash Security Protection Status Register
|
||||
uint32_t RESERVED2[51]; //!< 0x034 ~ 0x0FC Reserved
|
||||
__IO uint32_t VMCR; //!< 0x100 Flash Vector Mapping Control Register
|
||||
uint32_t RESERVED3[31]; //!< 0x104 ~ 0x17C Reserved
|
||||
__IO uint32_t MDID; //!< 0x180 Manufacturer and Device ID Register
|
||||
__IO uint32_t PNSR; //!< 0x184 Flash Page Number Status Register
|
||||
__IO uint32_t PSSR; //!< 0x188 Flash Page Size Status Register
|
||||
#if defined(HT32F165x)
|
||||
uint32_t RESERVED4[29]; //!< 0x18C ~ 0x1FC Reserved
|
||||
#else
|
||||
__IO uint32_t DID; //!< 0x18C Device ID Register
|
||||
uint32_t RESERVED4[28]; //!< 0x190 ~ 0x1FC Reserved
|
||||
#endif
|
||||
__IO uint32_t CFCR; //!< 0x200 Flash Cache and Pre-fetch Control Register
|
||||
uint32_t RESERVED5[63]; //!< 0x204 ~ 0x2FC Reserved
|
||||
__IO uint32_t SBVT[4]; //!< 0x300 ~ 0x30C SRAM Booting Vector (4x32Bit)
|
||||
#if defined(HT32F165x)
|
||||
#else
|
||||
__IO uint32_t CID[4]; //!< 0x310 ~ 0x31C Custom ID Register
|
||||
#endif
|
||||
} FMC_TypeDef;
|
||||
|
||||
#define FMC_OCMR_CMD_MASK (0xF << 0)
|
||||
#define FMC_OCMR_CMD_IDLE (0x0 << 0)
|
||||
#define FMC_OCMR_CMD_WORD_PROGRAM (0x4 << 0)
|
||||
#define FMC_OCMR_CMD_PAGE_ERASE (0x8 << 0)
|
||||
#define FMC_OCMR_CMD_MASS_ERASE (0xA << 0)
|
||||
#define FMC_OPCR_OPM_MASK (0xF << 1)
|
||||
#define FMC_OPCR_OPM_IDLE (0x6 << 1)
|
||||
#define FMC_OPCR_OPM_COMMIT (0xA << 1)
|
||||
#define FMC_OPCR_OPM_FINISHED (0xE << 1)
|
||||
#define FMC_CFCR_CE (1U << 12)
|
||||
#define FMC_CFCR_WAIT_MASK (7U << 0)
|
||||
#define FMC_CFCR_WAIT_0 (1U)
|
||||
#define FMC_CFCR_WAIT_1 (2U)
|
||||
#define FMC_CFCR_WAIT_2 (3U)
|
||||
|
||||
// Power Control Unit
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
uint32_t RESERVE0[64];
|
||||
__IO uint32_t BAKSR; //!< 0x000 Status Register
|
||||
__IO uint32_t BAKCR; //!< 0x004 Control Register
|
||||
__IO uint32_t BAKTEST; //!< 0x008 Test Register
|
||||
__IO uint32_t HSIRCR; //!< 0x00C HSI Ready Counter Control Register
|
||||
__IO uint32_t LVDCSR; //!< 0x010 Low Voltage/Brown Out Detect Control and Status Register
|
||||
uint32_t RESERVE1[59]; //!< 0x014 ~ 0x0FC Reserved
|
||||
__IO uint32_t BAKREG[10]; //!< 0x100 ~ 0x124 Backup Register 0 ~ 9
|
||||
} PWRCU_TypeDef;
|
||||
|
||||
// Clock Control Unit
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t GCFGR; //!< 0x000 Global Clock Configuration Register
|
||||
__IO uint32_t GCCR; //!< 0x004 Global Clock Control Register
|
||||
__IO uint32_t GCSR; //!< 0x008 Global Clock Status Register
|
||||
__IO uint32_t GCIR; //!< 0x00C Global Clock Interrupt Register
|
||||
uint32_t RESERVED0[2]; //!< 0x010 ~ 0x014 Reserved
|
||||
__IO uint32_t PLLCFGR; //!< 0x018 PLL Configuration Register
|
||||
__IO uint32_t PLLCR; //!< 0x01C PLL Control Register
|
||||
__IO uint32_t AHBCFGR; //!< 0x020 AHB Configuration Register
|
||||
__IO uint32_t AHBCCR; //!< 0x024 AHB Clock Control Register
|
||||
__IO uint32_t APBCFGR; //!< 0x028 APB Configuration Register
|
||||
__IO uint32_t APBCCR0; //!< 0x02C APB Clock Control Register 0
|
||||
__IO uint32_t APBCCR1; //!< 0x030 APB Clock Control Register 1
|
||||
__IO uint32_t CKST; //!< 0x034 Clock source status Register
|
||||
#if defined(HT32F1653_4)
|
||||
__IO uint32_t APBPCSR0; //!< 0x038 APB Peripheral Clock Selection Register 0
|
||||
__IO uint32_t APBPCSR1; //!< 0x03C APB Peripheral Clock Selection Register 1
|
||||
__IO uint32_t HSICR; //!< 0x040 HSI Control Register
|
||||
__IO uint32_t HSIATCR; //!< 0x044 HSI Auto Trimming Counter Register
|
||||
#else
|
||||
uint32_t RESERVED1[4]; //!< 0x038 ~ 0x044 Reserved
|
||||
#endif
|
||||
uint32_t RESERVED2[174]; //!< 0x048 ~ 0x2FC Reserved
|
||||
__IO uint32_t LPCR; //!< 0x300 Low Power Control Register
|
||||
__IO uint32_t MCUDBGCR; //!< 0x304 MCU Debug Control Register
|
||||
} CKCU_TypeDef;
|
||||
|
||||
#define CKCU_GCFGR_LPMOD_MASK (7U << 29)
|
||||
#define CKCU_GCFGR_USBPRE_MASK (3U << 22)
|
||||
#define CKCU_GCFGR_URPRE_MASK (3U << 20)
|
||||
#define CKCU_GCFGR_PLLSRC (1U << 8)
|
||||
#define CKCU_GCFGR_CKOUTSRC_MASK (7U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_REF (0U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_AHB (1U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_SYS (2U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_HSE (3U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_HSI (4U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_LSE (5U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_LSI (6U << 0)
|
||||
#define CKCU_GCCR_PSRCEN (1U << 17)
|
||||
#define CKCU_GCCR_CKMEN (1U << 16)
|
||||
#define CKCU_GCCR_HSIEN (1U << 11)
|
||||
#define CKCU_GCCR_HSEEN (1U << 10)
|
||||
#define CKCU_GCCR_PLLEN (1U << 9)
|
||||
#define CKCU_GCCR_SW_MASK (3U << 0)
|
||||
#define CKCU_GCCR_SW_PLL (1U << 0)
|
||||
#define CKCU_GCCR_SW_HSE (2U << 0)
|
||||
#define CKCU_GCCR_SW_HSI (3U << 0)
|
||||
#define CKCU_GCSR_LSIRDY (1U << 5)
|
||||
#define CKCU_GCSR_LSERDY (1U << 4)
|
||||
#define CKCU_GCSR_HSIRDY (1U << 3)
|
||||
#define CKCU_GCSR_HSERDY (1U << 2)
|
||||
#define CKCU_GCSR_PLLRDY (1U << 1)
|
||||
#define CKCU_PLLCFGR_PFBD_MASK (0x3fU << 23)
|
||||
#define CKCU_PLLCFGR_POTD_MASK (3U << 21)
|
||||
#define CKCU_PLLCR_PLLBPS (1U << 31)
|
||||
#define CKCU_AHBCFGR_AHBPRE_MASK (3U << 0)
|
||||
#define CKCU_AHBCCR_PAEN (1U << 16)
|
||||
#define CKCU_AHBCCR_CRCEN (1U << 13)
|
||||
#define CKCU_AHBCCR_EBIEN (1U << 12)
|
||||
#define CKCU_AHBCCR_CKREFEN (1U << 11)
|
||||
#define CKCU_AHBCCR_USBEN (1U << 10)
|
||||
#define CKCU_APBCFGR_ADCDIV_MASK (7U << 16)
|
||||
#define CKCU_APBCCR0_I2SEN (1U << 25)
|
||||
#define CKCU_APBCCR0_SCIEN (1U << 24)
|
||||
#define CKCU_APBCCR0_EXTIEN (1U << 15)
|
||||
#define CKCU_APBCCR0_AFIOEN (1U << 14)
|
||||
#define CKCU_APBCCR0_UR1EN (1U << 11)
|
||||
#define CKCU_APBCCR0_UR0EN (1U << 10)
|
||||
#define CKCU_APBCCR0_USR1EN (1U << 9)
|
||||
#define CKCU_APBCCR0_USR0EN (1U << 8)
|
||||
#define CKCU_APBCCR0_SPI1EN (1U << 5)
|
||||
#define CKCU_APBCCR0_SPI0EN (1U << 4)
|
||||
#define CKCU_APBCCR0_I2C1EN (1U << 1)
|
||||
#define CKCU_APBCCR0_I2C0EN (1U << 0)
|
||||
#define CKCU_APBCCR1_ADCEN (1U << 24)
|
||||
#define CKCU_APBCCR1_OPA1EN (1U << 23)
|
||||
#define CKCU_APBCCR1_OPA0EN (1U << 22)
|
||||
#define CKCU_APBCCR1_BFTM1EN (1U << 17)
|
||||
#define CKCU_APBCCR1_BFTM0EN (1U << 16)
|
||||
#define CKCU_APBCCR1_GPTM1EN (1U << 9)
|
||||
#define CKCU_APBCCR1_GPTM0EN (1U << 8)
|
||||
#define CKCU_APBCCR1_BKPREN (1U << 6)
|
||||
#define CKCU_APBCCR1_WDTREN (1U << 4)
|
||||
#define CKCU_APBCCR1_MCTM1EN (1U << 1)
|
||||
#define CKCU_APBCCR1_MCTM0EN (1U << 0)
|
||||
#define CKCU_CKST_CKSWST_MASK (3U << 30)
|
||||
#define CKCU_CKST_HSIST_MASK (7U << 24)
|
||||
#define CKCU_CKST_HSEST_MASK (3U << 16)
|
||||
#define CKCU_CKST_PLLST_MASK (0xfU << 8)
|
||||
#define CKCU_LPCR_USBSLEEP (1U << 8)
|
||||
#define CKCU_LPCR_BKISO (1U << 0)
|
||||
|
||||
// Reset Control Unit
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t GRSR; //!< 0x000 Global Reset Status Register
|
||||
__IO uint32_t AHBPRSTR; //!< 0x004 AHB Peripheral Reset Register
|
||||
__IO uint32_t APBPRSTR0; //!< 0x008 APB Peripheral Reset Register 0
|
||||
__IO uint32_t APBPRSTR1; //!< 0x00C APB Peripheral Reset Register 1
|
||||
} RSTCU_TypeDef;
|
||||
|
||||
#define RSTCU_GRSR_PORSTF (1U << 3)
|
||||
#define RSTCU_GRSR_WDTRSTF (1U << 2)
|
||||
#define RSTCU_GRSR_EXTRSTF (1U << 1)
|
||||
#define RSTCU_GRSR_SYSRSTF (1U << 0)
|
||||
#define RSTCU_AHBPRSTR_PxRST(n) ((1U << 8) << (n))
|
||||
#define RSTCU_AHBPRSTR_CRCRST (1U << 7)
|
||||
#define RSTCU_AHBPRSTR_EBIRST (1U << 6)
|
||||
#define RSTCU_AHBPRSTR_USBRST (1U << 5)
|
||||
#define RSTCU_AHBPRSTR_DMARST (1U << 0)
|
||||
#define RSTCU_APBPRSTR0_I2SRST (1U << 25)
|
||||
#define RSTCU_APBPRSTR0_SCIRST (1U << 24)
|
||||
#define RSTCU_APBPRSTR0_EXTIRST (1U << 15)
|
||||
#define RSTCU_APBPRSTR0_AFIORST (1U << 14)
|
||||
#define RSTCU_APBPRSTR0_UR1RST (1U << 11)
|
||||
#define RSTCU_APBPRSTR0_UR0RST (1U << 10)
|
||||
#define RSTCU_APBPRSTR0_USR1RST (1U << 9)
|
||||
#define RSTCU_APBPRSTR0_USR0RST (1U << 8)
|
||||
#define RSTCU_APBPRSTR0_SPI1RST (1U << 5)
|
||||
#define RSTCU_APBPRSTR0_SPI0RST (1U << 4)
|
||||
#define RSTCU_APBPRSTR0_I2C1RST (1U << 1)
|
||||
#define RSTCU_APBPRSTR0_I2C0RST (1U << 0)
|
||||
#define RSTCU_APBPRSTR1_ADCRST (1U << 24)
|
||||
#define RSTCU_APBPRSTR1_OPA1RST (1U << 23)
|
||||
#define RSTCU_APBPRSTR1_OPA0RST (1U << 22)
|
||||
#define RSTCU_APBPRSTR1_BFTM1RST (1U << 17)
|
||||
#define RSTCU_APBPRSTR1_BFTM0RST (1U << 16)
|
||||
#define RSTCU_APBPRSTR1_GPTM1RST (1U << 9)
|
||||
#define RSTCU_APBPRSTR1_GPTM0RST (1U << 8)
|
||||
#define RSTCU_APBPRSTR1_WDTRST (1U << 4)
|
||||
#define RSTCU_APBPRSTR1_MCTM1RST (1U << 1)
|
||||
#define RSTCU_APBPRSTR1_MCTM0RST (1U << 0)
|
||||
|
||||
// General Purpose I/O
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t DIRCR; //!< 0x000 Data Direction Control Register
|
||||
__IO uint32_t INER; //!< 0x004 Input function enable register
|
||||
__IO uint32_t PUR; //!< 0x008 Pull-Up Selection Register
|
||||
__IO uint32_t PDR; //!< 0x00C Pull-Down Selection Register
|
||||
__IO uint32_t ODR; //!< 0x010 Open Drain Selection Register
|
||||
__IO uint32_t DRVR; //!< 0x014 Drive Current Selection Register
|
||||
__IO uint32_t LOCKR; //!< 0x018 Lock Register
|
||||
__IO uint32_t DINR; //!< 0x01c Data Input Register
|
||||
__IO uint32_t DOUTR; //!< 0x020 Data Output Register
|
||||
__IO uint32_t SRR; //!< 0x024 Output Set and Reset Control Register
|
||||
__IO uint32_t RR; //!< 0x028 Output Reset Control Register
|
||||
} GPIO_TypeDef;
|
||||
|
||||
// Alternate Function Input/Output
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t ESSR[2]; //!< 0x000 ~ 0x004 EXTI Source Selection Register 0 ~ 1
|
||||
uint32_t RESERVE0[6]; //!< 0x008 ~ 0x01C Reserved
|
||||
union {
|
||||
struct {
|
||||
__IO uint32_t GPACFGR[2]; //!< 0x020 ~ 0x024 GPIO Port A Configuration Register 0 ~ 1
|
||||
__IO uint32_t GPBCFGR[2]; //!< 0x028 ~ 0x02C GPIO Port B Configuration Register 0 ~ 1
|
||||
__IO uint32_t GPCCFGR[2]; //!< 0x030 ~ 0x034 GPIO Port C Configuration Register 0 ~ 1
|
||||
__IO uint32_t GPDCFGR[2]; //!< 0x038 ~ 0x03C GPIO Port D Configuration Register 0 ~ 1
|
||||
#if defined(HT32F1655_6)
|
||||
__IO uint32_t GPECFGR[2]; //!< 0x040 ~ 0x044 GPIO Port E Configuration Register 0 ~ 1
|
||||
#endif
|
||||
};
|
||||
// alternate mapping
|
||||
struct {
|
||||
__IO uint32_t GPxCFGR[0][2]; //!< 0x020 ~ 0x044 GPIO Port x Configuration Register 0 ~ 1
|
||||
};
|
||||
};
|
||||
} AFIO_TypeDef;
|
||||
|
||||
// Nested Vectored Interrupt Controller
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// Implemented in Cortex-M3 Headers
|
||||
|
||||
// External Interrupt/Event Controller
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CFGR0; //!< 0x000 EXTI Interrupt 0 Configuration Register
|
||||
__IO uint32_t CFGR1; //!< 0x004 EXTI Interrupt 1 Configuration Register
|
||||
__IO uint32_t CFGR2; //!< 0x008 EXTI Interrupt 2 Configuration Register
|
||||
__IO uint32_t CFGR3; //!< 0x00C EXTI Interrupt 3 Configuration Register
|
||||
__IO uint32_t CFGR4; //!< 0x010 EXTI Interrupt 4 Configuration Register
|
||||
__IO uint32_t CFGR5; //!< 0x014 EXTI Interrupt 5 Configuration Register
|
||||
__IO uint32_t CFGR6; //!< 0x018 EXTI Interrupt 6 Configuration Register
|
||||
__IO uint32_t CFGR7; //!< 0x01C EXTI Interrupt 7 Configuration Register
|
||||
__IO uint32_t CFGR8; //!< 0x020 EXTI Interrupt 8 Configuration Register
|
||||
__IO uint32_t CFGR9; //!< 0x024 EXTI Interrupt 9 Configuration Register
|
||||
__IO uint32_t CFGR10; //!< 0x028 EXTI Interrupt 10 Configuration Register
|
||||
__IO uint32_t CFGR11; //!< 0x02C EXTI Interrupt 11 Configuration Register
|
||||
__IO uint32_t CFGR12; //!< 0x030 EXTI Interrupt 12 Configuration Register
|
||||
__IO uint32_t CFGR13; //!< 0x034 EXTI Interrupt 13 Configuration Register
|
||||
__IO uint32_t CFGR14; //!< 0x038 EXTI Interrupt 14 Configuration Register
|
||||
__IO uint32_t CFGR15; //!< 0x03C EXTI Interrupt 15 Configuration Register
|
||||
__IO uint32_t CR; //!< 0x040 EXTI Interrupt Control Register
|
||||
__IO uint32_t EDGEFLGR; //!< 0x044 EXTI Interrupt Edge Flag Register
|
||||
__IO uint32_t EDGESR; //!< 0x048 EXTI Interrupt Edge Status Register
|
||||
__IO uint32_t SSCR; //!< 0x04C EXTI Interrupt Software Set Command Register
|
||||
__IO uint32_t WAKUPCR; //!< 0x050 EXTI Interrupt Wakeup Control Register
|
||||
__IO uint32_t WAKUPPOLR; //!< 0x054 EXTI Interrupt Wakeup Polarity Register
|
||||
__IO uint32_t WAKUPFLG; //!< 0x058 EXTI Interrupt Wakeup Flag Register
|
||||
} EXTI_TypeDef;
|
||||
|
||||
// Analog To Digital Converter
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Operational Amplifier / Comparator
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(HT32F1653_4)
|
||||
typedef struct {
|
||||
__IO uint32_t CR; //!< 0x000 Comparator Control Register
|
||||
__IO uint32_t VALR; //!< 0x004 Comparator Voltage Reference Register
|
||||
__IO uint32_t IER; //!< 0x008 Comparator Interrupt Enable Register
|
||||
__IO uint32_t TFR; //!< 0x00C Comparator Transition Flag Register
|
||||
} CMP_TypeDef;
|
||||
#else
|
||||
typedef struct {
|
||||
__IO uint32_t OPACR; //!< 0x000 Operational Amplifier Control Register
|
||||
__IO uint32_t OFVCR; //!< 0x004 Comparator Input Offset Voltage Cancellation Register
|
||||
__IO uint32_t CMPIER; //!< 0x008 Comparator Interrupt Enable Register
|
||||
__IO uint32_t CMPRSR; //!< 0x00C Comparator Raw Status Register
|
||||
__IO uint32_t CMPISR; //!< 0x010 Comparator Masked Interrupt Status Register
|
||||
__IO uint32_t CMPICLR; //!< 0x014 Comparator Interrupt Clear Register
|
||||
} OPACMP_TypeDef;
|
||||
#endif
|
||||
|
||||
// Basic Function Timers
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CR; //!< 0x000 Control Register
|
||||
__IO uint32_t SR; //!< 0x004 Status Register
|
||||
__IO uint32_t CNTR; //!< 0x008 Counter Value Register
|
||||
__IO uint32_t CMP; //!< 0x00C Compare Value Register
|
||||
} BFTM_TypeDef;
|
||||
|
||||
#define BFTM_CR_CEN (1U << 2)
|
||||
#define BFTM_CR_OSM (1U << 1)
|
||||
#define BFTM_CR_MIEN (1U << 0)
|
||||
#define BFTM_SR_MIF (1U << 0)
|
||||
|
||||
// General Purpose Timers
|
||||
// Motor Control Timers
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CNTCFR; //!< 0x000 Timer Counter Configuaration Register
|
||||
__IO uint32_t MDCFR; //!< 0x004 Timer Mode Configuration Register
|
||||
__IO uint32_t TRCFR; //!< 0x008 Timer Trigger Configuration Register
|
||||
uint32_t RESERVED0[1]; //!< 0x00C Reserved
|
||||
__IO uint32_t CTR; //!< 0x010 Timer Counter Register
|
||||
uint32_t RESERVED1[3]; //!< 0x014 ~ 0x01C Reserved
|
||||
__IO uint32_t CHnICFR[4]; //!< 0x020 ~ 0x02C Channel n Input Configuration Register
|
||||
uint32_t RESERVED2[4]; //!< 0x030 ~ 0x03C Reserved
|
||||
__IO uint32_t CHnOCFR[4]; //!< 0x040 ~ 0x04C Channel n Output Configuration Register
|
||||
__IO uint32_t CHCTR; //!< 0x050 Channel Control Register
|
||||
__IO uint32_t CHPOLR; //!< 0x054 Channel Polarity Control Register
|
||||
uint32_t RESERVED3[5]; //!< 0x058 ~ 0x068 Reserved
|
||||
// note: only available as MCTM
|
||||
__IO uint32_t CHBRKCFR; //!< 0x06C Channel Break Configuration Register
|
||||
__IO uint32_t CHBRKCTR; //!< 0x070 Channel Break Control Register
|
||||
// end note
|
||||
__IO uint32_t DICTR; //!< 0x074 Timer PDMA/Interrupt Control Register
|
||||
__IO uint32_t EVGR; //!< 0x078 Timer Event Generator Register
|
||||
__IO uint32_t INTSR; //!< 0x07C Timer Interrupt Status Register
|
||||
__IO uint32_t CNTR; //!< 0x080 Timer Counter Register
|
||||
__IO uint32_t PSCR; //!< 0x084 Timer Prescaler Register
|
||||
__IO uint32_t CRR; //!< 0x088 Timer Counter Reload Register
|
||||
// note: only available as MCTM
|
||||
__IO uint32_t REPR; //!< 0x08C Timer Repetition Register
|
||||
// end note
|
||||
__IO uint32_t CHnCCR[4]; //!< 0x090 ~ 0x09C Channel n Capture/Compare Register
|
||||
__IO uint32_t CHnACR[4]; //!< 0x0A0 ~ 0x0AC Channel n Asymmentric Compare Register
|
||||
} TM_TypeDef;
|
||||
|
||||
#define TM_CNTCFR_CMSEL_MASK (3U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_3 (3U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_2 (2U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_1 (1U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_0 (0U << 16)
|
||||
#define TM_CTR_CHCCDS (1U << 16)
|
||||
#define TM_CTR_COMUS (1U << 9)
|
||||
#define TM_CTR_COMPRE (1U << 8)
|
||||
#define TM_CTR_CRBE (1U << 1)
|
||||
#define TM_CTR_TME (1U << 0)
|
||||
#define TM_CHnOCFR_CHnPRE (1U << 4)
|
||||
#define TM_CHnOCFR_REFnCE (1U << 3)
|
||||
#define TM_CHnOCFR_CHnOM(n) ((((n)>>0)&7)|((((n)>>3)&1)<<8))
|
||||
#define TM_CHBRKCTR_CHMOE (1U << 4)
|
||||
|
||||
// Real Time Clock
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Watchdog Timer
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// I2C
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CR; //!< 0x000 Control Register
|
||||
__IO uint32_t IER; //!< 0x004 Interrupt Enable Register
|
||||
__IO uint32_t ADDR; //!< 0x008 Address Register
|
||||
__IO uint32_t SR; //!< 0x00C Status Register
|
||||
__IO uint32_t SHPGR; //!< 0x010 SCL High Period Generation Register
|
||||
__IO uint32_t SLPGR; //!< 0x014 SCL Low Period Generation Register
|
||||
__IO uint32_t DR; //!< 0x018 Data Register
|
||||
__IO uint32_t TAR; //!< 0x01C Target Register
|
||||
__IO uint32_t ADDMR; //!< 0x020 Address Mask Register
|
||||
__IO uint32_t ADDSR; //!< 0x024 Address Snoop Register
|
||||
__IO uint32_t TOUT; //!< 0x028 Timeout Register
|
||||
} I2C_TypeDef;
|
||||
|
||||
#define I2C_CR_SEQ_FILTER_MASK (3U << 14)
|
||||
#define I2C_CR_SEQ_FILTER_2_PCLK (2U << 14)
|
||||
#define I2C_CR_SEQ_FILTER_1_PCLK (1U << 14)
|
||||
#define I2C_CR_SEQ_FILTER_DISABLE (0U << 14)
|
||||
#define I2C_CR_COMB_FILTER_En (1U << 13)
|
||||
#define I2C_CR_ENTOUT (1U << 12)
|
||||
#define I2C_CR_DMANACK (1U << 10)
|
||||
#define I2C_CR_RXDMAE (1U << 9)
|
||||
#define I2C_CR_TXDMAE (1U << 8)
|
||||
#define I2C_CR_ADRM (1U << 7)
|
||||
#define I2C_CR_I2CEN (1U << 3)
|
||||
#define I2C_CR_GCEN (1U << 2)
|
||||
#define I2C_CR_STOP (1U << 1)
|
||||
#define I2C_CR_AA (1U << 0)
|
||||
#define I2C_IER_RXBFIE (1U << 18)
|
||||
#define I2C_IER_TXDEIE (1U << 17)
|
||||
#define I2C_IER_RXDNEIE (1U << 16)
|
||||
#define I2C_IER_TOUTIE (1U << 11)
|
||||
#define I2C_IER_BUSERRIE (1U << 10)
|
||||
#define I2C_IER_RXNACKIE (1U << 9)
|
||||
#define I2C_IER_ARBLOSIE (1U << 8)
|
||||
#define I2C_IER_GCSIE (1U << 3)
|
||||
#define I2C_IER_ADRSIE (1U << 2)
|
||||
#define I2C_IER_STOIE (1U << 1)
|
||||
#define I2C_IER_STAIE (1U << 0)
|
||||
#define I2C_SR_TXNRX (1U << 21)
|
||||
#define I2C_SR_MASTER (1U << 20)
|
||||
#define I2C_SR_BUSBUSY (1U << 19)
|
||||
#define I2C_SR_RXBF (1U << 18)
|
||||
#define I2C_SR_TXDE (1U << 17)
|
||||
#define I2C_SR_RXDNE (1U << 16)
|
||||
#define I2C_SR_TOUTF (1U << 11)
|
||||
#define I2C_SR_BUSERR (1U << 10)
|
||||
#define I2C_SR_RXNACK (1U << 9)
|
||||
#define I2C_SR_ARBLOS (1U << 8)
|
||||
#define I2C_SR_GCS (1U << 3)
|
||||
#define I2C_SR_ADRS (1U << 2)
|
||||
#define I2C_SR_STO (1U << 1)
|
||||
#define I2C_SR_STA (1U << 0)
|
||||
#define I2C_TAR_RWD (1U << 10)
|
||||
|
||||
// SPI
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CR0; //!< 0x000 Control Register 0
|
||||
__IO uint32_t CR1; //!< 0x004 Control Register 1
|
||||
__IO uint32_t IER; //!< 0x008 Interrupt Enable Register
|
||||
__IO uint32_t CPR; //!< 0x00C Clock Prescaler Register
|
||||
__IO uint32_t DR; //!< 0x010 Data Register
|
||||
__IO uint32_t SR; //!< 0x014 Status Register
|
||||
__IO uint32_t FCR; //!< 0x018 FIFO Control Register
|
||||
__IO uint32_t FSR; //!< 0x01C FIFO Status Register
|
||||
__IO uint32_t FTOCR; //!< 0x020 FIFO Time Out Counter Register
|
||||
} SPI_TypeDef;
|
||||
|
||||
#define SPI_CR0_GUADTEN (1U << 7)
|
||||
#define SPI_CR0_DUALEN (1U << 6)
|
||||
#define SPI_CR0_SSELC (1U << 4)
|
||||
#define SPI_CR0_SELOEN (1U << 3)
|
||||
#define SPI_CR0_SPIEN (1U << 0)
|
||||
#define SPI_CR1_MODE (1U << 14)
|
||||
#define SPI_CR1_SELM (1U << 13)
|
||||
#define SPI_CR1_FIRSTBIT (1U << 12)
|
||||
#define SPI_CR1_SELAP (1U << 11)
|
||||
#define SPI_CR1_FORMAT_MASK (7U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE0 (0x1U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE1 (0x2U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE2 (0x6U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE3 (0x5U << 8)
|
||||
#define SPI_IER_RXBNEIEN (1U << 2)
|
||||
#define SPI_IER_TXBEIEN (1U << 0)
|
||||
#define SPI_SR_RXBNE (1U << 2)
|
||||
#define SPI_SR_TXE (1U << 1)
|
||||
#define SPI_SR_TXBE (1U << 0)
|
||||
#define SPI_FCR_FIFOEN (1U << 10)
|
||||
#define SPI_FSR_TXFS_MASK (0xfU << 0)
|
||||
#define SPI_FSR_RXFS_MASK (0xfU << 4)
|
||||
|
||||
// USART
|
||||
// UART
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
union {
|
||||
__IO uint32_t RBR; //!< 0x000 Receive Buffer Register
|
||||
__IO uint32_t TBR; //!< 0x000 Transmit Holding Register
|
||||
__IO uint32_t DR; //!< 0x000 Data Register
|
||||
};
|
||||
__IO uint32_t IER; //!< 0x004 Interrupt Enable Register
|
||||
__IO uint32_t IIR; //!< 0x008 Interrupt Identification Register/FIFO Control Register
|
||||
__IO uint32_t FCR; //!< 0x00C FIFO Control Register
|
||||
__IO uint32_t LCR; //!< 0x010 Line Control Register
|
||||
// note: only available as USART
|
||||
__IO uint32_t MODCR; //!< 0x014 Modem Control Register
|
||||
// end note
|
||||
__IO uint32_t LSR; //!< 0x018 Line Status Register
|
||||
// note: only available as USART
|
||||
__IO uint32_t MODSR; //!< 0x01C Modem Status Register
|
||||
// end note
|
||||
__IO uint32_t TPR; //!< 0x020 Timing Parameter Register
|
||||
__IO uint32_t MDR; //!< 0x024 Mode Register
|
||||
// note: only available as USART
|
||||
__IO uint32_t IrDACR; //!< 0x028 IrDA Control Register
|
||||
__IO uint32_t RS485CR; //!< 0x02C RS485 Control Register
|
||||
__IO uint32_t SYNCR; //!< 0x030 Synchronous Control Register
|
||||
// end note
|
||||
__IO uint32_t FSR; //!< 0x034 FIFO Status Register
|
||||
__IO uint32_t DLR; //!< 0x038 Divisor Latch Register
|
||||
uint32_t RESERVED0; //!< 0x03C Reserved
|
||||
__IO uint32_t DEGTSTR; //!< 0x040 Debug/Test Register
|
||||
} USART_TypeDef;
|
||||
|
||||
#define USART_FCR_FME (1 << 0)
|
||||
#define USART_FCR_RFR (1 << 1)
|
||||
#define USART_FCR_TFR (1 << 2)
|
||||
#define USART_FCR_TFTL_MASK (0x3 << 4)
|
||||
#define USART_FCR_TFTL_0BYTE (0x0 << 4)
|
||||
#define USART_FCR_TFTL_2BYTE (0x1 << 4)
|
||||
#define USART_FCR_TFTL_4BYTE (0x2 << 4)
|
||||
#define USART_FCR_TFTL_8BYTE (0x3 << 4)
|
||||
#define USART_FCR_RFTL_MASK (0x3 << 6)
|
||||
#define USART_FCR_RFTL_1BYTE (0x0 << 6)
|
||||
#define USART_FCR_RFTL_4BYTE (0x1 << 6)
|
||||
#define USART_FCR_RFTL_8BYTE (0x2 << 6)
|
||||
#define USART_FCR_RFTL_14BYTE (0x3 << 6)
|
||||
#define USART_FCR_URTXEN (1 << 8)
|
||||
#define USART_FCR_URRXEN (1 << 9)
|
||||
#define USART_LCR_WLS_MASK (0x3 << 0)
|
||||
#define USART_LCR_WLS_7BIT (0x0 << 0)
|
||||
#define USART_LCR_WLS_8BIT (0x1 << 0)
|
||||
#define USART_LCR_WLS_9BIT (0x2 << 0)
|
||||
#define USART_LCR_NSB (1 << 2)
|
||||
#define USART_LCR_PBE (1 << 3)
|
||||
#define USART_LCR_EPE (1 << 4)
|
||||
#define USART_LCR_SPE (1 << 5)
|
||||
#define USART_LCR_BCB (1 << 6)
|
||||
#define USART_LSR_RFDR (1 << 0)
|
||||
#define USART_LSR_OEI (1 << 1)
|
||||
#define USART_LSR_PEI (1 << 2)
|
||||
#define USART_LSR_FEI (1 << 3)
|
||||
#define USART_LSR_BII (1 << 4)
|
||||
#define USART_LSR_TXFEMPT (1 << 5)
|
||||
#define USART_LSR_TXEMPT (1 << 6)
|
||||
#define USART_LSR_ERRRX (1 << 7)
|
||||
#define USART_LSR_RSADDEF (1 << 8)
|
||||
#define USART_MDR_MODE_MASK (0x3 << 0)
|
||||
#define USART_MDR_MODE_NORMAL (0x0 << 0)
|
||||
#define USART_MDR_MODE_IRDA (0x1 << 0)
|
||||
#define USART_MDR_MODE_RS485 (0x2 << 0)
|
||||
#define USART_MDR_MODE_SYNCHRONOUS (0x3 << 0)
|
||||
#define USART_MDR_TRSM (1 << 2)
|
||||
#define USART_MDR_TXDMAEN (1 << 4)
|
||||
#define USART_MDR_RXDMAEN (1 << 5)
|
||||
|
||||
// Smart Card Interface
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// USB
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CSR; //!< 0x000 USB Control and Status Register
|
||||
__IO uint32_t IER; //!< 0x004 USB Interrupt Enable Register
|
||||
__IO uint32_t ISR; //!< 0x008 USB Interrupt Status Register
|
||||
__IO uint32_t FCR; //!< 0x00C USB Frame Count Register
|
||||
__IO uint32_t DEVAR; //!< 0x010 USB Device Address Register
|
||||
struct {
|
||||
__IO uint32_t CSR; //!< 0x014 USB Endpoint n Control and Status Register
|
||||
__IO uint32_t IER; //!< 0x018 USB Endpoint n Interrupt Enable Register
|
||||
__IO uint32_t ISR; //!< 0x01C USB Endpoint n Interrupt Status Register
|
||||
__IO uint32_t TCR; //!< 0x020 USB Endpoint n Transfer Count Register
|
||||
__IO uint32_t CFGR; //!< 0x024 USB Endpoint n Configuration Register
|
||||
} EP[8];
|
||||
} USB_TypeDef;
|
||||
|
||||
// USBCSR
|
||||
#define USBCSR_FRES (0x002) // Force USB Reset Control
|
||||
#define USBCSR_PDWN (0x004) // Power Down Mode Control
|
||||
#define USBCSR_LPMODE (0x008) // Low-Power Mode Control
|
||||
#define USBCSR_GENRSM (0x020) // Resume Request Generation Control
|
||||
#define USBCSR_RXDP (0x040) // Received DP Line Status
|
||||
#define USBCSR_RXDM (0x080) // Received DM Line Status
|
||||
#define USBCSR_ADRSET (0x100) // Device Address Setting Control
|
||||
#define USBCSR_SRAMRSTC (0x200) // USB SRAM Reset Condition
|
||||
#define USBCSR_DPPUEN (0x400) // DP Pull Up Enable
|
||||
#define USBCSR_DPWKEN (0x800) // DP Wake Up Enable
|
||||
|
||||
// USBIER
|
||||
#define USBIER_UGIE (0x0001) // USB global Interrupt Enable
|
||||
#define USBIER_SOFIE (0x0002) // Start Of Frame Interrupt Enable
|
||||
#define USBIER_URSTIE (0x0004) // USB Reset Interrupt Enable
|
||||
#define USBIER_RSMIE (0x0008) // Resume Interrupt Enable
|
||||
#define USBIER_SUSPIE (0x0010) // Suspend Interrupt Enable
|
||||
#define USBIER_ESOFIE (0x0020) // Expected Start Of Frame Enable
|
||||
#define USBIER_EP0IE (0x0100) // Endpoint 0 Interrupt Enable
|
||||
#define USBIER_EP1IE (0x0200) // Endpoint 1 Interrupt Enable
|
||||
#define USBIER_EP2IE (0x0400) // Endpoint 2 Interrupt Enable
|
||||
#define USBIER_EP3IE (0x0800) // Endpoint 3 Interrupt Enable
|
||||
#define USBIER_EP4IE (0x1000) // Endpoint 4 Interrupt Enable
|
||||
#define USBIER_EP5IE (0x2000) // Endpoint 5 Interrupt Enable
|
||||
#define USBIER_EP6IE (0x4000) // Endpoint 6 Interrupt Enable
|
||||
#define USBIER_EP7IE (0x8000) // Endpoint 7 Interrupt Enable
|
||||
|
||||
// USBISR
|
||||
#define USBISR_SOFIF (0x0002) // Start Of Frame Interrupt Flag
|
||||
#define USBISR_URSTIF (0x0004) // USB Reset Interrupt Flag
|
||||
#define USBISR_RSMIF (0x0008) // Resume Interrupt Flag
|
||||
#define USBISR_SUSPIF (0x0010) // Suspend Interrupt Flag
|
||||
#define USBISR_ESOFIF (0x0020) // Expected Start Of Frame Interrupt
|
||||
#define USBISR_EP0IF (1U << 8) // Endpoint 0 Interrupt Flag
|
||||
#define USBISR_EP1IF (1U << 9) // Endpoint 1 Interrupt Flag
|
||||
#define USBISR_EP2IF (1U << 10) // Endpoint 2 Interrupt Flag
|
||||
#define USBISR_EP3IF (1U << 11) // Endpoint 3 Interrupt Flag
|
||||
#define USBISR_EP4IF (1U << 12) // Endpoint 4 Interrupt Flag
|
||||
#define USBISR_EP5IF (1U << 13) // Endpoint 5 Interrupt Flag
|
||||
#define USBISR_EP6IF (1U << 14) // Endpoint 6 Interrupt Flag
|
||||
#define USBISR_EP7IF (1U << 15) // Endpoint 7 Interrupt Flag
|
||||
#define USBISR_EPnIF (0xFF00) // Endpoint Interrupt Mask
|
||||
|
||||
// USBFCR
|
||||
#define USBFCR_FRNUM (0x7FF) // Frame Number
|
||||
#define USBFCR_SOFLCK (1U << 16) // Start-of-Frame Lock Flag
|
||||
#define USBFCR_LSOF (0x3U << 17) // Lost Start-of-Frame Number
|
||||
|
||||
// USBEPnCSR
|
||||
#define USBEPnCSR_DTGTX (0x01) // Data Toggle Status, for IN transfer
|
||||
#define USBEPnCSR_NAKTX (0x02) // NAK Status, for IN transfer
|
||||
#define USBEPnCSR_STLTX (0x04) // STALL Status, for IN transfer
|
||||
#define USBEPnCSR_DTGRX (0x08) // Data Toggle Status, for OUT transfer
|
||||
#define USBEPnCSR_NAKRX (0x10) // NAK Status, for OUT transfer
|
||||
#define USBEPnCSR_STLRX (0x20) // STALL Status, for OUT transfer
|
||||
|
||||
// USBEPnIER
|
||||
#define USBEPnIER_OTRXIE (0x001) // OUT Token Received Interrupt Enable
|
||||
#define USBEPnIER_ODRXIE (0x002) // OUT Data Received Interrupt Enable
|
||||
#define USBEPnIER_ODOVIE (0x004) // OUT Data Buffer Overrun Interrupt Enable
|
||||
#define USBEPnIER_ITRXIE (0x008) // IN Token Received Interrupt Enable
|
||||
#define USBEPnIER_IDTXIE (0x010) // IN Data Transmitted Interrupt Enable
|
||||
#define USBEPnIER_NAKIE (0x020) // NAK Transmitted Interrupt Enable
|
||||
#define USBEPnIER_STLIE (0x040) // STALL Transmitted Interrupt Enable
|
||||
#define USBEPnIER_UERIE (0x080) // USB Error Interrupt Enable
|
||||
#define USBEPnIER_STRXIE (0x100) // SETUP Token Received Interrupt Enable
|
||||
#define USBEPnIER_SDRXIE (0x200) // SETUP Data Received Interrupt Enable
|
||||
#define USBEPnIER_SDERIE (0x400) // SETUP Data Error Interrupt Enable
|
||||
#define USBEPnIER_ZLRXIE (0x800) // Zero Length Data Received Interrupt Enable
|
||||
|
||||
// USBEPnISR
|
||||
#define USBEPnISR_OTRXIF (0x001) // OUT Token Received Interrupt Flag
|
||||
#define USBEPnISR_ODRXIF (0x002) // OUT Data Received Interrupt Flag
|
||||
#define USBEPnISR_ODOVIF (0x004) // OUT Data Buffer Overrun Interrupt Flag
|
||||
#define USBEPnISR_ITRXIF (0x008) // IN Token Received Interrupt Flag
|
||||
#define USBEPnISR_IDTXIF (0x010) // IN Data Transmitted Interrupt Flag
|
||||
#define USBEPnISR_NAKIF (0x020) // NAK Transmitted Interrupt Flag
|
||||
#define USBEPnISR_STLIF (0x040) // STALL Transmitted Interrupt Flag
|
||||
#define USBEPnISR_UERIF (0x080) // USB Error Interrupt Flag
|
||||
#define USBEPnISR_STRXIF (0x100) // SETUP Token Received Interrupt Flag
|
||||
#define USBEPnISR_SDRXIF (0x200) // SETUP Data Received Interrupt Flag
|
||||
#define USBEPnISR_SDERIF (0x400) // SETUP Data Error Interrupt Flag
|
||||
#define USBEPnISR_ZLRXIF (0x800) // Zero Length Data Received Interrupt Flag
|
||||
|
||||
// USBEPnTCR
|
||||
#define USBEPnTCR_TCNT (0x1FF) // Transfer Byte Count
|
||||
|
||||
// USBEPnCFGR
|
||||
#define USBEPnCFGR_EPEN (1U << 31) // Endpoint Enable
|
||||
#define USBEPnCFGR_EPTYPE (1U << 29) // Transfer Type
|
||||
#define USBEPnCFGR_EPDIR (1U << 28) // Transfer Direction
|
||||
#define USBEPnCFGR_EPADR (0xFU << 24) // Endpoint Address
|
||||
#define USBEPnCFGR_EPLEN (0x7FU << 10) // Buffer Length
|
||||
#define USBEPnCFGR_EPBUFA (0x3FF) // Endpoint Buffer Address
|
||||
|
||||
// Peripheral Direct Memory Access
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Extend Bus Interface
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Inter-IC Sound
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CRC
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // HT32F165x_REG_H
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Codetector <codetector@codetector.cn>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(HT32F52342) || defined(HT32F52352)
|
||||
#define HT32F523x2
|
||||
#else
|
||||
#error "Unknown HT32 device"
|
||||
#endif
|
||||
|
||||
#if defined(HT32F523x2)
|
||||
#define HT32
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
* ---------- Interrupt Number Definition -----------------------
|
||||
* ==============================================================
|
||||
*/
|
||||
typedef enum IRQn
|
||||
{
|
||||
/****** Cortex-M3 Processor Exceptions Numbers ****************/
|
||||
InitialSP_IRQn = -16,
|
||||
InitialPC_IRQn = -15,
|
||||
NonMaskableInt_IRQn = -14,
|
||||
HardFault_IRQn = -13,
|
||||
SVCall_IRQn = -5,
|
||||
PendSV_IRQn = -2,
|
||||
SysTick_IRQn = -1,
|
||||
|
||||
/****** HT32F165x Specific Interrupt Numbers ***********************/
|
||||
LVD_IRQn = 0,
|
||||
RTC_IRQn = 1,
|
||||
FMC_IRQn = 2,
|
||||
WKUP_IRQn = 3,
|
||||
EXTI0_1_IRQn = 4,
|
||||
EXTI2_3_IRQn = 5,
|
||||
EXTI4_15_IRQn = 6,
|
||||
CMP_IRQn = 7,
|
||||
ADC_IRQn = 8,
|
||||
|
||||
MCTM_IRQn = 10,
|
||||
GPTM1_IRQn = 11,
|
||||
GPTM0_IRQn = 12,
|
||||
SCTM0_IRQn = 13,
|
||||
SCTM1_IRQn = 14,
|
||||
|
||||
BFTM0_IRQn = 17,
|
||||
BFTM1_IRQn = 18,
|
||||
I2C0_IRQn = 19,
|
||||
I2C1_IRQn = 20,
|
||||
SPI0_IRQn = 21,
|
||||
SPI1_IRQn = 22,
|
||||
USART0_IRQn = 23,
|
||||
USART1_IRQn = 24,
|
||||
UART0_IRQn = 25,
|
||||
UART1_IRQn = 26,
|
||||
SCI_IRQn = 27,
|
||||
I2S_IRQn = 28,
|
||||
USB_IRQn = 29,
|
||||
PDMA_CH0_1_IRQn = 30,
|
||||
PDMA_CH2_5_IRQn = 31
|
||||
} IRQn_Type;
|
||||
|
||||
/*
|
||||
* ==========================================================================
|
||||
* ----------- Processor and Core Peripheral Section ------------------------
|
||||
* ==========================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief HT32F165x Interrupt Number Definition, according to the selected device
|
||||
* in @ref Library_configuration_section
|
||||
*/
|
||||
#define __FPU_PRESENT 0
|
||||
#define __MPU_PRESENT 0
|
||||
#define __NVIC_PRIO_BITS 8
|
||||
#define __Vendor_SysTickConfig 0
|
||||
|
||||
#include "core_cm0plus.h" /* Cortex-M0+ processor and core peripherals */
|
||||
|
||||
/****************************************************************/
|
||||
/* Peripheral memory map */
|
||||
/****************************************************************/
|
||||
#define USART0_BASE ((uint32_t)0x40000000)
|
||||
#define UART0_BASE ((uint32_t)0x40001000)
|
||||
#define SPI0_BASE ((uint32_t)0x40004000)
|
||||
#define ADC_BASE ((uint32_t)0x40010000)
|
||||
|
||||
#define AFIO_BASE ((uint32_t)0x40022000)
|
||||
#define EXTI_BASE ((uint32_t)0x40024000)
|
||||
#define I2S_BASE ((uint32_t)0x40026000)
|
||||
#define MCTM0_BASE ((uint32_t)0x4002C000)
|
||||
#define MCTM1_BASE ((uint32_t)0x4002D000)
|
||||
|
||||
#define USART1_BASE ((uint32_t)0x40040000)
|
||||
#define UART1_BASE ((uint32_t)0x40041000)
|
||||
#define SCI_BASE ((uint32_t)0x40043000)
|
||||
#define SPI1_BASE ((uint32_t)0x40044000)
|
||||
#define I2C0_BASE ((uint32_t)0x40048000)
|
||||
#define I2C1_BASE ((uint32_t)0x40049000)
|
||||
|
||||
#define CMP0_BASE ((uint32_t)0x40058000)
|
||||
#define CMP1_BASE ((uint32_t)0x40058100)
|
||||
|
||||
#define WDT_BASE ((uint32_t)0x40068000)
|
||||
#define RTC_BASE ((uint32_t)0x4006A000)
|
||||
#define PWRCU_BASE ((uint32_t)0x4006A000)
|
||||
#define GPTM0_BASE ((uint32_t)0x4006E000)
|
||||
#define GPTM1_BASE ((uint32_t)0x4006F000)
|
||||
#define BFTM0_BASE ((uint32_t)0x40076000)
|
||||
#define BFTM1_BASE ((uint32_t)0x40077000)
|
||||
|
||||
#define FMC_BASE ((uint32_t)0x40080000)
|
||||
#define CKCU_BASE ((uint32_t)0x40088000)
|
||||
#define RSTCU_BASE ((uint32_t)0x40088000)
|
||||
#define CRC_BASE ((uint32_t)0x4008A000)
|
||||
#define PDMA_BASE ((uint32_t)0x40090000)
|
||||
#define EBI_BASE ((uint32_t)0x40098000)
|
||||
#define USB_BASE ((uint32_t)0x400A8000)
|
||||
#define USB_SRAM_BASE ((uint32_t)0x400AA000)
|
||||
#define GPIO_A_BASE ((uint32_t)0x400B0000)
|
||||
#define GPIO_B_BASE ((uint32_t)0x400B2000)
|
||||
#define GPIO_C_BASE ((uint32_t)0x400B4000)
|
||||
#define GPIO_D_BASE ((uint32_t)0x400B6000)
|
||||
|
||||
|
||||
// Registers Headers
|
||||
#include "ht32f523x2_reg.h"
|
||||
|
||||
/****************************************************************/
|
||||
/* Peripheral declaration */
|
||||
/****************************************************************/
|
||||
#define USART0 ((USART_TypeDef *) USART0_BASE)
|
||||
#define UART0 ((USART_TypeDef *) UART0_BASE)
|
||||
#define SPI0 ((SPI_TypeDef *) SPI0_BASE)
|
||||
#define ADC ((ADC_TypeDef *) ADC_BASE)
|
||||
|
||||
#define AFIO ((AFIO_TypeDef *) AFIO_BASE)
|
||||
#define EXTI ((EXTI_TypeDef *) EXTI_BASE)
|
||||
#define I2S ((I2S_TypeDef *) I2S_BASE)
|
||||
#define MCTM0 ((TM_TypeDef *) MCTM0_BASE)
|
||||
#define MCTM1 ((TM_TypeDef *) MCTM1_BASE)
|
||||
|
||||
#define USART1 ((USART_TypeDef *) USART1_BASE)
|
||||
#define UART1 ((USART_TypeDef *) UART1_BASE)
|
||||
#define SCI ((SCI_TypeDef *) SCI_BASE)
|
||||
#define SPI1 ((SPI_TypeDef *) SPI1_BASE)
|
||||
#define I2C0 ((I2C_TypeDef *) I2C0_BASE)
|
||||
#define I2C1 ((I2C_TypeDef *) I2C1_BASE)
|
||||
|
||||
#define CMP0 ((CMP_TypeDef *) CMP0_BASE)
|
||||
#define CMP1 ((CMP_TypeDef *) CMP1_BASE)
|
||||
|
||||
#define WDT ((WDT_TypeDef *) WDT_BASE)
|
||||
#define RTC ((RTC_TypeDef *) RTC_BASE)
|
||||
#define PWRCU ((PWRCU_TypeDef *) PWRCU_BASE)
|
||||
#define GPTM0 ((TM_TypeDef *) GPTM0_BASE)
|
||||
#define GPTM1 ((TM_TypeDef *) GPTM1_BASE)
|
||||
#define BFTM0 ((BFTM_TypeDef *) BFTM0_BASE)
|
||||
#define BFTM1 ((BFTM_TypeDef *) BFTM1_BASE)
|
||||
|
||||
#define FMC ((FMC_TypeDef *) FMC_BASE)
|
||||
#define CKCU ((CKCU_TypeDef *) CKCU_BASE)
|
||||
#define RSTCU ((RSTCU_TypeDef *) RSTCU_BASE)
|
||||
#define CRC ((CRC_TypeDef *) CRC_BASE)
|
||||
#define PDMA ((PDMA_TypeDef *) PDMA_BASE)
|
||||
#define EBI ((EBI_TypeDef *) EBI_BASE)
|
||||
#define USB ((USB_TypeDef *) USB_BASE)
|
||||
|
||||
#define GPIOA ((GPIO_TypeDef *) GPIO_A_BASE)
|
||||
#define GPIO_A GPIOA
|
||||
#define GPIOB ((GPIO_TypeDef *) GPIO_B_BASE)
|
||||
#define GPIO_B GPIOB
|
||||
#define GPIOC ((GPIO_TypeDef *) GPIO_C_BASE)
|
||||
#define GPIO_C GPIOC
|
||||
#define GPIOD ((GPIO_TypeDef *) GPIO_D_BASE)
|
||||
#define GPIO_D GPIOD
|
||||
|
|
@ -0,0 +1,657 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef __IO
|
||||
#define __IO volatile
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
#define AFIO_DEFAULT 0
|
||||
#define AFIO_GPIO 1
|
||||
#define AFIO_ADC 2
|
||||
#define AFIO_CMP 3
|
||||
#define AFIO_TM 4
|
||||
#define AFIO_SPI 5
|
||||
#define AFIO_USART 6
|
||||
#define AFIO_I2C 7
|
||||
#define AFIO_SMC 8
|
||||
#define AFIO_EBI 9
|
||||
#define AFIO_I2S 10
|
||||
#define AFIO_OTHER 15
|
||||
|
||||
// Flash Memory Controller
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t TADR; //!< 0x000 Flash Target Address Register
|
||||
__IO uint32_t WRDR; //!< 0x004 Flash Write Data Register
|
||||
uint32_t RESERVED0[1]; //!< 0x008 Reserved
|
||||
__IO uint32_t OCMR; //!< 0x00C Flash Operation Command Register
|
||||
__IO uint32_t OPCR; //!< 0x010 Flash Operation Control Register
|
||||
__IO uint32_t OIER; //!< 0x014 Flash Operation Interrupt Enable Register
|
||||
__IO uint32_t OISR; //!< 0x018 Flash Operation Interrupt and Status Register
|
||||
uint32_t RESERVED1[1]; //!< 0x01C Reserved
|
||||
__IO uint32_t PPSR[4]; //!< 0x020 ~ 0x02C Flash Page Erase/Program Protection Status Register
|
||||
__IO uint32_t CPSR; //!< 0x030 Flash Security Protection Status Register
|
||||
uint32_t RESERVED2[51]; //!< 0x034 ~ 0x0FC Reserved
|
||||
__IO uint32_t VMCR; //!< 0x100 Flash Vector Mapping Control Register
|
||||
uint32_t RESERVED3[31]; //!< 0x104 ~ 0x17C Reserved
|
||||
__IO uint32_t MDID; //!< 0x180 Manufacturer and Device ID Register
|
||||
__IO uint32_t PNSR; //!< 0x184 Flash Page Number Status Register
|
||||
__IO uint32_t PSSR; //!< 0x188 Flash Page Size Status Register
|
||||
#if defined(HT32F165x)
|
||||
uint32_t RESERVED4[29]; //!< 0x18C ~ 0x1FC Reserved
|
||||
#else
|
||||
__IO uint32_t DID; //!< 0x18C Device ID Register
|
||||
uint32_t RESERVED4[28]; //!< 0x190 ~ 0x1FC Reserved
|
||||
#endif
|
||||
__IO uint32_t CFCR; //!< 0x200 Flash Cache and Pre-fetch Control Register
|
||||
uint32_t RESERVED5[63]; //!< 0x204 ~ 0x2FC Reserved
|
||||
__IO uint32_t SBVT[4]; //!< 0x300 ~ 0x30C SRAM Booting Vector (4x32Bit)
|
||||
#if defined(HT32F165x)
|
||||
#else
|
||||
__IO uint32_t CID[4]; //!< 0x310 ~ 0x31C Custom ID Register
|
||||
#endif
|
||||
} FMC_TypeDef;
|
||||
|
||||
#define FMC_OCMR_CMD_MASK (0xF << 0)
|
||||
#define FMC_OCMR_CMD_IDLE (0x0 << 0)
|
||||
#define FMC_OCMR_CMD_WORD_PROGRAM (0x4 << 0)
|
||||
#define FMC_OCMR_CMD_PAGE_ERASE (0x8 << 0)
|
||||
#define FMC_OCMR_CMD_MASS_ERASE (0xA << 0)
|
||||
#define FMC_OPCR_OPM_MASK (0xF << 1)
|
||||
#define FMC_OPCR_OPM_IDLE (0x6 << 1)
|
||||
#define FMC_OPCR_OPM_COMMIT (0xA << 1)
|
||||
#define FMC_OPCR_OPM_FINISHED (0xE << 1)
|
||||
#define FMC_CFCR_CE (1U << 12)
|
||||
#define FMC_CFCR_WAIT_MASK (7U << 0)
|
||||
#define FMC_CFCR_WAIT_0 (1U)
|
||||
#define FMC_CFCR_WAIT_1 (2U)
|
||||
|
||||
// Power Control Unit
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
uint32_t RESERVE0[64];
|
||||
__IO uint32_t BAKSR; //!< 0x000 Status Register
|
||||
__IO uint32_t BAKCR; //!< 0x004 Control Register
|
||||
__IO uint32_t BAKTEST; //!< 0x008 Test Register
|
||||
__IO uint32_t HSIRCR; //!< 0x00C HSI Ready Counter Control Register
|
||||
__IO uint32_t LVDCSR; //!< 0x010 Low Voltage/Brown Out Detect Control and Status Register
|
||||
uint32_t RESERVE1[59]; //!< 0x014 ~ 0x0FC Reserved
|
||||
__IO uint32_t BAKREG[10]; //!< 0x100 ~ 0x124 Backup Register 0 ~ 9
|
||||
} PWRCU_TypeDef;
|
||||
|
||||
// Clock Control Unit
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t GCFGR; //!< 0x000 Global Clock Configuration Register
|
||||
__IO uint32_t GCCR; //!< 0x004 Global Clock Control Register
|
||||
__IO uint32_t GCSR; //!< 0x008 Global Clock Status Register
|
||||
__IO uint32_t GCIR; //!< 0x00C Global Clock Interrupt Register
|
||||
uint32_t RESERVED0[2]; //!< 0x010 ~ 0x014 Reserved
|
||||
__IO uint32_t PLLCFGR; //!< 0x018 PLL Configuration Register
|
||||
__IO uint32_t PLLCR; //!< 0x01C PLL Control Register
|
||||
__IO uint32_t AHBCFGR; //!< 0x020 AHB Configuration Register
|
||||
__IO uint32_t AHBCCR; //!< 0x024 AHB Clock Control Register
|
||||
__IO uint32_t APBCFGR; //!< 0x028 APB Configuration Register
|
||||
__IO uint32_t APBCCR0; //!< 0x02C APB Clock Control Register 0
|
||||
__IO uint32_t APBCCR1; //!< 0x030 APB Clock Control Register 1
|
||||
__IO uint32_t CKST; //!< 0x034 Clock source status Register
|
||||
|
||||
__IO uint32_t APBPCSR0; //!< 0x038 APB Peripheral Clock Selection Register 0
|
||||
__IO uint32_t APBPCSR1; //!< 0x03C APB Peripheral Clock Selection Register 1
|
||||
__IO uint32_t HSICR; //!< 0x040 HSI Control Register
|
||||
__IO uint32_t HSIATCR; //!< 0x044 HSI Auto Trimming Counter Register
|
||||
|
||||
uint32_t RESERVED2[174]; //!< 0x048 ~ 0x2FC Reserved
|
||||
__IO uint32_t LPCR; //!< 0x300 Low Power Control Register
|
||||
__IO uint32_t MCUDBGCR; //!< 0x304 MCU Debug Control Register
|
||||
} CKCU_TypeDef;
|
||||
|
||||
#define CKCU_GCFGR_LPMOD_MASK (7U << 29)
|
||||
#define CKCU_GCFGR_USBPRE_MASK (3U << 22)
|
||||
#define CKCU_GCFGR_PLLSRC (1U << 8)
|
||||
#define CKCU_GCFGR_CKOUTSRC_MASK (7U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_REF (0U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_AHB (1U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_SYS (2U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_HSE (3U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_HSI (4U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_LSE (5U << 0)
|
||||
#define CKCU_GCFGR_CKOUTSRC_CK_LSI (6U << 0)
|
||||
#define CKCU_GCCR_PSRCEN (1U << 17)
|
||||
#define CKCU_GCCR_CKMEN (1U << 16)
|
||||
#define CKCU_GCCR_HSIEN (1U << 11)
|
||||
#define CKCU_GCCR_HSEEN (1U << 10)
|
||||
#define CKCU_GCCR_PLLEN (1U << 9)
|
||||
#define CKCU_GCCR_SW_MASK (3U << 0)
|
||||
#define CKCU_GCCR_SW_PLL (1U << 0)
|
||||
#define CKCU_GCCR_SW_HSE (2U << 0)
|
||||
#define CKCU_GCCR_SW_HSI (3U << 0)
|
||||
#define CKCU_GCSR_LSIRDY (1U << 5)
|
||||
#define CKCU_GCSR_LSERDY (1U << 4)
|
||||
#define CKCU_GCSR_HSIRDY (1U << 3)
|
||||
#define CKCU_GCSR_HSERDY (1U << 2)
|
||||
#define CKCU_GCSR_PLLRDY (1U << 1)
|
||||
#define CKCU_PLLCFGR_PFBD_MASK (0x3fU << 23)
|
||||
#define CKCU_PLLCFGR_POTD_MASK (3U << 21)
|
||||
#define CKCU_PLLCR_PLLBPS (1U << 31)
|
||||
#define CKCU_AHBCFGR_AHBPRE_MASK (3U << 0)
|
||||
#define CKCU_AHBCCR_PAEN (1U << 16)
|
||||
#define CKCU_AHBCCR_CRCEN (1U << 13)
|
||||
#define CKCU_AHBCCR_EBIEN (1U << 12)
|
||||
#define CKCU_AHBCCR_CKREFEN (1U << 11)
|
||||
#define CKCU_AHBCCR_USBEN (1U << 10)
|
||||
#define CKCU_APBCFGR_ADCDIV_MASK (7U << 16)
|
||||
#define CKCU_APBCCR0_I2SEN (1U << 25)
|
||||
#define CKCU_APBCCR0_SCIEN (1U << 24)
|
||||
#define CKCU_APBCCR0_EXTIEN (1U << 15)
|
||||
#define CKCU_APBCCR0_AFIOEN (1U << 14)
|
||||
#define CKCU_APBCCR0_UR1EN (1U << 11)
|
||||
#define CKCU_APBCCR0_UR0EN (1U << 10)
|
||||
#define CKCU_APBCCR0_USR1EN (1U << 9)
|
||||
#define CKCU_APBCCR0_USR0EN (1U << 8)
|
||||
#define CKCU_APBCCR0_SPI1EN (1U << 5)
|
||||
#define CKCU_APBCCR0_SPI0EN (1U << 4)
|
||||
#define CKCU_APBCCR0_I2C1EN (1U << 1)
|
||||
#define CKCU_APBCCR0_I2C0EN (1U << 0)
|
||||
#define CKCU_APBCCR1_ADCEN (1U << 24)
|
||||
#define CKCU_APBCCR1_OPA1EN (1U << 23)
|
||||
#define CKCU_APBCCR1_OPA0EN (1U << 22)
|
||||
#define CKCU_APBCCR1_BFTM1EN (1U << 17)
|
||||
#define CKCU_APBCCR1_BFTM0EN (1U << 16)
|
||||
#define CKCU_APBCCR1_GPTM1EN (1U << 9)
|
||||
#define CKCU_APBCCR1_GPTM0EN (1U << 8)
|
||||
#define CKCU_APBCCR1_BKPREN (1U << 6)
|
||||
#define CKCU_APBCCR1_WDTREN (1U << 4)
|
||||
#define CKCU_APBCCR1_MCTM1EN (1U << 1)
|
||||
#define CKCU_APBCCR1_MCTM0EN (1U << 0)
|
||||
#define CKCU_CKST_CKSWST_MASK (3U << 30)
|
||||
#define CKCU_CKST_HSIST_MASK (7U << 24)
|
||||
#define CKCU_CKST_HSEST_MASK (3U << 16)
|
||||
#define CKCU_CKST_PLLST_MASK (0xfU << 8)
|
||||
#define CKCU_LPCR_USBSLEEP (1U << 8)
|
||||
#define CKCU_LPCR_BKISO (1U << 0)
|
||||
|
||||
// Reset Control Unit
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t GRSR; //!< 0x000 Global Reset Status Register
|
||||
__IO uint32_t AHBPRSTR; //!< 0x004 AHB Peripheral Reset Register
|
||||
__IO uint32_t APBPRSTR0; //!< 0x008 APB Peripheral Reset Register 0
|
||||
__IO uint32_t APBPRSTR1; //!< 0x00C APB Peripheral Reset Register 1
|
||||
} RSTCU_TypeDef;
|
||||
|
||||
#define RSTCU_GRSR_PORSTF (1U << 3)
|
||||
#define RSTCU_GRSR_WDTRSTF (1U << 2)
|
||||
#define RSTCU_GRSR_EXTRSTF (1U << 1)
|
||||
#define RSTCU_GRSR_SYSRSTF (1U << 0)
|
||||
#define RSTCU_AHBPRSTR_PxRST(n) ((1U << 8) << (n))
|
||||
#define RSTCU_AHBPRSTR_CRCRST (1U << 7)
|
||||
#define RSTCU_AHBPRSTR_EBIRST (1U << 6)
|
||||
#define RSTCU_AHBPRSTR_USBRST (1U << 5)
|
||||
#define RSTCU_AHBPRSTR_DMARST (1U << 0)
|
||||
#define RSTCU_APBPRSTR0_I2SRST (1U << 25)
|
||||
#define RSTCU_APBPRSTR0_SCIRST (1U << 24)
|
||||
#define RSTCU_APBPRSTR0_EXTIRST (1U << 15)
|
||||
#define RSTCU_APBPRSTR0_AFIORST (1U << 14)
|
||||
#define RSTCU_APBPRSTR0_UR1RST (1U << 11)
|
||||
#define RSTCU_APBPRSTR0_UR0RST (1U << 10)
|
||||
#define RSTCU_APBPRSTR0_USR1RST (1U << 9)
|
||||
#define RSTCU_APBPRSTR0_USR0RST (1U << 8)
|
||||
#define RSTCU_APBPRSTR0_SPI1RST (1U << 5)
|
||||
#define RSTCU_APBPRSTR0_SPI0RST (1U << 4)
|
||||
#define RSTCU_APBPRSTR0_I2C1RST (1U << 1)
|
||||
#define RSTCU_APBPRSTR0_I2C0RST (1U << 0)
|
||||
#define RSTCU_APBPRSTR1_ADCRST (1U << 24)
|
||||
#define RSTCU_APBPRSTR1_OPA1RST (1U << 23)
|
||||
#define RSTCU_APBPRSTR1_OPA0RST (1U << 22)
|
||||
#define RSTCU_APBPRSTR1_BFTM1RST (1U << 17)
|
||||
#define RSTCU_APBPRSTR1_BFTM0RST (1U << 16)
|
||||
#define RSTCU_APBPRSTR1_GPTM1RST (1U << 9)
|
||||
#define RSTCU_APBPRSTR1_GPTM0RST (1U << 8)
|
||||
#define RSTCU_APBPRSTR1_WDTRST (1U << 4)
|
||||
#define RSTCU_APBPRSTR1_MCTM1RST (1U << 1)
|
||||
#define RSTCU_APBPRSTR1_MCTM0RST (1U << 0)
|
||||
|
||||
// General Purpose I/O
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t DIRCR; //!< 0x000 Data Direction Control Register
|
||||
__IO uint32_t INER; //!< 0x004 Input function enable register
|
||||
__IO uint32_t PUR; //!< 0x008 Pull-Up Selection Register
|
||||
__IO uint32_t PDR; //!< 0x00C Pull-Down Selection Register
|
||||
__IO uint32_t ODR; //!< 0x010 Open Drain Selection Register
|
||||
__IO uint32_t DRVR; //!< 0x014 Drive Current Selection Register
|
||||
__IO uint32_t LOCKR; //!< 0x018 Lock Register
|
||||
__IO uint32_t DINR; //!< 0x01c Data Input Register
|
||||
__IO uint32_t DOUTR; //!< 0x020 Data Output Register
|
||||
__IO uint32_t SRR; //!< 0x024 Output Set and Reset Control Register
|
||||
__IO uint32_t RR; //!< 0x028 Output Reset Control Register
|
||||
} GPIO_TypeDef;
|
||||
|
||||
// Alternate Function Input/Output
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t ESSR[2]; //!< 0x000 ~ 0x004 EXTI Source Selection Register 0 ~ 1
|
||||
uint32_t RESERVE0[6]; //!< 0x008 ~ 0x01C Reserved
|
||||
union {
|
||||
struct {
|
||||
__IO uint32_t GPACFGR[2]; //!< 0x020 ~ 0x024 GPIO Port A Configuration Register 0 ~ 1
|
||||
__IO uint32_t GPBCFGR[2]; //!< 0x028 ~ 0x02C GPIO Port B Configuration Register 0 ~ 1
|
||||
__IO uint32_t GPCCFGR[2]; //!< 0x030 ~ 0x034 GPIO Port C Configuration Register 0 ~ 1
|
||||
__IO uint32_t GPDCFGR[2]; //!< 0x038 ~ 0x03C GPIO Port D Configuration Register 0 ~ 1
|
||||
};
|
||||
// alternate mapping
|
||||
struct {
|
||||
__IO uint32_t GPxCFGR[0][2]; //!< 0x020 ~ 0x03C GPIO Port x Configuration Register 0 ~ 1
|
||||
};
|
||||
};
|
||||
} AFIO_TypeDef;
|
||||
|
||||
// Nested Vectored Interrupt Controller
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// Implemented in Cortex-M3 Headers
|
||||
|
||||
// External Interrupt/Event Controller
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CFGR0; //!< 0x000 EXTI Interrupt 0 Configuration Register
|
||||
__IO uint32_t CFGR1; //!< 0x004 EXTI Interrupt 1 Configuration Register
|
||||
__IO uint32_t CFGR2; //!< 0x008 EXTI Interrupt 2 Configuration Register
|
||||
__IO uint32_t CFGR3; //!< 0x00C EXTI Interrupt 3 Configuration Register
|
||||
__IO uint32_t CFGR4; //!< 0x010 EXTI Interrupt 4 Configuration Register
|
||||
__IO uint32_t CFGR5; //!< 0x014 EXTI Interrupt 5 Configuration Register
|
||||
__IO uint32_t CFGR6; //!< 0x018 EXTI Interrupt 6 Configuration Register
|
||||
__IO uint32_t CFGR7; //!< 0x01C EXTI Interrupt 7 Configuration Register
|
||||
__IO uint32_t CFGR8; //!< 0x020 EXTI Interrupt 8 Configuration Register
|
||||
__IO uint32_t CFGR9; //!< 0x024 EXTI Interrupt 9 Configuration Register
|
||||
__IO uint32_t CFGR10; //!< 0x028 EXTI Interrupt 10 Configuration Register
|
||||
__IO uint32_t CFGR11; //!< 0x02C EXTI Interrupt 11 Configuration Register
|
||||
__IO uint32_t CFGR12; //!< 0x030 EXTI Interrupt 12 Configuration Register
|
||||
__IO uint32_t CFGR13; //!< 0x034 EXTI Interrupt 13 Configuration Register
|
||||
__IO uint32_t CFGR14; //!< 0x038 EXTI Interrupt 14 Configuration Register
|
||||
__IO uint32_t CFGR15; //!< 0x03C EXTI Interrupt 15 Configuration Register
|
||||
__IO uint32_t CR; //!< 0x040 EXTI Interrupt Control Register
|
||||
__IO uint32_t EDGEFLGR; //!< 0x044 EXTI Interrupt Edge Flag Register
|
||||
__IO uint32_t EDGESR; //!< 0x048 EXTI Interrupt Edge Status Register
|
||||
__IO uint32_t SSCR; //!< 0x04C EXTI Interrupt Software Set Command Register
|
||||
__IO uint32_t WAKUPCR; //!< 0x050 EXTI Interrupt Wakeup Control Register
|
||||
__IO uint32_t WAKUPPOLR; //!< 0x054 EXTI Interrupt Wakeup Polarity Register
|
||||
__IO uint32_t WAKUPFLG; //!< 0x058 EXTI Interrupt Wakeup Flag Register
|
||||
} EXTI_TypeDef;
|
||||
|
||||
// Analog To Digital Converter
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Operational Amplifier / Comparator
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CR; //!< 0x000 Comparator Control Register
|
||||
__IO uint32_t VALR; //!< 0x004 Comparator Voltage Reference Register
|
||||
__IO uint32_t IER; //!< 0x008 Comparator Interrupt Enable Register
|
||||
__IO uint32_t TFR; //!< 0x00C Comparator Transition Flag Register
|
||||
} CMP_TypeDef;
|
||||
|
||||
|
||||
// Basic Function Timers
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CR; //!< 0x000 Control Register
|
||||
__IO uint32_t SR; //!< 0x004 Status Register
|
||||
__IO uint32_t CNTR; //!< 0x008 Counter Value Register
|
||||
__IO uint32_t CMP; //!< 0x00C Compare Value Register
|
||||
} BFTM_TypeDef;
|
||||
|
||||
#define BFTM_CR_CEN (1U << 2)
|
||||
#define BFTM_CR_OSM (1U << 1)
|
||||
#define BFTM_CR_MIEN (1U << 0)
|
||||
#define BFTM_SR_MIF (1U << 0)
|
||||
|
||||
// General Purpose Timers
|
||||
// Motor Control Timers
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CNTCFR; //!< 0x000 Timer Counter Configuaration Register
|
||||
__IO uint32_t MDCFR; //!< 0x004 Timer Mode Configuration Register
|
||||
__IO uint32_t TRCFR; //!< 0x008 Timer Trigger Configuration Register
|
||||
uint32_t RESERVED0[1]; //!< 0x00C Reserved
|
||||
__IO uint32_t CTR; //!< 0x010 Timer Counter Register
|
||||
uint32_t RESERVED1[3]; //!< 0x014 ~ 0x01C Reserved
|
||||
__IO uint32_t CHnICFR[4]; //!< 0x020 ~ 0x02C Channel n Input Configuration Register
|
||||
uint32_t RESERVED2[4]; //!< 0x030 ~ 0x03C Reserved
|
||||
__IO uint32_t CHnOCFR[4]; //!< 0x040 ~ 0x04C Channel n Output Configuration Register
|
||||
__IO uint32_t CHCTR; //!< 0x050 Channel Control Register
|
||||
__IO uint32_t CHPOLR; //!< 0x054 Channel Polarity Control Register
|
||||
uint32_t RESERVED3[5]; //!< 0x058 ~ 0x068 Reserved
|
||||
// note: only available as MCTM
|
||||
__IO uint32_t CHBRKCFR; //!< 0x06C Channel Break Configuration Register
|
||||
__IO uint32_t CHBRKCTR; //!< 0x070 Channel Break Control Register
|
||||
// end note
|
||||
__IO uint32_t DICTR; //!< 0x074 Timer PDMA/Interrupt Control Register
|
||||
__IO uint32_t EVGR; //!< 0x078 Timer Event Generator Register
|
||||
__IO uint32_t INTSR; //!< 0x07C Timer Interrupt Status Register
|
||||
__IO uint32_t CNTR; //!< 0x080 Timer Counter Register
|
||||
__IO uint32_t PSCR; //!< 0x084 Timer Prescaler Register
|
||||
__IO uint32_t CRR; //!< 0x088 Timer Counter Reload Register
|
||||
// note: only available as MCTM
|
||||
__IO uint32_t REPR; //!< 0x08C Timer Repetition Register
|
||||
// end note
|
||||
__IO uint32_t CHnCCR[4]; //!< 0x090 ~ 0x09C Channel n Capture/Compare Register
|
||||
__IO uint32_t CHnACR[4]; //!< 0x0A0 ~ 0x0AC Channel n Asymmentric Compare Register
|
||||
} TM_TypeDef;
|
||||
|
||||
#define TM_CNTCFR_CMSEL_MASK (3U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_3 (3U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_2 (2U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_1 (1U << 16)
|
||||
#define TM_CNTCFR_CMSEL_MODE_0 (0U << 16)
|
||||
#define TM_CTR_CHCCDS (1U << 16)
|
||||
#define TM_CTR_COMUS (1U << 9)
|
||||
#define TM_CTR_COMPRE (1U << 8)
|
||||
#define TM_CTR_CRBE (1U << 1)
|
||||
#define TM_CTR_TME (1U << 0)
|
||||
#define TM_CHnOCFR_CHnPRE (1U << 4)
|
||||
#define TM_CHnOCFR_REFnCE (1U << 3)
|
||||
#define TM_CHnOCFR_CHnOM(n) ((((n)>>0)&7)|((((n)>>3)&1)<<8))
|
||||
#define TM_CHBRKCTR_CHMOE (1U << 4)
|
||||
|
||||
// Real Time Clock
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Watchdog Timer
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// I2C
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CR; //!< 0x000 Control Register
|
||||
__IO uint32_t IER; //!< 0x004 Interrupt Enable Register
|
||||
__IO uint32_t ADDR; //!< 0x008 Address Register
|
||||
__IO uint32_t SR; //!< 0x00C Status Register
|
||||
__IO uint32_t SHPGR; //!< 0x010 SCL High Period Generation Register
|
||||
__IO uint32_t SLPGR; //!< 0x014 SCL Low Period Generation Register
|
||||
__IO uint32_t DR; //!< 0x018 Data Register
|
||||
__IO uint32_t TAR; //!< 0x01C Target Register
|
||||
__IO uint32_t ADDMR; //!< 0x020 Address Mask Register
|
||||
__IO uint32_t ADDSR; //!< 0x024 Address Snoop Register
|
||||
__IO uint32_t TOUT; //!< 0x028 Timeout Register
|
||||
} I2C_TypeDef;
|
||||
|
||||
#define I2C_CR_SEQ_FILTER_MASK (3U << 14)
|
||||
#define I2C_CR_SEQ_FILTER_2_PCLK (2U << 14)
|
||||
#define I2C_CR_SEQ_FILTER_1_PCLK (1U << 14)
|
||||
#define I2C_CR_SEQ_FILTER_DISABLE (0U << 14)
|
||||
#define I2C_CR_COMB_FILTER_En (1U << 13)
|
||||
#define I2C_CR_ENTOUT (1U << 12)
|
||||
#define I2C_CR_DMANACK (1U << 10)
|
||||
#define I2C_CR_RXDMAE (1U << 9)
|
||||
#define I2C_CR_TXDMAE (1U << 8)
|
||||
#define I2C_CR_ADRM (1U << 7)
|
||||
#define I2C_CR_I2CEN (1U << 3)
|
||||
#define I2C_CR_GCEN (1U << 2)
|
||||
#define I2C_CR_STOP (1U << 1)
|
||||
#define I2C_CR_AA (1U << 0)
|
||||
#define I2C_IER_RXBFIE (1U << 18)
|
||||
#define I2C_IER_TXDEIE (1U << 17)
|
||||
#define I2C_IER_RXDNEIE (1U << 16)
|
||||
#define I2C_IER_TOUTIE (1U << 11)
|
||||
#define I2C_IER_BUSERRIE (1U << 10)
|
||||
#define I2C_IER_RXNACKIE (1U << 9)
|
||||
#define I2C_IER_ARBLOSIE (1U << 8)
|
||||
#define I2C_IER_GCSIE (1U << 3)
|
||||
#define I2C_IER_ADRSIE (1U << 2)
|
||||
#define I2C_IER_STOIE (1U << 1)
|
||||
#define I2C_IER_STAIE (1U << 0)
|
||||
#define I2C_SR_TXNRX (1U << 21)
|
||||
#define I2C_SR_MASTER (1U << 20)
|
||||
#define I2C_SR_BUSBUSY (1U << 19)
|
||||
#define I2C_SR_RXBF (1U << 18)
|
||||
#define I2C_SR_TXDE (1U << 17)
|
||||
#define I2C_SR_RXDNE (1U << 16)
|
||||
#define I2C_SR_TOUTF (1U << 11)
|
||||
#define I2C_SR_BUSERR (1U << 10)
|
||||
#define I2C_SR_RXNACK (1U << 9)
|
||||
#define I2C_SR_ARBLOS (1U << 8)
|
||||
#define I2C_SR_GCS (1U << 3)
|
||||
#define I2C_SR_ADRS (1U << 2)
|
||||
#define I2C_SR_STO (1U << 1)
|
||||
#define I2C_SR_STA (1U << 0)
|
||||
#define I2C_TAR_RWD (1U << 10)
|
||||
|
||||
// SPI
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CR0; //!< 0x000 Control Register 0
|
||||
__IO uint32_t CR1; //!< 0x004 Control Register 1
|
||||
__IO uint32_t IER; //!< 0x008 Interrupt Enable Register
|
||||
__IO uint32_t CPR; //!< 0x00C Clock Prescaler Register
|
||||
__IO uint32_t DR; //!< 0x010 Data Register
|
||||
__IO uint32_t SR; //!< 0x014 Status Register
|
||||
__IO uint32_t FCR; //!< 0x018 FIFO Control Register
|
||||
__IO uint32_t FSR; //!< 0x01C FIFO Status Register
|
||||
__IO uint32_t FTOCR; //!< 0x020 FIFO Time Out Counter Register
|
||||
} SPI_TypeDef;
|
||||
|
||||
#define SPI_CR0_GUADTEN (1U << 7)
|
||||
#define SPI_CR0_DUALEN (1U << 6)
|
||||
#define SPI_CR0_SSELC (1U << 4)
|
||||
#define SPI_CR0_SELOEN (1U << 3)
|
||||
#define SPI_CR0_SPIEN (1U << 0)
|
||||
#define SPI_CR1_MODE (1U << 14)
|
||||
#define SPI_CR1_SELM (1U << 13)
|
||||
#define SPI_CR1_FIRSTBIT (1U << 12)
|
||||
#define SPI_CR1_SELAP (1U << 11)
|
||||
#define SPI_CR1_FORMAT_MASK (7U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE0 (0x1U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE1 (0x2U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE2 (0x6U << 8)
|
||||
#define SPI_CR1_FORMAT_MODE3 (0x5U << 8)
|
||||
#define SPI_IER_RXBNEIEN (1U << 2)
|
||||
#define SPI_IER_TXBEIEN (1U << 0)
|
||||
#define SPI_SR_RXBNE (1U << 2)
|
||||
#define SPI_SR_TXE (1U << 1)
|
||||
#define SPI_SR_TXBE (1U << 0)
|
||||
#define SPI_FCR_FIFOEN (1U << 10)
|
||||
#define SPI_FSR_TXFS_MASK (0xfU << 0)
|
||||
#define SPI_FSR_RXFS_MASK (0xfU << 4)
|
||||
|
||||
// USART
|
||||
// UART
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t DR; //!< 0x000 Data Register
|
||||
__IO uint32_t CR; //!< 0x004 Control Register
|
||||
// Only USART
|
||||
__IO uint32_t FCR; //!< 0x008 FIFO Control Register
|
||||
__IO uint32_t IER; //!< 0x00C Interrupt Enable Register
|
||||
__IO uint32_t SIFR; //!< 0x010 Status & Interrupt Flag Register
|
||||
|
||||
__IO uint32_t TPR; //!< 0x014 Timing Parameter Register
|
||||
|
||||
__IO uint32_t IrDACR; //!< 0x018 IrDA Control Register
|
||||
__IO uint32_t RS485CR; //!< 0x01C RS485 Control Register
|
||||
__IO uint32_t SYNCR; //!< 0x020 Synchronous Control Register
|
||||
// end note
|
||||
__IO uint32_t DLR; //!< 0x024 Divider Latch Register
|
||||
__IO uint32_t TSTR; //!< 0x028 Debug/Test Register
|
||||
} USART_TypeDef;
|
||||
|
||||
// USART CR
|
||||
#define UART_CR_MODE_MASK (0b11 << 0)
|
||||
#define UART_CR_MODE_NORMAL (0 << 0)
|
||||
#define UART_CR_TRSM (1 << 2)
|
||||
#define UART_CR_HFCEN (1 << 3)
|
||||
#define UART_CR_URTXEN (1 << 4)
|
||||
#define UART_CR_URRXEN (1 << 5)
|
||||
#define UART_CR_TXDMAEN (1 << 6)
|
||||
#define UART_CR_RXDMAEN (1 << 7)
|
||||
#define UART_CR_WLS_MASK (0b11 << 8)
|
||||
#define UART_CR_WLS_7B (0b00 << 8)
|
||||
#define UART_CR_WLS_8B (0b01 << 8)
|
||||
#define UART_CR_WLS_9B (0b10 << 8)
|
||||
#define UART_CR_NSB (1 << 10)
|
||||
#define UART_CR_PBE (1 << 11)
|
||||
#define UART_CR_EPE (1 << 12)
|
||||
#define UART_CR_SPE (1 << 13)
|
||||
#define UART_CR_BCB (1 << 14)
|
||||
#define UART_CR_RTS (1 << 15)
|
||||
// USART FCR (FIFO CR)
|
||||
#define USART_FCR_TXR (1 << 0)
|
||||
#define USART_FCR_RXR (1 << 1)
|
||||
#define USART_FCR_TXTL_MASK (0b11 << 4)
|
||||
#define USART_FCR_RXTL_MASK (0b11 << 6)
|
||||
#define USART_FCR_TXFS_MASK (0xF << 16)
|
||||
#define USART_FCR_RXFS_MASK (0xF << 24)
|
||||
// USART SIFR Status and Interrupt Flag Register
|
||||
#define USART_SIFR_RXDNE (1 << 0)
|
||||
#define USART_SIFR_OEI (1 << 1)
|
||||
#define USART_SIFR_PEI (1 << 2)
|
||||
#define USART_SIFR_FEI (1 << 3)
|
||||
#define USART_SIFR_BII (1 << 4)
|
||||
#define USART_SIFR_RXDR (1 << 5)
|
||||
#define USART_SIFR_RXTOF (1 << 6)
|
||||
#define USART_SIFR_TXDE (1 << 7)
|
||||
#define USART_SIFR_TXC (1 << 8)
|
||||
#define USART_SIFR_RSADDE (1 << 9)
|
||||
#define USART_SIFR_CTSC (1 << 10)
|
||||
#define USART_SIFR_CTSS (1 << 11)
|
||||
// USART IER
|
||||
#define USART_IER_RXDRIE (1 << 0)
|
||||
#define USART_IER_TXDEIE (1 << 1)
|
||||
#define USART_IER_TXCIE (1 << 2)
|
||||
#define USART_IER_OEIE (1 << 3)
|
||||
#define USART_IER_PEIE (1 << 4)
|
||||
#define USART_IER_FEIE (1 << 5)
|
||||
#define USART_IER_BIE (1 << 6)
|
||||
#define USART_IER_RSADDIE (1 << 7)
|
||||
#define USART_IER_RXTOIE (1 << 8)
|
||||
#define USART_IER_CTSIE (1 << 9)
|
||||
|
||||
|
||||
// Smart Card Interface
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// USB
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct {
|
||||
__IO uint32_t CSR; //!< 0x000 USB Control and Status Register
|
||||
__IO uint32_t IER; //!< 0x004 USB Interrupt Enable Register
|
||||
__IO uint32_t ISR; //!< 0x008 USB Interrupt Status Register
|
||||
__IO uint32_t FCR; //!< 0x00C USB Frame Count Register
|
||||
__IO uint32_t DEVAR; //!< 0x010 USB Device Address Register
|
||||
struct {
|
||||
__IO uint32_t CSR; //!< 0x014 USB Endpoint n Control and Status Register
|
||||
__IO uint32_t IER; //!< 0x018 USB Endpoint n Interrupt Enable Register
|
||||
__IO uint32_t ISR; //!< 0x01C USB Endpoint n Interrupt Status Register
|
||||
__IO uint32_t TCR; //!< 0x020 USB Endpoint n Transfer Count Register
|
||||
__IO uint32_t CFGR; //!< 0x024 USB Endpoint n Configuration Register
|
||||
} EP[8];
|
||||
} USB_TypeDef;
|
||||
|
||||
// USBCSR
|
||||
#define USBCSR_FRES (0x002) // Force USB Reset Control
|
||||
#define USBCSR_PDWN (0x004) // Power Down Mode Control
|
||||
#define USBCSR_LPMODE (0x008) // Low-Power Mode Control
|
||||
#define USBCSR_GENRSM (0x020) // Resume Request Generation Control
|
||||
#define USBCSR_RXDP (0x040) // Received DP Line Status
|
||||
#define USBCSR_RXDM (0x080) // Received DM Line Status
|
||||
#define USBCSR_ADRSET (0x100) // Device Address Setting Control
|
||||
#define USBCSR_SRAMRSTC (0x200) // USB SRAM Reset Condition
|
||||
#define USBCSR_DPPUEN (0x400) // DP Pull Up Enable
|
||||
#define USBCSR_DPWKEN (0x800) // DP Wake Up Enable
|
||||
|
||||
// USBIER
|
||||
#define USBIER_UGIE (0x0001) // USB global Interrupt Enable
|
||||
#define USBIER_SOFIE (0x0002) // Start Of Frame Interrupt Enable
|
||||
#define USBIER_URSTIE (0x0004) // USB Reset Interrupt Enable
|
||||
#define USBIER_RSMIE (0x0008) // Resume Interrupt Enable
|
||||
#define USBIER_SUSPIE (0x0010) // Suspend Interrupt Enable
|
||||
#define USBIER_ESOFIE (0x0020) // Expected Start Of Frame Enable
|
||||
#define USBIER_EP0IE (0x0100) // Endpoint 0 Interrupt Enable
|
||||
#define USBIER_EP1IE (0x0200) // Endpoint 1 Interrupt Enable
|
||||
#define USBIER_EP2IE (0x0400) // Endpoint 2 Interrupt Enable
|
||||
#define USBIER_EP3IE (0x0800) // Endpoint 3 Interrupt Enable
|
||||
#define USBIER_EP4IE (0x1000) // Endpoint 4 Interrupt Enable
|
||||
#define USBIER_EP5IE (0x2000) // Endpoint 5 Interrupt Enable
|
||||
#define USBIER_EP6IE (0x4000) // Endpoint 6 Interrupt Enable
|
||||
#define USBIER_EP7IE (0x8000) // Endpoint 7 Interrupt Enable
|
||||
|
||||
// USBISR
|
||||
#define USBISR_SOFIF (0x0002) // Start Of Frame Interrupt Flag
|
||||
#define USBISR_URSTIF (0x0004) // USB Reset Interrupt Flag
|
||||
#define USBISR_RSMIF (0x0008) // Resume Interrupt Flag
|
||||
#define USBISR_SUSPIF (0x0010) // Suspend Interrupt Flag
|
||||
#define USBISR_ESOFIF (0x0020) // Expected Start Of Frame Interrupt
|
||||
#define USBISR_EP0IF (1U << 8) // Endpoint 0 Interrupt Flag
|
||||
#define USBISR_EP1IF (1U << 9) // Endpoint 1 Interrupt Flag
|
||||
#define USBISR_EP2IF (1U << 10) // Endpoint 2 Interrupt Flag
|
||||
#define USBISR_EP3IF (1U << 11) // Endpoint 3 Interrupt Flag
|
||||
#define USBISR_EP4IF (1U << 12) // Endpoint 4 Interrupt Flag
|
||||
#define USBISR_EP5IF (1U << 13) // Endpoint 5 Interrupt Flag
|
||||
#define USBISR_EP6IF (1U << 14) // Endpoint 6 Interrupt Flag
|
||||
#define USBISR_EP7IF (1U << 15) // Endpoint 7 Interrupt Flag
|
||||
#define USBISR_EPnIF (0xFF00) // Endpoint Interrupt Mask
|
||||
|
||||
// USBFCR
|
||||
#define USBFCR_FRNUM (0x7FF) // Frame Number
|
||||
#define USBFCR_SOFLCK (1U << 16) // Start-of-Frame Lock Flag
|
||||
#define USBFCR_LSOF (0x3U << 17) // Lost Start-of-Frame Number
|
||||
|
||||
// USBEPnCSR
|
||||
#define USBEPnCSR_DTGTX (0x01) // Data Toggle Status, for IN transfer
|
||||
#define USBEPnCSR_NAKTX (0x02) // NAK Status, for IN transfer
|
||||
#define USBEPnCSR_STLTX (0x04) // STALL Status, for IN transfer
|
||||
#define USBEPnCSR_DTGRX (0x08) // Data Toggle Status, for OUT transfer
|
||||
#define USBEPnCSR_NAKRX (0x10) // NAK Status, for OUT transfer
|
||||
#define USBEPnCSR_STLRX (0x20) // STALL Status, for OUT transfer
|
||||
|
||||
// USBEPnIER
|
||||
#define USBEPnIER_OTRXIE (0x001) // OUT Token Received Interrupt Enable
|
||||
#define USBEPnIER_ODRXIE (0x002) // OUT Data Received Interrupt Enable
|
||||
#define USBEPnIER_ODOVIE (0x004) // OUT Data Buffer Overrun Interrupt Enable
|
||||
#define USBEPnIER_ITRXIE (0x008) // IN Token Received Interrupt Enable
|
||||
#define USBEPnIER_IDTXIE (0x010) // IN Data Transmitted Interrupt Enable
|
||||
#define USBEPnIER_NAKIE (0x020) // NAK Transmitted Interrupt Enable
|
||||
#define USBEPnIER_STLIE (0x040) // STALL Transmitted Interrupt Enable
|
||||
#define USBEPnIER_UERIE (0x080) // USB Error Interrupt Enable
|
||||
#define USBEPnIER_STRXIE (0x100) // SETUP Token Received Interrupt Enable
|
||||
#define USBEPnIER_SDRXIE (0x200) // SETUP Data Received Interrupt Enable
|
||||
#define USBEPnIER_SDERIE (0x400) // SETUP Data Error Interrupt Enable
|
||||
#define USBEPnIER_ZLRXIE (0x800) // Zero Length Data Received Interrupt Enable
|
||||
|
||||
// USBEPnISR
|
||||
#define USBEPnISR_OTRXIF (0x001) // OUT Token Received Interrupt Flag
|
||||
#define USBEPnISR_ODRXIF (0x002) // OUT Data Received Interrupt Flag
|
||||
#define USBEPnISR_ODOVIF (0x004) // OUT Data Buffer Overrun Interrupt Flag
|
||||
#define USBEPnISR_ITRXIF (0x008) // IN Token Received Interrupt Flag
|
||||
#define USBEPnISR_IDTXIF (0x010) // IN Data Transmitted Interrupt Flag
|
||||
#define USBEPnISR_NAKIF (0x020) // NAK Transmitted Interrupt Flag
|
||||
#define USBEPnISR_STLIF (0x040) // STALL Transmitted Interrupt Flag
|
||||
#define USBEPnISR_UERIF (0x080) // USB Error Interrupt Flag
|
||||
#define USBEPnISR_STRXIF (0x100) // SETUP Token Received Interrupt Flag
|
||||
#define USBEPnISR_SDRXIF (0x200) // SETUP Data Received Interrupt Flag
|
||||
#define USBEPnISR_SDERIF (0x400) // SETUP Data Error Interrupt Flag
|
||||
#define USBEPnISR_ZLRXIF (0x800) // Zero Length Data Received Interrupt Flag
|
||||
|
||||
// USBEPnTCR
|
||||
#define USBEPnTCR_TCNT (0x1FF) // Transfer Byte Count
|
||||
|
||||
// USBEPnCFGR
|
||||
#define USBEPnCFGR_EPEN (1U << 31) // Endpoint Enable
|
||||
#define USBEPnCFGR_EPTYPE (1U << 29) // Transfer Type
|
||||
#define USBEPnCFGR_EPDIR (1U << 28) // Transfer Direction
|
||||
#define USBEPnCFGR_EPADR (0xFU << 24) // Endpoint Address
|
||||
#define USBEPnCFGR_EPLEN (0x7FU << 10) // Buffer Length
|
||||
#define USBEPnCFGR_EPBUFA (0x3FF) // Endpoint Buffer Address
|
||||
|
||||
// Peripheral Direct Memory Access
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Extend Bus Interface
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Inter-IC Sound
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CRC
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) Yaotian Feng, http://github.com/Codetector1374
|
||||
* codetector@codetector.cn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* HT32F1654 memory setup
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
flash0 : org = 0x00000000, len = 32k
|
||||
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 = 8k
|
||||
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,93 @@
|
|||
/*
|
||||
* Copyright (C) Yaotian Feng, http://github.com/Codetector1374
|
||||
* codetector@codetector.cn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* HT32F1654 memory setup
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
flash0 : org = 0x00000000, len = 63k
|
||||
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 = 16k
|
||||
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,93 @@
|
|||
/*
|
||||
* Copyright (C) Yaotian Feng, http://github.com/Codetector1374
|
||||
* codetector@codetector.cn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* HT32F5234x 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 = 8k
|
||||
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,93 @@
|
|||
/*
|
||||
* Copyright (C) Yaotian Feng, http://github.com/Codetector1374
|
||||
* codetector@codetector.cn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* HT32F5235x memory setup
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
flash0 : org = 0x00000000, len = 128k
|
||||
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 = 16k
|
||||
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,22 @@
|
|||
# ChibiOS/RT - Copyright (c) 2020 Yaotian Feng
|
||||
# startup_ht32f165x.mk - Makefile for Holtek HT32F165x series uC.
|
||||
|
||||
|
||||
# List of the ChibiOS generic HT32F165x startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.S \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.S
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld \
|
||||
$(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/devices/HT32F165x \
|
||||
$(CHIBIOS)/os/common/ext/ARM/CMSIS/Core/Include \
|
||||
$(CHIBIOS_CONTRIB)/os/common/ext/CMSIS/HT32/HT32F165x
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD_CONTRIB = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
||||
ALLXASMSRC += $(STARTUPASM)
|
||||
ALLCSRC += $(STARTUPSRC)
|
||||
ALLINC += $(STARTUPINC)
|
|
@ -0,0 +1,22 @@
|
|||
# ChibiOS/RT - Copyright (c) 2020 Yaotian Feng
|
||||
# startup_ht32f165x.mk - Makefile for Holtek HT32F523x2 series uC.
|
||||
|
||||
|
||||
# List of the ChibiOS generic HT32F523x2 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)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld \
|
||||
$(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/devices/HT32F523xx \
|
||||
$(CHIBIOS)/os/common/ext/ARM/CMSIS/Core/Include \
|
||||
$(CHIBIOS_CONTRIB)/os/common/ext/CMSIS/HT32/HT32F523xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD_CONTRIB = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
||||
ALLXASMSRC += $(STARTUPASM)
|
||||
ALLCSRC += $(STARTUPSRC)
|
||||
ALLINC += $(STARTUPINC)
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio.
|
||||
(C) 2015 RedoX https://github.com/RedoXyde
|
||||
(C) 2017 Charlie Waters <cawiii@me.com>
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file GCC/ARMCMx/HT32F165x/cmparams.h
|
||||
* @brief ARM Cortex-M3 parameters for the Holtek HT32F165x
|
||||
*
|
||||
* @defgroup ARMCMx_HT32F165x Holtek HT32F165x Specific Parameters
|
||||
* @ingroup ARMCMx_SPECIFIC
|
||||
* @details This file contains the Cortex-M3 specific parameters for the
|
||||
* Holtek HT32F165x platform.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CMPARAMS_H_
|
||||
#define _CMPARAMS_H_
|
||||
|
||||
/**
|
||||
* @brief Cortex core model.
|
||||
*/
|
||||
#define CORTEX_MODEL 3
|
||||
|
||||
/**
|
||||
* @brief Systick unit presence.
|
||||
*/
|
||||
#define CORTEX_HAS_ST TRUE
|
||||
|
||||
/**
|
||||
* @brief Floating Point unit presence.
|
||||
*/
|
||||
#define CORTEX_HAS_FPU FALSE
|
||||
|
||||
/**
|
||||
* @brief Number of bits in priority masks.
|
||||
*/
|
||||
#define CORTEX_PRIORITY_BITS 4
|
||||
|
||||
/**
|
||||
* @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 72
|
||||
|
||||
/* The following code is not processed when the file is included from an
|
||||
asm module.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
#if !defined (HT32F1653) && !defined (HT32F1654) && \
|
||||
!defined (HT32F1655) && !defined (HT32F1656)
|
||||
#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 "ht32f165x.h"
|
||||
|
||||
#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
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _CMPARAMS_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio.
|
||||
(C) 2015 RedoX https://github.com/RedoXyde
|
||||
(C) 2017 Charlie Waters <cawiii@me.com>
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file GCC/ARMCMx/HT32F165x/cmparams.h
|
||||
* @brief ARM Cortex-M3 parameters for the Holtek HT32F165x
|
||||
*
|
||||
* @defgroup ARMCMx_HT32F165x Holtek HT32F165x Specific Parameters
|
||||
* @ingroup ARMCMx_SPECIFIC
|
||||
* @details This file contains the Cortex-M3 specific parameters for the
|
||||
* Holtek HT32F165x platform.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CMPARAMS_H_
|
||||
#define _CMPARAMS_H_
|
||||
|
||||
/**
|
||||
* @brief Cortex core model.
|
||||
*/
|
||||
#define CORTEX_MODEL 0
|
||||
|
||||
/**
|
||||
* @brief Systick unit presence.
|
||||
*/
|
||||
#define CORTEX_HAS_ST TRUE
|
||||
|
||||
/**
|
||||
* @brief Floating Point unit presence.
|
||||
*/
|
||||
#define CORTEX_HAS_FPU FALSE
|
||||
|
||||
/**
|
||||
* @brief Number of bits in priority masks.
|
||||
*/
|
||||
#define CORTEX_PRIORITY_BITS 8
|
||||
|
||||
/**
|
||||
* @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 !defined (HT32F52342) && !defined(HT32F52352)
|
||||
#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 "ht32f523x2.h"
|
||||
|
||||
#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
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _CMPARAMS_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_lld.c
|
||||
* @brief PLATFORM HAL subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
void ht32_clock_init(void) {
|
||||
// Enable backup domain. Needed for USB
|
||||
CKCU->LPCR = CKCU_LPCR_BKISO;
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_BKPREN;
|
||||
while (PWRCU->BAKTEST != 0x27);
|
||||
|
||||
#if HT32_CKCU_SW == CKCU_GCCR_SW_HSE
|
||||
// Enable HSE
|
||||
CKCU->GCCR |= CKCU_GCCR_HSEEN;
|
||||
while ((CKCU->GCSR & CKCU_GCSR_HSERDY) == 0); // wait for HSE ready
|
||||
#endif
|
||||
|
||||
#if HT32_CKCU_SW == CKCU_GCCR_SW_PLL
|
||||
// Configure PLL
|
||||
#if HT32_PLL_USE_HSE == TRUE
|
||||
CKCU->GCFGR &= ~CKCU_GCFGR_PLLSRC; // HSE as PLL source
|
||||
#else
|
||||
CKCU->GCFGR |= CKCU_GCFGR_PLLSRC; // HSI as PLL source
|
||||
#endif
|
||||
CKCU->PLLCFGR = ((HT32_PLL_FBDIV & 0x3F) << 23) | ((HT32_PLL_OTDIV & 0x3) << 21);
|
||||
CKCU->GCCR |= CKCU_GCCR_PLLEN; // enable PLL
|
||||
while ((CKCU->GCSR & CKCU_GCSR_PLLRDY) == 0); // wait for PLL ready
|
||||
#endif
|
||||
|
||||
// flash wait states for core clock frequencies
|
||||
#if HT32_CK_AHB_FREQUENCY > 48000000
|
||||
FMC->CFCR = (FMC->CFCR & ~FMC_CFCR_WAIT_MASK) | FMC_CFCR_WAIT_2;
|
||||
#elif HT32_CK_AHB_FREQUENCY > 24000000
|
||||
FMC->CFCR = (FMC->CFCR & ~FMC_CFCR_WAIT_MASK) | FMC_CFCR_WAIT_1;
|
||||
#else
|
||||
FMC->CFCR = (FMC->CFCR & ~FMC_CFCR_WAIT_MASK) | FMC_CFCR_WAIT_0;
|
||||
#endif
|
||||
|
||||
// AHB prescaler
|
||||
#if HT32_AHB_PRESCALER == 1 || HT32_AHB_PRESCALER == 2
|
||||
CKCU->AHBCFGR = (CKCU->AHBCFGR & ~CKCU_AHBCFGR_AHBPRE_MASK) | (HT32_AHB_PRESCALER - 1);
|
||||
#elif HT32_AHB_PRESCALER == 4
|
||||
CKCU->AHBCFGR = (CKCU->AHBCFGR & ~CKCU_AHBCFGR_AHBPRE_MASK) | (2);
|
||||
#elif HT32_AHB_PRESCALER == 8
|
||||
CKCU->AHBCFGR = (CKCU->AHBCFGR & ~CKCU_AHBCFGR_AHBPRE_MASK) | (3);
|
||||
#else
|
||||
#error "Invalid AHB_PRESCALER value"
|
||||
#endif
|
||||
|
||||
// Clock switch
|
||||
CKCU->GCCR = (CKCU->GCCR & ~CKCU_GCCR_SW_MASK) | HT32_CKCU_SW;
|
||||
while ((CKCU->GCCR & CKCU_GCCR_SW_MASK) != HT32_CKCU_SW); // wait for clock switch
|
||||
|
||||
// HSI is needed for flash erase/write for some reason.
|
||||
// Only disable if you will not need to erase/write memory
|
||||
// with your debug probe after this firmware has booted.
|
||||
// /* CKCU->GCCR &= ~CKCU_GCCR_HSIEN; */
|
||||
|
||||
#if defined(HT32F1653_4)
|
||||
// Peripheral prescalers are not available on HT32F1655/6
|
||||
// So make sure all prescalers are 1x on HT32F1653/4
|
||||
CKCU->APBPCSR0 = 0;
|
||||
CKCU->APBPCSR1 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level HAL driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void hal_lld_init(void) {
|
||||
ht32_clock_init();
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_lld.h
|
||||
* @brief HT32 HAL subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HAL_LLD_H_
|
||||
#define _HAL_LLD_H_
|
||||
|
||||
#include "ht32_registry.h"
|
||||
#include "nvic.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Platform identification macros
|
||||
* @{
|
||||
*/
|
||||
#define PLATFORM_NAME "HT32"
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Configuration-related checks.
|
||||
*/
|
||||
#if !defined(HT32F165x_MCUCONF) && !defined(HT32F1654_MCUCONF) && \
|
||||
!defined(HT32F1653_MCUCONF)
|
||||
#error "Using a wrong mcuconf.h file, HT32_MCUCONF not defined"
|
||||
#endif
|
||||
|
||||
#define HT32_CK_HSI_FREQUENCY 8000000UL // 8 MHz
|
||||
|
||||
#if HT32_CKCU_SW == CKCU_GCCR_SW_HSI
|
||||
#define HT32_CK_SYS_FREQUENCY HT32_CK_HSI_FREQUENCY
|
||||
|
||||
#elif HT32_CKCU_SW == CKCU_GCCR_SW_HSE
|
||||
#if !defined(HT32_CK_HSE_FREQUENCY)
|
||||
#error "HT32_CK_HSE_FREQUENCY must be defined"
|
||||
#endif
|
||||
#define HT32_CK_SYS_FREQUENCY HT32_CK_HSE_FREQUENCY
|
||||
|
||||
#elif HT32_CKCU_SW == CKCU_GCCR_SW_PLL
|
||||
#if !defined(HT32_PLL_USE_HSE)
|
||||
#error "HT32_PLL_USE_HSE must be defined"
|
||||
#endif
|
||||
|
||||
#if HT32_PLL_USE_HSE == TRUE
|
||||
#if !defined(HT32_CK_HSE_FREQUENCY)
|
||||
#error "HT32_CK_HSE_FREQUENCY must be defined"
|
||||
#endif
|
||||
#define HT32_PLL_IN_FREQ HT32_CK_HSE_FREQUENCY
|
||||
#else
|
||||
#define HT32_PLL_IN_FREQ HT32_CK_HSI_FREQUENCY
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_PLL_FBDIV)
|
||||
#error "HT32_PLL_FBDIV must be defined"
|
||||
#endif
|
||||
#if !defined(HT32_PLL_OTDIV)
|
||||
#error "HT32_PLL_OTDIV must be defined"
|
||||
#endif
|
||||
|
||||
#define HT32_CK_PLL_FREQUENCY ((HT32_PLL_IN_FREQ * HT32_PLL_FBDIV) / (1 << HT32_PLL_OTDIV))
|
||||
#define HT32_CK_SYS_FREQUENCY HT32_CK_PLL_FREQUENCY
|
||||
|
||||
#else
|
||||
#error "HT32_CKCU_SW is invalid"
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_AHB_PRESCALER)
|
||||
#define HT32_AHB_PRESCALER 1
|
||||
#endif
|
||||
|
||||
// AHB clock
|
||||
#define HT32_CK_AHB_FREQUENCY (HT32_CK_SYS_FREQUENCY / HT32_AHB_PRESCALER) // Max 72 MHz
|
||||
// SysTick (may also use HCLK)
|
||||
#define HT32_STCLK_FREQUENCY (HT32_CK_AHB_FREQUENCY / 8) // Max 8MHz
|
||||
// CPU clock
|
||||
#define HT32_HCLK_FREQUENCY HT32_CK_AHB_FREQUENCY
|
||||
// Peripheral clocks
|
||||
#define HT32_PCLK_FREQUENCY HT32_CK_AHB_FREQUENCY
|
||||
|
||||
// Checks
|
||||
#if HT32_CK_SYS_FREQUENCY > 144000000
|
||||
#error "HT32 CK_SYS invalid"
|
||||
#endif
|
||||
#if HT32_CK_AHB_FREQUENCY > 72000000
|
||||
#error "HT32 CK_AHB invalid"
|
||||
#endif
|
||||
|
||||
#if (HAL_USE_UART == TRUE || HAL_USE_SERIAL == TRUE)
|
||||
#define HT32_CK_USART_FREQUENCY (HT32_CK_AHB_FREQUENCY / HT32_USART_PRESCALER) // Max 72 MHz
|
||||
#if HT32_CK_USART_FREQUENCY > 72000000
|
||||
#error "HT32 CK_USART invalid"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAL_USE_USB == TRUE
|
||||
#if HT32_CKCU_SW != CKCU_GCCR_SW_PLL
|
||||
#error "HT32 USB requires PLL"
|
||||
#endif
|
||||
#define HT32_CK_USB_FREQUENCY (HT32_CK_PLL_FREQUENCY / HT32_USB_PRESCALER) // Max 48 MHz
|
||||
|
||||
#if HT32_CK_USB_FREQUENCY > 48000000
|
||||
#error "HT32 CK_USB invalid"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void hal_lld_init(void);
|
||||
void ht32_clock_init(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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 HT32F165x/ht32_registry.h
|
||||
* @brief HT32F165x capabilities registry.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HT32_REGISTRY_H
|
||||
#define HT32_REGISTRY_H
|
||||
|
||||
/**
|
||||
* @brief Sub-family identifier.
|
||||
*/
|
||||
#if defined(HT32F1653) || defined(HT32F1654) || \
|
||||
defined(HT32F1655) || defined(HT32F1656) || \
|
||||
defined(__DOXYGEN__)
|
||||
#define HT32F165x
|
||||
#else
|
||||
#error unknown/unsupported HT32 microcontroller
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Platform capabilities. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(HT32F165x) || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Maximum system and core clock (f_SYS) frequency.
|
||||
*/
|
||||
#define HT32_SYSCLK_MAX 72000000L
|
||||
|
||||
/**
|
||||
* @brief Maximum bus clock (f_BUS) frequency.
|
||||
*/
|
||||
#define HT32_BUSCLK_MAX 72000000L
|
||||
|
||||
/**
|
||||
* @brief Maximum flash clock (f_FLASH) frequency.
|
||||
*/
|
||||
#define HT32_FLASHCLK_MAX 72000000L
|
||||
|
||||
/**
|
||||
* @name HT32F165x attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* GPIO attributes.*/
|
||||
#if defined(HT32F1655) || defined(HT32F1656)
|
||||
#define HT32_NUM_GPIO 5
|
||||
#else
|
||||
#define HT32_NUM_GPIO 4
|
||||
#endif
|
||||
#define HT32_GPIO_INDEX_BITS 13
|
||||
#define HT32_CCR_PAEN CKCU_AHBCCR_PAEN
|
||||
|
||||
/* EXTI attributes */
|
||||
#define HT32_HAS_EXTI TRUE
|
||||
#define HT32_NUM_EXTI 16
|
||||
#define HT32_EVWUP_IRQ_VECTOR Vector58
|
||||
#define HT32_EXTI0_IRQ_VECTOR Vector60
|
||||
#define HT32_EXTI1_IRQ_VECTOR Vector64
|
||||
#define HT32_EXTI2_IRQ_VECTOR Vector68
|
||||
#define HT32_EXTI3_IRQ_VECTOR Vector6C
|
||||
#define HT32_EXTI4_IRQ_VECTOR Vector70
|
||||
#define HT32_EXTI5_IRQ_VECTOR Vector74
|
||||
#define HT32_EXTI6_IRQ_VECTOR Vector78
|
||||
#define HT32_EXTI7_IRQ_VECTOR Vector7C
|
||||
#define HT32_EXTI8_IRQ_VECTOR Vector80
|
||||
#define HT32_EXTI9_IRQ_VECTOR Vector84
|
||||
#define HT32_EXTI10_IRQ_VECTOR Vector88
|
||||
#define HT32_EXTI11_IRQ_VECTOR Vector8C
|
||||
#define HT32_EXTI12_IRQ_VECTOR Vector90
|
||||
#define HT32_EXTI13_IRQ_VECTOR Vector94
|
||||
#define HT32_EXTI14_IRQ_VECTOR Vector98
|
||||
#define HT32_EXTI15_IRQ_VECTOR Vector9C
|
||||
|
||||
/* I2C attributes.*/
|
||||
#define HT32_HAS_I2C0 TRUE
|
||||
#define HT32_I2C0_IRQ_VECTOR VectorEC
|
||||
#define HT32_HAS_I2C1 TRUE
|
||||
#define HT32_I2C1_IRQ_VECTOR VectorF0
|
||||
|
||||
/* SPI attributes.*/
|
||||
#define HT32_HAS_SPI0 TRUE
|
||||
#define HT32_SPI0_IRQ_VECTOR VectorF4
|
||||
#define HT32_HAS_SPI1 TRUE
|
||||
#define HT32_SPI1_IRQ_VECTOR VectorF8
|
||||
|
||||
/* UART attributes.*/
|
||||
#define HT32_HAS_USART0 TRUE
|
||||
#define HT32_USART0_IRQ_VECTOR VectorFC
|
||||
#define HT32_HAS_USART1 TRUE
|
||||
#define HT32_USART1_IRQ_VECTOR Vector100
|
||||
#define HT32_HAS_UART0 TRUE
|
||||
#define HT32_UART0_IRQ_VECTOR Vector104
|
||||
#define HT32_HAS_UART1 TRUE
|
||||
#define HT32_UART1_IRQ_VECTOR Vector108
|
||||
|
||||
/* USB attributes.*/
|
||||
#define HT32_HAS_USB TRUE
|
||||
#define HT32_USB_IRQ_VECTOR Vector114
|
||||
#define HT32_USB0_IS_USBOTG FALSE
|
||||
#define HT32_HAS_USB_CLOCK_RECOVERY FALSE
|
||||
|
||||
/* BFTM attributes. */
|
||||
#define HT32_BFTM0_IRQ_VECTOR VectorE4
|
||||
#define HT32_BFTM1_IRQ_VECTOR VectorE8
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* defined(HT32F165x) */
|
||||
|
||||
#endif /* HT32_REGISTRY_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,35 @@
|
|||
# List of all the platform files.
|
||||
PLATFORMSRC = $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
|
||||
$(CHIBIOS_CONTRIB)/os/hal/ports/HT32/HT32F165x/hal_lld.c
|
||||
|
||||
|
||||
# Required include directories
|
||||
PLATFORMINC = $(CHIBIOS)/os/hal/ports/common/ARMCMx \
|
||||
$(CHIBIOS_CONTRIB)/os/hal/ports/HT32/HT32F165x
|
||||
|
||||
# Optional platform files.
|
||||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
|
||||
# Configuration files directory
|
||||
ifeq ($(HALCONFDIR),)
|
||||
ifeq ($(CONFDIR),)
|
||||
HALCONFDIR = .
|
||||
else
|
||||
HALCONFDIR := $(CONFDIR)
|
||||
endif
|
||||
endif
|
||||
|
||||
HALCONF := $(strip $(shell cat $(HALCONFDIR)/halconf.h | egrep -e "\#define"))
|
||||
endif #ifeq ($(USE_SMART_BUILD), yes)
|
||||
|
||||
# Drivers compatible with the platform.
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/SPIv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/GPIOv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USBv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F165x/driver.mk
|
||||
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(PLATFORMSRC)
|
||||
ALLINC += $(PLATFORMINC)
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_lld.c
|
||||
* @brief PLATFORM HAL subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
void ht32_clock_init(void) {
|
||||
// Enable backup domain. Needed for USB
|
||||
CKCU->LPCR = CKCU_LPCR_BKISO;
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_BKPREN;
|
||||
while (PWRCU->BAKTEST != 0x27);
|
||||
|
||||
#if HT32_CKCU_SW == CKCU_GCCR_SW_HSE
|
||||
// Enable HSE
|
||||
CKCU->GCCR |= CKCU_GCCR_HSEEN;
|
||||
while ((CKCU->GCSR & CKCU_GCSR_HSERDY) == 0); // wait for HSE ready
|
||||
#endif
|
||||
|
||||
#if HT32_CKCU_SW == CKCU_GCCR_SW_PLL
|
||||
// Configure PLL
|
||||
#if HT32_PLL_USE_HSE == TRUE
|
||||
CKCU->GCFGR &= ~CKCU_GCFGR_PLLSRC; // HSE as PLL source
|
||||
#else
|
||||
CKCU->GCFGR |= CKCU_GCFGR_PLLSRC; // HSI as PLL source
|
||||
#endif
|
||||
CKCU->PLLCFGR = ((HT32_PLL_FBDIV & 0x3F) << 23) | ((HT32_PLL_OTDIV & 0x3) << 21);
|
||||
CKCU->GCCR |= CKCU_GCCR_PLLEN; // enable PLL
|
||||
while ((CKCU->GCSR & CKCU_GCSR_PLLRDY) == 0); // wait for PLL ready
|
||||
#endif
|
||||
|
||||
// flash wait states for core clock frequencies
|
||||
#if HT32_CK_AHB_FREQUENCY > 24000000
|
||||
FMC->CFCR = (FMC->CFCR & ~FMC_CFCR_WAIT_MASK) | FMC_CFCR_WAIT_1;
|
||||
#else
|
||||
FMC->CFCR = (FMC->CFCR & ~FMC_CFCR_WAIT_MASK) | FMC_CFCR_WAIT_0;
|
||||
#endif
|
||||
|
||||
// AHB prescaler
|
||||
#if HT32_AHB_PRESCALER == 1 || HT32_AHB_PRESCALER == 2
|
||||
CKCU->AHBCFGR = (CKCU->AHBCFGR & ~CKCU_AHBCFGR_AHBPRE_MASK) | (HT32_AHB_PRESCALER - 1);
|
||||
#elif HT32_AHB_PRESCALER == 4
|
||||
CKCU->AHBCFGR = (CKCU->AHBCFGR & ~CKCU_AHBCFGR_AHBPRE_MASK) | (2);
|
||||
#elif HT32_AHB_PRESCALER == 8
|
||||
CKCU->AHBCFGR = (CKCU->AHBCFGR & ~CKCU_AHBCFGR_AHBPRE_MASK) | (3);
|
||||
#else
|
||||
#error "Invalid AHB_PRESCALER value"
|
||||
#endif
|
||||
|
||||
// Clock switch
|
||||
CKCU->GCCR = (CKCU->GCCR & ~CKCU_GCCR_SW_MASK) | HT32_CKCU_SW;
|
||||
while ((CKCU->GCCR & CKCU_GCCR_SW_MASK) != HT32_CKCU_SW); // wait for clock switch
|
||||
|
||||
// HSI is needed for flash erase/write for some reason.
|
||||
// Only disable if you will not need to erase/write memory
|
||||
// with your debug probe after this firmware has booted.
|
||||
// /* CKCU->GCCR &= ~CKCU_GCCR_HSIEN; */
|
||||
|
||||
#if defined(HT32F1653_4)
|
||||
// Peripheral prescalers are not available on HT32F1655/6
|
||||
// So make sure all prescalers are 1x on HT32F1653/4
|
||||
CKCU->APBPCSR0 = 0;
|
||||
CKCU->APBPCSR1 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level HAL driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void hal_lld_init(void) {
|
||||
CKCU->APBCCR0 &= ~(CKCU_APBCCR0_EXTIEN | CKCU_APBCCR0_UR0EN | CKCU_APBCCR0_USR0EN | CKCU_APBCCR0_UR1EN | CKCU_APBCCR0_USR1EN);
|
||||
ht32_clock_init();
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_lld.h
|
||||
* @brief HT32 HAL subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HAL_LLD_H_
|
||||
#define _HAL_LLD_H_
|
||||
|
||||
#include "ht32_registry.h"
|
||||
#include "nvic.h"
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Platform identification macros
|
||||
* @{
|
||||
*/
|
||||
#define PLATFORM_NAME "HT32"
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Configuration-related checks.
|
||||
*/
|
||||
#if !defined(HT32F52342_MCUCONF) && !defined(HT32F52352_MCUCONF) && \
|
||||
!defined(HT32F523x2_MCUCONF)
|
||||
#error "Using a wrong mcuconf.h file, HT32_MCUCONF not defined"
|
||||
#endif
|
||||
|
||||
#define HT32_CK_HSI_FREQUENCY 8000000UL // 8 MHz
|
||||
|
||||
#if HT32_CKCU_SW == CKCU_GCCR_SW_HSI
|
||||
#define HT32_CK_SYS_FREQUENCY HT32_CK_HSI_FREQUENCY
|
||||
|
||||
#elif HT32_CKCU_SW == CKCU_GCCR_SW_HSE
|
||||
#if !defined(HT32_CK_HSE_FREQUENCY)
|
||||
#error "HT32_CK_HSE_FREQUENCY must be defined"
|
||||
#endif
|
||||
#define HT32_CK_SYS_FREQUENCY HT32_CK_HSE_FREQUENCY
|
||||
|
||||
#elif HT32_CKCU_SW == CKCU_GCCR_SW_PLL
|
||||
#if !defined(HT32_PLL_USE_HSE)
|
||||
#error "HT32_PLL_USE_HSE must be defined"
|
||||
#endif
|
||||
|
||||
#if HT32_PLL_USE_HSE == TRUE
|
||||
#if !defined(HT32_CK_HSE_FREQUENCY)
|
||||
#error "HT32_CK_HSE_FREQUENCY must be defined"
|
||||
#endif
|
||||
#define HT32_PLL_IN_FREQ HT32_CK_HSE_FREQUENCY
|
||||
#else
|
||||
#define HT32_PLL_IN_FREQ HT32_CK_HSI_FREQUENCY
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_PLL_FBDIV)
|
||||
#error "HT32_PLL_FBDIV must be defined"
|
||||
#endif
|
||||
#if !defined(HT32_PLL_OTDIV)
|
||||
#error "HT32_PLL_OTDIV must be defined"
|
||||
#endif
|
||||
|
||||
#define HT32_CK_PLL_FREQUENCY ((HT32_PLL_IN_FREQ * HT32_PLL_FBDIV) / (1 << HT32_PLL_OTDIV))
|
||||
#define HT32_CK_SYS_FREQUENCY HT32_CK_PLL_FREQUENCY
|
||||
|
||||
#else
|
||||
#error "HT32_CKCU_SW is invalid"
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_AHB_PRESCALER)
|
||||
#define HT32_AHB_PRESCALER 1
|
||||
#endif
|
||||
|
||||
// AHB clock
|
||||
#define HT32_CK_AHB_FREQUENCY (HT32_CK_SYS_FREQUENCY / HT32_AHB_PRESCALER) // Max 48 MHz
|
||||
// SysTick (may also use HCLK)
|
||||
#define HT32_STCLK_FREQUENCY (HT32_CK_AHB_FREQUENCY / 8) // Max 8MHz
|
||||
// CPU clock
|
||||
#define HT32_HCLK_FREQUENCY HT32_CK_AHB_FREQUENCY
|
||||
// Peripheral clocks
|
||||
#define HT32_PCLK_FREQUENCY HT32_CK_AHB_FREQUENCY
|
||||
|
||||
// Checks
|
||||
#if HT32_CK_SYS_FREQUENCY > 48000000
|
||||
#error "HT32 CK_SYS invalid"
|
||||
#endif
|
||||
#if HT32_CK_AHB_FREQUENCY > 48000000
|
||||
#error "HT32 CK_AHB invalid"
|
||||
#endif
|
||||
|
||||
#if HAL_USE_UART == TRUE || HAL_USE_SERIAL == TRUE
|
||||
#define HT32_CK_USART_FREQUENCY (HT32_CK_AHB_FREQUENCY / HT32_USART_PRESCALER) // Max 48 MHz
|
||||
|
||||
#if HT32_CK_USART_FREQUENCY > 48000000
|
||||
#error "HT32 CK_USART invalid"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAL_USE_USB == TRUE
|
||||
#if HT32_CKCU_SW != CKCU_GCCR_SW_PLL
|
||||
#error "HT32 USB requires PLL"
|
||||
#endif
|
||||
#define HT32_CK_USB_FREQUENCY (HT32_CK_PLL_FREQUENCY / HT32_USB_PRESCALER) // Max 48 MHz
|
||||
|
||||
#if HT32_CK_USB_FREQUENCY > 48000000
|
||||
#error "HT32 CK_USB invalid"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void hal_lld_init(void);
|
||||
void ht32_clock_init(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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 HT32F165x/ht32_registry.h
|
||||
* @brief HT32F165x capabilities registry.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sub-family identifier.
|
||||
*/
|
||||
#if defined(HT32F52342) || defined(HT32F52352) || \
|
||||
defined(__DOXYGEN__)
|
||||
#define HT32F523x2
|
||||
#else
|
||||
#error unknown/unsupported HT32 microcontroller
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Platform capabilities. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(HT32F523x2) || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Maximum system and core clock (f_SYS) frequency.
|
||||
*/
|
||||
#define HT32_SYSCLK_MAX 48000000L
|
||||
|
||||
/**
|
||||
* @brief Maximum bus clock (f_BUS) frequency.
|
||||
*/
|
||||
#define HT32_BUSCLK_MAX 48000000L
|
||||
|
||||
/**
|
||||
* @brief Maximum flash clock (f_FLASH) frequency.
|
||||
*/
|
||||
#define HT32_FLASHCLK_MAX 48000000L
|
||||
|
||||
/**
|
||||
* @name HT32F52342x attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* GPIO attributes.*/
|
||||
|
||||
#define HT32_NUM_GPIO 4
|
||||
#define HT32_GPIO_INDEX_BITS 13
|
||||
#define HT32_CCR_PAEN CKCU_AHBCCR_PAEN
|
||||
|
||||
/* EXTI attributes */
|
||||
#define HT32_HAS_EXTI TRUE
|
||||
#define HT32_NUM_EXTI 3
|
||||
#define HT32_EVWUP_IRQ_VECTOR Vector4C
|
||||
#define HT32_EXTI0_1_IRQ_VECTOR Vector50
|
||||
#define HT32_EXTI2_3_IRQ_VECTOR Vector54
|
||||
#define HT32_EXTI4_15_IRQ_VECTOR Vector58
|
||||
|
||||
/* BFTM attributes. */
|
||||
#define HT32_BFTM0_IRQ_VECTOR Vector84
|
||||
#define HT32_BFTM1_IRQ_VECTOR Vector88
|
||||
|
||||
/* I2C attributes.*/
|
||||
#define HT32_HAS_I2C0 TRUE
|
||||
#define HT32_I2C0_IRQ_VECTOR Vector8C
|
||||
#define HT32_HAS_I2C1 TRUE
|
||||
#define HT32_I2C1_IRQ_VECTOR Vector90
|
||||
|
||||
/* SPI attributes.*/
|
||||
#define HT32_HAS_SPI0 TRUE
|
||||
#define HT32_SPI0_IRQ_VECTOR Vector94
|
||||
#define HT32_HAS_SPI1 TRUE
|
||||
#define HT32_SPI1_IRQ_VECTOR Vector98
|
||||
|
||||
/* UART attributes.*/
|
||||
#define HT32_HAS_USART0 TRUE
|
||||
#define HT32_USART0_IRQ_VECTOR Vector9C
|
||||
#define HT32_HAS_USART1 TRUE
|
||||
#define HT32_USART1_IRQ_VECTOR VectorA0
|
||||
#define HT32_HAS_UART0 TRUE
|
||||
#define HT32_UART0_IRQ_VECTOR VectorA4
|
||||
#define HT32_HAS_UART1 TRUE
|
||||
#define HT32_UART1_IRQ_VECTOR VectorA8
|
||||
|
||||
/* USB attributes.*/
|
||||
#define HT32_HAS_USB TRUE
|
||||
#define HT32_USB_IRQ_VECTOR VectorB4
|
||||
#define HT32_USB0_IS_USBOTG FALSE
|
||||
#define HT32_HAS_USB_CLOCK_RECOVERY FALSE
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* defined(HT32F165x) */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,35 @@
|
|||
# List of all the platform files.
|
||||
PLATFORMSRC = $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
|
||||
$(CHIBIOS_CONTRIB)/os/hal/ports/HT32/HT32F523xx/hal_lld.c
|
||||
|
||||
|
||||
# Required include directories
|
||||
PLATFORMINC = $(CHIBIOS)/os/hal/ports/common/ARMCMx \
|
||||
$(CHIBIOS_CONTRIB)/os/hal/ports/HT32/HT32F523xx
|
||||
|
||||
# Optional platform files.
|
||||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
|
||||
# Configuration files directory
|
||||
ifeq ($(HALCONFDIR),)
|
||||
ifeq ($(CONFDIR),)
|
||||
HALCONFDIR = .
|
||||
else
|
||||
HALCONFDIR := $(CONFDIR)
|
||||
endif
|
||||
endif
|
||||
|
||||
HALCONF := $(strip $(shell cat $(HALCONFDIR)/halconf.h | egrep -e "\#define"))
|
||||
endif #ifeq ($(USE_SMART_BUILD), yes)
|
||||
|
||||
# Drivers compatible with the platform.
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/SPIv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/GPIOv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USBv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F5xxxx/driver.mk
|
||||
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(PLATFORMSRC)
|
||||
ALLINC += $(PLATFORMINC)
|
|
@ -0,0 +1,9 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/GPIOv1/hal_pal_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/GPIOv1/hal_pal_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/GPIOv1
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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 HT32 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. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void initgpio(ioportid_t port, const struct port_setup * const setup) {
|
||||
PAL_PORT(port)->DIRCR = setup->DIR;
|
||||
PAL_PORT(port)->INER = setup->INE;
|
||||
PAL_PORT(port)->PUR = setup->PU;
|
||||
PAL_PORT(port)->PDR = setup->PD;
|
||||
PAL_PORT(port)->ODR = setup->OD;
|
||||
PAL_PORT(port)->DRVR = setup->DRV;
|
||||
const uint32_t portidx = HT32_PAL_IDX(port);
|
||||
AFIO->GPxCFGR[portidx][0] = setup->CFG[0];
|
||||
AFIO->GPxCFGR[portidx][1] = setup->CFG[1];
|
||||
if (setup->LOCK != 0) {
|
||||
PAL_PORT(port)->LOCKR = 0x5FA00000 | setup->LOCK;
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief HT32 I/O ports configuration.
|
||||
* @details Ports A-D(E, F, G, H) clocks enabled.
|
||||
*
|
||||
* @param[in] config the HT32 ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_init(const PALConfig *config) {
|
||||
|
||||
CKCU->AHBCCR |= (HT32_CCR_PAEN << HT32_NUM_GPIO) - HT32_CCR_PAEN;
|
||||
// enable AFIO
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_AFIOEN;
|
||||
|
||||
if (config == NULL)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < HT32_NUM_GPIO; i++) {
|
||||
initgpio(HT32_PAL_ID(i), &(config->setup[i]));
|
||||
}
|
||||
AFIO->ESSR[0] = config->ESSR[0];
|
||||
AFIO->ESSR[1] = config->ESSR[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
|
||||
if ((mode & PAL_HT32_MODE_AFE) != 0) {
|
||||
const uint32_t afn = (mode >> 8) & 0xf;
|
||||
const uint32_t portidx = HT32_PAL_IDX(port);
|
||||
uint32_t cfg[2];
|
||||
cfg[0] = AFIO->GPxCFGR[portidx][0];
|
||||
cfg[1] = AFIO->GPxCFGR[portidx][1];
|
||||
for (size_t i = 0; i < PAL_IOPORTS_WIDTH; i++) {
|
||||
if ((mask & (1U << i)) == 0)
|
||||
continue;
|
||||
cfg[i / 8] &= ~(0xfU << ((i % 8) * 4));
|
||||
cfg[i / 8] |= afn << ((i % 8) * 4);
|
||||
}
|
||||
AFIO->GPxCFGR[portidx][0] = cfg[0];
|
||||
AFIO->GPxCFGR[portidx][1] = cfg[1];
|
||||
}
|
||||
|
||||
if ((mode & PAL_HT32_MODE_DIR) != 0) {
|
||||
PAL_PORT(port)->DIRCR |= mask;
|
||||
} else {
|
||||
PAL_PORT(port)->DIRCR &= ~mask;
|
||||
}
|
||||
|
||||
if ((mode & PAL_HT32_MODE_INE) != 0) {
|
||||
PAL_PORT(port)->INER |= mask;
|
||||
} else {
|
||||
PAL_PORT(port)->INER &= ~mask;
|
||||
}
|
||||
|
||||
if ((mode & PAL_HT32_MODE_PU) != 0) {
|
||||
PAL_PORT(port)->PUR |= mask;
|
||||
} else {
|
||||
PAL_PORT(port)->PUR &= ~mask;
|
||||
}
|
||||
|
||||
if ((mode & PAL_HT32_MODE_PD) != 0) {
|
||||
PAL_PORT(port)->PDR |= mask;
|
||||
} else {
|
||||
PAL_PORT(port)->PDR &= ~mask;
|
||||
}
|
||||
|
||||
if ((mode & PAL_HT32_MODE_OD) != 0) {
|
||||
PAL_PORT(port)->ODR |= mask;
|
||||
} else {
|
||||
PAL_PORT(port)->ODR &= ~mask;
|
||||
}
|
||||
|
||||
if ((mode & PAL_HT32_MODE_DRV) != 0) {
|
||||
PAL_PORT(port)->DRVR |= mask;
|
||||
} else {
|
||||
PAL_PORT(port)->DRVR &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PAL == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,482 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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.h
|
||||
* @brief PLATFORM PAL subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_PAL_LLD_H
|
||||
#define HAL_PAL_LLD_H
|
||||
|
||||
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Unsupported modes and specific modes */
|
||||
/*===========================================================================*/
|
||||
|
||||
#undef PAL_MODE_RESET
|
||||
#undef PAL_MODE_UNCONNECTED
|
||||
#undef PAL_MODE_INPUT
|
||||
#undef PAL_MODE_INPUT_PULLUP
|
||||
#undef PAL_MODE_INPUT_PULLDOWN
|
||||
#undef PAL_MODE_INPUT_ANALOG
|
||||
#undef PAL_MODE_OUTPUT_PUSHPULL
|
||||
#undef PAL_MODE_OUTPUT_OPENDRAIN
|
||||
|
||||
#define PAL_HT32_MODE_DIR ( 1U << 0)
|
||||
#define PAL_HT32_MODE_INE ( 1U << 1)
|
||||
#define PAL_HT32_MODE_PU ( 1U << 2)
|
||||
#define PAL_HT32_MODE_PD ( 1U << 3)
|
||||
#define PAL_HT32_MODE_OD ( 1U << 4)
|
||||
#define PAL_HT32_MODE_DRV ( 1U << 5)
|
||||
#define PAL_HT32_MODE_LOCK ( 1U << 6)
|
||||
#define PAL_HT32_MODE_AF_MASK (15U << 8)
|
||||
#define PAL_HT32_MODE_AFE ( 1U << 15)
|
||||
#define PAL_HT32_MODE_AF(m) (PAL_HT32_MODE_AFE | ((m) << 8))
|
||||
|
||||
//#define PAL_MODE_RESET (0)
|
||||
#define PAL_MODE_UNCONNECTED (PAL_HT32_MODE_LOCK)
|
||||
#define PAL_MODE_INPUT (PAL_HT32_MODE_INE)
|
||||
#define PAL_MODE_INPUT_PULLUP (PAL_HT32_MODE_PU|PAL_HT32_MODE_INE)
|
||||
#define PAL_MODE_INPUT_PULLDOWN (PAL_HT32_MODE_PD|PAL_HT32_MODE_INE)
|
||||
#define PAL_MODE_INPUT_ANALOG (PAL_HT32_MODE_AF(2))
|
||||
#define PAL_MODE_OUTPUT_PUSHPULL (PAL_HT32_MODE_DIR)
|
||||
#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_HT32_MODE_OD|PAL_HT32_MODE_DIR)
|
||||
#define PAL_MODE_HT32_AF PAL_HT32_MODE_AF
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Types and constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Port related definitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Width, in bits, of an I/O port.
|
||||
*/
|
||||
#define PAL_IOPORTS_WIDTH 16U
|
||||
|
||||
/**
|
||||
* @brief Whole port mask.
|
||||
* @details This macro specifies all the valid bits into a port.
|
||||
*/
|
||||
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFU)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Line handling macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Forms a line identifier.
|
||||
* @details A port/pad pair are encoded into an @p ioline_t type. The encoding
|
||||
* of this type is platform-dependent.
|
||||
*/
|
||||
#define PAL_LINE(port, pad) \
|
||||
((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
|
||||
|
||||
/**
|
||||
* @brief Decodes a port identifier from a line identifier.
|
||||
*/
|
||||
#define PAL_PORT(line) \
|
||||
((GPIO_TypeDef *)(((uint32_t)(line)) & 0xFFFFFFC0U))
|
||||
|
||||
/**
|
||||
* @brief Decodes a pad identifier from a line identifier.
|
||||
*/
|
||||
#define PAL_PAD(line) \
|
||||
((uint32_t)((uint32_t)(line) & 0x0000000FU))
|
||||
|
||||
/**
|
||||
* @brief Value identifying an invalid line.
|
||||
*/
|
||||
#define PAL_NOLINE 0U
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Generic I/O ports static initializer.
|
||||
* @details An instance of this structure must be passed to @p palInit() at
|
||||
* system startup time in order to initialized the digital I/O
|
||||
* subsystem. This represents only the initial setup, specific pads
|
||||
* or whole ports can be reprogrammed at later time.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
struct port_setup {
|
||||
uint16_t DIR;
|
||||
uint16_t INE;
|
||||
uint16_t PU;
|
||||
uint16_t PD;
|
||||
uint16_t OD;
|
||||
uint16_t DRV;
|
||||
uint16_t LOCK;
|
||||
uint16_t OUT;
|
||||
uint32_t CFG[2];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct port_setup setup[HT32_NUM_GPIO];
|
||||
uint32_t ESSR[2];
|
||||
} PALConfig;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O port sized unsigned type.
|
||||
*/
|
||||
typedef uint16_t ioportmask_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O modes.
|
||||
*/
|
||||
typedef uint16_t iomode_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an I/O line.
|
||||
*/
|
||||
typedef uintptr_t ioline_t;
|
||||
|
||||
/**
|
||||
* @brief Port Identifier.
|
||||
* @details This type can be a scalar or some kind of pointer, do not make
|
||||
* any assumption about it, use the provided macros when populating
|
||||
* variables of this type.
|
||||
*/
|
||||
typedef GPIO_TypeDef * ioportid_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an pad identifier
|
||||
*/
|
||||
typedef uint32_t iopadid_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Identifiers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief First I/O port identifier.
|
||||
* @details Low level drivers can define multiple ports, it is suggested to
|
||||
* use this naming convention.
|
||||
*/
|
||||
#define HT32_PAL_ID(x) ((ioportid_t)(GPIO_A_BASE + (x << HT32_GPIO_INDEX_BITS)))
|
||||
#define HT32_PAL_IDX(x) (((uintptr_t)(x) - GPIO_A_BASE) >> HT32_GPIO_INDEX_BITS)
|
||||
#define IOPORT1 HT32_PAL_ID(0)
|
||||
#define IOPORT2 HT32_PAL_ID(1)
|
||||
#define IOPORT3 HT32_PAL_ID(2)
|
||||
#define IOPORT4 HT32_PAL_ID(3)
|
||||
#define IOPORT5 HT32_PAL_ID(4)
|
||||
#define IOPORTA IOPORT1
|
||||
#define IOPORTB IOPORT2
|
||||
#define IOPORTC IOPORT3
|
||||
#define IOPORTD IOPORT4
|
||||
#define IOPORTE IOPORT5
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Implementation, some of the following macros could be implemented as */
|
||||
/* functions, if so please put them in pal_lld.c. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level PAL subsystem initialization.
|
||||
*
|
||||
* @param[in] config architecture-dependent ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_init(config) _pal_lld_init(config)
|
||||
|
||||
/**
|
||||
* @brief Reads the physical I/O port states.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The port bits.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readport(port) (PAL_PORT(port)->DINR)
|
||||
|
||||
/**
|
||||
* @brief Reads the output latch.
|
||||
* @details The purpose of this function is to read back the latched output
|
||||
* value.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readlatch(port) (PAL_PORT(port)->DOUTR)
|
||||
|
||||
/**
|
||||
* @brief Writes a bits mask on a I/O port.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be written on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writeport(port, bits) \
|
||||
do { \
|
||||
PAL_PORT(port)->DOUTR = (bits); \
|
||||
} while (false)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sets a bits mask on a I/O port.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be ORed on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setport(port, bits) \
|
||||
do { \
|
||||
PAL_PORT(port)->SRR = (bits); \
|
||||
} while (false)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clears a bits mask on a I/O port.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be cleared on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_clearport(port, bits) \
|
||||
do { \
|
||||
PAL_PORT(port)->RR = (bits); \
|
||||
} while (false)
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief Toggles a bits mask on a I/O port.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be XORed on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_toggleport(port, bits) \
|
||||
do { \
|
||||
(void)port; \
|
||||
(void)bits; \
|
||||
} while (false)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reads a group of bits.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @return The group logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readgroup(port, mask, offset) 0U
|
||||
|
||||
/**
|
||||
* @brief Writes a group of bits.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] bits bits to be written. Values exceeding the group width
|
||||
* are masked.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writegroup(port, mask, offset, bits) \
|
||||
do { \
|
||||
(void)port; \
|
||||
(void)mask; \
|
||||
(void)offset; \
|
||||
(void)bits; \
|
||||
} while (false)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Pads group mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] mode group mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setgroupmode(port, mask, offset, mode) \
|
||||
_pal_lld_setgroupmode(port, mask << offset, mode)
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief Reads a logical state from an I/O pad.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @return The logical state.
|
||||
* @retval PAL_LOW low logical state.
|
||||
* @retval PAL_HIGH high logical state.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readpad(port, pad) PAL_LOW
|
||||
|
||||
/**
|
||||
* @brief Writes a logical state on an output pad.
|
||||
* @note This function is not meant to be invoked directly by the
|
||||
* application code.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] bit logical value, the value must be @p PAL_LOW or
|
||||
* @p PAL_HIGH
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writepad(port, pad, bit) \
|
||||
do { \
|
||||
(void)port; \
|
||||
(void)pad; \
|
||||
(void)bit; \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Sets a pad logical state to @p PAL_HIGH.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setpad(port, pad) \
|
||||
do { \
|
||||
(void)port; \
|
||||
(void)pad; \
|
||||
} while (false)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clears a pad logical state to @p PAL_LOW.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_clearpad(port, pad) \
|
||||
do { \
|
||||
(void)port; \
|
||||
(void)pad; \
|
||||
} while (false)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Toggles a pad logical state.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_togglepad(port, pad) \
|
||||
do { \
|
||||
(void)port; \
|
||||
(void)pad; \
|
||||
} while (false)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Pad mode setup.
|
||||
* @details This function programs a pad with the specified mode.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] mode pad mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setpadmode(port, pad, mode) \
|
||||
do { \
|
||||
(void)port; \
|
||||
(void)pad; \
|
||||
(void)mode; \
|
||||
} while (false)
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern const PALConfig pal_default_config;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _pal_lld_init(const PALConfig *config);
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PAL == TRUE */
|
||||
|
||||
#endif /* HAL_PAL_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,9 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/SPIv1/hal_spi_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/SPIv1/hal_spi_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/SPIv1
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_spi_lld.c
|
||||
* @brief HT32 SPI subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_SPI == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief SPI0 driver identifier.
|
||||
*/
|
||||
#if (HT32_SPI_USE_SPI0 == TRUE) || defined(__DOXYGEN__)
|
||||
SPIDriver SPID0;
|
||||
#endif
|
||||
#if (HT32_SPI_USE_SPI1 == TRUE) || defined(__DOXYGEN__)
|
||||
SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_SPI_USE_SPI0 == TRUE) || (HT32_SPI_USE_SPI1 == TRUE) || defined(__DOXYGEN__)
|
||||
static void spi_lld_rx(SPIDriver * const spip) {
|
||||
uint32_t fd;
|
||||
uint32_t sr;
|
||||
|
||||
while (spip->rxcnt) {
|
||||
sr = spip->SPI->SR;
|
||||
if ((sr & SPI_SR_RXBNE) == 0)
|
||||
return;
|
||||
fd = spip->SPI->DR;
|
||||
if (spip->rxptr) {
|
||||
*spip->rxptr++ = fd & 0xff;
|
||||
}
|
||||
spip->rxcnt--;
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_lld_tx(SPIDriver * const spip) {
|
||||
uint32_t fd;
|
||||
uint32_t sr;
|
||||
|
||||
while (spip->txcnt) {
|
||||
sr = spip->SPI->SR;
|
||||
if ((sr & SPI_SR_TXBE) == 0)
|
||||
return;
|
||||
if (spip->txptr) {
|
||||
fd = *spip->txptr++;
|
||||
} else {
|
||||
fd = '\xff';
|
||||
}
|
||||
spip->SPI->DR = fd;
|
||||
spip->txcnt--;
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_lld_handler(SPIDriver * const spip) {
|
||||
//uint32_t sr = spip->SPI->SR; // & ((1U<<8)|spip->SPI->IER);
|
||||
spi_lld_rx(spip);
|
||||
spi_lld_tx(spip);
|
||||
if (spip->rxcnt == 0) {
|
||||
spip->SPI->IER = 0;
|
||||
_spi_isr_code(spip);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_SPI_USE_SPI0 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_SPI0_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
spi_lld_handler(&SPID0);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HT32_SPI_USE_SPI1 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_SPI1_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
spi_lld_handler(&SPID1);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level SPI driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_init(void) {
|
||||
/* Driver initialization.*/
|
||||
#if HT32_SPI_USE_SPI0 == TRUE
|
||||
spiObjectInit(&SPID0);
|
||||
SPID0.SPI = SPI0;
|
||||
// CKCU->APBCCR0 |= CKCU_APBCCR0_SPI0EN;
|
||||
#endif
|
||||
#if HT32_SPI_USE_SPI1 == TRUE
|
||||
spiObjectInit(&SPID1);
|
||||
SPID1.SPI = SPI1;
|
||||
// CKCU->APBCCR0 |= CKCU_APBCCR0_SPI1EN;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_start(SPIDriver *spip) {
|
||||
if (spip->state == SPI_STOP) {
|
||||
/* Enables the peripheral.*/
|
||||
#if HT32_SPI_USE_SPI0 == TRUE
|
||||
if (&SPID0 == spip) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_SPI0EN;
|
||||
nvicEnableVector(SPI0_IRQn, HT32_SPI0_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_SPI_USE_SPI1 == TRUE
|
||||
if (&SPID1 == spip) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_SPI1EN;
|
||||
nvicEnableVector(SPI1_IRQn, HT32_SPI1_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configures the peripheral.*/
|
||||
spip->SPI->CR0 = spip->config->cr0;
|
||||
spip->SPI->CR1 = spip->config->cr1;
|
||||
spip->SPI->CPR = spip->config->cpr;
|
||||
//spip->SPI->FCR = 0; //SPI_FCR_FIFOEN | (1U << 4) | (1U << 0);
|
||||
spip->SPI->FCR = spip->config->fcr;
|
||||
spip->SPI->CR0 |= SPI_CR0_SPIEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_stop(SPIDriver *spip) {
|
||||
if (spip->state == SPI_READY) {
|
||||
/* Disables the peripheral.*/
|
||||
#if HT32_SPI_USE_SPI0 == TRUE
|
||||
if (&SPID0 == spip) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_SPI0RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_SPI0EN;
|
||||
nvicDisableVector(SPI0_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_SPI_USE_SPI1 == TRUE
|
||||
if (&SPID1 == spip) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_SPI1RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_SPI1EN;
|
||||
nvicDisableVector(SPI1_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Asserts the slave select signal and prepares for transfers.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_select(SPIDriver *spip) {
|
||||
spip->SPI->CR0 |= SPI_CR0_SSELC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deasserts the slave select signal.
|
||||
* @details The previously selected peripheral is unselected.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_unselect(SPIDriver *spip) {
|
||||
spip->SPI->CR0 &= ~SPI_CR0_SSELC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ignores data on the SPI bus.
|
||||
* @details This asynchronous function starts the transmission of a series of
|
||||
* idle words on the SPI bus and ignores the received data.
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||
spi_lld_exchange(spip, n, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges data on the SPI bus.
|
||||
* @details This asynchronous function starts a simultaneous transmit/receive
|
||||
* operation.
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be exchanged
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
spip->txptr = txbuf;
|
||||
spip->rxptr = rxbuf;
|
||||
spip->rxcnt = spip->txcnt = n;
|
||||
spip->SPI->IER = SPI_IER_RXBNEIEN | SPI_IER_TXBEIEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the SPI bus.
|
||||
* @details This asynchronous function starts a transmit operation.
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
spi_lld_exchange(spip, n, txbuf, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives data from the SPI bus.
|
||||
* @details This asynchronous function starts a receive operation.
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
spi_lld_exchange(spip, n, NULL, rxbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges one frame using a polled wait.
|
||||
* @details This synchronous function exchanges one frame using a polled
|
||||
* synchronization method. This function is useful when exchanging
|
||||
* small amount of data on high speed channels, usually in this
|
||||
* situation is much more efficient just wait for completion using
|
||||
* polling than suspending the thread waiting for an interrupt.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] frame the data frame to send over the SPI bus
|
||||
* @return The received data frame from the SPI bus.
|
||||
*/
|
||||
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
|
||||
spip->SPI->DR = frame;
|
||||
while((spip->SPI->SR & SPI_SR_RXBNE) == 0);
|
||||
return (spip->SPI->DR & 0xffff);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SPI == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
|
||||
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_spi_lld.h
|
||||
* @brief HT32 SPI subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
#ifndef HAL_SPI_LLD_H
|
||||
#define HAL_SPI_LLD_H
|
||||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name HT32 configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief SPI0 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SPI0 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(HT32_SPI_USE_SPI0) || defined(__DOXYGEN__)
|
||||
#define HT32_SPI_USE_SPI0 FALSE
|
||||
#endif
|
||||
#if !defined(HT32_SPI_USE_SPI1) || defined(__DOXYGEN__)
|
||||
#define HT32_SPI_USE_SPI1 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Low Level fields of the SPI driver structure.
|
||||
*/
|
||||
#define spi_lld_driver_fields \
|
||||
SPI_TypeDef *SPI; \
|
||||
uint8_t *rxptr; \
|
||||
const uint8_t *txptr; \
|
||||
size_t rxcnt; \
|
||||
size_t txcnt; \
|
||||
|
||||
/**
|
||||
* @brief Low Level fields of the SPI configuration structure.
|
||||
*/
|
||||
#define spi_lld_config_fields \
|
||||
uint32_t cr0; \
|
||||
uint32_t cr1; \
|
||||
uint32_t cpr; \
|
||||
uint32_t fcr;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_SPI_USE_SPI0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID0;
|
||||
#endif
|
||||
#if (HT32_SPI_USE_SPI1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void spi_lld_init(void);
|
||||
void spi_lld_start(SPIDriver *spip);
|
||||
void spi_lld_stop(SPIDriver *spip);
|
||||
void spi_lld_select(SPIDriver *spip);
|
||||
void spi_lld_unselect(SPIDriver *spip);
|
||||
void spi_lld_ignore(SPIDriver *spip, size_t n);
|
||||
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SPI == TRUE */
|
||||
|
||||
#endif /* HAL_SPI_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,15 @@
|
|||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1/hal_st_lld.c
|
||||
|
||||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_GPT TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1/hal_gpt_lld.c
|
||||
endif
|
||||
ifneq ($(findstring HAL_USE_PWM TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1/hal_pwm_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1/hal_gpt_lld.c
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1/hal_pwm_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/TIMv1
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_gpt_lld.c
|
||||
* @brief PLATFORM GPT subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup GPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_GPT == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPTD1 driver identifier.
|
||||
*/
|
||||
#if (HT32_GPT_USE_BFTM0 == TRUE) || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD_BFTM0;
|
||||
#endif
|
||||
|
||||
#if (HT32_GPT_USE_BFTM1 == TRUE) || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD_BFTM1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void gpt_lld_handler(GPTDriver *gptp) {
|
||||
if(gptp->BFTM->SR & BFTM_SR_MIF){
|
||||
gptp->BFTM->SR = 0;
|
||||
if(gptp->config->callback)
|
||||
gptp->config->callback(gptp);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_GPT_USE_BFTM0 == TRUE) || defined(__DOXYGEN__)
|
||||
#ifndef HT32_BFTM0_IRQ_VECTOR
|
||||
#error "HT32_BFTM0_IRQ_VECTOR is not defined"
|
||||
#endif
|
||||
OSAL_IRQ_HANDLER(HT32_BFTM0_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
gpt_lld_handler(&GPTD_BFTM0);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HT32_GPT_USE_BFTM1 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_BFTM1_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
gpt_lld_handler(&GPTD_BFTM1);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level GPT driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_init(void) {
|
||||
/* Driver initialization.*/
|
||||
#if HT32_GPT_USE_BFTM0 == TRUE
|
||||
gptObjectInit(&GPTD_BFTM0);
|
||||
GPTD_BFTM0.BFTM = BFTM0;
|
||||
#endif
|
||||
#if HT32_GPT_USE_BFTM1 == TRUE
|
||||
gptObjectInit(&GPTD_BFTM1);
|
||||
GPTD_BFTM0.BFTM = BFTM1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the GPT peripheral.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_start(GPTDriver *gptp) {
|
||||
if (gptp->state == GPT_STOP) {
|
||||
/* Enables the peripheral.*/
|
||||
#if HT32_GPT_USE_BFTM0 == TRUE
|
||||
if (&GPTD_BFTM0 == gptp) {
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_BFTM0EN;
|
||||
nvicEnableVector(BFTM0_IRQn, HT32_GPT_BFTM0_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_GPT_USE_BFTM1 == TRUE
|
||||
if (&GPTD_BFTM1 == gptp) {
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_BFTM1EN;
|
||||
nvicEnableVector(BFTM1_IRQn, HT32_GPT_BFTM1_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configures the peripheral.*/
|
||||
gptp->BFTM->CR = 0;
|
||||
// counter frequency depends on the AHB clock, we can't
|
||||
// change anything here
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the GPT peripheral.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_stop(GPTDriver *gptp) {
|
||||
if (gptp->state == GPT_READY) {
|
||||
/* Resets the peripheral.*/
|
||||
/* Disables the peripheral.*/
|
||||
#if HT32_GPT_USE_BFTM0 == TRUE
|
||||
if (&GPTD_BFTM0 == gptp) {
|
||||
RSTCU->APBPRSTR1 = RSTCU_APBPRSTR1_BFTM0RST;
|
||||
CKCU->APBCCR1 &= ~CKCU_APBCCR1_BFTM0EN;
|
||||
nvicDisableVector(BFTM0_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_GPT_USE_BFTM1 == TRUE
|
||||
if (&GPTD_BFTM1 == gptp) {
|
||||
RSTCU->APBPRSTR1 = RSTCU_APBPRSTR1_BFTM1RST;
|
||||
CKCU->APBCCR1 &= ~CKCU_APBCCR1_BFTM1EN;
|
||||
nvicDisableVector(BFTM1_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the timer in continuous mode.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
* @param[in] interval period in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
|
||||
gptp->BFTM->SR = 0;
|
||||
gptp->BFTM->CNTR = 0;
|
||||
gptp->BFTM->CMP = (HT32_CK_AHB_FREQUENCY / gptp->config->frequency) * interval;
|
||||
gptp->BFTM->CR = BFTM_CR_CEN | BFTM_CR_MIEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the timer.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_stop_timer(GPTDriver *gptp) {
|
||||
gptp->BFTM->CR = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the timer in one shot mode and waits for completion.
|
||||
* @details This function specifically polls the timer waiting for completion
|
||||
* in order to not have extra delays caused by interrupt servicing,
|
||||
* this function is only recommended for short delays.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
* @param[in] interval time interval in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
|
||||
gptp->BFTM->SR = 0;
|
||||
gptp->BFTM->CNTR = 0;
|
||||
gptp->BFTM->CMP = (HT32_CK_AHB_FREQUENCY / gptp->config->frequency) * interval;
|
||||
gptp->BFTM->CR = BFTM_CR_CEN | BFTM_CR_OSM;
|
||||
while(!(gptp->BFTM->SR & BFTM_SR_MIF));
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_GPT == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_gpt_lld.h
|
||||
* @brief PLATFORM GPT subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup GPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_GPT_LLD_H
|
||||
#define HAL_GPT_LLD_H
|
||||
|
||||
#if (HAL_USE_GPT == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief GPTD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPTD1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(HT32_GPT_USE_BFTM0) || defined(__DOXYGEN__)
|
||||
#define HT32_GPT_USE_BFTM0 FALSE
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_GPT_USE_BFTM1) || defined(__DOXYGEN__)
|
||||
#define HT32_GPT_USE_BFTM1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(HT32_GPT_BFTM0_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define HT32_GPT_BFTM0_IRQ_PRIORITY 7
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_GPT_BFTM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define HT32_GPT_BFTM1_IRQ_PRIORITY 7
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPT frequency type.
|
||||
*/
|
||||
typedef uint32_t gptfreq_t;
|
||||
|
||||
/**
|
||||
* @brief GPT counter type.
|
||||
*/
|
||||
typedef uint16_t gptcnt_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
gptfreq_t frequency;
|
||||
/**
|
||||
* @brief Timer callback pointer.
|
||||
* @note This callback is invoked on GPT counter events.
|
||||
*/
|
||||
gptcallback_t callback;
|
||||
/* End of the mandatory fields.*/
|
||||
} GPTConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a GPT driver.
|
||||
*/
|
||||
struct GPTDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
gptstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const GPTConfig *config;
|
||||
#if defined(GPT_DRIVER_EXT_FIELDS)
|
||||
GPT_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
BFTM_TypeDef *BFTM;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Changes the interval of GPT peripheral.
|
||||
* @details This function changes the interval of a running GPT unit.
|
||||
* @pre The GPT unit must have been activated using @p gptStart().
|
||||
* @pre The GPT unit must have been running in continuous mode using
|
||||
* @p gptStartContinuous().
|
||||
* @post The GPT unit interval is changed to the new value.
|
||||
* @note The function has effect at the next cycle start.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
* @param[in] interval new cycle time in timer ticks
|
||||
* @notapi
|
||||
*/
|
||||
#define gpt_lld_change_interval(gptp, interval) \
|
||||
((gptp)->BFTM->CMP = (HT32_CK_AHB_FREQUENCY / (gptp)->config->frequency) * (interval))
|
||||
|
||||
/**
|
||||
* @brief Returns the interval of GPT peripheral.
|
||||
* @pre The GPT unit must be running in continuous mode.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
* @return The current interval.
|
||||
* @notapi
|
||||
*/
|
||||
#define gpt_lld_get_interval(gptp) \
|
||||
((gptcnt_t)(gptp)->BFTM->CMP / (HT32_CK_AHB_FREQUENCY / (gptp)->config->frequency))
|
||||
|
||||
/**
|
||||
* @brief Returns the counter value of GPT peripheral.
|
||||
* @pre The GPT unit must be running in continuous mode.
|
||||
* @note The nature of the counter is not defined, it may count upward
|
||||
* or downward, it could be continuously running or not.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
* @return The current counter value.
|
||||
* @notapi
|
||||
*/
|
||||
#define gpt_lld_get_counter(gptp) \
|
||||
((gptcnt_t)((gptp)->BFTM->CNTR / (HT32_CK_AHB_FREQUENCY / (gptp)->config->frequency)))
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_GPT_USE_BFTM0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD_BFTM0;
|
||||
#endif
|
||||
#if (HT32_GPT_USE_BFTM1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD_BFTM1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void gpt_lld_init(void);
|
||||
void gpt_lld_start(GPTDriver *gptp);
|
||||
void gpt_lld_stop(GPTDriver *gptp);
|
||||
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval);
|
||||
void gpt_lld_stop_timer(GPTDriver *gptp);
|
||||
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_GPT == TRUE */
|
||||
|
||||
#endif /* HAL_GPT_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_pwm_lld.c
|
||||
* @brief HT32 PWM subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup PWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_PWM == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief PWMD0 driver identifier.
|
||||
* @note The driver PWMD0 allocates the complex timer XXX when enabled.
|
||||
*/
|
||||
#if (HT32_PWM_USE_MCTM0 == TRUE) || defined(__DOXYGEN__)
|
||||
PWMDriver PWMD_MCTM0;
|
||||
#endif
|
||||
|
||||
#if (HT32_PWM_USE_MCTM1 == TRUE) || defined(__DOXYGEN__)
|
||||
PWMDriver PWMD_MCTM1;
|
||||
#endif
|
||||
|
||||
#if (HT32_PWM_USE_GPTM0 == TRUE) || defined(__DOXYGEN__)
|
||||
PWMDriver PWMD_GPTM0;
|
||||
#endif
|
||||
|
||||
#if (HT32_PWM_USE_GPTM1 == TRUE) || defined(__DOXYGEN__)
|
||||
PWMDriver PWMD_GPTM1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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) {
|
||||
|
||||
#if HT32_PWM_USE_MCTM0 == TRUE
|
||||
/* Driver initialization.*/
|
||||
pwmObjectInit(&PWMD_MCTM0);
|
||||
#endif
|
||||
#if HT32_PWM_USE_MCTM1 == TRUE
|
||||
pwmObjectInit(&PWMD_MCTM1);
|
||||
#endif
|
||||
#if HT32_PWM_USE_GPTM0 == TRUE
|
||||
pwmObjectInit(&PWMD_GPTM0);
|
||||
#endif
|
||||
#if HT32_PWM_USE_GPTM1 == TRUE
|
||||
pwmObjectInit(&PWMD_GPTM1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the PWM peripheral.
|
||||
* @note Starting a driver that is already in the @p PWM_READY state
|
||||
* disables all the active channels.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_start(PWMDriver *pwmp) {
|
||||
|
||||
if (pwmp->state == PWM_STOP) {
|
||||
/* Clock activation and timer reset.*/
|
||||
#if HT32_PWM_USE_MCTM0 == TRUE
|
||||
if (&PWMD_MCTM0 == pwmp) {
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_MCTM0EN;
|
||||
pwmp->TM = MCTM0;
|
||||
}
|
||||
#endif
|
||||
#if HT32_PWM_USE_MCTM1 == TRUE
|
||||
if (&PWMD_MCTM1 == pwmp) {
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_MCTM1EN;
|
||||
pwmp->TM = MCTM1;
|
||||
}
|
||||
#endif
|
||||
#if HT32_PWM_USE_GPTM0 == TRUE
|
||||
if (&PWMD_GPTM0 == pwmp) {
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_GPTM0EN;
|
||||
pwmp->TM = GPTM0;
|
||||
}
|
||||
#endif
|
||||
#if HT32_PWM_USE_GPTM1 == TRUE
|
||||
if (&PWMD_GPTM1 == pwmp) {
|
||||
CKCU->APBCCR1 |= CKCU_APBCCR1_GPTM1EN;
|
||||
pwmp->TM = GPTM1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
pwmp->TM->CNTCFR = TM_CNTCFR_CMSEL_MODE_0;
|
||||
pwmp->TM->PSCR = (HT32_CK_AHB_FREQUENCY / pwmp->config->frequency) - 1;
|
||||
pwmp->TM->CRR = pwmp->config->period;
|
||||
pwmp->TM->CNTR = 0;
|
||||
pwmp->TM->CTR = TM_CTR_TME;
|
||||
pwmp->TM->CHCTR = 0;
|
||||
#if (HT32_PWM_USE_MCTM0 == TRUE) || (HT32_PWM_USE_MCTM1 == TRUE)
|
||||
if (pwmp->TM == MCTM0 || pwmp->TM == MCTM1)
|
||||
pwmp->TM->CHBRKCTR = TM_CHBRKCTR_CHMOE;
|
||||
#endif
|
||||
for (size_t channel = 0; channel < PWM_CHANNELS; channel++) {
|
||||
switch (pwmp->config->channels[channel].mode & PWM_OUTPUT_MASK) {
|
||||
case PWM_OUTPUT_DISABLED:
|
||||
break;
|
||||
case PWM_OUTPUT_ACTIVE_HIGH:
|
||||
pwmp->TM->CHPOLR &= ~(1U << (2*channel));
|
||||
break;
|
||||
case PWM_OUTPUT_ACTIVE_LOW:
|
||||
pwmp->TM->CHPOLR |= 1U << (2*channel);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pwmp->TM->CHnOCFR[channel] = TM_CHnOCFR_CHnPRE|TM_CHnOCFR_CHnOM(6);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the PWM peripheral.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_stop(PWMDriver *pwmp) {
|
||||
|
||||
/* If in ready state then disables the PWM clock.*/
|
||||
if (pwmp->state == PWM_READY) {
|
||||
#if HT32_PWM_USE_MCTM0 == TRUE
|
||||
if (&PWMD_MCTM0 == pwmp) {
|
||||
CKCU->APBCCR1 &= ~CKCU_APBCCR1_MCTM0EN;
|
||||
}
|
||||
#endif
|
||||
#if HT32_PWM_USE_MCTM1 == TRUE
|
||||
if (&PWMD_MCTM1 == pwmp) {
|
||||
CKCU->APBCCR1 &= ~CKCU_APBCCR1_MCTM1EN;
|
||||
}
|
||||
#endif
|
||||
#if HT32_PWM_USE_GPTM0 == TRUE
|
||||
if (&PWMD_GPTM0 == pwmp) {
|
||||
CKCU->APBCCR1 &= ~CKCU_APBCCR1_GPTM0EN;
|
||||
}
|
||||
#endif
|
||||
#if HT32_PWM_USE_GPTM1 == TRUE
|
||||
if (&PWMD_GPTM1 == pwmp) {
|
||||
CKCU->APBCCR1 &= ~CKCU_APBCCR1_GPTM1EN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a PWM channel.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is active using the specified configuration.
|
||||
* @note The function has effect at the next cycle start.
|
||||
* @note Channel notification is not enabled.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
* @param[in] width PWM pulse width as clock pulses number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||
pwmchannel_t channel,
|
||||
pwmcnt_t width) {
|
||||
|
||||
pwmp->TM->CHnCCR[channel] = width;
|
||||
pwmp->TM->CHCTR |= 1U << (2*channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a PWM channel and its notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is disabled and its output line returned to the
|
||||
* idle state.
|
||||
* @note The function has effect at the next cycle start.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
|
||||
|
||||
pwmp->TM->CHCTR &= ~(1U << (2*channel));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the periodic activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @note If the notification is already enabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
|
||||
|
||||
(void)pwmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the periodic activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @note If the notification is already disabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
|
||||
|
||||
(void)pwmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a channel de-activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @pre The channel must have been activated using @p pwmEnableChannel().
|
||||
* @note If the notification is already enabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
|
||||
pwmchannel_t channel) {
|
||||
|
||||
(void)pwmp;
|
||||
(void)channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a channel de-activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @pre The channel must have been activated using @p pwmEnableChannel().
|
||||
* @note If the notification is already disabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
|
||||
pwmchannel_t channel) {
|
||||
|
||||
(void)pwmp;
|
||||
(void)channel;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PWM == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_pwm_lld.h
|
||||
* @brief HT32 PWM subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup PWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_PWM_LLD_H
|
||||
#define HAL_PWM_LLD_H
|
||||
|
||||
#if (HAL_USE_PWM == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of PWM channels per PWM driver.
|
||||
*/
|
||||
#define PWM_CHANNELS 4
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name HT32 configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief PWMD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWM1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(HT32_PWM_USE_MCTM0) || defined(__DOXYGEN__)
|
||||
#define HT32_PWM_USE_MCTM0 FALSE
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_PWM_USE_MCTM1) || defined(__DOXYGEN__)
|
||||
#define HT32_PWM_USE_MCTM1 FALSE
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_PWM_USE_GPTM0) || defined(__DOXYGEN__)
|
||||
#define HT32_PWM_USE_GPTM0 FALSE
|
||||
#endif
|
||||
|
||||
#if !defined(HT32_PWM_USE_GPTM1) || defined(__DOXYGEN__)
|
||||
#define HT32_PWM_USE_GPTM1 FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Configuration checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM mode.
|
||||
*/
|
||||
typedef uint32_t pwmmode_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM channel.
|
||||
*/
|
||||
typedef uint8_t pwmchannel_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a channels mask.
|
||||
*/
|
||||
typedef uint32_t pwmchnmsk_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM counter.
|
||||
*/
|
||||
typedef uint32_t pwmcnt_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM driver channel configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel active logic level.
|
||||
*/
|
||||
pwmmode_t mode;
|
||||
/**
|
||||
* @brief Channel callback pointer.
|
||||
* @note This callback is invoked on the channel compare event. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/* End of the mandatory fields.*/
|
||||
} PWMChannelConfig;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
uint32_t frequency;
|
||||
/**
|
||||
* @brief PWM period in ticks.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* period specifications.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
/**
|
||||
* @brief Periodic callback pointer.
|
||||
* @note This callback is invoked on PWM counter reset. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/**
|
||||
* @brief Channels configurations.
|
||||
*/
|
||||
PWMChannelConfig channels[PWM_CHANNELS];
|
||||
/* End of the mandatory fields.*/
|
||||
} PWMConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a PWM driver.
|
||||
*/
|
||||
struct PWMDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
pwmstate_t state;
|
||||
/**
|
||||
* @brief Current driver configuration data.
|
||||
*/
|
||||
const PWMConfig *config;
|
||||
/**
|
||||
* @brief Current PWM period in ticks.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
/**
|
||||
* @brief Mask of the enabled channels.
|
||||
*/
|
||||
pwmchnmsk_t enabled;
|
||||
/**
|
||||
* @brief Number of channels in this instance.
|
||||
*/
|
||||
pwmchannel_t channels;
|
||||
#if defined(PWM_DRIVER_EXT_FIELDS)
|
||||
PWM_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to timer register block.
|
||||
*/
|
||||
TM_TypeDef *TM;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Changes the period the PWM peripheral.
|
||||
* @details This function changes the period of a PWM unit that has already
|
||||
* been activated using @p pwmStart().
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The PWM unit period is changed to the new value.
|
||||
* @note The function has effect at the next cycle start.
|
||||
* @note If a period is specified that is shorter than the pulse width
|
||||
* programmed in one of the channels then the behavior is not
|
||||
* guaranteed.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] period new cycle time in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pwm_lld_change_period(pwmp, period) \
|
||||
do { \
|
||||
(pwmp)->TM->CRR = (period);\
|
||||
} while (0)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_PWM_USE_MCTM0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD_MCTM0;
|
||||
#endif
|
||||
#if (HT32_PWM_USE_MCTM1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD_MCTM1;
|
||||
#endif
|
||||
#if (HT32_PWM_USE_GPTM0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD_GPTM0;
|
||||
#endif
|
||||
#if (HT32_PWM_USE_GPTM1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD_GPTM1;
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PWM == TRUE */
|
||||
|
||||
#endif /* HAL_PWM_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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.c
|
||||
* @brief PLATFORM ST subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup ST
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level ST driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void st_lld_init(void) {
|
||||
#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
|
||||
/* Periodic systick mode, the Cortex-Mx internal systick timer is used
|
||||
in this mode.*/
|
||||
#if defined(HT32_ST_USE_HCLK)
|
||||
SysTick->LOAD = (HT32_HCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1;
|
||||
#else
|
||||
SysTick->LOAD = (HT32_STCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1;
|
||||
#endif
|
||||
SysTick->VAL = 0;
|
||||
SysTick->CTRL =
|
||||
#if defined(HT32_ST_USE_HCLK)
|
||||
SysTick_CTRL_CLKSOURCE_Msk |
|
||||
#endif
|
||||
SysTick_CTRL_ENABLE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk;
|
||||
|
||||
/* IRQ enabled.*/
|
||||
nvicSetSystemHandlerPriority(HANDLER_SYSTICK, HT32_ST_IRQ_PRIORITY);
|
||||
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
|
||||
}
|
||||
|
||||
#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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 SYST_RVRthe License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hal_st_lld.h
|
||||
* @brief PLATFORM ST 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"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief SysTick timer IRQ priority.
|
||||
*/
|
||||
#if !defined(HT32_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define HT32_ST_IRQ_PRIORITY 8
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) && (OSAL_ST_MODE != OSAL_ST_MODE_PERIODIC)
|
||||
#error Only OSAL_ST_MODE_PERIODIC is supported
|
||||
#endif
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void st_lld_init(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define SYST_CSR (*((volatile uint32_t*)0xE000E010))
|
||||
#define SYST_RVR (*((volatile uint32_t*)0xE000E014))
|
||||
#define SYST_CVR (*((volatile uint32_t*)0xE000E018))
|
||||
#define SYST_CALIB (*((volatile uint32_t*)0xE000E01C))
|
||||
|
||||
/**
|
||||
* @brief Returns the time counter value.
|
||||
*
|
||||
* @return The counter value.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline systime_t st_lld_get_counter(void) {
|
||||
return (systime_t) SYST_CVR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the alarm.
|
||||
* @note Makes sure that no spurious alarms are triggered after
|
||||
* this call.
|
||||
*
|
||||
* @param[in] abstime the time to be set for the first alarm
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void st_lld_start_alarm(systime_t abstime) {
|
||||
SYST_RVR = (uint32_t)abstime;
|
||||
SYST_CSR = 0b111;
|
||||
SYST_CVR = 0; // Trigger reload
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the alarm interrupt.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void st_lld_stop_alarm(void) {
|
||||
SYST_CVR &= ~((uint32_t)0b10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the alarm time.
|
||||
*
|
||||
* @param[in] abstime the time to be set for the next alarm
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void st_lld_set_alarm(systime_t abstime) {
|
||||
SYST_RVR = (uint32_t)abstime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)SYST_RVR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 ((SYST_CVR & 0b10) != 0);
|
||||
}
|
||||
|
||||
#endif /* HAL_ST_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,13 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F165x/hal_serial_lld.c
|
||||
endif
|
||||
ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F165x/hal_uart_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F165x/hal_serial_lld.c
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F165x/hal_uart_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F165x
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_serial_lld.c
|
||||
* @brief HT32 serial subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_SERIAL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief USART0 serial driver identifier.*/
|
||||
#if (HT32_SERIAL_USE_USART0 == TRUE) || defined(__DOXYGEN__)
|
||||
SerialDriver SD0;
|
||||
#endif
|
||||
#if (HT32_SERIAL_USE_USART1 == TRUE) || defined(__DOXYGEN__)
|
||||
SerialDriver SD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver default configuration.
|
||||
*/
|
||||
static const SerialConfig default_config = {
|
||||
SERIAL_DEFAULT_BITRATE
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void load(SerialDriver *sdp)
|
||||
{
|
||||
USART_TypeDef *u = sdp->usart;
|
||||
|
||||
#define TFTLIE (1U << 1)
|
||||
u->IER |= TFTLIE;
|
||||
}
|
||||
|
||||
#if HT32_SERIAL_USE_USART0 == TRUE
|
||||
static void notify0(io_queue_t *qp)
|
||||
{
|
||||
(void)qp;
|
||||
load(&SD0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HT32_SERIAL_USE_USART1 == TRUE
|
||||
static void notify1(io_queue_t *qp)
|
||||
{
|
||||
(void)qp;
|
||||
load(&SD1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void serial_interrupt(SerialDriver *sdp)
|
||||
{
|
||||
USART_TypeDef *u = sdp->usart;
|
||||
|
||||
while ((u->IIR & 1) == 0) {
|
||||
switch ((u->IIR >> 1) & 7) {
|
||||
case 0:
|
||||
/* modem status */
|
||||
break;
|
||||
case 1:
|
||||
/* TX FIFO level */
|
||||
{
|
||||
do {
|
||||
msg_t b;
|
||||
osalSysLockFromISR();
|
||||
b = oqGetI(&sdp->oqueue);
|
||||
osalSysUnlockFromISR();
|
||||
if (b < MSG_OK) {
|
||||
u->IER &= ~TFTLIE;
|
||||
osalSysLockFromISR();
|
||||
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||
osalSysUnlockFromISR();
|
||||
break;
|
||||
}
|
||||
u->TBR = b;
|
||||
} while (0);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* RX FIFO level */
|
||||
case 6:
|
||||
/* RX FIFO timeout */
|
||||
osalSysLockFromISR();
|
||||
if (iqIsEmptyI(&sdp->iqueue))
|
||||
chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
|
||||
osalSysUnlockFromISR();
|
||||
while ((u->LSR & 1) != 0) {
|
||||
osalSysLockFromISR();
|
||||
if (iqPutI(&sdp->iqueue, u->RBR) < MSG_OK)
|
||||
chnAddFlagsI(sdp, SD_OVERRUN_ERROR);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* RX line status */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usart_init(SerialDriver *sdp, const SerialConfig *config)
|
||||
{
|
||||
USART_TypeDef *u = sdp->usart;
|
||||
|
||||
u->DLR = (uint32_t)(HT32_CK_USART_FREQUENCY / config->speed); /* XXX */
|
||||
u->LCR = 0x01; /* 8-bit, one stop, no parity */
|
||||
u->FCR = 0x301;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if HT32_SERIAL_USE_USART0 == TRUE
|
||||
CH_IRQ_HANDLER(HT32_USART0_IRQ_VECTOR) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
serial_interrupt(&SD0);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HT32_SERIAL_USE_USART1 == TRUE
|
||||
CH_IRQ_HANDLER(HT32_USART1_IRQ_VECTOR) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
serial_interrupt(&SD1);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_init(void) {
|
||||
|
||||
#if HT32_SERIAL_USE_USART0 == TRUE
|
||||
sdObjectInit(&SD0, NULL, notify0);
|
||||
SD0.usart = USART0;
|
||||
#endif
|
||||
#if HT32_SERIAL_USE_USART1 == TRUE
|
||||
sdObjectInit(&SD1, NULL, notify1);
|
||||
SD1.usart = USART1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver configuration and (re)start.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] config the architecture-dependent serial driver configuration.
|
||||
* If this parameter is set to @p NULL then a default
|
||||
* configuration is used.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
|
||||
|
||||
if (config == NULL) {
|
||||
config = &default_config;
|
||||
}
|
||||
|
||||
|
||||
if (sdp->state == SD_STOP) {
|
||||
#if HT32_SERIAL_USE_USART0 == TRUE
|
||||
if (&SD0 == sdp) {
|
||||
CKCU->APBCCR0 |= (1U << 8);
|
||||
nvicEnableVector(USART0_IRQn, HT32_USART0_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_SERIAL_USE_USART1 == TRUE
|
||||
if (&SD1 == sdp) {
|
||||
CKCU->APBCCR0 |= (1U << 9);
|
||||
nvicEnableVector(USART1_IRQn, HT32_USART1_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
usart_init(sdp, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver stop.
|
||||
* @details De-initializes the USART, stops the associated clock, resets the
|
||||
* interrupt vector.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_stop(SerialDriver *sdp) {
|
||||
|
||||
if (sdp->state == SD_READY) {
|
||||
#if PLATFORM_SERIAL_USE_USART0 == TRUE
|
||||
if (&SD0 == sdp) {
|
||||
|
||||
}
|
||||
#endif
|
||||
#if PLATFORM_SERIAL_USE_USART1 == TRUE
|
||||
if (&SD1 == sdp) {
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SERIAL == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_serial_lld.h
|
||||
* @brief PLATFORM serial subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_SERIAL_LLD_H
|
||||
#define HAL_SERIAL_LLD_H
|
||||
|
||||
#if (HAL_USE_SERIAL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief USART0 driver enable switch.
|
||||
* @details If set to @p TRUE the support for USART0 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(PLATFORM_SERIAL_USE_USART0) || defined(__DOXYGEN__)
|
||||
#define PLATFORM_SERIAL_USE_USART0 FALSE
|
||||
#endif
|
||||
|
||||
#if !defined(PLATFORM_SERIAL_USE_USART1) || defined(__DOXYGEN__)
|
||||
#define PLATFORM_SERIAL_USE_USART1 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief PLATFORM Serial Driver configuration structure.
|
||||
* @details An instance of this structure must be passed to @p sdStart()
|
||||
* in order to configure and start a serial driver operations.
|
||||
* @note This structure content is architecture dependent, each driver
|
||||
* implementation defines its own version and the custom static
|
||||
* initializers.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Bit rate.
|
||||
*/
|
||||
uint32_t speed;
|
||||
/* End of the mandatory fields.*/
|
||||
} SerialConfig;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
#define _serial_driver_data \
|
||||
_base_asynchronous_channel_data \
|
||||
/* Driver state.*/ \
|
||||
sdstate_t state; \
|
||||
/* Input queue.*/ \
|
||||
input_queue_t iqueue; \
|
||||
/* Output queue.*/ \
|
||||
output_queue_t oqueue; \
|
||||
/* Input circular buffer.*/ \
|
||||
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
|
||||
/* Output circular buffer.*/ \
|
||||
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
USART_TypeDef *usart;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_SERIAL_USE_USART0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD0;
|
||||
#endif
|
||||
#if (HT32_SERIAL_USE_USART1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sd_lld_init(void);
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
|
||||
void sd_lld_stop(SerialDriver *sdp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SERIAL == TRUE */
|
||||
|
||||
#endif /* HAL_SERIAL_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_uart_lld.c
|
||||
* @brief PLATFORM UART subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup UART
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_UART == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART1 driver identifier.
|
||||
*/
|
||||
#if (HT32_UART_USE_UART0 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver UARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_UART1 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver UARTD1;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART0 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver USARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART1 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver USARTD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void uart_lld_handler(UARTDriver *uartp) {
|
||||
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_UART_USE_UART0 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_UART0_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&UARTD0);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
#if (HT32_UART_USE_UART1 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_UART1_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&UARTD1);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HT32_UART_USE_USART0 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_USART0_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&USARTD0);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART1 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_USART1_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&USARTD1);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level UART driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_init(void) {
|
||||
/* Driver initialization. */
|
||||
#if HT32_UART_USE_UART0 == TRUE
|
||||
uartObjectInit(&UARTD0);
|
||||
UARTD0.UART = UART0;
|
||||
#endif
|
||||
#if HT32_UART_USE_UART1 == TRUE
|
||||
uartObjectInit(&UARTD1);
|
||||
UARTD1.UART = UART1;
|
||||
#endif
|
||||
#if HT32_UART_USE_USART0 == TRUE
|
||||
uartObjectInit(&USARTD0);
|
||||
USARTD0.UART = USART0;
|
||||
#endif
|
||||
#if HT32_UART_USE_USART1 == TRUE
|
||||
uartObjectInit(&USARTD1);
|
||||
USARTD1.UART = USART1;
|
||||
#endif
|
||||
|
||||
/* Peripheral initialization. */
|
||||
CKCU->GCFGR = (CKCU->GCFGR & ~CKCU_GCFGR_URPRE_MASK) | ((HT32_USART_PRESCALER - 1) << 22);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the UART peripheral.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_start(UARTDriver *uartp) {
|
||||
if (uartp->state == UART_STOP) {
|
||||
/* Enables the peripheral.*/
|
||||
#if HT32_UART_USE_UART0 == TRUE
|
||||
if (&UARTD1 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_UR0EN;
|
||||
nvicEnableVector(UART0_IRQn, HT32_UART0_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_UART1 == TRUE
|
||||
if (&UARTD1 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_UR1EN;
|
||||
nvicEnableVector(UART1_IRQn, HT32_UART1_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART0 == TRUE
|
||||
if (&USARTD0 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_USR0EN;
|
||||
nvicEnableVector(USART0_IRQn, HT32_USART0_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART1 == TRUE
|
||||
if (&USARTD1 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_USR1EN;
|
||||
nvicEnableVector(USART1_IRQn, HT32_USART1_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configures the peripheral.*/
|
||||
uartp->UART->FCR = uartp->config->fcr;
|
||||
uartp->UART->LCR = uartp->config->lcr;
|
||||
uartp->UART->MDR = uartp->config->mdr;
|
||||
// baud = ck_ahb / dlr value
|
||||
uartp->UART->DLR = HT32_CK_AHB_FREQUENCY / uartp->config->baud;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the UART peripheral.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_stop(UARTDriver *uartp) {
|
||||
if (uartp->state == UART_READY) {
|
||||
/* Resets the peripheral.*/
|
||||
/* Disables the peripheral.*/
|
||||
#if HT32_UART_USE_UART0 == TRUE
|
||||
if (&UARTD0 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_UR0RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_UR0EN;
|
||||
nvicDisableVector(UART0_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_UART1 == TRUE
|
||||
if (&UARTD1 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_UR1RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_UR1EN;
|
||||
nvicDisableVector(UART1_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART0 == TRUE
|
||||
if (&USARTD0 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_USR0RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_USR0EN;
|
||||
nvicDisableVector(USART0_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART1 == TRUE
|
||||
if (&USARTD1 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_USR1RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_USR1EN;
|
||||
nvicDisableVector(USART1_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a transmission on the UART peripheral.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below
|
||||
* or equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
* @param[in] n number of data frames to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
|
||||
if ((uartp->config->lcr & 3) == 2) {
|
||||
uint16_t *txdata = (uint16_t *)txbuf;
|
||||
while(n > 0){
|
||||
uartp->UART->TBR = *txdata;
|
||||
while(!(uartp->UART->LSR & USART_LSR_TXEMPT));
|
||||
txdata++;
|
||||
n--;
|
||||
}
|
||||
} else {
|
||||
uint8_t *txdata = (uint8_t *)txbuf;
|
||||
while(n > 0){
|
||||
uartp->UART->TBR = *txdata;
|
||||
while(!(uartp->UART->LSR & USART_LSR_TXEMPT));
|
||||
txdata++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops any ongoing transmission.
|
||||
* @note Stopping a transmission also suppresses the transmission callbacks.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @return The number of data frames not transmitted by the
|
||||
* stopped transmit operation.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
size_t uart_lld_stop_send(UARTDriver *uartp) {
|
||||
|
||||
(void)uartp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a receive operation on the UART peripheral.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below
|
||||
* or equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
* @param[in] n number of data frames to send
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
|
||||
|
||||
(void)uartp;
|
||||
(void)n;
|
||||
(void)rxbuf;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops any ongoing receive operation.
|
||||
* @note Stopping a receive operation also suppresses the receive callbacks.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @return The number of data frames not received by the
|
||||
* stopped receive operation.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
size_t uart_lld_stop_receive(UARTDriver *uartp) {
|
||||
|
||||
(void)uartp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_UART == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_uart_lld.h
|
||||
* @brief PLATFORM UART subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup UART
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_UART_LLD_H
|
||||
#define HAL_UART_LLD_H
|
||||
|
||||
#if (HAL_USE_UART == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief UART driver enable switch.
|
||||
* @details If set to @p TRUE the support for UART1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(HT32_UART_USE_UART0) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_UART0 FALSE
|
||||
#endif
|
||||
#if !defined(HT32_UART_USE_UART1) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_UART1 FALSE
|
||||
#endif
|
||||
#if !defined(HT32_UART_USE_USART0) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_USART0 FALSE
|
||||
#endif
|
||||
#if !defined(HT32_UART_USE_USART1) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_USART1 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART driver condition flags type.
|
||||
*/
|
||||
typedef uint32_t uartflags_t;
|
||||
|
||||
/**
|
||||
* @brief Type of structure representing an UART driver.
|
||||
*/
|
||||
typedef struct UARTDriver UARTDriver;
|
||||
|
||||
/**
|
||||
* @brief Generic UART notification callback type.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*/
|
||||
typedef void (*uartcb_t)(UARTDriver *uartp);
|
||||
|
||||
/**
|
||||
* @brief Character received UART notification callback type.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object triggering the
|
||||
* callback
|
||||
* @param[in] c received character
|
||||
*/
|
||||
typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
|
||||
|
||||
/**
|
||||
* @brief Receive error UART notification callback type.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object triggering the
|
||||
* callback
|
||||
* @param[in] e receive error mask
|
||||
*/
|
||||
typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief End of transmission buffer callback.
|
||||
*/
|
||||
uartcb_t txend1_cb;
|
||||
/**
|
||||
* @brief Physical end of transmission callback.
|
||||
*/
|
||||
uartcb_t txend2_cb;
|
||||
/**
|
||||
* @brief Receive buffer filled callback.
|
||||
*/
|
||||
uartcb_t rxend_cb;
|
||||
/**
|
||||
* @brief Character received while out if the @p UART_RECEIVE state.
|
||||
*/
|
||||
uartccb_t rxchar_cb;
|
||||
/**
|
||||
* @brief Receive error callback.
|
||||
*/
|
||||
uartecb_t rxerr_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
uint32_t fcr;
|
||||
uint32_t lcr;
|
||||
uint32_t mdr;
|
||||
|
||||
/**
|
||||
* @brief Baud rate.
|
||||
*/
|
||||
uint32_t baud;
|
||||
} UARTConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an UART driver.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
struct UARTDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
uartstate_t state;
|
||||
/**
|
||||
* @brief Transmitter state.
|
||||
*/
|
||||
uarttxstate_t txstate;
|
||||
/**
|
||||
* @brief Receiver state.
|
||||
*/
|
||||
uartrxstate_t rxstate;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const UARTConfig *config;
|
||||
#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Synchronization flag for transmit operations.
|
||||
*/
|
||||
bool early;
|
||||
/**
|
||||
* @brief Waiting thread on RX.
|
||||
*/
|
||||
thread_reference_t threadrx;
|
||||
/**
|
||||
* @brief Waiting thread on TX.
|
||||
*/
|
||||
thread_reference_t threadtx;
|
||||
#endif /* UART_USE_WAIT */
|
||||
#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the peripheral.
|
||||
*/
|
||||
mutex_t mutex;
|
||||
#endif /* UART_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(UART_DRIVER_EXT_FIELDS)
|
||||
UART_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
USART_TypeDef *UART;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_UART_USE_UART0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver UARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_UART1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver UARTD1;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver USARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver USARTD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void uart_lld_init(void);
|
||||
void uart_lld_start(UARTDriver *uartp);
|
||||
void uart_lld_stop(UARTDriver *uartp);
|
||||
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf);
|
||||
size_t uart_lld_stop_send(UARTDriver *uartp);
|
||||
void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
|
||||
size_t uart_lld_stop_receive(UARTDriver *uartp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_UART == TRUE */
|
||||
|
||||
#endif /* HAL_UART_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,13 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F5xxxx/hal_serial_lld.c
|
||||
endif
|
||||
ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F5xxxx/hal_uart_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F5xxxx/hal_serial_lld.c
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F5xxxx/hal_uart_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USART_F5xxxx
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_serial_lld.c
|
||||
* @brief HT32 serial subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_SERIAL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief USART0 serial driver identifier.*/
|
||||
# if (HT32_SERIAL_USE_USART0 == TRUE) || defined(__DOXYGEN__)
|
||||
SerialDriver SD0;
|
||||
# endif
|
||||
# if (HT32_SERIAL_USE_USART1 == TRUE) || defined(__DOXYGEN__)
|
||||
SerialDriver SD1;
|
||||
# endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver default configuration.
|
||||
*/
|
||||
static const SerialConfig default_config = {SERIAL_DEFAULT_BITRATE};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void load(SerialDriver *sdp) {
|
||||
USART_TypeDef *u = sdp->usart;
|
||||
|
||||
u->IER |= (USART_IER_TXDEIE | USART_IER_TXCIE);
|
||||
}
|
||||
|
||||
# if HT32_SERIAL_USE_USART0 == TRUE
|
||||
static void notify0(io_queue_t *qp) {
|
||||
(void)qp;
|
||||
load(&SD0);
|
||||
}
|
||||
# endif
|
||||
|
||||
# if HT32_SERIAL_USE_USART1 == TRUE
|
||||
static void notify1(io_queue_t *qp) {
|
||||
(void)qp;
|
||||
load(&SD1);
|
||||
}
|
||||
# endif
|
||||
|
||||
static void serialInterrupt(SerialDriver *pSd) {
|
||||
USART_TypeDef *u = pSd->usart;
|
||||
|
||||
uint32_t sifr = u->SIFR;
|
||||
// Rx has data, timeout or crossed threashold
|
||||
// TX Below threash or complete
|
||||
if ((sifr & USART_SIFR_TXDE) || (sifr & USART_SIFR_TXC)) {
|
||||
msg_t b;
|
||||
osalSysLockFromISR();
|
||||
{
|
||||
b = oqGetI(&(pSd->oqueue));
|
||||
if (b < MSG_OK) {
|
||||
u->IER &= ~(USART_IER_TXDEIE | USART_IER_TXCIE);
|
||||
chnAddFlagsI(pSd, CHN_OUTPUT_EMPTY);
|
||||
} else {
|
||||
u->DR = b;
|
||||
}
|
||||
}
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
if (sifr & (USART_SIFR_RXDNE | USART_SIFR_RXDR | USART_SIFR_RXTOF)) {
|
||||
osalSysLockFromISR();
|
||||
{
|
||||
if (iqIsEmptyI(&pSd->iqueue)) chnAddFlagsI(pSd, CHN_INPUT_AVAILABLE);
|
||||
|
||||
while ((u->SIFR) & USART_SIFR_RXDNE) {
|
||||
if (iqPutI(&(pSd->iqueue), u->DR) < MSG_OK) chnAddFlagsI(pSd, SD_OVERRUN_ERROR);
|
||||
}
|
||||
|
||||
// Clear Timeout if it occours
|
||||
if (sifr & USART_SIFR_RXTOF) u->SIFR = USART_SIFR_RXTOF;
|
||||
}
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
// Clear all remaining flags.
|
||||
u->SIFR &= 0x3FF;
|
||||
}
|
||||
|
||||
static void usartInit(SerialDriver *sdp, const SerialConfig *config) {
|
||||
USART_TypeDef *u = sdp->usart;
|
||||
|
||||
u->DLR = (uint32_t)(HT32_CK_USART_FREQUENCY / config->speed); /* Data Rate */
|
||||
u->CR = (UART_CR_MODE_NORMAL | UART_CR_URTXEN | UART_CR_URRXEN | UART_CR_WLS_8B); /* 8-bit, one stop, no parity */
|
||||
u->FCR = USART_FCR_TXR | USART_FCR_RXR; // Reset FIFOs.
|
||||
u->IER = USART_IER_RXDRIE | USART_IER_TXDEIE | USART_IER_TXCIE;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
# if HT32_SERIAL_USE_USART0 == TRUE
|
||||
CH_IRQ_HANDLER(HT32_USART0_IRQ_VECTOR) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
serialInterrupt(&SD0);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
# endif
|
||||
|
||||
# if HT32_SERIAL_USE_USART1 == TRUE
|
||||
CH_IRQ_HANDLER(HT32_USART1_IRQ_VECTOR) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
serialInterrupt(&SD1);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
# endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_init(void) {
|
||||
# if HT32_SERIAL_USE_USART0 == TRUE
|
||||
sdObjectInit(&SD0, NULL, notify0);
|
||||
SD0.usart = USART0;
|
||||
# endif
|
||||
# if HT32_SERIAL_USE_USART1 == TRUE
|
||||
sdObjectInit(&SD1, NULL, notify1);
|
||||
SD1.usart = USART1;
|
||||
# endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver configuration and (re)start.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] config the architecture-dependent serial driver configuration.
|
||||
* If this parameter is set to @p NULL then a default
|
||||
* configuration is used.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
|
||||
if (config == NULL) {
|
||||
config = &default_config;
|
||||
}
|
||||
|
||||
if (sdp->state == SD_STOP) {
|
||||
# if HT32_SERIAL_USE_USART0 == TRUE
|
||||
if (&SD0 == sdp) {
|
||||
CKCU->APBCCR0 |= (1U << 8);
|
||||
nvicEnableVector(USART0_IRQn, HT32_USART0_IRQ_PRIORITY);
|
||||
}
|
||||
# endif
|
||||
# if HT32_SERIAL_USE_USART1 == TRUE
|
||||
if (&SD1 == sdp) {
|
||||
CKCU->APBCCR0 |= (1U << 9);
|
||||
nvicEnableVector(USART1_IRQn, HT32_USART1_IRQ_PRIORITY);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
usartInit(sdp, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver stop.
|
||||
* @details De-initializes the USART, stops the associated clock, resets the
|
||||
* interrupt vector.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_stop(SerialDriver *sdp) {
|
||||
if (sdp->state == SD_READY) {
|
||||
USART_TypeDef *u = sdp->usart;
|
||||
|
||||
# if HT32_SERIAL_USE_USART0 == TRUE
|
||||
if (&SD0 == sdp) {
|
||||
nvicDisableVector(USART0_IRQn);
|
||||
u -> IER = 0; // Disable all interrupts
|
||||
}
|
||||
# endif // HT32_SERIAL_USE_USART0 == TRUE
|
||||
# if HT32_SERIAL_USE_USART1 == TRUE
|
||||
if (&SD1 == sdp) {
|
||||
nvicDisableVector(USART1_IRQn);
|
||||
u -> IER = 0; // Disable all interrupts
|
||||
}
|
||||
# endif // HT32_SERIAL_USE_USART1 == TRUE
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SERIAL == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_serial_lld.h
|
||||
* @brief PLATFORM serial subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_SERIAL_LLD_H
|
||||
#define HAL_SERIAL_LLD_H
|
||||
|
||||
#if (HAL_USE_SERIAL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief USART0 driver enable switch.
|
||||
* @details If set to @p TRUE the support for USART0 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(PLATFORM_SERIAL_USE_USART0) || defined(__DOXYGEN__)
|
||||
#define PLATFORM_SERIAL_USE_USART0 FALSE
|
||||
#endif
|
||||
|
||||
#if !defined(PLATFORM_SERIAL_USE_USART1) || defined(__DOXYGEN__)
|
||||
#define PLATFORM_SERIAL_USE_USART1 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief PLATFORM Serial Driver configuration structure.
|
||||
* @details An instance of this structure must be passed to @p sdStart()
|
||||
* in order to configure and start a serial driver operations.
|
||||
* @note This structure content is architecture dependent, each driver
|
||||
* implementation defines its own version and the custom static
|
||||
* initializers.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Bit rate.
|
||||
*/
|
||||
uint32_t speed;
|
||||
/* End of the mandatory fields.*/
|
||||
} SerialConfig;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
#define _serial_driver_data \
|
||||
_base_asynchronous_channel_data \
|
||||
/* Driver state.*/ \
|
||||
sdstate_t state; \
|
||||
/* Input queue.*/ \
|
||||
input_queue_t iqueue; \
|
||||
/* Output queue.*/ \
|
||||
output_queue_t oqueue; \
|
||||
/* Input circular buffer.*/ \
|
||||
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
|
||||
/* Output circular buffer.*/ \
|
||||
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
USART_TypeDef *usart;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_SERIAL_USE_USART0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD0;
|
||||
#endif
|
||||
#if (HT32_SERIAL_USE_USART1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sd_lld_init(void);
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
|
||||
void sd_lld_stop(SerialDriver *sdp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SERIAL == TRUE */
|
||||
|
||||
#endif /* HAL_SERIAL_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_uart_lld.c
|
||||
* @brief PLATFORM UART subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup UART
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_UART == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART1 driver identifier.
|
||||
*/
|
||||
#if (HT32_UART_USE_UART0 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver UARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_UART1 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver UARTD1;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART0 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver USARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART1 == TRUE) || defined(__DOXYGEN__)
|
||||
UARTDriver USARTD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void uart_lld_handler(UARTDriver *uartp) {
|
||||
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_UART_USE_UART0 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_UART0_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&UARTD0);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
#if (HT32_UART_USE_UART1 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_UART1_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&UARTD1);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HT32_UART_USE_USART0 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_USART0_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&USARTD0);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART1 == TRUE) || defined(__DOXYGEN__)
|
||||
OSAL_IRQ_HANDLER(HT32_USART1_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
uart_lld_handler(&USARTD1);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level UART driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_init(void) {
|
||||
/* Driver initialization. */
|
||||
#if HT32_UART_USE_UART0 == TRUE
|
||||
uartObjectInit(&UARTD0);
|
||||
UARTD0.UART = UART0;
|
||||
#endif
|
||||
#if HT32_UART_USE_UART1 == TRUE
|
||||
uartObjectInit(&UARTD1);
|
||||
UARTD1.UART = UART1;
|
||||
#endif
|
||||
#if HT32_UART_USE_USART0 == TRUE
|
||||
uartObjectInit(&USARTD0);
|
||||
USARTD0.UART = USART0;
|
||||
#endif
|
||||
#if HT32_UART_USE_USART1 == TRUE
|
||||
uartObjectInit(&USARTD1);
|
||||
USARTD1.UART = USART1;
|
||||
#endif
|
||||
|
||||
/* Peripheral initialization. */
|
||||
CKCU->GCFGR = (CKCU->GCFGR & ~CKCU_GCFGR_URPRE_MASK) | ((HT32_USART_PRESCALER - 1) << 22);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the UART peripheral.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_start(UARTDriver *uartp) {
|
||||
if (uartp->state == UART_STOP) {
|
||||
/* Enables the peripheral.*/
|
||||
#if HT32_UART_USE_UART0 == TRUE
|
||||
if (&UARTD1 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_UR0EN;
|
||||
nvicEnableVector(UART0_IRQn, HT32_UART0_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_UART1 == TRUE
|
||||
if (&UARTD1 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_UR1EN;
|
||||
nvicEnableVector(UART1_IRQn, HT32_UART1_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART0 == TRUE
|
||||
if (&USARTD0 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_USR0EN;
|
||||
nvicEnableVector(USART0_IRQn, HT32_USART0_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART1 == TRUE
|
||||
if (&USARTD1 == uartp) {
|
||||
CKCU->APBCCR0 |= CKCU_APBCCR0_USR1EN;
|
||||
nvicEnableVector(USART1_IRQn, HT32_USART1_IRQ_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configures the peripheral.*/
|
||||
uartp->UART->FCR = uartp->config->fcr;
|
||||
uartp->UART->LCR = uartp->config->lcr;
|
||||
uartp->UART->MDR = uartp->config->mdr;
|
||||
// baud = ck_ahb / dlr value
|
||||
uartp->UART->DLR = HT32_CK_AHB_FREQUENCY / uartp->config->baud;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the UART peripheral.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_stop(UARTDriver *uartp) {
|
||||
if (uartp->state == UART_READY) {
|
||||
/* Resets the peripheral.*/
|
||||
/* Disables the peripheral.*/
|
||||
#if HT32_UART_USE_UART0 == TRUE
|
||||
if (&UARTD0 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_UR0RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_UR0EN;
|
||||
nvicDisableVector(UART0_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_UART1 == TRUE
|
||||
if (&UARTD1 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_UR1RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_UR1EN;
|
||||
nvicDisableVector(UART1_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART0 == TRUE
|
||||
if (&USARTD0 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_USR0RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_USR0EN;
|
||||
nvicDisableVector(USART0_IRQn);
|
||||
}
|
||||
#endif
|
||||
#if HT32_UART_USE_USART1 == TRUE
|
||||
if (&USARTD1 == uartp) {
|
||||
RSTCU->APBPRSTR0 = RSTCU_APBPRSTR0_USR1RST;
|
||||
CKCU->APBCCR0 &= ~CKCU_APBCCR0_USR1EN;
|
||||
nvicDisableVector(USART1_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a transmission on the UART peripheral.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below
|
||||
* or equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
* @param[in] n number of data frames to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
|
||||
if ((uartp->config->lcr & 3) == 2) {
|
||||
uint16_t *txdata = (uint16_t *)txbuf;
|
||||
while(n > 0){
|
||||
uartp->UART->TBR = *txdata;
|
||||
while(!(uartp->UART->LSR & USART_LSR_TXEMPT));
|
||||
txdata++;
|
||||
n--;
|
||||
}
|
||||
} else {
|
||||
uint8_t *txdata = (uint8_t *)txbuf;
|
||||
while(n > 0){
|
||||
uartp->UART->TBR = *txdata;
|
||||
while(!(uartp->UART->LSR & USART_LSR_TXEMPT));
|
||||
txdata++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops any ongoing transmission.
|
||||
* @note Stopping a transmission also suppresses the transmission callbacks.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @return The number of data frames not transmitted by the
|
||||
* stopped transmit operation.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
size_t uart_lld_stop_send(UARTDriver *uartp) {
|
||||
|
||||
(void)uartp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a receive operation on the UART peripheral.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below
|
||||
* or equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
* @param[in] n number of data frames to send
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
|
||||
|
||||
(void)uartp;
|
||||
(void)n;
|
||||
(void)rxbuf;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops any ongoing receive operation.
|
||||
* @note Stopping a receive operation also suppresses the receive callbacks.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*
|
||||
* @return The number of data frames not received by the
|
||||
* stopped receive operation.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
size_t uart_lld_stop_receive(UARTDriver *uartp) {
|
||||
|
||||
(void)uartp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_UART == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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_uart_lld.h
|
||||
* @brief PLATFORM UART subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup UART
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_UART_LLD_H
|
||||
#define HAL_UART_LLD_H
|
||||
|
||||
#if (HAL_USE_UART == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief UART driver enable switch.
|
||||
* @details If set to @p TRUE the support for UART1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(HT32_UART_USE_UART0) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_UART0 FALSE
|
||||
#endif
|
||||
#if !defined(HT32_UART_USE_UART1) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_UART1 FALSE
|
||||
#endif
|
||||
#if !defined(HT32_UART_USE_USART0) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_USART0 FALSE
|
||||
#endif
|
||||
#if !defined(HT32_UART_USE_USART1) || defined(__DOXYGEN__)
|
||||
#define HT32_UART_USE_USART1 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART driver condition flags type.
|
||||
*/
|
||||
typedef uint32_t uartflags_t;
|
||||
|
||||
/**
|
||||
* @brief Type of structure representing an UART driver.
|
||||
*/
|
||||
typedef struct UARTDriver UARTDriver;
|
||||
|
||||
/**
|
||||
* @brief Generic UART notification callback type.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*/
|
||||
typedef void (*uartcb_t)(UARTDriver *uartp);
|
||||
|
||||
/**
|
||||
* @brief Character received UART notification callback type.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object triggering the
|
||||
* callback
|
||||
* @param[in] c received character
|
||||
*/
|
||||
typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
|
||||
|
||||
/**
|
||||
* @brief Receive error UART notification callback type.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object triggering the
|
||||
* callback
|
||||
* @param[in] e receive error mask
|
||||
*/
|
||||
typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief End of transmission buffer callback.
|
||||
*/
|
||||
uartcb_t txend1_cb;
|
||||
/**
|
||||
* @brief Physical end of transmission callback.
|
||||
*/
|
||||
uartcb_t txend2_cb;
|
||||
/**
|
||||
* @brief Receive buffer filled callback.
|
||||
*/
|
||||
uartcb_t rxend_cb;
|
||||
/**
|
||||
* @brief Character received while out if the @p UART_RECEIVE state.
|
||||
*/
|
||||
uartccb_t rxchar_cb;
|
||||
/**
|
||||
* @brief Receive error callback.
|
||||
*/
|
||||
uartecb_t rxerr_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
uint32_t fcr;
|
||||
uint32_t lcr;
|
||||
uint32_t mdr;
|
||||
|
||||
/**
|
||||
* @brief Baud rate.
|
||||
*/
|
||||
uint32_t baud;
|
||||
} UARTConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an UART driver.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
struct UARTDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
uartstate_t state;
|
||||
/**
|
||||
* @brief Transmitter state.
|
||||
*/
|
||||
uarttxstate_t txstate;
|
||||
/**
|
||||
* @brief Receiver state.
|
||||
*/
|
||||
uartrxstate_t rxstate;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const UARTConfig *config;
|
||||
#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Synchronization flag for transmit operations.
|
||||
*/
|
||||
bool early;
|
||||
/**
|
||||
* @brief Waiting thread on RX.
|
||||
*/
|
||||
thread_reference_t threadrx;
|
||||
/**
|
||||
* @brief Waiting thread on TX.
|
||||
*/
|
||||
thread_reference_t threadtx;
|
||||
#endif /* UART_USE_WAIT */
|
||||
#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the peripheral.
|
||||
*/
|
||||
mutex_t mutex;
|
||||
#endif /* UART_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(UART_DRIVER_EXT_FIELDS)
|
||||
UART_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
USART_TypeDef *UART;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_UART_USE_UART0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver UARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_UART1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver UARTD1;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART0 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver USARTD0;
|
||||
#endif
|
||||
#if (HT32_UART_USE_USART1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern UARTDriver USARTD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void uart_lld_init(void);
|
||||
void uart_lld_start(UARTDriver *uartp);
|
||||
void uart_lld_stop(UARTDriver *uartp);
|
||||
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf);
|
||||
size_t uart_lld_stop_send(UARTDriver *uartp);
|
||||
void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
|
||||
size_t uart_lld_stop_receive(UARTDriver *uartp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_UART == TRUE */
|
||||
|
||||
#endif /* HAL_UART_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,9 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USBv1/hal_usb_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USBv1/hal_usb_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/HT32/LLD/USBv1
|
|
@ -0,0 +1,712 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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 HT32 USB subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup USB
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define roundup2(x, m) (((x) + (m) - 1) & ~((m) - 1))
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief USB1 driver identifier.
|
||||
*/
|
||||
#if HT32_USB_USE_USB0 || defined(__DOXYGEN__)
|
||||
USBDriver USBD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EP0 state.
|
||||
* @note It is an union because IN and OUT endpoints are never used at the
|
||||
* same time for EP0.
|
||||
*/
|
||||
static union {
|
||||
/**
|
||||
* @brief IN EP0 state.
|
||||
*/
|
||||
USBInEndpointState in;
|
||||
/**
|
||||
* @brief OUT EP0 state.
|
||||
*/
|
||||
USBOutEndpointState out;
|
||||
} ep0_state;
|
||||
|
||||
/**
|
||||
* @brief EP0 initialization structure.
|
||||
*/
|
||||
static const USBEndpointConfig ep0config = {
|
||||
USB_EP_MODE_TYPE_CTRL,
|
||||
_usb_ep0setup,
|
||||
_usb_ep0in,
|
||||
_usb_ep0out,
|
||||
0x40,
|
||||
0x40,
|
||||
&ep0_state.in,
|
||||
&ep0_state.out
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static uint32_t usb_get_int_flags(void){
|
||||
return USB->IER & USB->ISR;
|
||||
}
|
||||
|
||||
static void usb_clear_int_flags(uint32_t flags){
|
||||
// flags are cleared by writing 1
|
||||
// except ESOFIF, which is written normally
|
||||
USB->ISR = flags ^ USBISR_ESOFIF;
|
||||
}
|
||||
|
||||
static uint32_t usb_get_ep_int_flags(int ep){
|
||||
return USB->EP[ep].IER & USB->EP[ep].ISR;
|
||||
}
|
||||
|
||||
static void usb_clear_ep_int_flags(int ep, uint32_t flags){
|
||||
// flags are cleared by writing 1
|
||||
USB->EP[ep].ISR = flags;
|
||||
}
|
||||
|
||||
static size_t usb_epmem_alloc(USBDriver *usbp, size_t size) {
|
||||
const size_t epmo = usbp->epmem_next;
|
||||
|
||||
usbp->epmem_next = roundup2(epmo + size, 4);
|
||||
osalDbgAssert(usbp->epmem_next <= 0x400, "EPSRAM exhausted");
|
||||
return epmo;
|
||||
}
|
||||
|
||||
static void usb_packet_transmit(USBDriver *usbp, usbep_t ep, size_t n)
|
||||
{
|
||||
const USBEndpointConfig * const epc = usbp->epc[ep];
|
||||
USBInEndpointState * const isp = epc->in_state;
|
||||
|
||||
if (n > (size_t)epc->in_maxsize)
|
||||
n = (size_t)epc->in_maxsize;
|
||||
|
||||
if ((USB->EP[ep].TCR & 0xffffU) == 0) {
|
||||
const uint32_t cfgr = USB->EP[ep].CFGR;
|
||||
volatile uint32_t * const EPSRAM = (void *)(USB_SRAM_BASE + (cfgr & 0x3ff));
|
||||
for (size_t i = 0; i < n; i += 4) {
|
||||
uint32_t word = 0;
|
||||
if (i + 0 < n)
|
||||
word |= (uint32_t)isp->txbuf[i+0]<<0;
|
||||
if (i + 1 < n)
|
||||
word |= (uint32_t)isp->txbuf[i+1]<<8;
|
||||
if (i + 2 < n)
|
||||
word |= (uint32_t)isp->txbuf[i+2]<<16;
|
||||
if (i + 3 < n)
|
||||
word |= (uint32_t)isp->txbuf[i+3]<<24;
|
||||
EPSRAM[i/4] = word;
|
||||
}
|
||||
|
||||
USB->EP[ep].TCR = n;
|
||||
isp->txlastpktlen = n;
|
||||
USB->EP[ep].CSR &= USBEPnCSR_NAKTX;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t usb_packet_receive(USBDriver *usbp, usbep_t ep) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
const size_t n = USB->EP[ep].TCR >> ((ep == 0) ? 16 : 0);
|
||||
const uint32_t cfgr = USB->EP[ep].CFGR;
|
||||
volatile uint32_t *const EPSRAM = (void *)(USB_SRAM_BASE + (cfgr & 0x3ff) + ((ep == 0) ? ((cfgr >> 10) & 0x7f) : 0));
|
||||
|
||||
for (size_t i = 0; i < n; i += 4) {
|
||||
if(!osp->rxbuf)
|
||||
break;
|
||||
const uint32_t word = EPSRAM[i/4];
|
||||
if (i + 0 < n)
|
||||
osp->rxbuf[i + 0] = word >> 0;
|
||||
if (i + 1 < n)
|
||||
osp->rxbuf[i + 1] = word >> 8;
|
||||
if (i + 2 < n)
|
||||
osp->rxbuf[i + 2] = word >> 16;
|
||||
if (i + 3 < n)
|
||||
osp->rxbuf[i + 3] = word >> 24;
|
||||
}
|
||||
|
||||
osp->rxbuf += n;
|
||||
osp->rxcnt += n;
|
||||
osp->rxsize -= n;
|
||||
osp->rxpkts--;
|
||||
return n;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers and threads. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_USB_USE_USB0 == TRUE) || defined(__DOXYGEN__) || 1
|
||||
|
||||
/**
|
||||
* @brief USB interrupt handler.
|
||||
* @isr
|
||||
*/
|
||||
|
||||
OSAL_IRQ_HANDLER(HT32_USB_IRQ_VECTOR) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
USBDriver *usbp = &USBD1;
|
||||
|
||||
uint32_t isr = usb_get_int_flags();
|
||||
|
||||
// Start of Frame Interrupt
|
||||
if(isr & USBISR_SOFIF){
|
||||
// Start of Frame callback
|
||||
_usb_isr_invoke_sof_cb(usbp);
|
||||
usb_clear_int_flags(USBISR_SOFIF);
|
||||
}
|
||||
|
||||
// Suspend Interrupt
|
||||
if(isr & USBISR_SUSPIF){
|
||||
usb_clear_int_flags(USBISR_SUSPIF);
|
||||
// Suspend routine and event callback
|
||||
_usb_suspend(usbp);
|
||||
#if 0
|
||||
USB->CSR &= USBCSR_DPPUEN; /* POWER_ON */
|
||||
USB->CSR |= USBCSR_GENRSM;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Reset Interrupt
|
||||
if(isr & USBISR_URSTIF){
|
||||
// Reset routine and event callback
|
||||
_usb_reset(usbp);
|
||||
usb_clear_int_flags(USBISR_URSTIF);
|
||||
}
|
||||
|
||||
// Resume Interrupt
|
||||
if(isr & USBISR_RSMIF){
|
||||
// Resume/Wakeup routine and callback
|
||||
_usb_wakeup(usbp);
|
||||
usb_clear_int_flags(USBISR_RSMIF);
|
||||
}
|
||||
|
||||
// EP0 Interrupt
|
||||
if(isr & USBISR_EP0IF){
|
||||
uint32_t episr = usb_get_ep_int_flags(0);
|
||||
|
||||
#if 0
|
||||
// SETUP Token Received
|
||||
if(episr & USBEPnISR_STRXIF){
|
||||
usb_clear_ep_int_flags(0, USBEPnISR_STRXIF);
|
||||
}
|
||||
#endif
|
||||
|
||||
// SETUP Data Received
|
||||
if(episr & USBEPnISR_SDRXIF){
|
||||
// SETUP callback
|
||||
_usb_isr_invoke_setup_cb(usbp, 0);
|
||||
usb_clear_ep_int_flags(0, USBEPnISR_SDRXIF);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// OUT Token Received
|
||||
if(episr & USBEPnISR_OTRXIF){
|
||||
usb_clear_ep_int_flags(0, USBEPnISR_OTRXIF);
|
||||
}
|
||||
#endif
|
||||
|
||||
// OUT Data Received
|
||||
if(episr & USBEPnISR_ODRXIF){
|
||||
USBOutEndpointState *osp = usbp->epc[0]->out_state;
|
||||
size_t n = usb_packet_receive(usbp, 0);
|
||||
if ((n < usbp->epc[0]->out_maxsize) || (osp->rxpkts == 0)) {
|
||||
// OUT callback
|
||||
_usb_isr_invoke_out_cb(usbp, 0);
|
||||
} else {
|
||||
USB->EP[0].CSR &= USBEPnCSR_NAKRX;
|
||||
}
|
||||
usb_clear_ep_int_flags(0, USBEPnISR_ODRXIF);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// IN Token Received
|
||||
if(episr & USBEPnISR_ITRXIF){
|
||||
usb_clear_ep_int_flags(0, USBEPnISR_ITRXIF);
|
||||
}
|
||||
#endif
|
||||
|
||||
// IN Data Transmitted
|
||||
if(episr & USBEPnISR_IDTXIF){
|
||||
USBInEndpointState *isp = usbp->epc[0]->in_state;
|
||||
size_t n = isp->txlastpktlen;
|
||||
isp->txcnt += n;
|
||||
if (isp->txcnt < isp->txsize) {
|
||||
isp->txbuf += n;
|
||||
osalSysLockFromISR();
|
||||
usb_packet_transmit(usbp, 0, isp->txsize - isp->txcnt);
|
||||
osalSysUnlockFromISR();
|
||||
} else {
|
||||
// IN callback
|
||||
_usb_isr_invoke_in_cb(usbp, 0);
|
||||
}
|
||||
usb_clear_ep_int_flags(0, USBEPnISR_IDTXIF);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// STALL Transmitted
|
||||
if(episr & USBEPnISR_STLIF){
|
||||
usb_clear_ep_int_flags(0, USBEPnISR_STLIF);
|
||||
}
|
||||
#endif
|
||||
|
||||
usb_clear_int_flags(USBISR_EP0IF);
|
||||
}
|
||||
|
||||
// EP 1-7 Interrupt
|
||||
uint32_t mask = USBISR_EP1IF;
|
||||
for(int i = 1; i < 8; ++i){
|
||||
// EPn Interrupt
|
||||
if(isr & mask){
|
||||
uint32_t episr = usb_get_ep_int_flags(i);
|
||||
|
||||
usb_clear_ep_int_flags(i, episr);
|
||||
usb_clear_int_flags(mask);
|
||||
|
||||
#if 0
|
||||
// OUT Token Received
|
||||
if(episr & USBEPnISR_OTRXIF){
|
||||
usb_clear_ep_int_flags(i, USBEPnISR_OTRXIF);
|
||||
}
|
||||
#endif
|
||||
|
||||
// OUT Data Received
|
||||
if(episr & USBEPnISR_ODRXIF){
|
||||
USBOutEndpointState *osp = usbp->epc[i]->out_state;
|
||||
size_t n = usb_packet_receive(usbp, i);
|
||||
if ((n < usbp->epc[i]->out_maxsize) || (osp->rxpkts == 0)) {
|
||||
// OUT callback
|
||||
_usb_isr_invoke_out_cb(usbp, i);
|
||||
} else {
|
||||
USB->EP[i].CSR &= USBEPnCSR_NAKRX;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// IN Token Received
|
||||
if(episr & USBEPnISR_ITRXIF){
|
||||
usb_clear_ep_int_flags(i, USBEPnISR_ITRXIF);
|
||||
}
|
||||
#endif
|
||||
|
||||
// IN Data Transmitted
|
||||
if(episr & USBEPnISR_IDTXIF){
|
||||
USBInEndpointState *isp = usbp->epc[i]->in_state;
|
||||
size_t n = isp->txlastpktlen;
|
||||
isp->txcnt += n;
|
||||
if (isp->txcnt < isp->txsize) {
|
||||
isp->txbuf += n;
|
||||
osalSysLockFromISR();
|
||||
usb_packet_transmit(usbp, i, isp->txsize - isp->txcnt);
|
||||
osalSysUnlockFromISR();
|
||||
} else {
|
||||
// IN callback
|
||||
_usb_isr_invoke_in_cb(usbp, i);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// STALL Transmitted
|
||||
if(episr & USBEPnISR_STLIF){
|
||||
usb_clear_ep_int_flags(i, USBEPnISR_STLIF);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
mask = mask << 1;
|
||||
}
|
||||
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level USB driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_init(void){
|
||||
#if HT32_USB_USE_USB0 == TRUE
|
||||
/* Driver initialization.*/
|
||||
usbObjectInit(&USBD1);
|
||||
|
||||
// USB prescaler
|
||||
CKCU->GCFGR = (CKCU->GCFGR & ~CKCU_GCFGR_USBPRE_MASK) | ((HT32_USB_PRESCALER - 1) << 22);
|
||||
// enable USB clock
|
||||
CKCU->AHBCCR |= CKCU_AHBCCR_USBEN;
|
||||
#endif // HT32_USB_USE_USB1
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 HT32_USB_USE_USB0 == TRUE
|
||||
if (&USBD1 == usbp) {
|
||||
// enable USB IRQ
|
||||
nvicEnableVector(USB_IRQn, HT32_USB_USB0_IRQ_PRIORITY);
|
||||
/* USBD_PowerUp */
|
||||
USB->CSR = USBCSR_DPWKEN | USBCSR_DPPUEN | USBCSR_LPMODE | USBCSR_PDWN;
|
||||
// enable usb interrupts
|
||||
USB->ISR = ~0U;
|
||||
USB->CSR &= ~USBCSR_DPWKEN;
|
||||
USB->IER = USBIER_UGIE | USBIER_SOFIE |
|
||||
USBIER_URSTIE | USBIER_RSMIE | USBIER_SUSPIE |
|
||||
USBIER_EP0IE;
|
||||
}
|
||||
#endif // HT32_USB_USE_USB1
|
||||
}
|
||||
/* Configures the peripheral.*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 HT32_USB_USE_USB0 == TRUE
|
||||
if (&USBD1 == usbp) {
|
||||
nvicDisableVector(USB_IRQn);
|
||||
/* Resets the peripheral.*/
|
||||
RSTCU->AHBPRSTR = RSTCU_AHBPRSTR_USBRST;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB low level reset routine.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_reset(USBDriver *usbp) {
|
||||
// USB Reset
|
||||
// Clear CSR, except for DP pull up
|
||||
USB->CSR &= USBCSR_DPPUEN;
|
||||
|
||||
/* Post reset initialization.*/
|
||||
usbp->epmem_next = 8;
|
||||
|
||||
/* EP0 initialization.*/
|
||||
usbp->epc[0] = &ep0config;
|
||||
usb_lld_init_endpoint(usbp, 0);
|
||||
|
||||
USB->IER = USBIER_UGIE | USBIER_SOFIE |
|
||||
USBIER_URSTIE | USBIER_RSMIE | USBIER_SUSPIE |
|
||||
USBIER_EP0IE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the USB address.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_set_address(USBDriver *usbp) {
|
||||
USB->CSR |= USBCSR_ADRSET;
|
||||
USB->DEVAR = usbp->address & 0x7f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
if(ep > USB_MAX_ENDPOINTS)
|
||||
return;
|
||||
|
||||
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||
uint32_t cfgr = USBEPnCFGR_EPEN | ((uint32_t)ep<<24);
|
||||
size_t epmo;
|
||||
|
||||
switch(epcp->ep_mode & USB_EP_MODE_TYPE){
|
||||
case USB_EP_MODE_TYPE_CTRL:
|
||||
break;
|
||||
case USB_EP_MODE_TYPE_ISOC:
|
||||
cfgr |= USBEPnCFGR_EPTYPE;
|
||||
break;
|
||||
case USB_EP_MODE_TYPE_BULK:
|
||||
break;
|
||||
case USB_EP_MODE_TYPE_INTR:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (epcp->in_state != NULL) {
|
||||
epmo = usb_epmem_alloc(usbp, epcp->in_maxsize);
|
||||
cfgr |= epmo << 0;
|
||||
cfgr |= roundup2(epcp->in_maxsize, 4) << 10;
|
||||
cfgr |= USBEPnCFGR_EPDIR;
|
||||
}
|
||||
|
||||
if (epcp->out_state != NULL) {
|
||||
epmo = usb_epmem_alloc(usbp, epcp->out_maxsize);
|
||||
if (ep > 0) {
|
||||
cfgr |= epmo << 0;
|
||||
cfgr |= roundup2(epcp->out_maxsize, 4) << 10;
|
||||
}
|
||||
}
|
||||
|
||||
USB->EP[ep].CFGR = cfgr;
|
||||
USB->EP[ep].IER = (ep == 0) ?
|
||||
(USBEPnIER_SDRXIE|USBEPnIER_IDTXIE|USBEPnIER_ODRXIE) :
|
||||
(USBEPnIER_ODRXIE|USBEPnIER_IDTXIE);
|
||||
USB->IER |= (USBIER_EP0IE << ep);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
for(int i = 1; i < USB_MAX_ENDPOINTS; ++i) {
|
||||
USB->EP[i].CFGR &= ~USBEPnCFGR_EPEN;
|
||||
USB->IER &= ~(USBIER_EP0IE << i);
|
||||
}
|
||||
|
||||
const uint32_t cfgr = USB->EP[0].CFGR;
|
||||
usbp->epmem_next = (cfgr & 0x3ff) + ((cfgr >> 10) & 0x7f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
if (ep > USB_MAX_ENDPOINTS)
|
||||
return EP_STATUS_DISABLED;
|
||||
if ((USB->EP[ep].CFGR & USBEPnCFGR_EPEN) == 0)
|
||||
return EP_STATUS_DISABLED;
|
||||
if ((USB->EP[ep].CSR & USBEPnCSR_STLRX) != 0)
|
||||
return EP_STATUS_STALLED;
|
||||
return EP_STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
if (ep > USB_MAX_ENDPOINTS)
|
||||
return EP_STATUS_DISABLED;
|
||||
if ((USB->EP[ep].CFGR & USBEPnCFGR_EPEN) == 0)
|
||||
return EP_STATUS_DISABLED;
|
||||
if ((USB->EP[ep].CSR & USBEPnCSR_STLRX) != 0)
|
||||
return EP_STATUS_STALLED;
|
||||
return EP_STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
volatile uint32_t * const EPSRAM = (void *)(USB_SRAM_BASE + 0);
|
||||
for (size_t i = 0; i < 8; i += 4) {
|
||||
const uint32_t word = EPSRAM[i/4];
|
||||
buf[i + 0] = (word>>0);
|
||||
buf[i + 1] = (word>>8);
|
||||
buf[i + 2] = (word>>16);
|
||||
buf[i + 3] = (word>>24);
|
||||
}
|
||||
(void)usbp;
|
||||
(void)ep;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
USBOutEndpointState * const osp = usbp->epc[ep]->out_state;
|
||||
|
||||
if (osp->rxsize == 0)
|
||||
osp->rxpkts = 1;
|
||||
else
|
||||
osp->rxpkts = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
|
||||
usbp->epc[ep]->out_maxsize;
|
||||
USB->EP[ep].CSR &= USBEPnCSR_NAKRX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
USBInEndpointState * const isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txlastpktlen = 0;
|
||||
usb_packet_transmit(usbp, ep, isp->txsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
USB->EP[ep].CSR = USBEPnCSR_STLRX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
USB->EP[ep].CSR = USBEPnCSR_STLTX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
USB->EP[ep].CSR &= USBEPnCSR_STLRX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
USB->EP[ep].CSR &= USBEPnCSR_STLTX;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_USB == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
Copyright (C) 2020 Yaotian Feng
|
||||
|
||||
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 HT32 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 7
|
||||
|
||||
/**
|
||||
* @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_EARLY_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 HT32 configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief USB driver enable switch.
|
||||
* @details If set to @p TRUE the support for USB0 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(HT32_USB_USE_USB0) || defined(__DOXYGEN__)
|
||||
#define HT32_USB_USE_USB0 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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.*/
|
||||
uint16_t txlastpktlen;
|
||||
} 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.*/
|
||||
uint16_t rxpkts;
|
||||
} 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.*/
|
||||
} 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.*/
|
||||
uint16_t epmem_next;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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) (USB->FCR & USBFCR_FRNUM)
|
||||
|
||||
/**
|
||||
* @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) \
|
||||
do { \
|
||||
USB->CSR |= USBCSR_DPPUEN; \
|
||||
} while (FALSE)
|
||||
|
||||
/**
|
||||
* @brief Disconnect the USB device.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define usb_lld_disconnect_bus(usbp) \
|
||||
do { \
|
||||
USB->CSR &= ~USBCSR_DPPUEN; \
|
||||
} while (FALSE)
|
||||
|
||||
/**
|
||||
* @brief Start of host wake-up procedure.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define usb_lld_wakeup_host(usbp) \
|
||||
do { \
|
||||
USB->CSR |= USBCSR_GENRSM; \
|
||||
} while (FALSE)
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (HT32_USB_USE_USB0 == 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_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 */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue