commit
faab9f4a74
96 changed files with 3717 additions and 788 deletions
72
.github/workflows/build.yml
vendored
72
.github/workflows/build.yml
vendored
|
|
@ -9,6 +9,8 @@ on:
|
|||
- 'src/**'
|
||||
- '.github/actions/**'
|
||||
- '.github/workflows/build.yml'
|
||||
- '.github/workflows/build_util.yml'
|
||||
- '.github/workflows/build_ghostfat.yml'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths:
|
||||
|
|
@ -18,6 +20,8 @@ on:
|
|||
- 'src/**'
|
||||
- '.github/actions/**'
|
||||
- '.github/workflows/build.yml'
|
||||
- '.github/workflows/build_util.yml'
|
||||
- '.github/workflows/build_ghostfat.yml'
|
||||
repository_dispatch:
|
||||
release:
|
||||
types:
|
||||
|
|
@ -57,7 +61,7 @@ jobs:
|
|||
matrix:
|
||||
port:
|
||||
# Alphabetical order
|
||||
#- 'kinetis_k32l2' skip since self-update is not implemented
|
||||
- 'kinetis_k32l2'
|
||||
- 'lpc55'
|
||||
- 'mimxrt10xx'
|
||||
- 'stm32f3'
|
||||
|
|
@ -73,6 +77,7 @@ jobs:
|
|||
# Build ESP
|
||||
# ---------------------------------------
|
||||
esp:
|
||||
#if: false
|
||||
needs: set-matrix
|
||||
uses: ./.github/workflows/build_util.yml
|
||||
with:
|
||||
|
|
@ -82,51 +87,30 @@ jobs:
|
|||
toolchain: 'esp-idf'
|
||||
toolchain_url: 'v5.1.1'
|
||||
|
||||
# ---------------------------------------
|
||||
# Build RISC-V
|
||||
# ---------------------------------------
|
||||
riscv:
|
||||
needs: set-matrix
|
||||
uses: ./.github/workflows/build_util.yml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
port:
|
||||
# Alphabetical order
|
||||
- 'ch32v20x'
|
||||
with:
|
||||
port: ${{ matrix.port }}
|
||||
boards: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.port].board) }}
|
||||
build-system: 'make'
|
||||
toolchain: 'riscv-gcc'
|
||||
toolchain_url: 'https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz'
|
||||
|
||||
# ---------------------------------------
|
||||
# Unit testing with ghostfat
|
||||
# ---------------------------------------
|
||||
ghostfat:
|
||||
needs: set-matrix
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: ${{ fromJSON(needs.set-matrix.outputs.json)['test_ghostfat'].board }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
make -C ports/test_ghostfat/ BOARD=${{ matrix.board }} all
|
||||
|
||||
- name: Decompress known good filesystem image
|
||||
run: |
|
||||
# copy
|
||||
cp ./boards/${{ matrix.board }}/knowngood.img.gz.gz ./_build/${{ matrix.board }}/
|
||||
|
||||
# NOTE: test_huge's knowngood.img file starts as 1.5 GiB
|
||||
# Compressing once with GZip results gives 85 MiB
|
||||
# Compressing it a second time gives 10 MiB ...
|
||||
# Therefore, store known good images double-compressed...
|
||||
gzip --decompress ./_build/${{ matrix.board }}/knowngood.img.gz.gz
|
||||
gzip --decompress ./_build/${{ matrix.board }}/knowngood.img.gz
|
||||
working-directory: ports/test_ghostfat
|
||||
|
||||
- name: Execute native self-test
|
||||
run: |
|
||||
chmod +x ./tinyuf2-${{ matrix.board }}.elf
|
||||
./tinyuf2-${{ matrix.board }}.elf
|
||||
|
||||
# Compress (double) newly generated self-test images
|
||||
mv ghostfat.img ghostfat_${{ matrix.board }}.img
|
||||
gzip --keep ghostfat_${{ matrix.board }}.img
|
||||
gzip --keep --force --best ghostfat_${{ matrix.board }}.img.gz
|
||||
working-directory: ports/test_ghostfat/_build/${{ matrix.board }}
|
||||
|
||||
- name: Save newly generated self-test images as CI artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ghostfat_selftest_images
|
||||
path: ./ports/test_ghostfat/_build/${{ matrix.board }}/ghostfat_${{ matrix.board }}.img.gz.gz
|
||||
uses: ./.github/workflows/build_ghostfat.yml
|
||||
with:
|
||||
boards: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['test_ghostfat'].board) }}
|
||||
|
|
|
|||
2
.github/workflows/build_cmake.yml
vendored
2
.github/workflows/build_cmake.yml
vendored
|
|
@ -37,7 +37,7 @@ jobs:
|
|||
board:
|
||||
# Alphabetical order by family
|
||||
- 'metro_m7_1011'
|
||||
- 'stm32f303disco'
|
||||
# - 'stm32f303disco' # overflows flash
|
||||
- 'stm32f411ve_discovery'
|
||||
|
||||
steps:
|
||||
|
|
|
|||
51
.github/workflows/build_ghostfat.yml
vendored
Normal file
51
.github/workflows/build_ghostfat.yml
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
name: Testing ghostfat
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
boards:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
board:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: ${{ fromJSON(inputs.boards) }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
make -C ports/test_ghostfat/ BOARD=${{ matrix.board }} all
|
||||
|
||||
- name: Decompress known good filesystem image
|
||||
run: |
|
||||
# NOTE: test_huge's knowngood.img file starts as 1.5 GiB
|
||||
# Compressing once with GZip results gives 85 MiB
|
||||
# Compressing it a second time gives 10 MiB ...
|
||||
# Therefore, store known good images double-compressed...
|
||||
cp ./boards/${{ matrix.board }}/knowngood.img.gz.gz ./_build/${{ matrix.board }}/
|
||||
gzip --decompress ./_build/${{ matrix.board }}/knowngood.img.gz.gz
|
||||
gzip --decompress ./_build/${{ matrix.board }}/knowngood.img.gz
|
||||
working-directory: ports/test_ghostfat
|
||||
|
||||
- name: Execute native self-test
|
||||
run: |
|
||||
chmod +x ./tinyuf2-${{ matrix.board }}.elf
|
||||
./tinyuf2-${{ matrix.board }}.elf
|
||||
|
||||
# Compress (double) newly generated self-test images
|
||||
mv ghostfat.img ghostfat_${{ matrix.board }}.img
|
||||
gzip --keep ghostfat_${{ matrix.board }}.img
|
||||
gzip --keep --force --best ghostfat_${{ matrix.board }}.img.gz
|
||||
working-directory: ports/test_ghostfat/_build/${{ matrix.board }}
|
||||
|
||||
- name: Save newly generated self-test images as CI artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ghostfat_selftest_images
|
||||
path: ./ports/test_ghostfat/_build/${{ matrix.board }}/ghostfat_${{ matrix.board }}.img.gz.gz
|
||||
4
.github/workflows/build_util.yml
vendored
4
.github/workflows/build_util.yml
vendored
|
|
@ -50,7 +50,9 @@ jobs:
|
|||
if: inputs.toolchain != 'esp-idf'
|
||||
run: |
|
||||
make -C ports/${{ inputs.port }} BOARD=${{ matrix.board }} all self-update copy-artifact
|
||||
for app in ports/${{ inputs.port }}/apps/*/; do if [ $app != 'apps/self_update/' ]; then make -C $app BOARD=${{ matrix.board }} all; fi done
|
||||
if [ -d "ports/${{ inputs.port }}/apps" ]; then
|
||||
for app in ports/${{ inputs.port }}/apps/*/; do if [ $app != 'apps/self_update/' ]; then make -C $app BOARD=${{ matrix.board }} all; fi done
|
||||
fi
|
||||
|
||||
- name: Build using ESP-IDF docker
|
||||
if: inputs.toolchain == 'esp-idf'
|
||||
|
|
|
|||
4
.github/workflows/ci_set_matrix.py
vendored
4
.github/workflows/ci_set_matrix.py
vendored
|
|
@ -8,13 +8,13 @@ TOP = Path(__file__).parent.parent.parent.resolve()
|
|||
def set_matrix_json():
|
||||
ports_dir = Path(TOP / 'ports')
|
||||
matrix = {}
|
||||
for p in ports_dir.iterdir():
|
||||
for p in sorted(ports_dir.iterdir()):
|
||||
if p.is_dir() and p.name != 'template_port':
|
||||
matrix[p.name] = {}
|
||||
boards_dir = ports_dir / p / 'boards'
|
||||
if boards_dir.exists():
|
||||
matrix[p.name]['board'] = []
|
||||
for b in boards_dir.iterdir():
|
||||
for b in sorted(boards_dir.iterdir()):
|
||||
if b.is_dir():
|
||||
matrix[p.name]['board'].append(b.name)
|
||||
print(json.dumps(matrix))
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board_api.h"
|
||||
|
||||
|
|
@ -33,34 +31,25 @@
|
|||
* writing the erase magic and reset to let bootloader do its work
|
||||
*/
|
||||
|
||||
#ifndef DBL_TAP_REG
|
||||
// defined by linker script
|
||||
extern uint32_t _board_dfu_dbl_tap[];
|
||||
#define DBL_TAP_REG _board_dfu_dbl_tap[0]
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
board_init();
|
||||
printf("Erase Application Firmware\r\n");
|
||||
|
||||
// set magic then reset
|
||||
DBL_TAP_REG = DBL_TAP_MAGIC_ERASE_APP;
|
||||
TINYUF2_DBL_TAP_REG = DBL_TAP_MAGIC_ERASE_APP;
|
||||
|
||||
board_reset();
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
while (1) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
void board_timer_handler(void)
|
||||
{
|
||||
void board_timer_handler(void) {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -75,8 +64,7 @@ void board_timer_handler(void)
|
|||
#include "SEGGER_RTT.h"
|
||||
#endif
|
||||
|
||||
__attribute__ ((used)) int _write (int fhdl, const void *buf, size_t count)
|
||||
{
|
||||
__attribute__ ((used)) int _write(int fhdl, const void* buf, size_t count) {
|
||||
(void) fhdl;
|
||||
|
||||
#if defined(LOGGER_RTT)
|
||||
|
|
|
|||
21
cmake/cpu/arm1176jzf-s.cmake
Normal file
21
cmake/cpu/arm1176jzf-s.cmake
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mcpu=arm1176jzf-s
|
||||
-ffreestanding
|
||||
)
|
||||
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=arm1176jzf-s
|
||||
-mfpu=none
|
||||
-mfloat-abi=soft
|
||||
-ffreestanding
|
||||
)
|
||||
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
message(FATAL_ERROR "IAR not supported")
|
||||
|
||||
endif ()
|
||||
21
cmake/cpu/arm926ej-s.cmake
Normal file
21
cmake/cpu/arm926ej-s.cmake
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mcpu=arm926ej-s
|
||||
-ffreestanding
|
||||
)
|
||||
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=arm926ej-s
|
||||
-mfpu=none
|
||||
-mfloat-abi=soft
|
||||
-ffreestanding
|
||||
)
|
||||
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
message(FATAL_ERROR "IAR not supported")
|
||||
|
||||
endif ()
|
||||
17
cmake/cpu/cortex-a53.cmake
Normal file
17
cmake/cpu/cortex-a53.cmake
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mcpu=cortex-a53
|
||||
)
|
||||
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-a53
|
||||
)
|
||||
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
message(FATAL_ERROR "IAR not supported")
|
||||
|
||||
endif ()
|
||||
17
cmake/cpu/cortex-a72.cmake
Normal file
17
cmake/cpu/cortex-a72.cmake
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mcpu=cortex-a72
|
||||
)
|
||||
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-a72
|
||||
)
|
||||
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
message(FATAL_ERROR "IAR not supported")
|
||||
|
||||
endif ()
|
||||
22
cmake/cpu/cortex-m0.cmake
Normal file
22
cmake/cpu/cortex-m0.cmake
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m0plus
|
||||
-mfloat-abi=soft
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m0
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m0
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
22
cmake/cpu/cortex-m0plus.cmake
Normal file
22
cmake/cpu/cortex-m0plus.cmake
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m0plus
|
||||
-mfloat-abi=soft
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m0plus
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m0
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
22
cmake/cpu/cortex-m23.cmake
Normal file
22
cmake/cpu/cortex-m23.cmake
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m23
|
||||
-mfloat-abi=soft
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m23
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m23
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
21
cmake/cpu/cortex-m3.cmake
Normal file
21
cmake/cpu/cortex-m3.cmake
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m3
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m3
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m3
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM3 CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
18
cmake/cpu/cortex-m33-nodsp-nofp.cmake
Normal file
18
cmake/cpu/cortex-m33-nodsp-nofp.cmake
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m33+nodsp
|
||||
-mfloat-abi=soft
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
message(FATAL_ERROR "Clang is not supported for this target")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m33+nodsp
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
25
cmake/cpu/cortex-m33.cmake
Normal file
25
cmake/cpu/cortex-m33.cmake
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m33
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv5-sp-d16
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m33
|
||||
-mfpu=fpv5-sp-d16
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m33
|
||||
--fpu VFPv5-SP
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
|
|
@ -1,23 +1,32 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m4
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv4-sp-d16
|
||||
)
|
||||
|
||||
if (NOT DEFINED FREERTOS_PORT)
|
||||
set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "")
|
||||
endif ()
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m4
|
||||
--fpu VFPv4
|
||||
)
|
||||
|
||||
if (NOT DEFINED FREERTOS_PORT)
|
||||
set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "")
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m4
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv4-sp-d16
|
||||
)
|
||||
if (NOT DEFINED FREERTOS_PORT)
|
||||
set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "")
|
||||
endif ()
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m4
|
||||
-mfpu=fpv4-sp-d16
|
||||
)
|
||||
if (NOT DEFINED FREERTOS_PORT)
|
||||
set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "")
|
||||
endif ()
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m4
|
||||
--fpu VFPv4_sp
|
||||
)
|
||||
|
||||
if (NOT DEFINED FREERTOS_PORT)
|
||||
set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "")
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
|
|
|
|||
25
cmake/cpu/cortex-m7-fpsp.cmake
Normal file
25
cmake/cpu/cortex-m7-fpsp.cmake
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m7
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv5-sp-d16
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m7
|
||||
-mfpu=fpv5-sp-d16
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m7
|
||||
--fpu VFPv5_sp
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
|
|
@ -1,19 +1,25 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m7
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv5-d16
|
||||
)
|
||||
|
||||
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m7
|
||||
--fpu VFPv5_D16
|
||||
)
|
||||
|
||||
set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m7
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv5-d16
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--target=arm-none-eabi
|
||||
-mcpu=cortex-m7
|
||||
-mfpu=fpv5-d16
|
||||
)
|
||||
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
--cpu cortex-m7
|
||||
--fpu VFPv5_D16
|
||||
)
|
||||
set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
|
|
|
|||
10
cmake/cpu/msp430.cmake
Normal file
10
cmake/cpu/msp430.cmake
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(FREERTOS_PORT GCC_MSP430F449 CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
message(FATAL_ERROR "Clang is not supported for this target")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
set(FREERTOS_PORT IAR_MSP430 CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
19
cmake/cpu/rv32i-ilp32.cmake
Normal file
19
cmake/cpu/rv32i-ilp32.cmake
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-march=rv32i_zicsr
|
||||
-mabi=ilp32
|
||||
)
|
||||
set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-march=rv32i_zicsr
|
||||
-mabi=ilp32
|
||||
)
|
||||
set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
message(FATAL_ERROR "IAR not supported")
|
||||
set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "")
|
||||
|
||||
endif ()
|
||||
18
cmake/cpu/rv32imac-ilp32.cmake
Normal file
18
cmake/cpu/rv32imac-ilp32.cmake
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-march=rv32imac_zicsr
|
||||
-mabi=ilp32
|
||||
)
|
||||
set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-march=rv32imac_zicsr
|
||||
-mabi=ilp32
|
||||
)
|
||||
set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "")
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
message(FATAL_ERROR "IAR not supported")
|
||||
set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "")
|
||||
endif ()
|
||||
21
cmake/toolchain/aarch64_gcc.cmake
Normal file
21
cmake/toolchain/aarch64_gcc.cmake
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER "aarch64-none-elf-gcc")
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER "aarch64-none-elf-g++")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
||||
set(CMAKE_SIZE "aarch64-none-elf-size" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJCOPY "aarch64-none-elf-objcopy" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJDUMP "aarch64-none-elf-objdump" CACHE FILEPATH "")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
|
||||
|
||||
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||
if (IS_IN_TRY_COMPILE)
|
||||
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib")
|
||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib")
|
||||
cmake_print_variables(CMAKE_C_LINK_FLAGS)
|
||||
endif ()
|
||||
21
cmake/toolchain/arm_clang.cmake
Normal file
21
cmake/toolchain/arm_clang.cmake
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER "clang")
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER "clang++")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
||||
set(CMAKE_SIZE "llvm-size" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJCOPY "llvm-objcopy" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJDUMP "llvm-objdump" CACHE FILEPATH "")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
|
||||
|
||||
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||
if (IS_IN_TRY_COMPILE)
|
||||
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib")
|
||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib")
|
||||
cmake_print_variables(CMAKE_C_LINK_FLAGS)
|
||||
endif ()
|
||||
|
|
@ -1,46 +1,21 @@
|
|||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
|
||||
set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
|
||||
set(CMAKE_CXX_COMPILER "arm-none-eabi-g++")
|
||||
set(CMAKE_ASM_COMPILER "arm-none-eabi-gcc")
|
||||
|
||||
set(CMAKE_SIZE "arm-none-eabi-size" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJCOPY "arm-none-eabi-objcopy" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJDUMP "arm-none-eabi-objdump" CACHE FILEPATH "")
|
||||
|
||||
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
|
||||
|
||||
# Look for includes and libraries only in the target system prefix.
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
|
||||
# pass TOOLCHAIN_CPU to
|
||||
set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake)
|
||||
|
||||
# enable all possible warnings for building examples
|
||||
list(APPEND TOOLCHAIN_COMMON_FLAGS
|
||||
-fdata-sections
|
||||
-ffunction-sections
|
||||
-fsingle-precision-constant
|
||||
-fno-strict-aliasing
|
||||
)
|
||||
|
||||
set(TOOLCHAIN_EXE_LINKER_FLAGS
|
||||
-Wl,--print-memory-usage
|
||||
-Wl,--gc-sections
|
||||
#-Wl,--cref
|
||||
)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake)
|
||||
|
||||
# try_compile is cmake test compiling its own example,
|
||||
# pass -nostdlib to skip stdlib linking
|
||||
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||
if (IS_IN_TRY_COMPILE)
|
||||
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib")
|
||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib")
|
||||
endif ()
|
||||
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER "arm-none-eabi-g++")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
||||
set(CMAKE_SIZE "arm-none-eabi-size" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJCOPY "arm-none-eabi-objcopy" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJDUMP "arm-none-eabi-objdump" CACHE FILEPATH "")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
|
||||
|
||||
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||
if (IS_IN_TRY_COMPILE)
|
||||
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib")
|
||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib")
|
||||
cmake_print_variables(CMAKE_C_LINK_FLAGS)
|
||||
endif ()
|
||||
|
|
|
|||
17
cmake/toolchain/arm_iar.cmake
Normal file
17
cmake/toolchain/arm_iar.cmake
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER "iccarm")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER "iccarm")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED CMAKE_ASM_COMPILER)
|
||||
set(CMAKE_ASM_COMPILER "iasmarm")
|
||||
endif()
|
||||
|
||||
set(CMAKE_SIZE "size" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJCOPY "ielftool" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJDUMP "iefdumparm" CACHE FILEPATH "")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
|
||||
64
cmake/toolchain/common.cmake
Normal file
64
cmake/toolchain/common.cmake
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
include(CMakePrintHelpers)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Common
|
||||
# ----------------------------------------------------------------------------
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
|
||||
|
||||
# Look for includes and libraries only in the target system prefix.
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
|
||||
# pass TOOLCHAIN_CPU to
|
||||
set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Compile flags
|
||||
# ----------------------------------------------------------------------------
|
||||
if (TOOLCHAIN STREQUAL "gcc")
|
||||
list(APPEND TOOLCHAIN_COMMON_FLAGS
|
||||
-fdata-sections
|
||||
-ffunction-sections
|
||||
-fsingle-precision-constant
|
||||
-fno-strict-aliasing
|
||||
)
|
||||
list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS
|
||||
-Wl,--print-memory-usage
|
||||
-Wl,--gc-sections
|
||||
-Wl,--cref
|
||||
)
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "iar")
|
||||
#list(APPEND TOOLCHAIN_COMMON_FLAGS)
|
||||
list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS
|
||||
--diag_suppress=Li065
|
||||
)
|
||||
|
||||
elseif (TOOLCHAIN STREQUAL "clang")
|
||||
list(APPEND TOOLCHAIN_COMMON_FLAGS
|
||||
-fdata-sections
|
||||
-ffunction-sections
|
||||
-fno-strict-aliasing
|
||||
)
|
||||
list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS
|
||||
-Wl,--print-memory-usage
|
||||
-Wl,--gc-sections
|
||||
-Wl,--cref
|
||||
)
|
||||
endif ()
|
||||
|
||||
# join the toolchain flags into a single string
|
||||
list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS)
|
||||
foreach (LANG IN ITEMS C CXX ASM)
|
||||
set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS})
|
||||
# optimization flags for LOG, LOGGER ?
|
||||
#set(CMAKE_${LANG}_FLAGS_RELEASE_INIT "-Os")
|
||||
#set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0")
|
||||
endforeach ()
|
||||
|
||||
# Linker
|
||||
list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT)
|
||||
15
cmake/toolchain/msp430_gcc.cmake
Normal file
15
cmake/toolchain/msp430_gcc.cmake
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER "msp430-elf-gcc")
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER "msp430-elf-g++")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
||||
|
||||
set(CMAKE_SIZE "msp430-elf-size" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJCOPY "msp430-elf-objcopy" CACHE FILEPATH "")
|
||||
set(CMAKE_OBJDUMP "msp430-elf-objdump" CACHE FILEPATH "")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
|
||||
30
cmake/toolchain/riscv_gcc.cmake
Normal file
30
cmake/toolchain/riscv_gcc.cmake
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# default Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
|
||||
if (NOT DEFINED CROSS_COMPILE)
|
||||
set(CROSS_COMPILE "riscv-none-elf-")
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++)
|
||||
endif ()
|
||||
|
||||
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
||||
set(CMAKE_SIZE ${CROSS_COMPILE}size CACHE FILEPATH "")
|
||||
set(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy CACHE FILEPATH "")
|
||||
set(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump CACHE FILEPATH "")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
|
||||
|
||||
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||
if (IS_IN_TRY_COMPILE)
|
||||
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib")
|
||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib")
|
||||
cmake_print_variables(CMAKE_C_LINK_FLAGS)
|
||||
endif ()
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
include(CMakePrintHelpers)
|
||||
|
||||
# join the toolchain flags into a single string
|
||||
list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS)
|
||||
|
||||
foreach (LANG IN ITEMS C CXX ASM)
|
||||
set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS})
|
||||
#cmake_print_variables(CMAKE_${LANG}_FLAGS_INIT)
|
||||
endforeach ()
|
||||
|
||||
# Linker
|
||||
list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT)
|
||||
28
ports/ch32v20x/CMakeLists.txt
Normal file
28
ports/ch32v20x/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
cmake_minimum_required(VERSION 3.17)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../family_support.cmake)
|
||||
|
||||
project(tinyuf2 C ASM)
|
||||
set(CMAKE_EXECUTABLE_SUFFIX .elf)
|
||||
|
||||
#------------------------------------
|
||||
# TinyUF2
|
||||
#------------------------------------
|
||||
add_executable(tinyuf2
|
||||
boards.c
|
||||
)
|
||||
target_link_options(tinyuf2 PUBLIC
|
||||
"LINKER:--script=${CMAKE_CURRENT_LIST_DIR}/linker/${CH32_FAMILY}_boot.ld"
|
||||
)
|
||||
|
||||
family_configure_tinyuf2(tinyuf2 OPT_MCU_CH32V20X)
|
||||
target_sources(tinyuf2-tinyusb PUBLIC
|
||||
${TOP}/lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||
${TOP}/lib/tinyusb/src/portable/wch/dcd_ch32_usbfs.c
|
||||
)
|
||||
family_flash_openocd_wch(tinyuf2)
|
||||
|
||||
#------------------------------------
|
||||
# Application (e.g self update)
|
||||
#------------------------------------
|
||||
#add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/apps/self_update)
|
||||
24
ports/ch32v20x/Makefile
Normal file
24
ports/ch32v20x/Makefile
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# List of git submodules that is included as part of the UF2 version
|
||||
GIT_SUBMODULES = tinyusb
|
||||
|
||||
include ../make.mk
|
||||
include port.mk
|
||||
include ../rules.mk
|
||||
|
||||
#------------------------------------------
|
||||
# Self-update
|
||||
#------------------------------------------
|
||||
|
||||
# directory containing Makefile for building update app
|
||||
SELF_DIR = apps/self_update
|
||||
|
||||
#$(SELF_DIR)/bootloader_bin.c: $(BUILD)/$(OUTNAME).bin
|
||||
# $(PYTHON3) $(TOP)/lib/uf2/utils/uf2conv.py --carray $^ -o $@
|
||||
#
|
||||
## remove bootloader_bin.c at the end to force re-generate each time
|
||||
#self-update: $(SELF_DIR)/bootloader_bin.c
|
||||
# make -C $(SELF_DIR) BOARD=$(BOARD) LOG=$(LOG) LOGGER=$(LOGGER) self-update
|
||||
# @rm -f $^
|
||||
|
||||
self-update:
|
||||
@echo "not implemented yet"
|
||||
297
ports/ch32v20x/boards.c
Normal file
297
ports/ch32v20x/boards.c
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Ha Thach for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ch32v20x.h"
|
||||
#include "board_api.h"
|
||||
|
||||
#ifndef BUILD_NO_TINYUSB
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
|
||||
#define CH32_UUID ((volatile uint32_t *) 0x1FFFF7E8UL)
|
||||
|
||||
#define BOARD_PAGE_SIZE 0x800
|
||||
#define FLASH_ADDR_PHY_BASE 0x08000000UL
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// convert to zero-based address
|
||||
#define ADDR_BASE0(_addr) ((_addr) & ~FLASH_ADDR_PHY_BASE)
|
||||
|
||||
// convert to absolute address
|
||||
#define ADDR_ABS(_addr) ((_addr) | FLASH_ADDR_PHY_BASE)
|
||||
|
||||
uint32_t SysTick_Config(uint32_t ticks) {
|
||||
NVIC_EnableIRQ(SysTicK_IRQn);
|
||||
SysTick->CTLR = 0;
|
||||
SysTick->SR = 0;
|
||||
SysTick->CNT = 0;
|
||||
SysTick->CMP = ticks - 1;
|
||||
SysTick->CTLR = 0xF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void board_init(void) {
|
||||
__disable_irq();
|
||||
|
||||
// double tap use backup register: enable PWR and BKP clock, and BKP write enable
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, ENABLE);
|
||||
PWR->CTLR |= PWR_CTLR_DBP;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {
|
||||
.GPIO_Pin = LED_PIN,
|
||||
.GPIO_Mode = GPIO_Mode_Out_OD,
|
||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||
};
|
||||
GPIO_Init(LED_PORT, &GPIO_InitStructure);
|
||||
|
||||
#if CFG_TUSB_DEBUG || TUF2_LOG
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
GPIO_InitTypeDef usart_init = {
|
||||
.GPIO_Pin = GPIO_Pin_9,
|
||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||
.GPIO_Mode = GPIO_Mode_AF_PP,
|
||||
};
|
||||
GPIO_Init(GPIOA, &usart_init);
|
||||
|
||||
USART_InitTypeDef usart = {
|
||||
.USART_BaudRate = 115200,
|
||||
.USART_WordLength = USART_WordLength_8b,
|
||||
.USART_StopBits = USART_StopBits_1,
|
||||
.USART_Parity = USART_Parity_No,
|
||||
.USART_Mode = USART_Mode_Tx,
|
||||
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
|
||||
};
|
||||
USART_Init(USART1, &usart);
|
||||
USART_Cmd(USART1, ENABLE);
|
||||
#endif
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void board_teardown(void) {
|
||||
}
|
||||
|
||||
void board_dfu_init(void) {
|
||||
__disable_irq();
|
||||
|
||||
uint8_t usb_div;
|
||||
switch (SystemCoreClock) {
|
||||
case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break;
|
||||
case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break;
|
||||
case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break;
|
||||
default: TU_ASSERT(0,); break;
|
||||
}
|
||||
RCC_USBCLKConfig(usb_div);
|
||||
|
||||
#if CFG_TUD_WCH_USBIP_USBFS
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_WCH_USBIP_FSDEV
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV
|
||||
#endif
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void board_reset(void) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void board_dfu_complete(void) {
|
||||
// Mostly reset
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
bool board_app_valid(void) {
|
||||
uint32_t app_start_contents = *((volatile uint32_t const*) ADDR_ABS(BOARD_FLASH_APP_START));
|
||||
TUF2_LOG1_HEX(app_start_contents);
|
||||
// for ch32 after erased the flash value is 0xe339e339 (mentioned in RM) instead of 0xffffffff
|
||||
return app_start_contents != 0xe339e339;
|
||||
}
|
||||
|
||||
// Jump to application code
|
||||
void board_app_jump(void) {
|
||||
TUF2_LOG2("Jump to app\r\n");
|
||||
board_timer_stop();
|
||||
asm volatile("j __flash_boot_size");
|
||||
}
|
||||
|
||||
uint8_t board_usb_get_serial(uint8_t serial_id[16]) {
|
||||
uint8_t const len = 12;
|
||||
uint32_t* serial_id32 = (uint32_t*) (uintptr_t) serial_id;
|
||||
|
||||
serial_id32[0] = CH32_UUID[0];
|
||||
serial_id32[1] = CH32_UUID[1];
|
||||
serial_id32[2] = CH32_UUID[2];
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// LED pattern
|
||||
//--------------------------------------------------------------------+
|
||||
void board_led_write(uint32_t state) {
|
||||
GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||
}
|
||||
|
||||
void board_rgb_write(uint8_t const rgb[]) {
|
||||
(void) rgb;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Timer
|
||||
//--------------------------------------------------------------------+
|
||||
void board_timer_start(uint32_t ms) {
|
||||
SysTick_Config( (SystemCoreClock/1000) * ms );
|
||||
}
|
||||
|
||||
void board_timer_stop(void) {
|
||||
SysTick->CTLR = 0;
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) __attribute__((used))
|
||||
void SysTick_Handler(void) {
|
||||
SysTick->SR = 0;
|
||||
board_timer_handler();
|
||||
}
|
||||
|
||||
int board_uart_write(void const* buf, int len) {
|
||||
#if CFG_TUSB_DEBUG || TUF2_LOG
|
||||
const char *bufc = (const char *) buf;
|
||||
for (int i = 0; i < len; i++) {
|
||||
USART_SendData(USART1, *bufc++);
|
||||
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
|
||||
}
|
||||
return len;
|
||||
#else
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Flash
|
||||
//--------------------------------------------------------------------+
|
||||
void board_flash_init(void) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
uint32_t board_flash_size(void) {
|
||||
return BOARD_FLASH_SIZE;
|
||||
}
|
||||
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len) {
|
||||
memcpy(buffer, (void*) addr, len);
|
||||
}
|
||||
|
||||
void board_flash_flush(void) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len) {
|
||||
TUF2_ASSERT(len == 256);
|
||||
|
||||
addr = ADDR_ABS(addr);
|
||||
|
||||
FLASH_Unlock_Fast();
|
||||
|
||||
FLASH_ErasePage_Fast(addr);
|
||||
FLASH_ProgramPage_Fast(addr, (uint32_t*) (uintptr_t ) data);
|
||||
|
||||
FLASH_Lock_Fast();
|
||||
|
||||
// verify contents
|
||||
if (memcmp((void*) addr, data, len) != 0) {
|
||||
TUF2_LOG1("Failed to write\r\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void) {
|
||||
// TODO implement later
|
||||
}
|
||||
|
||||
bool board_flash_protect_bootloader(bool protect) {
|
||||
// TODO implement later
|
||||
(void) protect;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TINYUF2_SELF_UPDATE
|
||||
void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len) {
|
||||
(void) bootloader_bin;
|
||||
(void) bootloader_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB Interrupt Handler
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifndef BUILD_NO_TINYUSB
|
||||
// USBFS
|
||||
__attribute__((interrupt)) __attribute__((used))
|
||||
void USBFS_IRQHandler(void) {
|
||||
#if CFG_TUD_WCH_USBIP_USBFS
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) __attribute__((used))
|
||||
void USBFSWakeUp_IRQHandler(void) {
|
||||
#if CFG_TUD_WCH_USBIP_USBFS
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// USBD (fsdev)
|
||||
__attribute__((interrupt)) __attribute__((used))
|
||||
void USB_LP_CAN1_RX0_IRQHandler(void) {
|
||||
#if CFG_TUD_WCH_USBIP_FSDEV
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) __attribute__((used))
|
||||
void USB_HP_CAN1_TX_IRQHandler(void) {
|
||||
#if CFG_TUD_WCH_USBIP_FSDEV
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) __attribute__((used))
|
||||
void USBWakeUp_IRQHandler(void) {
|
||||
#if CFG_TUD_WCH_USBIP_FSDEV
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Ha Thach for Adafruit Industries
|
||||
* Copyright (c) 2020 Ha Thach (tinyusb.org) for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -22,52 +22,29 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "board_api.h"
|
||||
#include "tusb.h" // for logging
|
||||
#ifndef BOARDS_H_
|
||||
#define BOARDS_H_
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
void board_flash_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint32_t board_flash_size(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len)
|
||||
{
|
||||
(void) addr; (void) buffer; (void) len;
|
||||
}
|
||||
|
||||
void board_flash_flush(void)
|
||||
{
|
||||
}
|
||||
|
||||
void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
||||
{
|
||||
(void) addr; (void) data; (void) len;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
{
|
||||
// TODO implement later
|
||||
}
|
||||
|
||||
bool board_flash_protect_bootloader(bool protect)
|
||||
{
|
||||
// TODO implement later
|
||||
(void) protect;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TINYUF2_SELF_UPDATE
|
||||
void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len)
|
||||
{
|
||||
(void) bootloader_bin;
|
||||
(void) bootloader_len;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ch32v20x.h"
|
||||
#include "board.h"
|
||||
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
#define TINYUF2_DBL_TAP_REG BKP->DATAR10
|
||||
#define TINYUF2_DBL_TAP_REG_SIZE 16
|
||||
|
||||
// symbol from linker
|
||||
extern uint32_t __flash_size[];
|
||||
extern uint32_t __flash_boot_size[];
|
||||
|
||||
#define BOARD_FLASH_SIZE ((uint32_t) __flash_size)
|
||||
#define BOARD_FLASH_APP_START ((uint32_t) __flash_boot_size)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BOARDS_H_ */
|
||||
6
ports/ch32v20x/boards/ch32v203_r0_1v0/board.cmake
Normal file
6
ports/ch32v20x/boards/ch32v203_r0_1v0/board.cmake
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
set(MCU_VARIANT D6)
|
||||
set(LD_FLASH_SIZE 64K)
|
||||
set(LD_RAM_SIZE 20K)
|
||||
|
||||
function(update_board TARGET)
|
||||
endfunction()
|
||||
65
ports/ch32v20x/boards/ch32v203_r0_1v0/board.h
Normal file
65
ports/ch32v20x/boards/ch32v203_r0_1v0/board.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Ha Thach for Adafruit Industries
|
||||
*
|
||||
* 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 BOARD_H_
|
||||
#define BOARD_H_
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Button
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// LED
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define LED_PORT GPIOA
|
||||
#define LED_PIN GPIO_Pin_15
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB UF2
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define USB_VID 0xcafe
|
||||
#define USB_PID 0xbabe
|
||||
#define USB_MANUFACTURER "Adafruit"
|
||||
#define USB_PRODUCT "Dummy"
|
||||
|
||||
#define UF2_PRODUCT_NAME USB_MANUFACTURER " " USB_PRODUCT
|
||||
#define UF2_BOARD_ID "Dummy"
|
||||
#define UF2_VOLUME_LABEL "CH32V2BOOT"
|
||||
#define UF2_INDEX_URL "https://www.adafruit.com"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// UART
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
//#define UART_DEV USART3
|
||||
//#define UART_CLOCK_ENABLE __HAL_RCC_USART3_CLK_ENABLE
|
||||
//#define UART_GPIO_PORT GPIOB
|
||||
//#define UART_GPIO_AF GPIO_AF7_USART3
|
||||
//#define UART_TX_PIN GPIO_PIN_10
|
||||
//#define UART_RX_PIN GPIO_PIN_11
|
||||
|
||||
#endif
|
||||
5
ports/ch32v20x/boards/ch32v203_r0_1v0/board.mk
Normal file
5
ports/ch32v20x/boards/ch32v203_r0_1v0/board.mk
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
MCU_VARIANT = D6
|
||||
|
||||
LDFLAGS += \
|
||||
-Wl,--defsym=__flash_size=64K \
|
||||
-Wl,--defsym=__ram_size=20K \
|
||||
36
ports/ch32v20x/ch32v20x_conf.h
Normal file
36
ports/ch32v20x/ch32v20x_conf.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Library configuration file.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_CONF_H
|
||||
#define __CH32V20x_CONF_H
|
||||
|
||||
#include "ch32v20x_adc.h"
|
||||
#include "ch32v20x_bkp.h"
|
||||
#include "ch32v20x_can.h"
|
||||
#include "ch32v20x_crc.h"
|
||||
#include "ch32v20x_dbgmcu.h"
|
||||
#include "ch32v20x_dma.h"
|
||||
#include "ch32v20x_exti.h"
|
||||
#include "ch32v20x_flash.h"
|
||||
#include "ch32v20x_gpio.h"
|
||||
#include "ch32v20x_i2c.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include "ch32v20x_pwr.h"
|
||||
#include "ch32v20x_rcc.h"
|
||||
#include "ch32v20x_rtc.h"
|
||||
#include "ch32v20x_spi.h"
|
||||
#include "ch32v20x_tim.h"
|
||||
#include "ch32v20x_usart.h"
|
||||
#include "ch32v20x_wwdg.h"
|
||||
#include "ch32v20x_it.h"
|
||||
#include "ch32v20x_misc.h"
|
||||
|
||||
#endif /* __CH32V20x_CONF_H */
|
||||
15
ports/ch32v20x/ch32v20x_it.h
Normal file
15
ports/ch32v20x/ch32v20x_it.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_IT_H
|
||||
#define __CH32V20x_IT_H
|
||||
|
||||
#endif /* __CH32V20x_IT_H */
|
||||
572
ports/ch32v20x/core_riscv.h
Normal file
572
ports/ch32v20x/core_riscv.h
Normal file
|
|
@ -0,0 +1,572 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : core_riscv.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CORE_RISCV_H__
|
||||
#define __CORE_RISCV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* IO definitions */
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /* defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /* defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /* defines 'write only' permissions */
|
||||
#define __IO volatile /* defines 'read / write' permissions */
|
||||
|
||||
/* Standard Peripheral Library old types (maintained for legacy purpose) */
|
||||
typedef __I uint64_t vuc64; /* Read Only */
|
||||
typedef __I uint32_t vuc32; /* Read Only */
|
||||
typedef __I uint16_t vuc16; /* Read Only */
|
||||
typedef __I uint8_t vuc8; /* Read Only */
|
||||
|
||||
typedef const uint64_t uc64; /* Read Only */
|
||||
typedef const uint32_t uc32; /* Read Only */
|
||||
typedef const uint16_t uc16; /* Read Only */
|
||||
typedef const uint8_t uc8; /* Read Only */
|
||||
|
||||
typedef __I int64_t vsc64; /* Read Only */
|
||||
typedef __I int32_t vsc32; /* Read Only */
|
||||
typedef __I int16_t vsc16; /* Read Only */
|
||||
typedef __I int8_t vsc8; /* Read Only */
|
||||
|
||||
typedef const int64_t sc64; /* Read Only */
|
||||
typedef const int32_t sc32; /* Read Only */
|
||||
typedef const int16_t sc16; /* Read Only */
|
||||
typedef const int8_t sc8; /* Read Only */
|
||||
|
||||
typedef __IO uint64_t vu64;
|
||||
typedef __IO uint32_t vu32;
|
||||
typedef __IO uint16_t vu16;
|
||||
typedef __IO uint8_t vu8;
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef __IO int64_t vs64;
|
||||
typedef __IO int32_t vs32;
|
||||
typedef __IO int16_t vs16;
|
||||
typedef __IO int8_t vs8;
|
||||
|
||||
typedef int64_t s64;
|
||||
typedef int32_t s32;
|
||||
typedef int16_t s16;
|
||||
typedef int8_t s8;
|
||||
|
||||
typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus;
|
||||
|
||||
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
|
||||
|
||||
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
|
||||
|
||||
#define RV_STATIC_INLINE static inline
|
||||
|
||||
/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
|
||||
typedef struct{
|
||||
__I uint32_t ISR[8];
|
||||
__I uint32_t IPR[8];
|
||||
__IO uint32_t ITHRESDR;
|
||||
__IO uint32_t RESERVED;
|
||||
__IO uint32_t CFGR;
|
||||
__I uint32_t GISR;
|
||||
__IO uint8_t VTFIDR[4];
|
||||
uint8_t RESERVED0[12];
|
||||
__IO uint32_t VTFADDR[4];
|
||||
uint8_t RESERVED1[0x90];
|
||||
__O uint32_t IENR[8];
|
||||
uint8_t RESERVED2[0x60];
|
||||
__O uint32_t IRER[8];
|
||||
uint8_t RESERVED3[0x60];
|
||||
__O uint32_t IPSR[8];
|
||||
uint8_t RESERVED4[0x60];
|
||||
__O uint32_t IPRR[8];
|
||||
uint8_t RESERVED5[0x60];
|
||||
__IO uint32_t IACTR[8];
|
||||
uint8_t RESERVED6[0xE0];
|
||||
__IO uint8_t IPRIOR[256];
|
||||
uint8_t RESERVED7[0x810];
|
||||
__IO uint32_t SCTLR;
|
||||
}PFIC_Type;
|
||||
|
||||
/* memory mapped structure for SysTick */
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t CTLR;
|
||||
__IO uint32_t SR;
|
||||
__IO uint64_t CNT;
|
||||
__IO uint64_t CMP;
|
||||
}SysTick_Type;
|
||||
|
||||
#define PFIC ((PFIC_Type *) 0xE000E000 )
|
||||
#define NVIC PFIC
|
||||
#define NVIC_KEY1 ((uint32_t)0xFA050000)
|
||||
#define NVIC_KEY2 ((uint32_t)0xBCAF0000)
|
||||
#define NVIC_KEY3 ((uint32_t)0xBEEF0000)
|
||||
|
||||
#define SysTick ((SysTick_Type *) 0xE000F000)
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __enable_irq
|
||||
*
|
||||
* @brief Enable Global Interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq(void)
|
||||
{
|
||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6088) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __disable_irq
|
||||
*
|
||||
* @brief Disable Global Interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq(void)
|
||||
{
|
||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6000) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __NOP
|
||||
*
|
||||
* @brief nop
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__asm volatile ("nop");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_EnableIRQ
|
||||
*
|
||||
* @brief Disable Interrupt
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_DisableIRQ
|
||||
*
|
||||
* @brief Disable Interrupt
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_GetStatusIRQ
|
||||
*
|
||||
* @brief Get Interrupt Enable State
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
*
|
||||
* @return 1 - Interrupt Pending Enable
|
||||
* 0 - Interrupt Pending Disable
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_GetPendingIRQ
|
||||
*
|
||||
* @brief Get Interrupt Pending State
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
*
|
||||
* @return 1 - Interrupt Pending Enable
|
||||
* 0 - Interrupt Pending Disable
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_SetPendingIRQ
|
||||
*
|
||||
* @brief Set Interrupt Pending
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_ClearPendingIRQ
|
||||
*
|
||||
* @brief Clear Interrupt Pending
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_GetActive
|
||||
*
|
||||
* @brief Get Interrupt Active State
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
*
|
||||
* @return 1 - Interrupt Active
|
||||
* 0 - Interrupt No Active
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_SetPriority
|
||||
*
|
||||
* @brief Set Interrupt Priority
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
* priority - bit7 - Pre-emption Priority
|
||||
* bit[6:5] - Subpriority
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
|
||||
{
|
||||
NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __WFI
|
||||
*
|
||||
* @brief Wait for Interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
NVIC->SCTLR &= ~(1<<3); // wfi
|
||||
asm volatile ("wfi");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn _SEV
|
||||
*
|
||||
* @brief Set Event
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
t = NVIC->SCTLR;
|
||||
NVIC->SCTLR |= (1<<3)|(1<<5);
|
||||
NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn _WFE
|
||||
*
|
||||
* @brief Wait for Events
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void)
|
||||
{
|
||||
NVIC->SCTLR |= (1<<3);
|
||||
asm volatile ("wfi");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __WFE
|
||||
*
|
||||
* @brief Wait for Events
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
_SEV();
|
||||
_WFE();
|
||||
_WFE();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetVTFIRQ
|
||||
*
|
||||
* @brief Set VTF Interrupt
|
||||
*
|
||||
* @param addr - VTF interrupt service function base address.
|
||||
* IRQn - Interrupt Numbers
|
||||
* num - VTF Interrupt Numbers
|
||||
* NewState - DISABLE or ENABLE
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){
|
||||
if(num > 3) return ;
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
NVIC->VTFIDR[num] = IRQn;
|
||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
|
||||
}
|
||||
else{
|
||||
NVIC->VTFIDR[num] = IRQn;
|
||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_SystemReset
|
||||
*
|
||||
* @brief Initiate a system reset request
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void)
|
||||
{
|
||||
NVIC->CFGR = NVIC_KEY3|(1<<7);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOADD_W
|
||||
*
|
||||
* @brief Atomic Add with 32bit value
|
||||
* Atomically ADD 32bit value with value in memory using amoadd.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be ADDed
|
||||
*
|
||||
* @return return memory value + add value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__asm volatile ("amoadd.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOAND_W
|
||||
*
|
||||
* @brief Atomic And with 32bit value
|
||||
* Atomically AND 32bit value with value in memory using amoand.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be ANDed
|
||||
*
|
||||
* @return return memory value & and value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__asm volatile ("amoand.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOMAX_W
|
||||
*
|
||||
* @brief Atomic signed MAX with 32bit value
|
||||
* Atomically signed max compare 32bit value with value in memory using amomax.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be compared
|
||||
*
|
||||
* @return the bigger value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__asm volatile ("amomax.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOMAXU_W
|
||||
*
|
||||
* @brief Atomic unsigned MAX with 32bit value
|
||||
* Atomically unsigned max compare 32bit value with value in memory using amomaxu.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be compared
|
||||
*
|
||||
* @return return the bigger value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__asm volatile ("amomaxu.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOMIN_W
|
||||
*
|
||||
* @brief Atomic signed MIN with 32bit value
|
||||
* Atomically signed min compare 32bit value with value in memory using amomin.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be compared
|
||||
*
|
||||
* @return the smaller value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__asm volatile ("amomin.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOMINU_W
|
||||
*
|
||||
* @brief Atomic unsigned MIN with 32bit value
|
||||
* Atomically unsigned min compare 32bit value with value in memory using amominu.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be compared
|
||||
*
|
||||
* @return the smaller value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__asm volatile ("amominu.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOOR_W
|
||||
*
|
||||
* @brief Atomic OR with 32bit value
|
||||
* Atomically OR 32bit value with value in memory using amoor.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be ORed
|
||||
*
|
||||
* @return return memory value | and value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__asm volatile ("amoor.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOSWAP_W
|
||||
*
|
||||
* @brief Atomically swap new 32bit value into memory using amoswap.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* newval - New value to be stored into the address
|
||||
*
|
||||
* @return return the original value in memory
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__asm volatile ("amoswap.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(newval) : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __AMOXOR_W
|
||||
*
|
||||
* @brief Atomic XOR with 32bit value
|
||||
* Atomically XOR 32bit value with value in memory using amoxor.d.
|
||||
*
|
||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
||||
* value - value to be XORed
|
||||
*
|
||||
* @return return memory value ^ and value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__asm volatile ("amoxor.w %0, %2, %1" : \
|
||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/* Core_Exported_Functions */
|
||||
extern uint32_t __get_MSTATUS(void);
|
||||
extern void __set_MSTATUS(uint32_t value);
|
||||
extern uint32_t __get_MISA(void);
|
||||
extern void __set_MISA(uint32_t value);
|
||||
extern uint32_t __get_MTVEC(void);
|
||||
extern void __set_MTVEC(uint32_t value);
|
||||
extern uint32_t __get_MSCRATCH(void);
|
||||
extern void __set_MSCRATCH(uint32_t value);
|
||||
extern uint32_t __get_MEPC(void);
|
||||
extern void __set_MEPC(uint32_t value);
|
||||
extern uint32_t __get_MCAUSE(void);
|
||||
extern void __set_MCAUSE(uint32_t value);
|
||||
extern uint32_t __get_MTVAL(void);
|
||||
extern void __set_MTVAL(uint32_t value);
|
||||
extern uint32_t __get_MVENDORID(void);
|
||||
extern uint32_t __get_MARCHID(void);
|
||||
extern uint32_t __get_MIMPID(void);
|
||||
extern uint32_t __get_MHARTID(void);
|
||||
extern uint32_t __get_SP(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
84
ports/ch32v20x/family.cmake
Normal file
84
ports/ch32v20x/family.cmake
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
include_guard()
|
||||
|
||||
set(UF2_FAMILY_ID 0x699b62ec)
|
||||
set(CH32_FAMILY ch32v20x)
|
||||
set(SDK_DIR ${TOP}/lib/mcu/wch/${CH32_FAMILY})
|
||||
set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||
|
||||
# enable LTO
|
||||
#set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
|
||||
set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor")
|
||||
set(CMAKE_TOOLCHAIN_FILE ${TOP}/cmake/toolchain/riscv_${TOOLCHAIN}.cmake)
|
||||
|
||||
set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg")
|
||||
|
||||
#------------------------------------
|
||||
# BOARD_TARGET
|
||||
#------------------------------------
|
||||
# used by all executable targets
|
||||
|
||||
# Port0 use FSDev, Port1 use USBFS
|
||||
if (NOT DEFINED USBPORT)
|
||||
set(USBPORT 0)
|
||||
endif()
|
||||
|
||||
function(family_add_board_target BOARD_TARGET)
|
||||
if (TARGET ${BOARD_TARGET})
|
||||
return()
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED STARTUP_FILE_GNU)
|
||||
set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S)
|
||||
endif ()
|
||||
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
|
||||
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
${SDK_SRC_DIR}/Core/core_riscv.c
|
||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_flash.c
|
||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c
|
||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c
|
||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c
|
||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
)
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${SDK_SRC_DIR}/Peripheral/inc
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||
)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
CH32V20x_${MCU_VARIANT}
|
||||
)
|
||||
|
||||
if (USBPORT EQUAL 0)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
CFG_TUD_WCH_USBIP_FSDEV=1
|
||||
)
|
||||
elseif (USBPORT EQUAL 1)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
CFG_TUD_WCH_USBIP_USBFS=1
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid PORT ${USBPORT}")
|
||||
endif()
|
||||
|
||||
update_board(${BOARD_TARGET})
|
||||
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
#CFG_TUSB_MCU=OPT_MCU_CH32V20X
|
||||
BOARD_UF2_FAMILY_ID=${UF2_FAMILY_ID}
|
||||
)
|
||||
target_compile_options(${BOARD_TARGET} PUBLIC
|
||||
-mcmodel=medany
|
||||
)
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
-Wl,--defsym=__flash_size=${LD_FLASH_SIZE}
|
||||
-Wl,--defsym=__ram_size=${LD_RAM_SIZE}
|
||||
-nostartfiles
|
||||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
endfunction()
|
||||
168
ports/ch32v20x/linker/ch32v20x_boot.ld
Normal file
168
ports/ch32v20x/linker/ch32v20x_boot.ld
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/* Define default values if not already defined */
|
||||
__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K;
|
||||
__flash_boot_size = 24K;
|
||||
__flash_app_size = __FLASH_SIZE - __flash_boot_size;
|
||||
|
||||
__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_boot_size
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE
|
||||
}
|
||||
|
||||
ENTRY( _start )
|
||||
|
||||
__stack_size = 2048;
|
||||
|
||||
PROVIDE( _stack_size = __stack_size );
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.init :
|
||||
{
|
||||
_sinit = .;
|
||||
. = ALIGN(4);
|
||||
KEEP(*(SORT_NONE(.init)))
|
||||
. = ALIGN(4);
|
||||
_einit = .;
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.vector :
|
||||
{
|
||||
*(.vector);
|
||||
. = ALIGN(64);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(4);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP(*(SORT_NONE(.fini)))
|
||||
. = ALIGN(4);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
PROVIDE( _etext = . );
|
||||
PROVIDE( _eitcm = . );
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.dalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_data_vma = .);
|
||||
} >RAM AT>FLASH
|
||||
|
||||
.dlalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_data_lma = .);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.data .data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
. = ALIGN(8);
|
||||
PROVIDE( __global_pointer$ = . + 0x800 );
|
||||
*(.sdata .sdata.*)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
. = ALIGN(8);
|
||||
*(.srodata.cst16)
|
||||
*(.srodata.cst8)
|
||||
*(.srodata.cst4)
|
||||
*(.srodata.cst2)
|
||||
*(.srodata .srodata.*)
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _edata = .);
|
||||
} >RAM AT>FLASH
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _sbss = .);
|
||||
*(.sbss*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.bss*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON*)
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _ebss = .);
|
||||
} >RAM AT>FLASH
|
||||
|
||||
PROVIDE( _end = _ebss);
|
||||
PROVIDE( end = . );
|
||||
|
||||
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
|
||||
{
|
||||
PROVIDE( _heap_end = . );
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_susrstack = . );
|
||||
. = . + __stack_size;
|
||||
PROVIDE( _eusrstack = .);
|
||||
} >RAM
|
||||
|
||||
}
|
||||
71
ports/ch32v20x/port.mk
Normal file
71
ports/ch32v20x/port.mk
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
UF2_FAMILY_ID = 0x699b62ec
|
||||
|
||||
# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
|
||||
CROSS_COMPILE ?= riscv-none-elf-
|
||||
|
||||
CH32_FAMILY = ch32v20x
|
||||
SDK_DIR = lib/mcu/wch/ch32v20x
|
||||
SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC
|
||||
|
||||
CPU_CORE ?= rv32imac-ilp32
|
||||
|
||||
CFLAGS += \
|
||||
-march=rv32imac_zicsr \
|
||||
-mabi=ilp32 \
|
||||
|
||||
# Port0 use FSDev, Port1 use USBFS
|
||||
USBPORT ?= 0
|
||||
|
||||
# Port Compiler Flags
|
||||
CFLAGS += \
|
||||
-mcmodel=medany \
|
||||
-ffat-lto-objects \
|
||||
-flto \
|
||||
-DCH32V20x_${MCU_VARIANT} \
|
||||
-DCFG_TUSB_MCU=OPT_MCU_CH32V20X
|
||||
|
||||
ifeq ($(USBPORT),0)
|
||||
$(info "Using FSDEV driver")
|
||||
CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1
|
||||
else
|
||||
$(info "Using USBFS driver")
|
||||
CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1
|
||||
endif
|
||||
|
||||
LDFLAGS += \
|
||||
-nostdlib -nostartfiles \
|
||||
#--specs=nosys.specs --specs=nano.specs \
|
||||
|
||||
# default linker file
|
||||
ifdef BUILD_APPLICATION
|
||||
LD_FILES ?= $(PORT_DIR)/linker/${CH32_FAMILY}.ld
|
||||
else
|
||||
LD_FILES ?= $(PORT_DIR)/linker/${CH32_FAMILY}_boot.ld
|
||||
endif
|
||||
|
||||
# Port source
|
||||
SRC_C += \
|
||||
$(PORT_DIR)/boards.c \
|
||||
$(PORT_DIR)/system_ch32v20x.c \
|
||||
$(SDK_SRC_DIR)/Core/core_riscv.c \
|
||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_flash.c \
|
||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \
|
||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \
|
||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_rcc.c \
|
||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_usart.c \
|
||||
|
||||
ifndef BUILD_NO_TINYUSB
|
||||
SRC_C += \
|
||||
lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||
lib/tinyusb/src/portable/wch/dcd_ch32_usbfs.c
|
||||
endif
|
||||
|
||||
SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S
|
||||
|
||||
# Port include
|
||||
INC += \
|
||||
$(TOP)/$(BOARD_DIR) \
|
||||
$(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \
|
||||
|
||||
OPENOCD_WCH_OPTION=-f $(TOP)/$(PORT_DIR)/wch-riscv.cfg
|
||||
flash: flash-openocd-wch
|
||||
976
ports/ch32v20x/system_ch32v20x.c
Normal file
976
ports/ch32v20x/system_ch32v20x.c
Normal file
|
|
@ -0,0 +1,976 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x.h"
|
||||
|
||||
/*
|
||||
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
|
||||
* reset the HSI is used as SYSCLK source).
|
||||
* If none of the define below is enabled, the HSI is used as System clock source.
|
||||
*/
|
||||
//#define SYSCLK_FREQ_HSE HSE_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSE 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||
// #define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSI 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSI 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#else
|
||||
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#endif
|
||||
|
||||
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
|
||||
/* system_private_function_proto_types */
|
||||
static void SetSysClock(void);
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
static void SetSysClockToHSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
static void SetSysClockTo48_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
static void SetSysClockTo56_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
static void SetSysClockTo72_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
static void SetSysClockTo96_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
static void SetSysClockTo120_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
static void SetSysClockTo144_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
static void SetSysClockTo48_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
static void SetSysClockTo56_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
static void SetSysClockTo72_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
static void SetSysClockTo96_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
static void SetSysClockTo120_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
static void SetSysClockTo144_HSI( void );
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemInit
|
||||
*
|
||||
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
|
||||
* the PLL and update the SystemCoreClock variable.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
RCC->CTLR |= (uint32_t)0x00000001;
|
||||
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
|
||||
RCC->INTR = 0x009F0000;
|
||||
SetSysClock();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemCoreClockUpdate
|
||||
*
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
|
||||
|
||||
tmp = RCC->CFGR0 & RCC_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08:
|
||||
pllmull = RCC->CFGR0 & RCC_PLLMULL;
|
||||
pllsource = RCC->CFGR0 & RCC_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
if(pllmull == 17) pllmull = 18;
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
|
||||
SystemCoreClock = HSI_VALUE * pllmull;
|
||||
}
|
||||
else{
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
if((RCC->CFGR0 & (3<<22)) == (3<<22))
|
||||
{
|
||||
SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = (HSE_VALUE>>2) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClock
|
||||
*
|
||||
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
SetSysClockToHSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
SetSysClockTo48_HSE();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
SetSysClockTo56_HSE();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
SetSysClockTo72_HSE();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
SetSysClockTo96_HSE();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
SetSysClockTo120_HSE();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
SetSysClockTo144_HSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
SetSysClockTo48_HSI();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
SetSysClockTo56_HSI();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
SetSysClockTo72_HSI();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
SetSysClockTo96_HSI();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
SetSysClockTo120_HSI();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
SetSysClockTo144_HSI();
|
||||
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock
|
||||
* source (default after reset)
|
||||
*/
|
||||
}
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockToHSE
|
||||
*
|
||||
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockToHSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* Select HSE as system clock source
|
||||
* CH32V20x_D6 (HSE=8MHZ)
|
||||
* CH32V20x_D8 (HSE=32MHZ)
|
||||
* CH32V20x_D8W (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
|
||||
|
||||
/* Wait till HSE is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if(HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
RCC->CFGR0 |= (uint32_t)(3<<22);
|
||||
/* HCLK = SYSCLK/2 */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
|
||||
#else
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
#endif
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
29
ports/ch32v20x/system_ch32v20x.h
Normal file
29
ports/ch32v20x/system_ch32v20x.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __SYSTEM_ch32v20x_H
|
||||
#define __SYSTEM_ch32v20x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V20x_SYSTEM_H */
|
||||
100
ports/ch32v20x/tusb_config.h
Normal file
100
ports/ch32v20x/tusb_config.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* 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 TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// COMMON CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
* e.g
|
||||
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||
*/
|
||||
#ifndef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_CDC 0
|
||||
#define CFG_TUD_MSC 1
|
||||
#define CFG_TUD_HID 0
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
||||
// MSC Buffer size of Device Mass storage
|
||||
#define CFG_TUD_MSC_BUFSIZE 4096
|
||||
|
||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
#define CFG_TUD_HID_BUFSIZE 64
|
||||
|
||||
// Vendor FIFO size of TX and RX
|
||||
// If not configured vendor endpoints will not be buffered
|
||||
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
|
||||
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
17
ports/ch32v20x/wch-riscv.cfg
Normal file
17
ports/ch32v20x/wch-riscv.cfg
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
adapter driver wlinke
|
||||
adapter speed 6000
|
||||
transport select sdi
|
||||
|
||||
wlink_set_address 0x00000000
|
||||
set _CHIPNAME wch_riscv
|
||||
sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
|
||||
target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME
|
||||
$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1
|
||||
set _FLASHNAME $_CHIPNAME.flash
|
||||
|
||||
flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0
|
||||
|
||||
echo "Ready for Remote Connections"
|
||||
|
|
@ -31,22 +31,6 @@
|
|||
#include "spi_flash_chip_driver.h"
|
||||
#include "board_api.h"
|
||||
|
||||
// Debug helper, remove later
|
||||
#define PRINTF(...) ESP_LOGI("uf2", __VA_ARGS__)
|
||||
#define PRINT_LOCATION() ESP_LOGI("uf2", "%s: %d", __PRETTY_FUNCTION__, __LINE__)
|
||||
#define PRINT_MESS(x) ESP_LOGI("uf2", "%s", (char*)(x))
|
||||
#define PRINT_STR(x) ESP_LOGI("uf2", #x " = %s" , (char*)(x) )
|
||||
#define PRINT_INT(x) ESP_LOGI("uf2", #x " = %d" , (int32_t) (x) )
|
||||
#define PRINT_HEX(x) ESP_LOGI("uf2", #x " = 0x%X", (uint32_t) (x) )
|
||||
|
||||
#define PRINT_BUFFER(buf, n) \
|
||||
do {\
|
||||
uint8_t const* p8 = (uint8_t const*) (buf);\
|
||||
printf(#buf ": ");\
|
||||
for(uint32_t i=0; i<(n); i++) printf("%x ", p8[i]);\
|
||||
printf("\n");\
|
||||
}while(0)
|
||||
|
||||
#define FLASH_CACHE_SIZE (64*1024)
|
||||
#define FLASH_CACHE_INVALID_ADDR 0xffffffff
|
||||
|
||||
|
|
@ -54,42 +38,36 @@ static uint32_t _fl_addr = FLASH_CACHE_INVALID_ADDR;
|
|||
static uint8_t _fl_buf[FLASH_CACHE_SIZE] __attribute__((aligned(4)));
|
||||
|
||||
// uf2 will always write to ota0 partition
|
||||
static esp_partition_t const * _part_ota0 = NULL;
|
||||
static esp_partition_t const* _part_ota0 = NULL;
|
||||
|
||||
void board_flash_init(void)
|
||||
{
|
||||
void board_flash_init(void) {
|
||||
_fl_addr = FLASH_CACHE_INVALID_ADDR;
|
||||
|
||||
_part_ota0 = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL);
|
||||
assert(_part_ota0 != NULL);
|
||||
}
|
||||
|
||||
uint32_t board_flash_size(void)
|
||||
{
|
||||
uint32_t board_flash_size(void) {
|
||||
return _part_ota0->size;
|
||||
}
|
||||
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len)
|
||||
{
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len) {
|
||||
esp_partition_read(_part_ota0, addr, buffer, len);
|
||||
}
|
||||
|
||||
void board_flash_flush(void)
|
||||
{
|
||||
if ( _fl_addr == FLASH_CACHE_INVALID_ADDR ) return;
|
||||
void board_flash_flush(void) {
|
||||
if (_fl_addr == FLASH_CACHE_INVALID_ADDR) return;
|
||||
|
||||
//PRINTF("Erase and Write at 0x%08X", _fl_addr);
|
||||
TUF2_LOG1("Erase and Write at 0x%08lX", _fl_addr);
|
||||
|
||||
// Check if contents already matched
|
||||
bool content_matches = true;
|
||||
uint32_t const verify_sz = 4096;
|
||||
uint8_t* verify_buf = malloc(verify_sz);
|
||||
|
||||
for(uint32_t count = 0; count < FLASH_CACHE_SIZE; count += verify_sz)
|
||||
{
|
||||
for (uint32_t count = 0; count < FLASH_CACHE_SIZE; count += verify_sz) {
|
||||
board_flash_read(_fl_addr + count, verify_buf, verify_sz);
|
||||
if ( 0 != memcmp(_fl_buf + count, verify_buf, verify_sz) )
|
||||
{
|
||||
if (0 != memcmp(_fl_buf + count, verify_buf, verify_sz)) {
|
||||
content_matches = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -97,8 +75,7 @@ void board_flash_flush(void)
|
|||
free(verify_buf);
|
||||
|
||||
// skip erase & write if content already matches
|
||||
if ( !content_matches )
|
||||
{
|
||||
if (!content_matches) {
|
||||
esp_partition_erase_range(_part_ota0, _fl_addr, FLASH_CACHE_SIZE);
|
||||
esp_partition_write(_part_ota0, _fl_addr, _fl_buf, FLASH_CACHE_SIZE);
|
||||
}
|
||||
|
|
@ -106,12 +83,10 @@ void board_flash_flush(void)
|
|||
_fl_addr = FLASH_CACHE_INVALID_ADDR;
|
||||
}
|
||||
|
||||
void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
||||
{
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len) {
|
||||
uint32_t new_addr = addr & ~(FLASH_CACHE_SIZE - 1);
|
||||
|
||||
if ( new_addr != _fl_addr )
|
||||
{
|
||||
if (new_addr != _fl_addr) {
|
||||
board_flash_flush();
|
||||
|
||||
_fl_addr = new_addr;
|
||||
|
|
@ -119,10 +94,11 @@ void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
|||
}
|
||||
|
||||
memcpy(_fl_buf + (addr & (FLASH_CACHE_SIZE - 1)), data, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool board_flash_protect_bootloader(bool protect)
|
||||
{
|
||||
bool board_flash_protect_bootloader(bool protect) {
|
||||
// TODO implement later
|
||||
(void) protect;
|
||||
return false;
|
||||
|
|
@ -134,8 +110,7 @@ bool board_flash_protect_bootloader(bool protect)
|
|||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifdef TINYUF2_SELF_UPDATE
|
||||
void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len)
|
||||
{
|
||||
void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len) {
|
||||
enum { SECTOR_SZ = 4096UL };
|
||||
esp_partition_t const * _part_uf2;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@
|
|||
// Flash Start Address of Application
|
||||
#define BOARD_FLASH_APP_START 0
|
||||
|
||||
// Double Reset tap to enter DFU
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 0
|
||||
// Double Reset tap to enter DFU, for ESP this is done in bootloader subproject
|
||||
#define TINYUF2_DBL_TAP_DFU 0
|
||||
|
||||
#ifdef DISPLAY_PIN_SCK
|
||||
#define TINYUF2_DISPLAY 1
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -42,15 +42,21 @@
|
|||
#define CFG_TUSB_MCU OPT_MCU_ESP32S3
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define CFG_TUSB_OS OPT_OS_FREERTOS
|
||||
|
||||
// Espressif IDF requires "freertos/" prefix in include path
|
||||
#define CFG_TUSB_OS_INC_PATH freertos/
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -115,4 +121,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -110,8 +110,9 @@ function(family_configure_common TARGET)
|
|||
|
||||
# Generate map file
|
||||
target_link_options(${TARGET} PUBLIC "LINKER:-Map=$<TARGET_FILE:${TARGET}>.map")
|
||||
#family_add_linkermap(${TARGET})
|
||||
|
||||
# All executable target linked with board target
|
||||
# executable target linked with board target
|
||||
family_add_board_target(board_${BOARD})
|
||||
target_link_libraries(${TARGET} PUBLIC board_${BOARD})
|
||||
|
||||
|
|
@ -162,7 +163,6 @@ function(family_add_tinyusb TARGET OPT_MCU RTOS)
|
|||
add_subdirectory(${TOP}/lib/tinyusb/src ${CMAKE_CURRENT_BINARY_DIR}/tinyusb)
|
||||
|
||||
if (RTOS STREQUAL "freertos")
|
||||
# link tinyusb with freeRTOS kernel
|
||||
target_link_libraries(${TARGET}-tinyusb PUBLIC freertos_kernel)
|
||||
endif ()
|
||||
|
||||
|
|
@ -202,20 +202,15 @@ endfunction()
|
|||
function(family_configure_tinyuf2 TARGET OPT_MCU)
|
||||
family_configure_common(${TARGET})
|
||||
|
||||
#target_include_directories(${TARGET} PUBLIC)
|
||||
#target_compile_definitions(${TARGET} PUBLIC)
|
||||
include(${TOP}/src/tinyuf2.cmake)
|
||||
add_tinyuf2(${TARGET})
|
||||
|
||||
family_add_uf2version(${TARGET} "${FAMILY_SUBMODULE_DEPS}")
|
||||
|
||||
family_add_tinyusb(tinyuf2 ${OPT_MCU} none)
|
||||
family_add_tinyusb(${TARGET} ${OPT_MCU} none)
|
||||
endfunction()
|
||||
|
||||
#----------------------------------
|
||||
# Output
|
||||
#----------------------------------
|
||||
|
||||
# Add bin/hex output
|
||||
function(family_add_bin_hex TARGET)
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin
|
||||
|
|
@ -243,6 +238,11 @@ function(family_add_uf2 TARGET FAMILY_ID)
|
|||
VERBATIM)
|
||||
endfunction()
|
||||
|
||||
function(family_add_linkermap TARGET)
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
COMMAND linkermap -v $<TARGET_FILE:${TARGET}>.map
|
||||
VERBATIM)
|
||||
endfunction()
|
||||
|
||||
#----------------------------------
|
||||
# Flashing target
|
||||
|
|
@ -254,6 +254,10 @@ function(family_flash_jlink TARGET)
|
|||
set(JLINKEXE JLinkExe)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED JLINK_IF)
|
||||
set(JLINK_IF swd)
|
||||
endif ()
|
||||
|
||||
if (ARGC GREATER 1)
|
||||
set(BIN_FILE $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.${ARGV1})
|
||||
else ()
|
||||
|
|
@ -271,7 +275,7 @@ exit"
|
|||
|
||||
add_custom_target(${TARGET}-jlink
|
||||
DEPENDS ${TARGET}
|
||||
COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if swd -JTAGConf -1,-1 -speed auto -CommandFile ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.jlink
|
||||
COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.jlink
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
|
@ -289,45 +293,35 @@ function(family_flash_stlink TARGET)
|
|||
endfunction()
|
||||
|
||||
|
||||
# Add flash pycod targe,t optional parameter is the extension of the binary file (default is elf)
|
||||
## If bin file is used, address is also required
|
||||
function(family_flash_pyocd TARGET)
|
||||
if (NOT DEFINED PYOC)
|
||||
set(PYOCD pyocd)
|
||||
# Add flash openocd target
|
||||
function(family_flash_openocd TARGET)
|
||||
if (NOT DEFINED OPENOCD)
|
||||
set(OPENOCD openocd)
|
||||
endif ()
|
||||
|
||||
set(ADDR_OPT "")
|
||||
if (ARGC GREATER 1)
|
||||
set(BIN_FILE $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.${ARGV1})
|
||||
if (${ARGV1} STREQUAL bin)
|
||||
set(ADDR_OPT "-a ${ARGV2}")
|
||||
endif ()
|
||||
else ()
|
||||
set(BIN_FILE $<TARGET_FILE:${TARGET}>)
|
||||
if (NOT DEFINED OPENOCD_OPTION2)
|
||||
set(OPENOCD_OPTION2 "")
|
||||
endif ()
|
||||
|
||||
add_custom_target(${TARGET}-pyocd
|
||||
separate_arguments(OPTION_LIST UNIX_COMMAND ${OPENOCD_OPTION})
|
||||
separate_arguments(OPTION_LIST2 UNIX_COMMAND ${OPENOCD_OPTION2})
|
||||
|
||||
# note skip verify since it has issue with rp2040
|
||||
add_custom_target(${TARGET}-openocd
|
||||
DEPENDS ${TARGET}
|
||||
COMMAND ${PYOCD} flash -t ${PYOCD_TARGET} ${ADDR_OPT} ${BIN_FILE}
|
||||
COMMAND ${OPENOCD} ${OPTION_LIST} -c "program $<TARGET_FILE:${TARGET}> reset" ${OPTION_LIST2} -c exit
|
||||
VERBATIM
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Add flash using NXP's LinkServer (redserver)
|
||||
# https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/linkserver-for-microcontrollers:LINKERSERVER
|
||||
function(family_flash_nxplink TARGET)
|
||||
if (NOT DEFINED LINKSERVER)
|
||||
set(LINKSERVER LinkServer)
|
||||
# Add flash openocd-wch target
|
||||
# compiled from https://github.com/hathach/riscv-openocd-wch or https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz
|
||||
function(family_flash_openocd_wch TARGET)
|
||||
if (NOT DEFINED OPENOCD)
|
||||
set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd)
|
||||
endif ()
|
||||
|
||||
# LinkServer has a bug that can only execute with full path otherwise it throws:
|
||||
# realpath error: No such file or directory
|
||||
execute_process(COMMAND which ${LINKSERVER} OUTPUT_VARIABLE LINKSERVER_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
add_custom_target(${TARGET}-nxplink
|
||||
DEPENDS ${TARGET}
|
||||
COMMAND ${LINKSERVER_PATH} flash ${NXPLINK_DEVICE} load $<TARGET_FILE:${TARGET}>
|
||||
)
|
||||
family_flash_openocd(${TARGET})
|
||||
endfunction()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,8 +121,7 @@ void board_flash_flush(void)
|
|||
}
|
||||
|
||||
|
||||
void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
||||
{
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len) {
|
||||
uint32_t newAddr = addr & ~(FLASH_PAGE_SIZE - 1);
|
||||
// int32_t result;
|
||||
|
||||
|
|
@ -136,8 +135,9 @@ void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
|||
// }
|
||||
}
|
||||
memcpy(bf_flash_cache + (addr & (FLASH_PAGE_SIZE - 1)), data, len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#include "board.h"
|
||||
#include "fsl_rtc.h"
|
||||
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 1
|
||||
#define DBL_TAP_REG RTC->TAR
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
#define TINYUF2_DBL_TAP_REG RTC->TAR
|
||||
#define BOARD_FLASH_APP_START 0x8000
|
||||
//#define BOARD_FLASH_SIZE (BOARD_FLASH_TOTAL - BOARD_FLASH_APP_START)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,15 +38,17 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
#define BOARD_DEVICE_RHPORT_NUM 0
|
||||
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -94,4 +96,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,17 +34,14 @@
|
|||
#include "clock_config.h"
|
||||
|
||||
#ifndef BUILD_NO_TINYUSB
|
||||
#include "tusb.h"
|
||||
|
||||
#include "tusb.h"
|
||||
#else
|
||||
|
||||
#define TU_LOG1(...)
|
||||
#define TU_LOG2(...)
|
||||
#define TU_LOG1(...)
|
||||
#define TU_LOG2(...)
|
||||
#endif
|
||||
|
||||
#if NEOPIXEL_NUMBER
|
||||
#include "sct_neopixel.h"
|
||||
|
||||
static uint32_t _pixelData[NEOPIXEL_NUMBER] = {0};
|
||||
#endif
|
||||
|
||||
|
|
@ -134,7 +131,7 @@ void board_flash_flush(void)
|
|||
_flash_page_addr = NO_CACHE;
|
||||
}
|
||||
|
||||
void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len)
|
||||
{
|
||||
uint32_t newAddr = addr & ~(FLASH_PAGE_SIZE - 1);
|
||||
int32_t status;
|
||||
|
|
@ -148,6 +145,8 @@ void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
|||
}
|
||||
}
|
||||
memcpy(_flash_cache + (addr & (FLASH_PAGE_SIZE - 1)), data, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
|
|
@ -202,7 +201,7 @@ void board_init(void)
|
|||
// Init 96 MHz clock
|
||||
BOARD_BootClockFROHF96M();
|
||||
|
||||
// Init RTC for access to DBL_TAP_REG
|
||||
// Init RTC for access to TINYUF2_DBL_TAP_REG
|
||||
RTC_Init(RTC);
|
||||
|
||||
// disable systick
|
||||
|
|
@ -276,17 +275,8 @@ void board_dfu_init(void)
|
|||
RESET_PeripheralReset(kUSB1_RST_SHIFT_RSTn);
|
||||
RESET_PeripheralReset(kUSB1RAM_RST_SHIFT_RSTn);
|
||||
|
||||
#if (defined CFG_TUSB_RHPORT1_MODE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
|
||||
CLOCK_EnableClock(kCLOCK_Usbh1);
|
||||
/* Put PHY powerdown under software control */
|
||||
USBHSH->PORTMODE = USBHSH_PORTMODE_SW_PDCOM_MASK;
|
||||
/* According to reference manual, device mode setting has to be set by access usb host register */
|
||||
USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
|
||||
/* enable usb1 host clock */
|
||||
CLOCK_DisableClock(kCLOCK_Usbh1);
|
||||
#endif
|
||||
|
||||
#if (defined CFG_TUSB_RHPORT0_MODE) && (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE)
|
||||
#ifndef BUILD_NO_TINYUSB
|
||||
#if BOARD_TUD_RHPORT == 0
|
||||
// Enable USB Clock Adjustments to trim the FRO for the full speed controller
|
||||
ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK;
|
||||
CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
|
||||
|
|
@ -298,6 +288,17 @@ void board_dfu_init(void)
|
|||
/* disable usb0 host clock */
|
||||
CLOCK_DisableClock(kCLOCK_Usbhsl0);
|
||||
CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); /* enable USB Device clock */
|
||||
#endif
|
||||
|
||||
#if BOARD_TUD_RHPORT == 1
|
||||
CLOCK_EnableClock(kCLOCK_Usbh1);
|
||||
/* Put PHY powerdown under software control */
|
||||
USBHSH->PORTMODE = USBHSH_PORTMODE_SW_PDCOM_MASK;
|
||||
/* According to reference manual, device mode setting has to be set by access usb host register */
|
||||
USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
|
||||
/* enable usb1 host clock */
|
||||
CLOCK_DisableClock(kCLOCK_Usbh1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TU_LOG2("FRO192M_CTRL: 0x%08lX\r\n", ANACTRL->FRO192M_CTRL);
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@
|
|||
// Flash Start Address of Application
|
||||
#define BOARD_FLASH_APP_START 0x10000
|
||||
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 1
|
||||
#define DBL_TAP_REG RTC->GPREG[7]
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
#define TINYUF2_DBL_TAP_REG RTC->GPREG[7]
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,14 +38,18 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
//#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
|
||||
//#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -88,4 +92,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ LDFLAGS += \
|
|||
# libc
|
||||
LIBS += -lgcc -lm -lc
|
||||
|
||||
# nanolib
|
||||
# nanolib: TODO remove
|
||||
ifneq ($(SKIP_NANOLIB), 1)
|
||||
LDFLAGS += -specs=nosys.specs -specs=nano.specs
|
||||
LIBS += -lnosys
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ UF2_MIMXRT1176_ADDR= 0x30000000
|
|||
SDP_PID = $(SDP_$(MCU)_PID)
|
||||
UF2_ADDR = $(UF2_$(MCU)_ADDR)
|
||||
|
||||
DBL_TAP_MAGIC_ERASE_APP = 0xf5e80ab4
|
||||
DBL_TAP_REG_ADDR = 0x400D410C
|
||||
|
||||
# extract _fcfb_origin and _ivt_origin from linker file
|
||||
|
|
|
|||
|
|
@ -22,5 +22,4 @@ function(configure_app TARGET)
|
|||
family_add_uf2(${TARGET} ${UF2_FAMILY_ID})
|
||||
family_flash_uf2(${TARGET} ${UF2_FAMILY_ID})
|
||||
family_flash_jlink(${TARGET} hex)
|
||||
#family_flash_pyocd(${TARGET} hex)
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,9 +38,13 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define CFG_TUSB_RHPORT1_MODE 0
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUD_ENABLED 1
|
||||
#define CFG_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
|
|
@ -83,4 +87,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,9 +38,13 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define CFG_TUSB_RHPORT1_MODE 0
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUD_ENABLED 1
|
||||
#define CFG_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
|
|
@ -87,4 +91,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,14 +38,17 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define CFG_TUSB_RHPORT1_MODE 0
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUD_ENABLED 1
|
||||
#define CFG_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -88,4 +91,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ void board_flash_flush(void)
|
|||
_flash_page_addr = NO_CACHE;
|
||||
}
|
||||
|
||||
void board_flash_write (uint32_t addr, void const *src, uint32_t len)
|
||||
bool board_flash_write (uint32_t addr, void const *src, uint32_t len)
|
||||
{
|
||||
uint32_t const page_addr = addr & ~(SECTOR_SIZE - 1);
|
||||
|
||||
|
|
@ -198,6 +198,8 @@ void board_flash_write (uint32_t addr, void const *src, uint32_t len)
|
|||
|
||||
// Overwrite part or all of the page cache with the src data.
|
||||
memcpy(_flash_cache + (addr & (SECTOR_SIZE - 1)), src, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
|
|
|
|||
|
|
@ -423,19 +423,16 @@ int board_uart_read(uint8_t* buf, int len)
|
|||
|
||||
#else
|
||||
|
||||
void board_uart_init(uint32_t baud_rate)
|
||||
{
|
||||
void board_uart_init(uint32_t baud_rate) {
|
||||
(void) baud_rate;
|
||||
}
|
||||
|
||||
int board_uart_write(void const * buf, int len)
|
||||
{
|
||||
int board_uart_write(void const * buf, int len) {
|
||||
(void) buf; (void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_uart_read(uint8_t* buf, int len)
|
||||
{
|
||||
int board_uart_read(uint8_t* buf, int len) {
|
||||
(void) buf; (void) len;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -449,37 +446,16 @@ int board_uart_read(uint8_t* buf, int len)
|
|||
|
||||
// The iMX RT 1040 is named without a number. We can always have this because
|
||||
// it'll get GC'd when not used.
|
||||
void USB_OTG_IRQHandler(void)
|
||||
{
|
||||
#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST
|
||||
tuh_int_handler(0);
|
||||
#endif
|
||||
|
||||
#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
void USB_OTG_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
void USB_OTG1_IRQHandler(void)
|
||||
{
|
||||
#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST
|
||||
tuh_int_handler(0);
|
||||
#endif
|
||||
|
||||
#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
void USB_OTG1_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
void USB_OTG2_IRQHandler(void)
|
||||
{
|
||||
#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST
|
||||
tuh_int_handler(1);
|
||||
#endif
|
||||
|
||||
#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE
|
||||
tud_int_handler(1);
|
||||
#endif
|
||||
void USB_OTG2_IRQHandler(void) {
|
||||
tud_int_handler(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -57,16 +57,16 @@ extern uint32_t _board_boot_length[];
|
|||
#endif
|
||||
|
||||
// Double Reset tap to enter DFU
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 1
|
||||
#define DBL_TAP_REG SNVS->LPGPR[3]
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
#define TINYUF2_DBL_TAP_REG SNVS->LPGPR[3]
|
||||
|
||||
// Brightness percentage from 1 to 255
|
||||
#ifndef NEOPIXEL_BRIGHTNESS
|
||||
#define NEOPIXEL_BRIGHTNESS 0x10
|
||||
#define NEOPIXEL_BRIGHTNESS 0x10
|
||||
#endif
|
||||
|
||||
#ifdef LED_PIN
|
||||
#define TINYUF2_LED 1
|
||||
#define TINYUF2_LED 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,25 +38,19 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
#define CFG_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
#if BOARD_TUD_RHPORT == 0
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define CFG_TUSB_RHPORT1_MODE 0
|
||||
#elif BOARD_TUD_RHPORT == 1
|
||||
#define CFG_TUSB_RHPORT0_MODE 0
|
||||
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#else
|
||||
#error "BOARD_TUD_RHPORT is not correct"
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -71,7 +65,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -79,7 +73,7 @@
|
|||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
|
|
@ -103,4 +97,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -196,3 +196,14 @@ flash-dfu-util: $(BUILD)/$(OUTNAME).bin
|
|||
|
||||
erase-dfu-util:
|
||||
dfu-util -R -a 0 --dfuse-address 0x08000000:mass-erase:force
|
||||
|
||||
# --------------- openocd-wch -----------------
|
||||
# wch-linke is not supported yet in official openOCD yet. We need to either use
|
||||
# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or
|
||||
# 2. compiled from https://github.com/hathach/riscv-openocd-wch or
|
||||
# https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz
|
||||
# with ./configure --disable-werror --enable-wlinke --enable-ch347=no
|
||||
OPENOCD_WCH ?= /home/${USER}/app/riscv-openocd-wch/src/openocd
|
||||
OPENOCD_WCH_OPTION ?=
|
||||
flash-openocd-wch: $(BUILD)/$(OUTNAME).elf
|
||||
$(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit
|
||||
|
|
|
|||
|
|
@ -39,38 +39,32 @@
|
|||
#define BOOTLOADER_PAGE_MASK (OB_WRP_PAGES0TO1 | OB_WRP_PAGES2TO3 | OB_WRP_PAGES4TO5 | OB_WRP_PAGES6TO7)
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
SECTOR_COUNT = (BOARD_FLASH_SIZE / BOARD_PAGE_SIZE),
|
||||
BOOTLOADER_SECTOR_COUNT = ((BOARD_FLASH_APP_START - FLASH_BASE_ADDR) / BOARD_PAGE_SIZE)
|
||||
};
|
||||
|
||||
static uint8_t erased_sectors[SECTOR_COUNT] = { 0 };
|
||||
static uint8_t erased_sectors[SECTOR_COUNT] = {0};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Internal Helper
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static inline uint32_t flash_sector_size(uint32_t sector)
|
||||
{
|
||||
static inline uint32_t flash_sector_size(uint32_t sector) {
|
||||
(void) sector;
|
||||
return BOARD_PAGE_SIZE;
|
||||
}
|
||||
|
||||
static bool is_blank(uint32_t addr, uint32_t size)
|
||||
{
|
||||
for ( uint32_t i = 0; i < size; i += sizeof(uint32_t) )
|
||||
{
|
||||
if ( *(uint32_t*) (addr + i) != 0xffffffff )
|
||||
{
|
||||
static bool is_blank(uint32_t addr, uint32_t size) {
|
||||
for (uint32_t i = 0; i < size; i += sizeof(uint32_t)) {
|
||||
if (*(uint32_t*) (addr + i) != 0xffffffff) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool flash_erase_sector(uint32_t addr)
|
||||
{
|
||||
static bool flash_erase_sector(uint32_t addr) {
|
||||
#ifndef TINYUF2_SELF_UPDATE
|
||||
// skip erasing bootloader if not self-update
|
||||
TUF2_ASSERT(addr >= BOARD_FLASH_APP_START);
|
||||
|
|
@ -81,13 +75,11 @@ static bool flash_erase_sector(uint32_t addr)
|
|||
bool erased = false;
|
||||
uint32_t size = 0;
|
||||
|
||||
for ( uint32_t i = 0; i < SECTOR_COUNT; i++ )
|
||||
{
|
||||
for (uint32_t i = 0; i < SECTOR_COUNT; i++) {
|
||||
TUF2_ASSERT(sector_addr < FLASH_BASE_ADDR + BOARD_FLASH_SIZE);
|
||||
|
||||
size = flash_sector_size(i);
|
||||
if ( sector_addr + size > addr )
|
||||
{
|
||||
if (sector_addr + size > addr) {
|
||||
erased = erased_sectors[i];
|
||||
erased_sectors[i] = 1; // don't erase anymore - we will continue writing here!
|
||||
break;
|
||||
|
|
@ -95,8 +87,7 @@ static bool flash_erase_sector(uint32_t addr)
|
|||
sector_addr += size;
|
||||
}
|
||||
|
||||
if ( !erased && !is_blank(sector_addr, size))
|
||||
{
|
||||
if (!erased && !is_blank(sector_addr, size)) {
|
||||
TUF2_LOG1("Erase: %08lX size = %lu KB ... ", sector_addr, size / 1024);
|
||||
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
|
|
@ -115,31 +106,26 @@ static bool flash_erase_sector(uint32_t addr)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void flash_write(uint32_t dst, const uint8_t *src, int len)
|
||||
{
|
||||
static void flash_write(uint32_t dst, const uint8_t* src, int len) {
|
||||
flash_erase_sector(dst);
|
||||
|
||||
TUF2_LOG1("Write flash at address %08lX\r\n", dst);
|
||||
for (int i = 0; i < len; i += 4)
|
||||
{
|
||||
uint32_t data = *( (uint32_t*) ((void*) (src + i)) );
|
||||
for (int i = 0; i < len; i += 4) {
|
||||
uint32_t data = *((uint32_t*) ((void*) (src + i)));
|
||||
|
||||
if ( HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, dst + i, (uint64_t) data) != HAL_OK )
|
||||
{
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, dst + i, (uint64_t) data) != HAL_OK) {
|
||||
TUF2_LOG1("Failed to write flash at address %08lX\r\n", dst + i);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( FLASH_WaitForLastOperation(HAL_MAX_DELAY) != HAL_OK )
|
||||
{
|
||||
if (FLASH_WaitForLastOperation(HAL_MAX_DELAY) != HAL_OK) {
|
||||
TUF2_LOG1("Waiting on last operation failed\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// verify contents
|
||||
if (memcmp((void*)dst, src, len) != 0)
|
||||
{
|
||||
if (memcmp((void*) dst, src, len) != 0) {
|
||||
TUF2_LOG1("Failed to write\r\n");
|
||||
}
|
||||
}
|
||||
|
|
@ -147,45 +133,41 @@ static void flash_write(uint32_t dst, const uint8_t *src, int len)
|
|||
//--------------------------------------------------------------------+
|
||||
// Board API
|
||||
//--------------------------------------------------------------------+
|
||||
void board_flash_init(void)
|
||||
{
|
||||
|
||||
void board_flash_init(void) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
uint32_t board_flash_size(void)
|
||||
{
|
||||
uint32_t board_flash_size(void) {
|
||||
return BOARD_FLASH_SIZE;
|
||||
}
|
||||
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len)
|
||||
{
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len) {
|
||||
memcpy(buffer, (void*) addr, len);
|
||||
}
|
||||
|
||||
void board_flash_flush(void)
|
||||
{
|
||||
void board_flash_flush(void) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// TODO not working quite yet
|
||||
void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
||||
{
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len) {
|
||||
// TODO skip matching contents
|
||||
HAL_FLASH_Unlock();
|
||||
flash_write(addr, data, len);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
{
|
||||
void board_flash_erase_app(void) {
|
||||
// TODO implement later
|
||||
}
|
||||
|
||||
bool board_flash_protect_bootloader(bool protect)
|
||||
{
|
||||
bool board_flash_protect_bootloader(bool protect) {
|
||||
// F3 reset every time Option Bytes is programmed
|
||||
// skip protecting bootloader if we just reset by option byte changes
|
||||
// since we want to disable protect mode for e.g self-updating
|
||||
if ( board_reset_by_option_bytes() ) {
|
||||
if (board_reset_by_option_bytes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -203,18 +185,15 @@ bool board_flash_protect_bootloader(bool protect)
|
|||
TUF2_LOG1("Protection: current = %u, request = %u\r\n", already_protected, protect);
|
||||
|
||||
// request and current state mismatched --> require ob program
|
||||
if (protect != already_protected)
|
||||
{
|
||||
if (protect != already_protected) {
|
||||
FLASH_OBProgramInitTypeDef ob_update = {0};
|
||||
ob_update.OptionType = OPTIONBYTE_WRP;
|
||||
ob_update.WRPPage = BOOTLOADER_PAGE_MASK;
|
||||
ob_update.WRPState = protect ? OB_WRPSTATE_ENABLE : OB_WRPSTATE_DISABLE;
|
||||
ob_update.WRPPage = BOOTLOADER_PAGE_MASK;
|
||||
ob_update.WRPState = protect ? OB_WRPSTATE_ENABLE : OB_WRPSTATE_DISABLE;
|
||||
|
||||
if (HAL_FLASHEx_OBProgram(&ob_update) == HAL_OK)
|
||||
{
|
||||
if (HAL_FLASHEx_OBProgram(&ob_update) == HAL_OK) {
|
||||
HAL_FLASH_OB_Launch(); // will reset
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -227,24 +206,20 @@ bool board_flash_protect_bootloader(bool protect)
|
|||
|
||||
#ifdef TINYUF2_SELF_UPDATE
|
||||
|
||||
bool is_new_bootloader_valid(const uint8_t * bootloader_bin, uint32_t bootloader_len)
|
||||
{
|
||||
bool is_new_bootloader_valid(const uint8_t* bootloader_bin, uint32_t bootloader_len) {
|
||||
// at least larger than vector table
|
||||
if (bootloader_len < 512 ) return false;
|
||||
if (bootloader_len < 512) return false;
|
||||
|
||||
// similar to board_app_valid() check
|
||||
if((((*(uint32_t*)bootloader_bin) - BOARD_RAM_START) <= BOARD_RAM_SIZE))
|
||||
{
|
||||
if ((((*(uint32_t*) bootloader_bin) - BOARD_RAM_START) <= BOARD_RAM_SIZE)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len)
|
||||
{
|
||||
void board_self_update(const uint8_t* bootloader_bin, uint32_t bootloader_len) {
|
||||
// check if the bootloader payload is valid
|
||||
if ( is_new_bootloader_valid(bootloader_bin, bootloader_len) )
|
||||
{
|
||||
if (is_new_bootloader_valid(bootloader_bin, bootloader_len)) {
|
||||
#if TINYUF2_PROTECT_BOOTLOADER
|
||||
// Note: Don't protect bootloader when done, leave that to the new bootloader
|
||||
// since it may or may not enable protection.
|
||||
|
|
@ -252,14 +227,12 @@ void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len)
|
|||
#endif
|
||||
|
||||
// keep writing until flash contents matches new bootloader data
|
||||
while( memcmp((const void*) FLASH_BASE_ADDR, bootloader_bin, bootloader_len) )
|
||||
{
|
||||
while (memcmp((const void*) FLASH_BASE_ADDR, bootloader_bin, bootloader_len)) {
|
||||
uint32_t sector_addr = FLASH_BASE_ADDR;
|
||||
const uint8_t * data = bootloader_bin;
|
||||
const uint8_t* data = bootloader_bin;
|
||||
uint32_t len = bootloader_len;
|
||||
|
||||
for ( uint32_t i = 0; i < BOOTLOADER_SECTOR_COUNT && len > 0; i++ )
|
||||
{
|
||||
for (uint32_t i = 0; i < BOOTLOADER_SECTOR_COUNT && len > 0; i++) {
|
||||
uint32_t const size = (flash_sector_size(i) < len ? flash_sector_size(i) : len);
|
||||
board_flash_write(sector_addr, data, size);
|
||||
|
||||
|
|
@ -275,12 +248,13 @@ void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len)
|
|||
__disable_irq();
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, BOARD_FLASH_APP_START , 0);
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, BOARD_FLASH_APP_START+4, 0);
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, BOARD_FLASH_APP_START, 0);
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, BOARD_FLASH_APP_START + 4, 0);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
// reset to run new bootloader
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -328,23 +328,20 @@ int board_uart_write(void const * buf, int len)
|
|||
|
||||
#ifndef BUILD_NO_TINYUSB
|
||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||
void USB_HP_IRQHandler(void)
|
||||
{
|
||||
void USB_HP_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
// USB low-priority interrupt (Channel 75): Triggered by all USB events
|
||||
// (Correct transfer, USB reset, etc.). The firmware has to check the
|
||||
// interrupt source before serving the interrupt.
|
||||
void USB_LP_IRQHandler(void)
|
||||
{
|
||||
void USB_LP_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
// USB wakeup interrupt (Channel 76): Triggered by the wakeup event from the USB
|
||||
// Suspend mode.
|
||||
void USBWakeUp_RMP_IRQHandler(void)
|
||||
{
|
||||
void USBWakeUp_RMP_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
|
|
@ -352,7 +349,5 @@ void USBWakeUp_RMP_IRQHandler(void)
|
|||
|
||||
// Required by __libc_init_array in startup code if we are compiling using
|
||||
// -nostdlib/-nostartfiles.
|
||||
__attribute__((used)) void _init(void)
|
||||
{
|
||||
|
||||
__attribute__((used)) void _init(void) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
#define BOARD_RAM_SIZE 0x9FFF
|
||||
|
||||
// Double Reset tap to enter DFU
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 1
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
|
||||
// Enable write protection
|
||||
#ifndef TINYUF2_PROTECT_BOOTLOADER
|
||||
|
|
|
|||
|
|
@ -62,7 +62,3 @@ function(family_add_board_target BOARD_TARGET)
|
|||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
endfunction()
|
||||
|
||||
#------------------------------------
|
||||
# Main target
|
||||
#------------------------------------
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,21 +38,19 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||
#ifndef BOARD_DEVICE_RHPORT_NUM
|
||||
#define BOARD_DEVICE_RHPORT_NUM 0
|
||||
#endif
|
||||
|
||||
// RHPort max operational speed can defined by board.mk
|
||||
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -67,7 +65,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -95,4 +93,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -193,12 +193,14 @@ void board_flash_flush(void)
|
|||
}
|
||||
|
||||
// TODO not working quite yet
|
||||
void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len)
|
||||
{
|
||||
// TODO skip matching contents
|
||||
HAL_FLASH_Unlock();
|
||||
flash_write(addr, data, len);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#endif
|
||||
|
||||
// Double Reset tap to enter DFU
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 1
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
|
||||
// Enable write protection
|
||||
#ifndef TINYUF2_PROTECT_BOOTLOADER
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,12 +38,18 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -58,7 +64,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -91,4 +97,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -152,9 +152,10 @@ void board_flash_read(uint32_t addr, void * data, uint32_t len)
|
|||
}
|
||||
}
|
||||
|
||||
void board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
||||
bool board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
||||
{
|
||||
TUF2_LOG1("Programming %lu byte(s) at 0x%08lx\r\n", len, addr);
|
||||
|
||||
// For external flash, W25Qx
|
||||
// TODO: these should be configurable parameters
|
||||
// Page size = 256 bytes
|
||||
|
|
@ -163,7 +164,7 @@ void board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
|||
if (IS_SPI_ADDR(addr) && IS_SPI_ADDR(addr + len - 1))
|
||||
{
|
||||
W25Qx_Write((uint8_t *) data, (addr - SPI_BASE_ADDR), len);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -176,7 +177,7 @@ void board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
|||
{
|
||||
__asm("bkpt #9");
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -186,7 +187,7 @@ void board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
|||
// This memory is cached, DCache is cleaned in dfu_complete
|
||||
SET_BOOT_ADDR(BOARD_AXISRAM_APP_ADDR);
|
||||
memcpy((void *) addr, data, len);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
#endif // BOARD_AXISRAM_EN
|
||||
|
||||
|
|
@ -198,13 +199,12 @@ void board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
|||
{
|
||||
// TODO: Implement this
|
||||
// SET_BOOT_ADDR(BOARD_PFLASH_APP_ADDR);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
// Invalid address write
|
||||
__asm("bkpt #4");
|
||||
}
|
||||
// Invalid address write
|
||||
__asm("bkpt #4");
|
||||
return false;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ void board_init(void)
|
|||
void board_dfu_init(void)
|
||||
{
|
||||
// Not quite sure what an RHPORT is :/
|
||||
#if BOARD_DEVICE_RHPORT_NUM == 0
|
||||
#if BOARD_TUD_RHPORT == 0
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
// Init USB Pins
|
||||
|
|
@ -81,9 +81,9 @@ void board_dfu_init(void)
|
|||
USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
|
||||
USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
|
||||
|
||||
#elif BOARD_DEVICE_RHPORT_NUM == 1
|
||||
// TODO: implement whatever this is
|
||||
#error "Sorry, not implemented yet"
|
||||
#elif BOARD_TUD_RHPORT == 1
|
||||
// TODO: implement whatever this is
|
||||
#error "Sorry, not implemented yet"
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
#define SET_BOOT_ADDR(x) board_save_app_start_address(x)
|
||||
|
||||
// Double Reset tap to enter DFU
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 1
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
|
||||
void board_flash_early_init(void);
|
||||
uint32_t board_get_app_start_address(void);
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ extern "C" {
|
|||
#define UF2_INDEX_URL "https://github.com/WeActStudio/MiniSTM32H7xx"
|
||||
|
||||
#define USB_NO_VBUS_PIN 1
|
||||
#define BOARD_DEVICE_RHPORT_NUM 0
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// UART
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ SRC_C += \
|
|||
|
||||
|
||||
ifndef BUILD_NO_TINYUSB
|
||||
SRC_C += lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c
|
||||
SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c
|
||||
endif
|
||||
|
||||
# Includes
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -38,17 +38,18 @@
|
|||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||
#ifndef BOARD_DEVICE_RHPORT_NUM
|
||||
#define BOARD_DEVICE_RHPORT_NUM 0
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -92,10 +93,8 @@
|
|||
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
|
||||
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
|
||||
|
||||
#define CFG_TUSB_RHPORT1_MODE 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -162,12 +162,14 @@ void board_flash_flush(void)
|
|||
}
|
||||
|
||||
// TODO not working quite yet
|
||||
void board_flash_write (uint32_t addr, void const *data, uint32_t len)
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len)
|
||||
{
|
||||
// TODO skip matching contents
|
||||
HAL_FLASH_Unlock();
|
||||
flash_write(addr, data, len);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
#define BOARD_PAGE_SIZE 0x1000
|
||||
|
||||
// Double Reset tap to enter DFU
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 1
|
||||
#define TINYUF2_DBL_TAP_DFU 1
|
||||
|
||||
// Brightness percentage from 1 to 255
|
||||
#ifndef NEOPIXEL_BRIGHTNESS
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -35,15 +35,21 @@
|
|||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#error CFG_TUSB_MCU must be defined
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
#ifndef BOARD_TUD_RHPORT
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
#endif
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
|
|
@ -58,7 +64,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -66,7 +72,7 @@
|
|||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
|
|
@ -91,4 +97,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,43 +23,42 @@
|
|||
*/
|
||||
|
||||
#include "board_api.h"
|
||||
|
||||
#ifndef BUILD_NO_TINYUSB
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
void board_init(void)
|
||||
{
|
||||
void board_init(void) {
|
||||
}
|
||||
|
||||
void board_dfu_init(void)
|
||||
{
|
||||
void board_teardown(void) {
|
||||
}
|
||||
|
||||
void board_dfu_init(void) {
|
||||
// Init USB for DFU
|
||||
}
|
||||
|
||||
void board_reset(void)
|
||||
{
|
||||
void board_reset(void) {
|
||||
// NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void board_dfu_complete(void)
|
||||
{
|
||||
void board_dfu_complete(void) {
|
||||
// Mostly reset
|
||||
// NVIC_SystemReset();
|
||||
}
|
||||
|
||||
bool board_app_valid(void)
|
||||
{
|
||||
bool board_app_valid(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void board_app_jump(void)
|
||||
{
|
||||
void board_app_jump(void) {
|
||||
// Jump to application code
|
||||
}
|
||||
|
||||
uint8_t board_usb_get_serial(uint8_t serial_id[16])
|
||||
{
|
||||
uint8_t board_usb_get_serial(uint8_t serial_id[16]) {
|
||||
(void) serial_id;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -68,13 +67,11 @@ uint8_t board_usb_get_serial(uint8_t serial_id[16])
|
|||
// LED pattern
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void board_led_write(uint32_t state)
|
||||
{
|
||||
void board_led_write(uint32_t state) {
|
||||
(void) state;
|
||||
}
|
||||
|
||||
void board_rgb_write(uint8_t const rgb[])
|
||||
{
|
||||
void board_rgb_write(uint8_t const rgb[]) {
|
||||
(void) rgb;
|
||||
}
|
||||
|
||||
|
|
@ -82,35 +79,78 @@ void board_rgb_write(uint8_t const rgb[])
|
|||
// Timer
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void board_timer_start(uint32_t ms)
|
||||
{
|
||||
void board_timer_start(uint32_t ms) {
|
||||
(void) ms;
|
||||
// SysTick_Config( (SystemCoreClock/1000) * ms );
|
||||
}
|
||||
|
||||
void board_timer_stop(void)
|
||||
{
|
||||
void board_timer_stop(void) {
|
||||
// SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
void SysTick_Handler (void)
|
||||
{
|
||||
void SysTick_Handler(void) {
|
||||
board_timer_handler();
|
||||
}
|
||||
|
||||
|
||||
int board_uart_write(void const * buf, int len)
|
||||
{
|
||||
(void) buf; (void) len;
|
||||
int board_uart_write(void const* buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef TINYUF2_SELF_UPDATE
|
||||
//--------------------------------------------------------------------+
|
||||
// Flash
|
||||
//--------------------------------------------------------------------+
|
||||
void board_flash_init(void) {
|
||||
|
||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||
void OTG_FS_IRQHandler(void)
|
||||
{
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
uint32_t board_flash_size(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len) {
|
||||
(void) addr;
|
||||
(void) buffer;
|
||||
(void) len;
|
||||
}
|
||||
|
||||
void board_flash_flush(void) {
|
||||
}
|
||||
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len) {
|
||||
(void) addr;
|
||||
(void) data;
|
||||
(void) len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_flash_erase_app(void) {
|
||||
// TODO implement later
|
||||
}
|
||||
|
||||
bool board_flash_protect_bootloader(bool protect) {
|
||||
// TODO implement later
|
||||
(void) protect;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TINYUF2_SELF_UPDATE
|
||||
void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len)
|
||||
{
|
||||
(void) bootloader_bin;
|
||||
(void) bootloader_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB Interrupt Handler
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifndef BUILD_NO_TINYUSB
|
||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||
void OTG_FS_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "board.h"
|
||||
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 0
|
||||
#define TINYUF2_DBL_TAP_DFU 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
2
ports/template_port/boards/dummy/board.cmake
Normal file
2
ports/template_port/boards/dummy/board.cmake
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
function(update_board TARGET)
|
||||
endfunction()
|
||||
|
|
@ -23,8 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
#ifndef TUSB_CONFIG_H_
|
||||
#define TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -35,17 +35,19 @@
|
|||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#error CFG_TUSB_MCU must be defined
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
|
|
@ -58,7 +60,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -66,7 +68,7 @@
|
|||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
|
|
@ -91,4 +93,4 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,46 +27,46 @@
|
|||
uint32_t board_flash_size(void) { return CFG_UF2_FLASH_SIZE; }
|
||||
|
||||
// not supported
|
||||
void board_flash_write(uint32_t addr, void const *data, uint32_t len) {
|
||||
(void)addr;
|
||||
(void)data;
|
||||
(void)len;
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len) {
|
||||
(void) addr;
|
||||
(void) data;
|
||||
(void) len;
|
||||
return true;
|
||||
}
|
||||
|
||||
// not supported
|
||||
void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len) {
|
||||
(void)bootloader_bin;
|
||||
(void)bootloader_len;
|
||||
void board_self_update(const uint8_t* bootloader_bin, uint32_t bootloader_len) {
|
||||
(void) bootloader_bin;
|
||||
(void) bootloader_len;
|
||||
}
|
||||
|
||||
// not supported
|
||||
void board_flash_flush(void) {}
|
||||
void board_flash_flush(void) {}
|
||||
|
||||
// not supported
|
||||
bool board_flash_protect_bootloader(bool protect)
|
||||
{
|
||||
bool board_flash_protect_bootloader(bool protect) {
|
||||
(void) protect;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------- Interesting part of flash support for this test -------------//
|
||||
void board_flash_read (uint32_t addr, void* buffer, uint32_t len) {
|
||||
if ((addr & 7) != 0) {
|
||||
// TODO - need to copy part of the first eight bytes
|
||||
exit(1); // failure exit
|
||||
addr += 8 - (addr & 7);
|
||||
}
|
||||
void board_flash_read(uint32_t addr, void* buffer, uint32_t len) {
|
||||
if ((addr & 7) != 0) {
|
||||
// TODO - need to copy part of the first eight bytes
|
||||
exit(1); // failure exit
|
||||
addr += 8 - (addr & 7);
|
||||
}
|
||||
|
||||
// EMBED address in each 32 bits of the FLASH
|
||||
uint32_t * dest = buffer;
|
||||
size_t incBytes = sizeof(*dest);
|
||||
uint32_t currentAddress = addr;
|
||||
// EMBED address in each 32 bits of the FLASH
|
||||
uint32_t* dest = buffer;
|
||||
size_t incBytes = sizeof(*dest);
|
||||
uint32_t currentAddress = addr;
|
||||
|
||||
while (len >= incBytes) {
|
||||
memcpy(dest, ¤tAddress, incBytes); // unaligned memory possible
|
||||
while (len >= incBytes) {
|
||||
memcpy(dest, ¤tAddress, incBytes); // unaligned memory possible
|
||||
|
||||
len -= incBytes;
|
||||
dest++;
|
||||
currentAddress += incBytes;
|
||||
}
|
||||
len -= incBytes;
|
||||
dest++;
|
||||
currentAddress += incBytes;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,23 @@
|
|||
#include <string.h>
|
||||
#include "boards.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Compiler
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define TUF2_TOKEN(x) x
|
||||
#define TUF2_STRING(x) #x // stringify without expand
|
||||
#define TUF2_XSTRING(x) TU_STRING(x) // expand then stringify
|
||||
|
||||
#define TUF2_STRCAT(a, b) a##b // concat without expand
|
||||
#define TUF2_STRCAT3(a, b, c) a##b##c // concat without expand
|
||||
|
||||
#define TUF2_XSTRCAT(a, b) TU_STRCAT(a, b) // expand then concat
|
||||
#define TUF2_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) // expand then concat 3 tokens
|
||||
|
||||
#define ATTR_WEAK __attribute__ ((weak))
|
||||
#define ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Features
|
||||
//--------------------------------------------------------------------+
|
||||
|
|
@ -43,14 +60,28 @@
|
|||
#define BOARD_FLASH_APP_START 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef TUF2_LOG
|
||||
#define TUF2_LOG 2
|
||||
#endif
|
||||
|
||||
// Use LED for part of indicator
|
||||
#ifndef TINYUF2_LED
|
||||
#define TINYUF2_LED 0
|
||||
#endif
|
||||
|
||||
// Use Double Tap method to enter DFU mode
|
||||
#ifndef TINYUF2_DFU_DOUBLE_TAP
|
||||
#define TINYUF2_DFU_DOUBLE_TAP 0
|
||||
#ifndef TINYUF2_DBL_TAP_DFU
|
||||
#define TINYUF2_DBL_TAP_DFU 0
|
||||
#endif
|
||||
|
||||
// timeout for double tap detection in ms
|
||||
#ifndef TINYUF2_DBL_TAP_DELAY
|
||||
#define TINYUF2_DBL_TAP_DELAY 500
|
||||
#endif
|
||||
|
||||
#ifndef TINYUF2_DBL_TAP_REG_SIZE
|
||||
#define TINYUF2_DBL_TAP_REG_SIZE 32
|
||||
#endif
|
||||
|
||||
// Use Display to draw DFU image
|
||||
|
|
@ -68,10 +99,6 @@
|
|||
#define TINYUF2_CONST
|
||||
#endif
|
||||
|
||||
#ifndef TUF2_LOG
|
||||
#define TUF2_LOG 0
|
||||
#endif
|
||||
|
||||
// Use favicon.ico + autorun.inf (only works with windows)
|
||||
// define TINYUF2_FAVICON_HEADER to enable this feature
|
||||
|
||||
|
|
@ -79,9 +106,26 @@
|
|||
// Constant
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define DBL_TAP_MAGIC 0xf01669ef // Enter DFU magic
|
||||
#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef // Skip double tap delay detection
|
||||
#define DBL_TAP_MAGIC_ERASE_APP 0xf5e80ab4 // Erase entire application !!
|
||||
// defined by linker script
|
||||
#if TINYUF2_DBL_TAP_REG_SIZE == 32
|
||||
#define DBL_TAP_TYPE uint32_t
|
||||
#elif TINYUF2_DBL_TAP_REG_SIZE == 16
|
||||
#define DBL_TAP_TYPE uint16_t
|
||||
#elif TINYUF2_DBL_TAP_REG_SIZE == 8
|
||||
#define DBL_TAP_TYPE uint8_t
|
||||
#else
|
||||
#error "Invalid TINYUF2_DBL_TAP_REG_SIZE"
|
||||
#endif
|
||||
|
||||
#ifndef TINYUF2_DBL_TAP_REG
|
||||
// defined by linker script
|
||||
extern DBL_TAP_TYPE _board_dfu_dbl_tap[];
|
||||
#define TINYUF2_DBL_TAP_REG _board_dfu_dbl_tap[0]
|
||||
#endif
|
||||
|
||||
#define DBL_TAP_MAGIC (0xf01669ef >> (32 - TINYUF2_DBL_TAP_REG_SIZE)) // Enter DFU magic
|
||||
#define DBL_TAP_MAGIC_QUICK_BOOT (0xf02669ef >> (32 - TINYUF2_DBL_TAP_REG_SIZE)) // Skip double tap delay detection
|
||||
#define DBL_TAP_MAGIC_ERASE_APP (0xf5e80ab4 >> (32 - TINYUF2_DBL_TAP_REG_SIZE)) // Erase entire application !!
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Basic API
|
||||
|
|
@ -105,7 +149,7 @@ void board_teardown(void) __attribute__ ((weak));
|
|||
// board_teardown2() is called immediately after board_init()
|
||||
void board_teardown2(void) __attribute__ ((weak));
|
||||
|
||||
// Reset board, not return
|
||||
// Reset board, no return
|
||||
void board_reset(void);
|
||||
|
||||
// Write PWM duty value to LED
|
||||
|
|
@ -135,7 +179,7 @@ bool board_app_valid(void);
|
|||
// Additional check if application is valid for custom board.
|
||||
bool board_app_valid2(void) __attribute__ ((weak));
|
||||
|
||||
// Jump to Application
|
||||
// Jump to Application, no return
|
||||
void board_app_jump(void);
|
||||
|
||||
// Init USB hardware (not used for now)
|
||||
|
|
@ -150,6 +194,9 @@ void board_dfu_complete(void);
|
|||
// Fill Serial Number and return its length (limit to 16 bytes)
|
||||
uint8_t board_usb_get_serial(uint8_t serial_id[16]);
|
||||
|
||||
// Check if NRST pin is used to reset the board
|
||||
// bool board_reseted_by_nrst(void);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Flash API
|
||||
//--------------------------------------------------------------------+
|
||||
|
|
@ -163,8 +210,8 @@ uint32_t board_flash_size(void);
|
|||
// Read from flash
|
||||
void board_flash_read (uint32_t addr, void* buffer, uint32_t len);
|
||||
|
||||
// Write to flash
|
||||
void board_flash_write(uint32_t addr, void const *data, uint32_t len);
|
||||
// Write to flash, len is uf2's payload size (often 256 bytes)
|
||||
bool board_flash_write(uint32_t addr, void const* data, uint32_t len);
|
||||
|
||||
// Flush/Sync flash contents
|
||||
void board_flash_flush(void);
|
||||
|
|
@ -219,12 +266,12 @@ void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len);
|
|||
#define TUF2_LOG1_MEM // tu_print_mem
|
||||
#define TUF2_LOG1_VAR(_x) // tu_print_var((uint8_t const*)(_x), sizeof(*(_x)))
|
||||
#define TUF2_LOG1_INT(_x) tuf2_printf(#_x " = %ld\r\n", (uint32_t) (_x) )
|
||||
#define TUF2_LOG1_HEX(_x) tuf2_printf(#_x " = %lX\r\n", (uint32_t) (_x) )
|
||||
#define TUF2_LOG1_HEX(_x) tuf2_printf(#_x " = 0x%lX\r\n", (uint32_t) (_x) )
|
||||
#define TUF2_LOG1_LOCATION() tuf2_printf("%s: %d:\r\n", __PRETTY_FUNCTION__, __LINE__)
|
||||
#define TUF2_LOG1_FAILED() tuf2_printf("%s: %d: Failed\r\n", __PRETTY_FUNCTION__, __LINE__)
|
||||
|
||||
// Log with debug level 2
|
||||
#if CFG_TUSB_DEBUG > 1
|
||||
#if TUF2_LOG > 1
|
||||
#define TUF2_LOG2 TUF2_LOG1
|
||||
#define TUF2_LOG2_MEM TUF2_LOG1_MEM
|
||||
#define TUF2_LOG2_VAR TUF2_LOG1_VAR
|
||||
|
|
@ -268,10 +315,8 @@ enum {
|
|||
|
||||
void indicator_set(uint32_t state);
|
||||
|
||||
static inline void rgb_brightness(uint8_t out[3], uint8_t const in[3], uint8_t brightness)
|
||||
{
|
||||
for(uint32_t i=0; i<3; i++ )
|
||||
{
|
||||
static inline void rgb_brightness(uint8_t out[3], uint8_t const in[3], uint8_t brightness) {
|
||||
for(uint32_t i=0; i<3; i++ ) {
|
||||
out[i] = (in[i]*brightness) >> 8;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "compile_date.h"
|
||||
|
|
@ -141,7 +140,7 @@ char infoUf2File[128*3] =
|
|||
"Date: " COMPILE_DATE "\r\n"
|
||||
"Flash Size: 0x";
|
||||
|
||||
const char indexFile[] =
|
||||
TINYUF2_CONST char indexFile[] =
|
||||
"<!doctype html>\n"
|
||||
"<html>"
|
||||
"<body>"
|
||||
|
|
@ -201,7 +200,7 @@ STATIC_ASSERT( CLUSTER_COUNT >= 0x1015 && CLUSTER_COUNT < 0xFFD5 );
|
|||
//
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static FAT_BootBlock const BootBlock = {
|
||||
static FAT_BootBlock TINYUF2_CONST BootBlock = {
|
||||
.JumpInstruction = {0xeb, 0x3c, 0x90},
|
||||
.OEMInfo = "UF2 UF2 ",
|
||||
.SectorSize = BPB_SECTOR_SIZE,
|
||||
|
|
|
|||
123
src/main.c
123
src/main.c
|
|
@ -37,21 +37,12 @@
|
|||
//--------------------------------------------------------------------+
|
||||
//#define USE_DFU_BUTTON 1
|
||||
|
||||
// timeout for double tap detection
|
||||
#define DBL_TAP_DELAY 500
|
||||
|
||||
#ifndef DBL_TAP_REG
|
||||
// defined by linker script
|
||||
extern uint32_t _board_dfu_dbl_tap[];
|
||||
#define DBL_TAP_REG _board_dfu_dbl_tap[0]
|
||||
#endif
|
||||
|
||||
uint8_t const RGB_USB_UNMOUNTED[] = { 0xff, 0x00, 0x00 }; // Red
|
||||
uint8_t const RGB_USB_MOUNTED[] = { 0x00, 0xff, 0x00 }; // Green
|
||||
uint8_t const RGB_WRITING[] = { 0xcc, 0x66, 0x00 };
|
||||
uint8_t const RGB_DOUBLE_TAP[] = { 0x80, 0x00, 0xff }; // Purple
|
||||
uint8_t const RGB_UNKNOWN[] = { 0x00, 0x00, 0x88 }; // for debug
|
||||
uint8_t const RGB_OFF[] = { 0x00, 0x00, 0x00 };
|
||||
uint8_t RGB_USB_UNMOUNTED[] = { 0xff, 0x00, 0x00 }; // Red
|
||||
uint8_t RGB_USB_MOUNTED[] = { 0x00, 0xff, 0x00 }; // Green
|
||||
uint8_t RGB_WRITING[] = { 0xcc, 0x66, 0x00 };
|
||||
uint8_t RGB_DOUBLE_TAP[] = { 0x80, 0x00, 0xff }; // Purple
|
||||
uint8_t RGB_UNKNOWN[] = { 0x00, 0x00, 0x88 }; // for debug
|
||||
uint8_t RGB_OFF[] = { 0x00, 0x00, 0x00 };
|
||||
|
||||
static volatile uint32_t _timer_count = 0;
|
||||
|
||||
|
|
@ -63,7 +54,7 @@ static bool check_dfu_mode(void);
|
|||
int main(void) {
|
||||
board_init();
|
||||
if (board_init2) board_init2();
|
||||
TU_LOG1("TinyUF2\r\n");
|
||||
TUF2_LOG1("TinyUF2\r\n");
|
||||
|
||||
#if TINYUF2_PROTECT_BOOTLOADER
|
||||
board_flash_protect_bootloader(true);
|
||||
|
|
@ -75,14 +66,16 @@ int main(void) {
|
|||
if (board_teardown) board_teardown();
|
||||
if (board_teardown2) board_teardown2();
|
||||
board_app_jump();
|
||||
TU_LOG1("Failed to jump\r\n");
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
TU_LOG1("Start DFU mode\r\n");
|
||||
TUF2_LOG1("Start DFU mode\r\n");
|
||||
board_dfu_init();
|
||||
board_flash_init();
|
||||
uf2_init();
|
||||
tusb_init();
|
||||
|
||||
tud_init(BOARD_TUD_RHPORT);
|
||||
|
||||
indicator_set(STATE_USB_UNPLUGGED);
|
||||
|
||||
|
|
@ -91,7 +84,7 @@ int main(void) {
|
|||
screen_draw_drag();
|
||||
#endif
|
||||
|
||||
#if (CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO)
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO
|
||||
while(1) {
|
||||
tud_task();
|
||||
}
|
||||
|
|
@ -100,44 +93,46 @@ int main(void) {
|
|||
|
||||
// return true if start DFU mode, else App mode
|
||||
static bool check_dfu_mode(void) {
|
||||
// TODO enable for all port instead of one with double tap
|
||||
#if TINYUF2_DFU_DOUBLE_TAP
|
||||
// TUF2_LOG1_HEX(&DBL_TAP_REG);
|
||||
|
||||
// Erase application
|
||||
if (DBL_TAP_REG == DBL_TAP_MAGIC_ERASE_APP) {
|
||||
DBL_TAP_REG = 0;
|
||||
|
||||
indicator_set(STATE_WRITING_STARTED);
|
||||
board_flash_erase_app();
|
||||
indicator_set(STATE_WRITING_FINISHED);
|
||||
|
||||
// TODO maybe reset is better than continue
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if app is valid
|
||||
if (!board_app_valid()) return true;
|
||||
if (board_app_valid2 && !board_app_valid2()) return true;
|
||||
|
||||
#if TINYUF2_DFU_DOUBLE_TAP
|
||||
// TU_LOG1_HEX(DBL_TAP_REG);
|
||||
|
||||
// App want to reboot quickly
|
||||
if (DBL_TAP_REG == DBL_TAP_MAGIC_QUICK_BOOT) {
|
||||
DBL_TAP_REG = 0;
|
||||
return false;
|
||||
if (!board_app_valid()) {
|
||||
TUF2_LOG1("App invalid\r\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DBL_TAP_REG == DBL_TAP_MAGIC) {
|
||||
// Double tap occurred
|
||||
DBL_TAP_REG = 0;
|
||||
TU_LOG1("Double Tap Reset\r\n");
|
||||
if (board_app_valid2 && !board_app_valid2()) {
|
||||
TUF2_LOG1("App invalid\r\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
#if TINYUF2_DBL_TAP_DFU
|
||||
TUF2_LOG1_HEX(TINYUF2_DBL_TAP_REG);
|
||||
|
||||
switch(TINYUF2_DBL_TAP_REG) {
|
||||
case DBL_TAP_MAGIC_QUICK_BOOT:
|
||||
// Boot to app quickly
|
||||
TUF2_LOG1("Quick boot to App\r\n");
|
||||
TINYUF2_DBL_TAP_REG = 0;
|
||||
return false;
|
||||
|
||||
case DBL_TAP_MAGIC:
|
||||
// Double tap occurred
|
||||
TUF2_LOG1("Double Tap Reset\r\n");
|
||||
TINYUF2_DBL_TAP_REG = 0;
|
||||
return true;
|
||||
|
||||
case DBL_TAP_MAGIC_ERASE_APP:
|
||||
TUF2_LOG1("Erase app\r\n");
|
||||
TINYUF2_DBL_TAP_REG = 0;
|
||||
indicator_set(STATE_WRITING_STARTED);
|
||||
board_flash_erase_app();
|
||||
indicator_set(STATE_WRITING_FINISHED);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Register our first reset for double reset detection
|
||||
DBL_TAP_REG = DBL_TAP_MAGIC;
|
||||
TINYUF2_DBL_TAP_REG = DBL_TAP_MAGIC;
|
||||
|
||||
_timer_count = 0;
|
||||
board_timer_start(1);
|
||||
|
|
@ -150,14 +145,14 @@ static bool check_dfu_mode(void) {
|
|||
board_rgb_write(RGB_DOUBLE_TAP);
|
||||
|
||||
// delay a fraction of second if Reset pin is tap during this delay --> we will enter dfu
|
||||
while(_timer_count < DBL_TAP_DELAY) {}
|
||||
while(_timer_count < TINYUF2_DBL_TAP_DELAY) {}
|
||||
board_timer_stop();
|
||||
|
||||
// Turn off indicator
|
||||
board_rgb_write(RGB_OFF);
|
||||
board_led_write(0x00);
|
||||
|
||||
DBL_TAP_REG = 0;
|
||||
TINYUF2_DBL_TAP_REG = 0;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
|
|
@ -181,27 +176,27 @@ void tud_umount_cb(void) {
|
|||
// Indicator
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static uint32_t _indicator_state = STATE_BOOTLOADER_STARTED;
|
||||
static uint8_t _indicator_rgb[3];
|
||||
static uint32_t indicator_state = STATE_BOOTLOADER_STARTED;
|
||||
static uint8_t indicator_rgb[3];
|
||||
|
||||
void indicator_set(uint32_t state) {
|
||||
_indicator_state = state;
|
||||
indicator_state = state;
|
||||
switch (state) {
|
||||
case STATE_USB_UNPLUGGED:
|
||||
board_timer_start(1);
|
||||
memcpy(_indicator_rgb, RGB_USB_UNMOUNTED, 3);
|
||||
board_rgb_write(_indicator_rgb);
|
||||
memcpy(indicator_rgb, RGB_USB_UNMOUNTED, 3);
|
||||
board_rgb_write(indicator_rgb);
|
||||
break;
|
||||
|
||||
case STATE_USB_PLUGGED:
|
||||
board_timer_start(5);
|
||||
memcpy(_indicator_rgb, RGB_USB_MOUNTED, 3);
|
||||
board_rgb_write(_indicator_rgb);
|
||||
memcpy(indicator_rgb, RGB_USB_MOUNTED, 3);
|
||||
board_rgb_write(indicator_rgb);
|
||||
break;
|
||||
|
||||
case STATE_WRITING_STARTED:
|
||||
board_timer_start(25);
|
||||
memcpy(_indicator_rgb, RGB_WRITING, 3);
|
||||
memcpy(indicator_rgb, RGB_WRITING, 3);
|
||||
break;
|
||||
|
||||
case STATE_WRITING_FINISHED:
|
||||
|
|
@ -217,7 +212,7 @@ void indicator_set(uint32_t state) {
|
|||
void board_timer_handler(void) {
|
||||
_timer_count++;
|
||||
|
||||
switch (_indicator_state) {
|
||||
switch (indicator_state) {
|
||||
case STATE_USB_UNPLUGGED:
|
||||
case STATE_USB_PLUGGED: {
|
||||
// Fading with LED TODO option to skip for unsupported MCUs
|
||||
|
|
@ -240,7 +235,7 @@ void board_timer_handler(void) {
|
|||
board_led_write(is_on ? 0xff : 0x000);
|
||||
|
||||
// blink RGB if available
|
||||
board_rgb_write(is_on ? _indicator_rgb : RGB_OFF);
|
||||
board_rgb_write(is_on ? indicator_rgb : RGB_OFF);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +249,7 @@ void board_timer_handler(void) {
|
|||
//--------------------------------------------------------------------+
|
||||
|
||||
// Enable only with LOG is enabled (Note: ESP32-S2 has built-in support already)
|
||||
#if CFG_TUSB_DEBUG && (CFG_TUSB_MCU != OPT_MCU_ESP32S2 && CFG_TUSB_MCU != OPT_MCU_RP2040)
|
||||
#if (CFG_TUSB_DEBUG || TUF2_LOG) && (CFG_TUSB_MCU != OPT_MCU_ESP32S2 && CFG_TUSB_MCU != OPT_MCU_RP2040)
|
||||
#if defined(LOGGER_RTT)
|
||||
#include "SEGGER_RTT.h"
|
||||
#endif
|
||||
|
|
|
|||
87
src/msc.c
87
src/msc.c
|
|
@ -35,7 +35,7 @@
|
|||
static uint32_t _write_ms;
|
||||
#endif
|
||||
|
||||
static WriteState _wr_state = { 0 };
|
||||
static WriteState _wr_state = {0};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// tinyusb callbacks
|
||||
|
|
@ -43,23 +43,21 @@ static WriteState _wr_state = { 0 };
|
|||
|
||||
// Invoked when received SCSI_CMD_INQUIRY
|
||||
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
|
||||
{
|
||||
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
|
||||
(void) lun;
|
||||
|
||||
const char vid[] = "Adafruit";
|
||||
const char pid[] = "UF2 Bootloader";
|
||||
const char rev[] = "1.0";
|
||||
|
||||
memcpy(vendor_id , vid, strlen(vid));
|
||||
memcpy(product_id , pid, strlen(pid));
|
||||
memcpy(vendor_id, vid, strlen(vid));
|
||||
memcpy(product_id, pid, strlen(pid));
|
||||
memcpy(product_rev, rev, strlen(rev));
|
||||
}
|
||||
|
||||
// Invoked when received Test Unit Ready command.
|
||||
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||
bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
||||
{
|
||||
bool tud_msc_test_unit_ready_cb(uint8_t lun) {
|
||||
(void) lun;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -67,20 +65,18 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
|||
// Callback invoked when received an SCSI command not in built-in list below
|
||||
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
||||
// - READ10 and WRITE10 has their own callbacks
|
||||
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
|
||||
{
|
||||
int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) {
|
||||
void const* response = NULL;
|
||||
uint16_t resplen = 0;
|
||||
|
||||
// most scsi handled is input
|
||||
bool in_xfer = true;
|
||||
|
||||
switch (scsi_cmd[0])
|
||||
{
|
||||
switch (scsi_cmd[0]) {
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
// Host is about to read/write etc ... better not to disconnect disk
|
||||
resplen = 0;
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Set Sense = Invalid Command Operation
|
||||
|
|
@ -88,19 +84,16 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||
|
||||
// negative means error -> tinyusb could stall and/or response with failed status
|
||||
resplen = -1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
// return resplen must not larger than bufsize
|
||||
if ( resplen > bufsize ) resplen = bufsize;
|
||||
if (resplen > bufsize) resplen = bufsize;
|
||||
|
||||
if ( response && (resplen > 0) )
|
||||
{
|
||||
if(in_xfer)
|
||||
{
|
||||
if (response && (resplen > 0)) {
|
||||
if (in_xfer) {
|
||||
memcpy(buffer, response, resplen);
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
// SCSI output
|
||||
}
|
||||
}
|
||||
|
|
@ -110,8 +103,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||
|
||||
// Callback invoked when received READ10 command.
|
||||
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
||||
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
|
||||
{
|
||||
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
|
||||
(void) lun;
|
||||
memset(buffer, 0, bufsize);
|
||||
|
||||
|
|
@ -120,13 +112,12 @@ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buf
|
|||
|
||||
uint32_t count = 0;
|
||||
|
||||
while ( count < bufsize )
|
||||
{
|
||||
while (count < bufsize) {
|
||||
uf2_read_block(lba, buffer);
|
||||
|
||||
lba++;
|
||||
buffer += 512;
|
||||
count += 512;
|
||||
count += 512;
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
@ -134,43 +125,36 @@ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buf
|
|||
|
||||
// Callback invoked when received WRITE10 command.
|
||||
// Process data in buffer to disk's storage and return number of written bytes
|
||||
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
|
||||
{
|
||||
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
|
||||
(void) lun;
|
||||
(void) offset;
|
||||
|
||||
uint32_t count = 0;
|
||||
while ( count < bufsize )
|
||||
{
|
||||
while (count < bufsize) {
|
||||
// Consider non-uf2 block write as successful
|
||||
// only break if write_block is busy with flashing (return 0)
|
||||
if ( 0 == uf2_write_block(lba, buffer, &_wr_state) ) break;
|
||||
if (0 == uf2_write_block(lba, buffer, &_wr_state)) break;
|
||||
|
||||
lba++;
|
||||
buffer += 512;
|
||||
count += 512;
|
||||
count += 512;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
|
||||
void tud_msc_write10_complete_cb(uint8_t lun)
|
||||
{
|
||||
void tud_msc_write10_complete_cb(uint8_t lun) {
|
||||
(void) lun;
|
||||
static bool first_write = true;
|
||||
|
||||
// abort the DFU, uf2 block failed integrity check
|
||||
if ( _wr_state.aborted )
|
||||
{
|
||||
if (_wr_state.aborted) {
|
||||
// aborted and reset
|
||||
indicator_set(STATE_WRITING_FINISHED);
|
||||
}
|
||||
else if ( _wr_state.numBlocks )
|
||||
{
|
||||
} else if (_wr_state.numBlocks) {
|
||||
// Start LED writing pattern with first write
|
||||
if (first_write)
|
||||
{
|
||||
if (first_write) {
|
||||
#if DEBUG_SPEED_TEST
|
||||
_write_ms = esp_log_timestamp();
|
||||
#endif
|
||||
|
|
@ -180,8 +164,7 @@ void tud_msc_write10_complete_cb(uint8_t lun)
|
|||
}
|
||||
|
||||
// All block of uf2 file is complete --> complete DFU process
|
||||
if (_wr_state.numWritten >= _wr_state.numBlocks)
|
||||
{
|
||||
if (_wr_state.numWritten >= _wr_state.numBlocks) {
|
||||
#if DEBUG_SPEED_TEST
|
||||
uint32_t const wr_byte = _wr_state.numWritten*256;
|
||||
_write_ms = esp_log_timestamp()-_write_ms;
|
||||
|
|
@ -189,41 +172,37 @@ void tud_msc_write10_complete_cb(uint8_t lun)
|
|||
printf("Speed : %.02f KB/s\r\n", (wr_byte / 1000.0F) / (_write_ms / 1000.0F));
|
||||
#endif
|
||||
|
||||
TUF2_LOG1("Writing finished\r\n");
|
||||
indicator_set(STATE_WRITING_FINISHED);
|
||||
board_dfu_complete();
|
||||
|
||||
// board_dfu_complete() should not return
|
||||
// getting here is an indicator of error
|
||||
while(1) {}
|
||||
while (1) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||
// Application update block count and block size
|
||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
||||
{
|
||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
|
||||
(void) lun;
|
||||
|
||||
*block_count = CFG_UF2_NUM_BLOCKS;
|
||||
*block_size = 512;
|
||||
*block_size = 512;
|
||||
}
|
||||
|
||||
// Invoked when received Start Stop Unit command
|
||||
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
|
||||
{
|
||||
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
|
||||
(void) lun;
|
||||
(void) power_condition;
|
||||
|
||||
if ( load_eject )
|
||||
{
|
||||
if (start)
|
||||
{
|
||||
if (load_eject) {
|
||||
if (start) {
|
||||
// load disk storage
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
// unload disk storage
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ uint8_t const* tud_descriptor_device_cb(void) {
|
|||
#define EPNUM_CDC_IN 0x83
|
||||
#endif
|
||||
|
||||
uint8_t const desc_configuration[] = {
|
||||
uint8_t TINYUF2_CONST desc_configuration[] = {
|
||||
// Config number, interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
#if CFG_TUD_CDC
|
||||
|
|
@ -152,7 +152,6 @@ static uint16_t _desc_str[48 + 1];
|
|||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
(void) langid;
|
||||
|
||||
uint8_t chr_count;
|
||||
|
||||
switch (index) {
|
||||
|
|
@ -161,12 +160,10 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
|||
chr_count = 1;
|
||||
break;
|
||||
|
||||
// TODO light alternation such as +1 to prevent conflict with application
|
||||
// TODO light alternation such as +1 to prevent conflict with application
|
||||
case STRID_SERIAL: {
|
||||
uint8_t serial_id[16] TU_ATTR_ALIGNED(4);
|
||||
uint8_t serial_len;
|
||||
|
||||
serial_len = board_usb_get_serial(serial_id);
|
||||
uint8_t serial_len = board_usb_get_serial(serial_id);
|
||||
chr_count = 2 * serial_len;
|
||||
|
||||
for (uint8_t i = 0; i < serial_len; i++) {
|
||||
|
|
@ -174,7 +171,6 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
|||
const char nibble_to_hex[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
uint8_t nibble = (serial_id[i] >> (j * 4)) & 0xf;
|
||||
_desc_str[1 + i * 2 + (1 - j)] = nibble_to_hex[nibble]; // UTF-16-LE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ deps_optional = {
|
|||
'lib/mcu/st/stm32l4xx_hal_driver': ['https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git',
|
||||
'aee3d5bf283ae5df87532b781bdd01b7caf256fc',
|
||||
'stm32l4'],
|
||||
# 'lib/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git',
|
||||
# 'c4c38f507e258a4e69b059ccc2dc27dde33cea1b',
|
||||
# 'ch32v20x'],
|
||||
'lib/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git',
|
||||
'c4c38f507e258a4e69b059ccc2dc27dde33cea1b',
|
||||
'ch32v20x'],
|
||||
'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git',
|
||||
'497ca8974927e3b853fd80c8fc35f4e557af79b9',
|
||||
'lpc55'],
|
||||
|
|
|
|||
Loading…
Reference in a new issue